@gunshi/bone 0.33.0 → 0.34.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/lib/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- //#region ../../node_modules/.pnpm/args-tokens@0.25.0/node_modules/args-tokens/lib/parser-D95CJBHr.d.ts
1
+ //#region ../../node_modules/.pnpm/args-tokens@0.26.1/node_modules/args-tokens/lib/parser-DT7Ztcch.d.ts
2
2
  //#region src/parser.d.ts
3
3
  /**
4
4
  * Entry point of argument parser.
@@ -55,7 +55,7 @@ interface ArgToken {
55
55
  * Parser Options.
56
56
  */
57
57
  //#endregion
58
- //#region ../../node_modules/.pnpm/args-tokens@0.25.0/node_modules/args-tokens/lib/resolver.d.ts
58
+ //#region ../../node_modules/.pnpm/args-tokens@0.26.1/node_modules/args-tokens/lib/resolver.d.ts
59
59
  //#region src/resolver.d.ts
60
60
  /**
61
61
  * An argument schema definition for command-line argument parsing.
@@ -172,7 +172,10 @@ interface ArgSchema {
172
172
  * When `true`, the argument must be provided by the user.
173
173
  * If missing, an `ArgResolveError` with type 'required' will be thrown.
174
174
  *
175
- * Note: Only `true` is allowed (not `false`) to make intent explicit.
175
+ * For single-value positional arguments, omitting `required` keeps the argument
176
+ * required for compatibility. Set `required: false` to make a positional argument
177
+ * optional. Optional positional arguments leave enough input values for later
178
+ * required positional arguments before consuming a value.
176
179
  *
177
180
  * @example
178
181
  * Required arguments:
@@ -196,7 +199,8 @@ interface ArgSchema {
196
199
  *
197
200
  * When `true`, the resolved value becomes an array.
198
201
  * For options: can be specified multiple times (--tag foo --tag bar)
199
- * For positional: collects remaining positional arguments
202
+ * For positional: collects remaining positional arguments after preserving values for
203
+ * later required positional arguments.
200
204
  *
201
205
  * Note: Only `true` is allowed (not `false`) to make intent explicit.
202
206
  *
@@ -276,7 +280,11 @@ interface ArgSchema {
276
280
  * - `boolean` type: boolean default
277
281
  * - `number` type: number default
278
282
  * - `enum` type: must be one of the `choices` values
279
- * - `positional`/`custom` type: any appropriate default
283
+ * - `positional`/`custom` type: string, boolean, or number default
284
+ *
285
+ * For single-value positional arguments, the default is used when the positional
286
+ * value is missing or when the value is preserved for later required positional
287
+ * arguments, unless `required: true` is set.
280
288
  *
281
289
  * @example
282
290
  * Default values by type:
@@ -533,7 +541,8 @@ type FilterArgs<A extends Args, V extends Record<keyof A, unknown>, K extends ke
533
541
  *
534
542
  * @internal
535
543
  */
536
- type FilterPositionalArgs<A extends Args, V extends Record<keyof A, unknown>> = { [Arg in keyof A as A[Arg]['type'] extends 'positional' ? Arg : never]: V[Arg] };
544
+ type FilterPositionalArgs<A extends Args, V extends Record<keyof A, unknown>> = { [Arg in keyof A as IsRequiredPositionalArg<A[Arg]> extends true ? Arg : never]: V[Arg] };
545
+ type IsRequiredPositionalArg<A extends ArgSchema> = A['type'] extends 'positional' ? A['multiple'] extends true ? A['required'] extends true ? true : false : A['required'] extends false ? A['default'] extends {} ? true : false : true : false;
537
546
  /**
538
547
  * An arguments for {@link resolveArgs | resolve arguments}.
539
548
  */
package/lib/index.js CHANGED
@@ -1,4 +1,4 @@
1
- //#region ../../node_modules/.pnpm/args-tokens@0.25.0/node_modules/args-tokens/lib/parser.js
1
+ //#region ../../node_modules/.pnpm/args-tokens@0.26.1/node_modules/args-tokens/lib/parser.js
2
2
  /**
3
3
  * forked from `nodejs/node` (`pkgjs/parseargs`)
4
4
  * repository url: https://github.com/nodejs/node (https://github.com/pkgjs/parseargs)
@@ -203,7 +203,7 @@ function hasOptionValue(value) {
203
203
  return !(value == null) && value.codePointAt(0) !== HYPHEN_CODE;
204
204
  }
205
205
  //#endregion
206
- //#region ../../node_modules/.pnpm/args-tokens@0.25.0/node_modules/args-tokens/lib/utils.js
206
+ //#region ../../node_modules/.pnpm/args-tokens@0.26.1/node_modules/args-tokens/lib/utils.js
207
207
  /**
208
208
  * Entry point of utils.
209
209
  *
@@ -225,7 +225,7 @@ function kebabnize(str) {
225
225
  return str.replace(/[A-Z]/g, (match, offset) => (offset > 0 ? "-" : "") + match.toLowerCase());
226
226
  }
227
227
  //#endregion
228
- //#region ../../node_modules/.pnpm/args-tokens@0.25.0/node_modules/args-tokens/lib/resolver.js
228
+ //#region ../../node_modules/.pnpm/args-tokens@0.26.1/node_modules/args-tokens/lib/resolver.js
229
229
  /**
230
230
  * Entry point of argument options resolver.
231
231
  *
@@ -368,6 +368,8 @@ function resolveArgs(args, tokens, { shortGrouping = false, skipPositional = SKI
368
368
  const errors = [];
369
369
  const explicit = Object.create(null);
370
370
  const actualInputNames = /* @__PURE__ */ new Map();
371
+ const argEntries = Object.entries(args);
372
+ let requiredPositionalsAfter;
371
373
  function checkTokenName(option, schema, token) {
372
374
  return token.name === (schema.type === "boolean" ? schema.negatable && token.name?.startsWith("no-") ? `no-${option}` : option : option);
373
375
  }
@@ -375,14 +377,21 @@ function resolveArgs(args, tokens, { shortGrouping = false, skipPositional = SKI
375
377
  function getPositionalSkipIndex() {
376
378
  return Math.min(skipPositionalIndex, positionalItemCount);
377
379
  }
380
+ function getRequiredPositionalsAfter(rawArg) {
381
+ requiredPositionalsAfter ??= createRequiredPositionalsAfter(argEntries);
382
+ return requiredPositionalsAfter[rawArg] ?? 0;
383
+ }
378
384
  let positionalsCount = 0;
379
- for (const [rawArg, schema] of Object.entries(args)) {
385
+ for (const [rawArg, schema] of argEntries) {
380
386
  const arg = toKebab || schema.toKebab ? kebabnize(rawArg) : rawArg;
381
387
  explicit[rawArg] = false;
382
388
  if (schema.type === "positional") {
383
389
  if (skipPositionalIndex > SKIP_POSITIONAL_DEFAULT) while (positionalsCount <= getPositionalSkipIndex()) positionalsCount++;
390
+ const requiredPositionals = getRequiredPositionalsAfter(rawArg);
391
+ const availablePositionals = Math.max(positionalTokens.length - positionalsCount, 0);
384
392
  if (schema.multiple) {
385
- const remainingPositionals = positionalTokens.slice(positionalsCount);
393
+ const positionalsToConsume = Math.max(availablePositionals - requiredPositionals, 0);
394
+ const remainingPositionals = positionalTokens.slice(positionalsCount, positionalsCount + positionalsToConsume);
386
395
  if (remainingPositionals.length > 0) {
387
396
  if (typeof schema.parse === "function") {
388
397
  const parsed = [];
@@ -398,7 +407,7 @@ function resolveArgs(args, tokens, { shortGrouping = false, skipPositional = SKI
398
407
  } else if (schema.required) errors.push(createRequireError(arg, schema));
399
408
  } else {
400
409
  const positional = positionalTokens[positionalsCount];
401
- if (positional != null) {
410
+ if (positional != null && (shouldRequireMissingSinglePositional(schema) || availablePositionals > requiredPositionals)) {
402
411
  if (typeof schema.parse === "function") try {
403
412
  values[rawArg] = schema.parse(positional.value);
404
413
  } catch (error) {
@@ -406,8 +415,9 @@ function resolveArgs(args, tokens, { shortGrouping = false, skipPositional = SKI
406
415
  }
407
416
  else values[rawArg] = positional.value;
408
417
  explicit[rawArg] = true;
409
- } else errors.push(createRequireError(arg, schema));
410
- positionalsCount++;
418
+ positionalsCount++;
419
+ } else if (shouldRequireMissingSinglePositional(schema)) errors.push(createRequireError(arg, schema));
420
+ else if (hasDefault(schema)) values[rawArg] = schema.default;
411
421
  }
412
422
  continue;
413
423
  }
@@ -476,6 +486,30 @@ function parse(token, option, schema) {
476
486
  function createRequireError(option, schema) {
477
487
  return new ArgResolveError(schema.type === "positional" ? `Positional argument '${option}' is required` : `Optional argument '--${option}' ${schema.short ? `or '-${schema.short}' ` : ""}is required`, option, "required", schema);
478
488
  }
489
+ function hasDefault(schema) {
490
+ return schema.default != null;
491
+ }
492
+ function shouldRequireMissingSinglePositional(schema) {
493
+ if (schema.required === true) return true;
494
+ if (schema.required === false) return false;
495
+ return !hasDefault(schema);
496
+ }
497
+ function getRequiredPositionalInputCount(schema) {
498
+ if (schema.type !== "positional") return 0;
499
+ if (schema.multiple) return schema.required === true ? 1 : 0;
500
+ return shouldRequireMissingSinglePositional(schema) ? 1 : 0;
501
+ }
502
+ function createRequiredPositionalsAfter(argEntries) {
503
+ const requiredPositionalsAfter = Object.create(null);
504
+ let minimumRequiredPositionals = 0;
505
+ for (let i = argEntries.length - 1; i >= 0; i--) {
506
+ const [rawArg, schema] = argEntries[i];
507
+ if (schema.type !== "positional") continue;
508
+ requiredPositionalsAfter[rawArg] = minimumRequiredPositionals;
509
+ minimumRequiredPositionals += getRequiredPositionalInputCount(schema);
510
+ }
511
+ return requiredPositionalsAfter;
512
+ }
479
513
  /**
480
514
  * An error that occurs when resolving arguments.
481
515
  * This error is thrown when the argument is not valid.
@@ -525,7 +559,7 @@ function checkConflicts(args, explicit, toKebab, actualInputNames) {
525
559
  return [];
526
560
  }
527
561
  //#endregion
528
- //#region ../../node_modules/.pnpm/args-tokens@0.25.0/node_modules/args-tokens/lib/index.js
562
+ //#region ../../node_modules/.pnpm/args-tokens@0.26.1/node_modules/args-tokens/lib/index.js
529
563
  /**
530
564
  * @author kazuya kawaguchi (a.k.a. kazupon)
531
565
  * @license MIT
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@gunshi/bone",
3
3
  "description": "gunshi minimum",
4
- "version": "0.33.0",
4
+ "version": "0.34.0",
5
5
  "author": {
6
6
  "name": "kazuya kawaguchi",
7
7
  "email": "kawakazu80@gmail.com"
@@ -56,10 +56,10 @@
56
56
  "jsr-exports-lint": "^0.4.2",
57
57
  "publint": "^0.3.20",
58
58
  "tsdown": "0.21.0",
59
- "@gunshi/plugin-renderer": "0.33.0",
60
- "gunshi": "0.33.0",
61
- "@gunshi/plugin-global": "0.33.0",
62
- "@gunshi/definition": "0.33.0"
59
+ "@gunshi/definition": "0.34.0",
60
+ "@gunshi/plugin-renderer": "0.34.0",
61
+ "gunshi": "0.34.0",
62
+ "@gunshi/plugin-global": "0.34.0"
63
63
  },
64
64
  "scripts": {
65
65
  "build": "tsdown",