Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions configs/tsconfig-mongosh/tsconfig.common.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"removeComments": true,
"target": "es2018",
"lib": ["es2019"],
"module": "commonjs",
"moduleResolution": "node"
"module": "nodenext",
"moduleResolution": "nodenext"
}
}
123 changes: 99 additions & 24 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions packages/arg-parser/.depcheckrc
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,7 @@ ignores:
- eslint-config-mongodb-js
# needed as a peer dependency of @mongodb-js/devtools-connect
- mongodb
# only used in arg-parser export; should be removed once switched to knip
- yargs-parser
ignore-patterns:
- .eslintrc.js
21 changes: 19 additions & 2 deletions packages/arg-parser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@
"version": "3.22.2",
"description": "MongoDB Shell CLI Argument List Parser Package",
"main": "./lib/index.js",
"types": "./lib/index.d.ts",
"exports": {
".": {
"default": "./lib/index.js",
"types": "./lib/index.d.ts"
},
"./arg-parser": {
"default": "./lib/arg-parser.js",
"types": "./lib/arg-parser.d.ts"
}
},
"repository": {
"type": "git",
"url": "git://github.com/mongodb-js/mongosh.git"
Expand Down Expand Up @@ -37,16 +48,22 @@
"dependencies": {
"@mongosh/errors": "2.4.4",
"@mongosh/i18n": "^2.19.0",
"mongodb-connection-string-url": "^3.0.2"
"mongodb-connection-string-url": "^3.0.2",
"yargs-parser": "^20.2.4"
},
"peerDependencies": {
"zod": "^3.25.76"
},
"devDependencies": {
"@mongodb-js/devtools-connect": "^3.9.4",
"@mongodb-js/eslint-config-mongosh": "^1.0.0",
"@mongodb-js/prettier-config-devtools": "^1.0.1",
"@mongodb-js/tsconfig-mongosh": "^1.0.0",
"@types/yargs-parser": "^21.0.3",
"depcheck": "^1.4.7",
"eslint": "^7.25.0",
"mongodb": "^6.19.0",
"prettier": "^2.8.8"
"prettier": "^2.8.8",
"strip-ansi": "^7.1.2"
}
}
84 changes: 84 additions & 0 deletions packages/arg-parser/src/arg-metadata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import z from 'zod/v4';

/**
* Registry for argument options metadata
*/
export const argMetadata = z.registry<ArgumentMetadata>();

/**
* Metadata that can be used to define field's parsing behavior
*/
export type ArgumentMetadata = {
/** If set, sets this field as deprecated and replaces this field with the set field. */
deprecationReplacement?: string;
/** If set, gets replaced with a differet field name (without deprecation) */
replacement?: string;
/** Whether this argument is unsupported. Always throws an error if set to true. */
unsupported?: boolean;
/** Aliases for this argument. */
alias?: string[];
};

/**
* Extract metadata for a field using the custom registry
*/
export function getArgumentMetadata(
schema: z.ZodObject,
fieldName: string
): ArgumentMetadata | undefined {
const fieldSchema = schema.shape[fieldName as keyof typeof schema.shape];
if (!fieldSchema) {
return undefined;
}
return argMetadata.get(fieldSchema);
}

/**
* Maps deprecated arguments to their new counterparts, derived from schema metadata.
*/
export function getDeprecatedArgsWithReplacement<T>(
schema: z.ZodObject
): Record<keyof z.infer<typeof schema>, T> {
const deprecated: Record<string, T> = {};
for (const fieldName of Object.keys(schema.shape)) {
const meta = getArgumentMetadata(schema, fieldName);
if (meta?.deprecationReplacement) {
deprecated[fieldName] = meta.deprecationReplacement as T;
}
}
return deprecated;
}

/**
* Get list of unsupported arguments, derived from schema metadata.
*/
export function getUnsupportedArgs(schema: z.ZodObject): string[] {
const unsupported: string[] = [];
for (const fieldName of Object.keys(schema.shape)) {
const meta = getArgumentMetadata(schema, fieldName);
if (meta?.unsupported) {
unsupported.push(fieldName);
}
}
return unsupported;
}

export class UnknownCliArgumentError extends Error {
/** The argument that was not parsed. */
readonly argument: string;
constructor(argument: string) {
super(`Unknown argument: ${argument}`);
this.name = 'UnknownCliArgumentError';
this.argument = argument;
}
}

export class UnsupportedCliArgumentError extends Error {
/** The argument that was not supported. */
readonly argument: string;
constructor(argument: string) {
super(`Unsupported argument: ${argument}`);
this.name = 'UnsupportedCliArgumentError';
this.argument = argument;
}
}
Loading