Files
scriptc/tests/corpus/node24-parseargs.js
Chris Tate c76ac2b95f Expand Node 24 dynamic argument parsing compatibility (#632)
* Expand Node 24 dynamic argument parsing compatibility

* Match Node argument error string truncation and quoting
2026-10-03 09:29:06 -05:00

75 lines
3.7 KiB
JavaScript

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();