import { parseArgs } from "node:util"; /** @param {any} config */ function show(config) { try { const result = parseArgs(config); console.log(JSON.stringify(result)); console.log("null-prototype", Object.getPrototypeOf(result.values) === null); } catch (error) { console.log(error.name, error.code, error.message); } } function report() { const options = { alpha: { type: "boolean", short: "a" }, beta: { type: "boolean", short: "b" }, name: { type: "string", short: "n" }, flag: { type: "boolean", short: "f", multiple: true }, }; const argsCases = [ [], ["-abnhello", "--name=last"], ["-abn", "hello", "tail"], ["--name", "-dash"], ["-n", "--flag"], ["--name=-dash"], ["-n-dash"], ["--name"], ["-n"], ["--flag=yes"], ["--unknown"], ["--unknown=value"], ["--", "--unknown"], ["-"], ["--flag", "--no-flag", "--flag"], ["--no-unknown"], ["--=odd"], ["--__proto__=x", "--constructor=y"], ]; for (const args of argsCases) { for (const strict of [true, false]) { for (const allowPositionals of [true, false]) { show({ args, options, strict, allowPositionals, allowNegative: true, tokens: true }); } } } for (const options of [ { "no-x": { type: "boolean" }, x: { type: "boolean", multiple: true } }, { x: { type: "boolean", multiple: true, default: [true] } }, { x: { type: "string", default: "default" } }, { "__proto__": null, constructor: { type: "boolean", default: true } }, ]) show({ args: ["--no-x"], options, allowNegative: true, strict: false, tokens: true }); for (const config of [ null, { args: [], strict: "has'quote" }, { args: [], strict: "line\nend" }, { args: [], strict: "x".repeat(28) }, { args: [], strict: "x".repeat(29) }, { args: [], options: { x: { type: "invalid".repeat(8) } } }, { args: "bad", strict: 1 }, { args: [], strict: 1 }, { args: [], allowPositionals: 1 }, { args: [], tokens: "yes" }, { args: [], allowNegative: 0 }, { args: [], options: [] }, { args: [], options: { x: null } }, { args: [], options: { x: {} } }, { args: [], options: { x: { type: "number" } } }, { args: [], options: { x: { type: "string", short: "ab" } } }, { args: [], options: { x: { type: "string", short: undefined } } }, { args: [], options: { x: { type: "boolean", multiple: null } } }, { args: [], options: { x: { type: "string", default: 2 } } }, { args: [], options: { x: { type: "boolean", multiple: true, default: [true, 2] } } }, { args: [], options: { x: { type: "string", multiple: true, default: "bad" } } }, { args: ["--unknown", null] }, { args: ["--", null], strict: false }, { args: ["--name", null], options }, { args: [1, false, {}], strict: false }, { args: [], strict: null, tokens: null, allowNegative: null, options: null }, ]) show(config); show(Object.assign(Object.create({ strict: false, options: { inherited: { type: "boolean" } } }), { args: ["--inherited"] })); show({ args: ["--inherited"], options: Object.create({ inherited: { type: "boolean" } }) }); show({ args: [], options: { x: Object.create({ type: "boolean" }) } }); show({ args: [], options: { x: Object.assign(Object.create({ multiple: true, default: ["ignored"] }), { type: "string" }) } }); const protoOptions = Object.create(null); protoOptions.__proto__ = { type: "string", default: "ignored" }; show({ args: ["--__proto__=ignored"], options: protoOptions, tokens: true }); const defaults = ["initial"]; const result = parseArgs({ args: [], options: { name: { type: "string", multiple: true, default: defaults } } }); console.log("default-identity", result.values.name === defaults); defaults.push("updated"); console.log("default-live", JSON.stringify(result)); } report();