Skip to content

Commit 442d4a5

Browse files
committed
feat(mongodb-runner): add mongodb-runner ls --json
Provide JSON-formatted output that contains serialized cluster data.
1 parent 63b1749 commit 442d4a5

5 files changed

Lines changed: 54 additions & 9 deletions

File tree

packages/mongodb-runner/src/cli.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ import type { MongoClientOptions } from 'mongodb';
7979
})
8080
.option('debug', { type: 'boolean', describe: 'Enable debug output' })
8181
.option('verbose', { type: 'boolean', describe: 'Enable verbose output' })
82+
.option('json', {
83+
type: 'boolean',
84+
describe: 'Output machine-readable JSON ("ls" only)',
85+
})
8286
.command('start', 'Start a MongoDB instance')
8387
.command('stop', 'Stop a MongoDB instance')
8488
.command('prune', 'Clean up metadata for any dead MongoDB instances')
@@ -149,8 +153,18 @@ import type { MongoClientOptions } from 'mongodb';
149153
}
150154

151155
async function ls() {
152-
for await (const { id, connectionString } of utilities.instances(argv)) {
153-
console.log(`${id}: ${connectionString}`);
156+
if (argv.json) {
157+
let first = true;
158+
for await (const { serialized, ...rest } of utilities.instances(argv)) {
159+
console.log(first ? '[' : ',');
160+
first = false;
161+
console.log(JSON.stringify({ ...rest, ...serialized }, null, 2));
162+
}
163+
console.log(']');
164+
} else {
165+
for await (const { id, connectionString } of utilities.instances(argv)) {
166+
console.log(`${id}: ${connectionString}`);
167+
}
154168
}
155169
}
156170

packages/mongodb-runner/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export {
22
MongoServer,
33
type MongoServerEvents,
44
MongoServerOptions,
5+
SerializedServerProperties as MongoServerSerializedProperties,
56
} from './mongoserver';
67
export {
78
MongoCluster,
@@ -12,6 +13,7 @@ export {
1213
RSOptions as MongoClusterRSOptions,
1314
CommonOptions as MongoClusterCommonOptions,
1415
ShardedOptions as MongoClusterShardedOptions,
16+
SerializedClusterProperties as MongoClusterSerializedProperties,
1517
} from './mongocluster';
1618
export type { LogEntry } from './mongologreader';
1719
export type { ConnectionString } from 'mongodb-connection-string-url';

packages/mongodb-runner/src/mongocluster.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import type { MongoServerEvents, MongoServerOptions } from './mongoserver';
1+
import type {
2+
MongoServerEvents,
3+
MongoServerOptions,
4+
SerializedServerProperties,
5+
} from './mongoserver';
26
import { MongoServer } from './mongoserver';
37
import { ConnectionString } from 'mongodb-connection-string-url';
48
import type { DownloadOptions } from '@mongodb-js/mongodb-downloader';
@@ -162,6 +166,17 @@ export type MongoClusterEvents = {
162166
removeListener: [keyof MongoClusterEvents];
163167
};
164168

169+
export interface SerializedClusterProperties {
170+
topology: MongoClusterOptions['topology'];
171+
replSetName?: string;
172+
servers: SerializedServerProperties[];
173+
shards: SerializedClusterProperties[];
174+
oidcMockProviderProcess?: ReturnType<OIDCMockProviderProcess['serialize']>;
175+
defaultConnectionOptions: Partial<MongoClientOptions>;
176+
users: MongoDBUserDoc[];
177+
options?: MongoClusterOptions;
178+
}
179+
165180
function removePortArg([...args]: string[]): string[] {
166181
let portArgIndex = -1;
167182
if ((portArgIndex = args.indexOf('--port')) !== -1) {
@@ -278,6 +293,7 @@ export class MongoCluster extends EventEmitter<MongoClusterEvents> {
278293
private oidcMockProviderProcess?: OIDCMockProviderProcess;
279294
private defaultConnectionOptions: Partial<MongoClientOptions> = {};
280295
private users: MongoDBUserDoc[] = [];
296+
private originalOptions?: MongoClusterOptions;
281297

282298
private constructor() {
283299
super();
@@ -309,7 +325,7 @@ export class MongoCluster extends EventEmitter<MongoClusterEvents> {
309325
});
310326
}
311327

312-
serialize(): unknown /* JSON-serializable */ {
328+
serialize(): SerializedClusterProperties {
313329
return {
314330
topology: this.topology,
315331
replSetName: this.replSetName,
@@ -318,6 +334,7 @@ export class MongoCluster extends EventEmitter<MongoClusterEvents> {
318334
oidcMockProviderProcess: this.oidcMockProviderProcess?.serialize(),
319335
defaultConnectionOptions: jsonClone(this.defaultConnectionOptions ?? {}),
320336
users: jsonClone(this.users),
337+
options: jsonClone(this.originalOptions),
321338
};
322339
}
323340

@@ -328,7 +345,9 @@ export class MongoCluster extends EventEmitter<MongoClusterEvents> {
328345
return true;
329346
}
330347

331-
static async deserialize(serialized: any): Promise<MongoCluster> {
348+
static async deserialize(
349+
serialized: SerializedClusterProperties,
350+
): Promise<MongoCluster> {
332351
const cluster = new MongoCluster();
333352
cluster.topology = serialized.topology;
334353
cluster.replSetName = serialized.replSetName;
@@ -343,6 +362,7 @@ export class MongoCluster extends EventEmitter<MongoClusterEvents> {
343362
cluster.oidcMockProviderProcess = serialized.oidcMockProviderProcess
344363
? OIDCMockProviderProcess.deserialize(serialized.oidcMockProviderProcess)
345364
: undefined;
365+
cluster.originalOptions = serialized.options;
346366
return cluster;
347367
}
348368

@@ -380,6 +400,7 @@ export class MongoCluster extends EventEmitter<MongoClusterEvents> {
380400
options = { ...options, ...(await handleTLSClientKeyOptions(options)) };
381401

382402
const cluster = new MongoCluster();
403+
cluster.originalOptions = options;
383404
cluster.topology = options.topology;
384405
cluster.users = options.users ?? [];
385406
cluster.defaultConnectionOptions = { ...options.internalClientOptions };

packages/mongodb-runner/src/mongoserver.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export interface MongoServerOptions {
5353
keyFileContents?: string;
5454
}
5555

56-
interface SerializedServerProperties {
56+
export interface SerializedServerProperties {
5757
_id: string;
5858
pid?: number;
5959
port?: number;
@@ -66,6 +66,7 @@ interface SerializedServerProperties {
6666
isMongos?: boolean;
6767
isConfigSvr?: boolean;
6868
keyFileContents?: string;
69+
commandline?: string[];
6970
}
7071

7172
export interface MongoServerEvents {
@@ -98,6 +99,7 @@ export class MongoServer extends EventEmitter<MongoServerEvents> {
9899
private isConfigSvr = false;
99100
private keyFileContents?: string;
100101
private defaultConnectionOptions?: Partial<MongoClientOptions>;
102+
private commandline: string[] = [];
101103

102104
get id(): string {
103105
return this.uuid;
@@ -122,6 +124,7 @@ export class MongoServer extends EventEmitter<MongoServerEvents> {
122124
isMongos: this.isMongos,
123125
isConfigSvr: this.isConfigSvr,
124126
keyFileContents: this.keyFileContents,
127+
commandline: this.commandline,
125128
};
126129
}
127130

@@ -140,6 +143,7 @@ export class MongoServer extends EventEmitter<MongoServerEvents> {
140143
srv.isMongos = !!serialized.isMongos;
141144
srv.isConfigSvr = !!serialized.isConfigSvr;
142145
srv.keyFileContents = serialized.keyFileContents;
146+
srv.commandline = serialized.commandline ?? [];
143147
if (!srv.closing) {
144148
srv.pid = serialized.pid;
145149
srv.dbPath = serialized.dbPath;
@@ -261,6 +265,7 @@ export class MongoServer extends EventEmitter<MongoServerEvents> {
261265

262266
debug('starting server', commandline);
263267
const [executable, ...args] = commandline;
268+
srv.commandline = commandline;
264269
const proc = spawn(executable, args, {
265270
stdio: ['inherit', 'pipe', 'pipe'],
266271
cwd: options.tmpDir,

packages/mongodb-runner/src/runner-helpers.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { BSON } from 'mongodb';
22
import path from 'path';
3-
import type { MongoClusterOptions } from './mongocluster';
3+
import type {
4+
MongoClusterOptions,
5+
SerializedClusterProperties,
6+
} from './mongocluster';
47
import { MongoCluster } from './mongocluster';
58
import { parallelForEach } from './util';
69
import * as fs from 'fs/promises';
@@ -10,7 +13,7 @@ import { once } from 'events';
1013
interface StoredInstance {
1114
id: string;
1215
filepath: string;
13-
serialized: string;
16+
serialized: SerializedClusterProperties;
1417
connectionString: string;
1518
}
1619

@@ -31,7 +34,7 @@ export async function start(
3134
...argv,
3235
args,
3336
});
34-
const serialized = await cluster.serialize();
37+
const serialized = cluster.serialize();
3538
const { connectionString } = cluster;
3639

3740
await fs.writeFile(

0 commit comments

Comments
 (0)