@alcyone-labs/arg-parser 2.12.3 → 2.13.0

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 };
@@ -4430,7 +4433,11 @@ class ArgParserBase {
4430
4433
  const autoDiscoveredEnvFile = this.#configurationManager.discoverEnvFile(basePath);
4431
4434
  if (autoDiscoveredEnvFile) {
4432
4435
  console.warn(`Auto-discovered env file: ${autoDiscoveredEnvFile}`);
4433
- dotenv.config({ path: autoDiscoveredEnvFile, quiet: true, override: true });
4436
+ dotenv.config({
4437
+ path: autoDiscoveredEnvFile,
4438
+ quiet: true,
4439
+ override: true
4440
+ });
4434
4441
  try {
4435
4442
  const { finalParser: envFinalParser, parserChain: envParserChain } = this.#_identifyCommandChainAndParsers(
4436
4443
  processArgs,
@@ -5175,6 +5182,31 @@ class ArgParserBase {
5175
5182
  }
5176
5183
  }
5177
5184
  }
5185
+ const trailingArgs = [];
5186
+ for (let i = 0; i < args.length; i++) {
5187
+ if (!consumedIndices.has(i)) {
5188
+ const arg = args[i];
5189
+ if (!arg.startsWith("-")) {
5190
+ trailingArgs.push({ index: i, value: arg });
5191
+ }
5192
+ }
5193
+ }
5194
+ const positionalFlags = flags.filter(
5195
+ (f) => typeof f["positional"] === "number" && f["positional"] > 0
5196
+ ).sort(
5197
+ (a, b) => a["positional"] - b["positional"]
5198
+ );
5199
+ for (const posFlag of positionalFlags) {
5200
+ const posIndex = posFlag["positional"] - 1;
5201
+ const existingValue = output[posFlag["name"]];
5202
+ const hasExistingValue = posFlag["allowMultiple"] ? Array.isArray(existingValue) && existingValue.length > 0 : existingValue !== void 0;
5203
+ if (hasExistingValue) continue;
5204
+ if (posIndex < trailingArgs.length) {
5205
+ const trailing = trailingArgs[posIndex];
5206
+ await this._addToOutput(posFlag, trailing.value, output, options);
5207
+ consumedIndices.add(trailing.index);
5208
+ }
5209
+ }
5178
5210
  let firstUnconsumedIndex = args.length;
5179
5211
  for (let i = 0; i < args.length; i++) {
5180
5212
  if (!consumedIndices.has(i)) {
@@ -5208,6 +5240,22 @@ class ArgParserBase {
5208
5240
  `;
5209
5241
  }
5210
5242
  const indent = (level = 1) => " ".repeat(level);
5243
+ const positionalFlagsForUsage = this.#flagManager.flags.filter(
5244
+ (f) => typeof f["positional"] === "number" && f["positional"] > 0
5245
+ ).sort(
5246
+ (a, b) => a["positional"] - b["positional"]
5247
+ );
5248
+ if (positionalFlagsForUsage.length > 0) {
5249
+ const commandName = this.#subCommandName || this.#appCommandName || this.#appName;
5250
+ const posArgs = positionalFlagsForUsage.map((f) => {
5251
+ const isMandatory = typeof f["mandatory"] === "function" ? true : f["mandatory"];
5252
+ const argName = f["valueHint"] || f["name"].toUpperCase();
5253
+ return isMandatory ? `<${argName}>` : `[${argName}]`;
5254
+ }).join(" ");
5255
+ help += `${cyan("Usage:")} ${commandName} [OPTIONS] ${posArgs}
5256
+
5257
+ `;
5258
+ }
5211
5259
  if (this.#subCommands.size > 0) {
5212
5260
  help += `${cyan("Available sub-commands:")}
5213
5261
  `;
@@ -5344,6 +5392,9 @@ ${cyan("Flags:")}
5344
5392
  `Allowed values: ${flag["enum"].map((v) => `'${v}'`).join(", ")}`
5345
5393
  );
5346
5394
  }
5395
+ if (typeof flag["positional"] === "number" && flag["positional"] > 0) {
5396
+ metaLines.push(`Positional argument #${flag["positional"]}`);
5397
+ }
5347
5398
  const maxOptionLength = Math.max(
5348
5399
  ...localFlags.map(
5349
5400
  (f) => f["options"].join(", ").length