@alcyone-labs/arg-parser 2.12.3 → 2.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1588,6 +1588,9 @@ const zodFlagSchema = z.object({
1588
1588
  ),
1589
1589
  setWorkingDirectory: z.boolean().optional().describe(
1590
1590
  "If true, this flag's value becomes the effective working directory for file operations."
1591
+ ),
1592
+ positional: z.number().int().positive("Positional index must be a positive integer (1, 2, 3...)").optional().describe(
1593
+ "If set, this flag captures the Nth trailing positional argument (1-indexed). Multiple flags can have different positional values to capture multiple trailing args in order."
1591
1594
  )
1592
1595
  }).transform((obj) => {
1593
1596
  const newObj = { ...obj };
@@ -4062,6 +4065,9 @@ class ArgParserBase {
4062
4065
  if (!subParser.#appCommandName && this.#appCommandName) {
4063
4066
  subParser.#appCommandName = this.#appCommandName;
4064
4067
  }
4068
+ if (subCommandConfig.description) {
4069
+ subParser.#description = subCommandConfig.description;
4070
+ }
4065
4071
  subParser.#autoExit = this.#autoExit;
4066
4072
  subParser.#triggerAutoHelpIfNoHandler = this.#triggerAutoHelpIfNoHandler;
4067
4073
  const shouldInherit = subParser.#inheritParentFlags === true || subParser.#inheritParentFlags === FlagInheritance.DirectParentOnly || subParser.#inheritParentFlags === FlagInheritance.AllParents;
@@ -4430,7 +4436,11 @@ class ArgParserBase {
4430
4436
  const autoDiscoveredEnvFile = this.#configurationManager.discoverEnvFile(basePath);
4431
4437
  if (autoDiscoveredEnvFile) {
4432
4438
  console.warn(`Auto-discovered env file: ${autoDiscoveredEnvFile}`);
4433
- dotenv.config({ path: autoDiscoveredEnvFile, quiet: true, override: true });
4439
+ dotenv.config({
4440
+ path: autoDiscoveredEnvFile,
4441
+ quiet: true,
4442
+ override: true
4443
+ });
4434
4444
  try {
4435
4445
  const { finalParser: envFinalParser, parserChain: envParserChain } = this.#_identifyCommandChainAndParsers(
4436
4446
  processArgs,
@@ -5175,6 +5185,31 @@ class ArgParserBase {
5175
5185
  }
5176
5186
  }
5177
5187
  }
5188
+ const trailingArgs = [];
5189
+ for (let i = 0; i < args.length; i++) {
5190
+ if (!consumedIndices.has(i)) {
5191
+ const arg = args[i];
5192
+ if (!arg.startsWith("-")) {
5193
+ trailingArgs.push({ index: i, value: arg });
5194
+ }
5195
+ }
5196
+ }
5197
+ const positionalFlags = flags.filter(
5198
+ (f) => typeof f["positional"] === "number" && f["positional"] > 0
5199
+ ).sort(
5200
+ (a, b) => a["positional"] - b["positional"]
5201
+ );
5202
+ for (const posFlag of positionalFlags) {
5203
+ const posIndex = posFlag["positional"] - 1;
5204
+ const existingValue = output[posFlag["name"]];
5205
+ const hasExistingValue = posFlag["allowMultiple"] ? Array.isArray(existingValue) && existingValue.length > 0 : existingValue !== void 0;
5206
+ if (hasExistingValue) continue;
5207
+ if (posIndex < trailingArgs.length) {
5208
+ const trailing = trailingArgs[posIndex];
5209
+ await this._addToOutput(posFlag, trailing.value, output, options);
5210
+ consumedIndices.add(trailing.index);
5211
+ }
5212
+ }
5178
5213
  let firstUnconsumedIndex = args.length;
5179
5214
  for (let i = 0; i < args.length; i++) {
5180
5215
  if (!consumedIndices.has(i)) {
@@ -5208,6 +5243,22 @@ class ArgParserBase {
5208
5243
  `;
5209
5244
  }
5210
5245
  const indent = (level = 1) => " ".repeat(level);
5246
+ const positionalFlagsForUsage = this.#flagManager.flags.filter(
5247
+ (f) => typeof f["positional"] === "number" && f["positional"] > 0
5248
+ ).sort(
5249
+ (a, b) => a["positional"] - b["positional"]
5250
+ );
5251
+ if (positionalFlagsForUsage.length > 0) {
5252
+ const commandName = this.#subCommandName || this.#appCommandName || this.#appName;
5253
+ const posArgs = positionalFlagsForUsage.map((f) => {
5254
+ const isMandatory = typeof f["mandatory"] === "function" ? true : f["mandatory"];
5255
+ const argName = f["valueHint"] || f["name"].toUpperCase();
5256
+ return isMandatory ? `<${argName}>` : `[${argName}]`;
5257
+ }).join(" ");
5258
+ help += `${cyan("Usage:")} ${commandName} [OPTIONS] ${posArgs}
5259
+
5260
+ `;
5261
+ }
5211
5262
  if (this.#subCommands.size > 0) {
5212
5263
  help += `${cyan("Available sub-commands:")}
5213
5264
  `;
@@ -5344,6 +5395,9 @@ ${cyan("Flags:")}
5344
5395
  `Allowed values: ${flag["enum"].map((v) => `'${v}'`).join(", ")}`
5345
5396
  );
5346
5397
  }
5398
+ if (typeof flag["positional"] === "number" && flag["positional"] > 0) {
5399
+ metaLines.push(`Positional argument #${flag["positional"]}`);
5400
+ }
5347
5401
  const maxOptionLength = Math.max(
5348
5402
  ...localFlags.map(
5349
5403
  (f) => f["options"].join(", ").length