@crustjs/core 0.0.15 → 0.0.17

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.d.ts CHANGED
@@ -21,10 +21,19 @@ interface CommandRoute {
21
21
  *
22
22
  * Resolution rules:
23
23
  * 1. If `argv[0]` matches a subcommand key, recurse into that subcommand
24
- * 2. If no match and the current command has `run()`, return it (args passed to parser)
25
- * 3. If no match and the current command has NO `run()`, it signals the caller
24
+ * 2. If `argv[0]` matches a sibling's `meta.aliases` entry, recurse into
25
+ * that sibling and record the **canonical** name in `commandPath`
26
+ * 3. If no match and the current command has `run()`, return it (args passed to parser)
27
+ * 4. If no match and the current command has NO `run()`, it signals the caller
26
28
  * should show help (the `showHelp` flag is set in the result)
27
- * 4. Unknown subcommands produce a structured COMMAND_NOT_FOUND error
29
+ * 5. Unknown subcommands produce a structured COMMAND_NOT_FOUND error whose
30
+ * `details.available` lists the canonical sibling names (aliases are
31
+ * discoverable via `details.parentCommand.subCommands[name].meta.aliases`)
32
+ *
33
+ * Implementation: linear scan over siblings on miss. Command trees are small
34
+ * and resolution runs once per invocation, so the cost is negligible compared
35
+ * to building/freezing a parallel alias→canonical map. The scan does NOT
36
+ * mutate `CommandNode`.
28
37
  *
29
38
  * @param command - The root command to resolve from
30
39
  * @param argv - The argv array to resolve against
@@ -48,9 +57,21 @@ interface ArgDefBase {
48
57
  name: string;
49
58
  /** Human-readable description for help text */
50
59
  description?: string;
51
- /** When `true`, the parser throws if the argument is not provided */
60
+ /**
61
+ * When `true`, the parser throws if the argument is not provided.
62
+ *
63
+ * For variadic args, this means the array cannot be empty — the runtime
64
+ * value is still `T[]`, just rejected when it has length 0.
65
+ */
52
66
  required?: true;
53
- /** When `true`, collects all remaining positional values into an array */
67
+ /**
68
+ * When `true`, collects all remaining positional values into an array.
69
+ *
70
+ * The inferred TypeScript type is always `T[]` — never `T[] | undefined` —
71
+ * regardless of `required` or `default`. `required` only controls whether
72
+ * an empty array fails validation; it does not change the runtime shape
73
+ * or the inferred type.
74
+ */
54
75
  variadic?: true;
55
76
  }
56
77
  /** A positional argument whose value is a string */
@@ -58,6 +79,23 @@ interface StringArgDef extends ArgDefBase {
58
79
  type: "string";
59
80
  /** Default string value when the argument is not provided */
60
81
  default?: string;
82
+ /**
83
+ * Static enum of valid values for this argument.
84
+ *
85
+ * `choices` is a **hint for tooling** — it is consumed by shell-completion
86
+ * plugins (e.g. `@crustjs/plugins/completion`) to emit value candidates
87
+ * and may be consumed by future opt-in validation. It is **NOT** enforced
88
+ * at parse time in this version: passing a value outside `choices` does
89
+ * not throw, the value is still parsed as a string and delivered to your
90
+ * `run` handler. Validate explicitly inside your handler if you need
91
+ * runtime rejection today.
92
+ *
93
+ * Only available on string-typed args; not supported on number/boolean.
94
+ *
95
+ * @example
96
+ * { name: "target", type: "string", choices: ["browser", "bun", "node"] }
97
+ */
98
+ choices?: readonly string[];
61
99
  }
62
100
  /** A positional argument whose value is a number */
63
101
  interface NumberArgDef extends ArgDefBase {
@@ -112,6 +150,23 @@ interface StringFlagDef extends SingleFlagBase {
112
150
  type: "string";
113
151
  /** Default string value */
114
152
  default?: string;
153
+ /**
154
+ * Static enum of valid values for this flag.
155
+ *
156
+ * `choices` is a **hint for tooling** — it is consumed by shell-completion
157
+ * plugins (e.g. `@crustjs/plugins/completion`) to emit value candidates
158
+ * and may be consumed by future opt-in validation. It is **NOT** enforced
159
+ * at parse time in this version: passing a value outside `choices` does
160
+ * not throw, the value is still parsed as a string and delivered to your
161
+ * `run` handler. Validate explicitly inside your handler if you need
162
+ * runtime rejection today.
163
+ *
164
+ * Only available on string-typed flags; not supported on number/boolean.
165
+ *
166
+ * @example
167
+ * { type: "string", choices: ["browser", "bun", "node"] }
168
+ */
169
+ choices?: readonly string[];
115
170
  }
116
171
  /** A single-value number flag */
117
172
  interface NumberFlagDef extends SingleFlagBase {
@@ -124,6 +179,8 @@ interface BooleanFlagDef extends SingleFlagBase {
124
179
  type: "boolean";
125
180
  /** Default boolean value */
126
181
  default?: boolean;
182
+ /** When `true`, hide the generated `--no-{name}` help label */
183
+ noNegate?: true;
127
184
  }
128
185
  /** Base for multi-value flags — `multiple` is required as `true` */
129
186
  interface MultiFlagBase extends FlagDefBase {
@@ -135,6 +192,23 @@ interface StringMultiFlagDef extends MultiFlagBase {
135
192
  type: "string";
136
193
  /** Default string array value */
137
194
  default?: string[];
195
+ /**
196
+ * Static enum of valid values for each occurrence of this flag.
197
+ *
198
+ * `choices` is a **hint for tooling** — it is consumed by shell-completion
199
+ * plugins (e.g. `@crustjs/plugins/completion`) to emit value candidates
200
+ * and may be consumed by future opt-in validation. It is **NOT** enforced
201
+ * at parse time in this version: passing a value outside `choices` does
202
+ * not throw, the value is still parsed as a string and collected into the
203
+ * array. Validate explicitly inside your handler if you need runtime
204
+ * rejection today.
205
+ *
206
+ * Only available on string-typed multi-flags; not supported on number/boolean.
207
+ *
208
+ * @example
209
+ * { type: "string", multiple: true, choices: ["unit", "integration"] }
210
+ */
211
+ choices?: readonly string[];
138
212
  }
139
213
  /** A multi-value number flag (collects repeated values into an array) */
140
214
  interface NumberMultiFlagDef extends MultiFlagBase {
@@ -147,6 +221,8 @@ interface BooleanMultiFlagDef extends MultiFlagBase {
147
221
  type: "boolean";
148
222
  /** Default boolean array value */
149
223
  default?: boolean[];
224
+ /** When `true`, hide the generated `--no-{name}` help label */
225
+ noNegate?: true;
150
226
  }
151
227
  /**
152
228
  * Defines a single named flag for a CLI command.
@@ -381,9 +457,14 @@ type EffectiveFlags<
381
457
  /**
382
458
  * Infer the resolved type for a single ArgDef:
383
459
  *
384
- * - **variadic** → `primitive[]`
460
+ * - **variadic** → `primitive[]` (always an array, never `undefined`,
461
+ * regardless of `required` or `default`)
385
462
  * - **required** or **has default** → `primitive` (non-optional)
386
463
  * - otherwise → `primitive | undefined`
464
+ *
465
+ * The variadic branch is checked first and takes precedence. Combining
466
+ * `variadic: true` with `required: true` keeps the inferred type as `T[]`;
467
+ * `required` only gates empty-array validation, not the type.
387
468
  */
388
469
  type InferArgValue<A extends ArgDef> = A extends {
389
470
  variadic: true;
@@ -454,6 +535,65 @@ interface CommandMeta {
454
535
  description?: string;
455
536
  /** Custom usage string (overrides auto-generated usage) */
456
537
  usage?: string;
538
+ /**
539
+ * Alternative names that resolve to the same command.
540
+ *
541
+ * Each entry is a sibling-level alternative for `name`. For example,
542
+ * `meta: { name: "issue", aliases: ["issues", "i"] }` makes `cli issue`,
543
+ * `cli issues`, and `cli i` all route to the same command node.
544
+ *
545
+ * **Conflict policy.** Alias strings must not collide with this command's
546
+ * own canonical `name`, with any sibling's `name`, or with any sibling's
547
+ * own alias. Collisions throw a `CrustError("DEFINITION", …)` at
548
+ * registration time (or during `validateCommandTree` for plugin-installed
549
+ * subcommands). Each alias must also be a non-empty string with no
550
+ * whitespace and must not start with `-`.
551
+ *
552
+ * **Display contract.** Help output renders the canonical name with
553
+ * aliases inline as `name (a, b, c)`. The canonical `name` is what
554
+ * appears in `commandPath`, error messages, and suggestions from
555
+ * `didYouMeanPlugin` — it does not depend on which alias the user typed.
556
+ *
557
+ * @example
558
+ * meta: { name: "issue", aliases: ["issues", "i"] }
559
+ */
560
+ aliases?: readonly string[];
561
+ /**
562
+ * When `true`, omit this command from every tooling surface that
563
+ * enumerates the command tree for users:
564
+ *
565
+ * - `helpPlugin` rendered output (subcommand list + USAGE token)
566
+ * - `@crustjs/man` generated man pages (`SUBCOMMANDS` section)
567
+ * - `completionPlugin` candidate lists (recursively — hidden
568
+ * subcommands and their descendants never appear in generated
569
+ * bash/zsh/fish scripts)
570
+ * - `didYouMeanPlugin` typo suggestions and "Available commands"
571
+ * list (so internal names never surface in error UX)
572
+ * - `skillPlugin` manifests
573
+ *
574
+ * The command is **only hidden from listings**: routing in
575
+ * `@crustjs/core` does not consult `meta.hidden`, so it stays fully
576
+ * invocable by direct name (or alias). The intended use case is
577
+ * internal/runtime commands like a `__complete` shell-completion
578
+ * entrypoint. Marking a user-facing command `hidden` is supported but
579
+ * unusual.
580
+ *
581
+ * **Scope: commands only.** There is no analogous `hidden` field on
582
+ * `FlagDef` or `ArgDef`; flags and positional arguments always surface
583
+ * in help, completion, and man output. If you need a flag that does
584
+ * not advertise itself, the workaround is to register it through a
585
+ * plugin's `setup()` hook without describing it (omit `description`),
586
+ * which suppresses its description body but still lists the spelling
587
+ * — there is intentionally no full hide mechanism at the flag layer.
588
+ *
589
+ * Tooling contract: any renderer or generator that walks
590
+ * `subCommands` to produce a user-facing listing should skip nodes
591
+ * where `meta.hidden === true`.
592
+ *
593
+ * @example
594
+ * meta: { name: "__complete", hidden: true, description: "Internal" }
595
+ */
596
+ hidden?: boolean;
457
597
  }
458
598
  /**
459
599
  * The result of parsing argv against a command's arg/flag definitions.
@@ -583,11 +723,30 @@ interface CrustCommandContext<
583
723
  * Build-time validation protocol.
584
724
  *
585
725
  * `crust build` spawns the user's entrypoint as a subprocess with
586
- * `CRUST_INTERNAL_VALIDATE_ONLY=1`. When `.execute()` detects this env flag
587
- * it runs validation, surfaces errors via stderr/exitCode, then force-exits.
726
+ * `CRUST_INTERNAL_VALIDATE_ONLY=1` (and the companion
727
+ * {@link VALIDATION_FORCE_EXIT_ENV}=`1`). When `.execute()` detects
728
+ * `VALIDATION_MODE_ENV` it runs the validation pipeline and surfaces errors
729
+ * via stderr and `process.exitCode`.
730
+ *
731
+ * Process termination is opt-in via {@link VALIDATION_FORCE_EXIT_ENV} so
732
+ * that in-process callers (tests, embedders) that set only this env get
733
+ * the validation result without having their host process killed.
588
734
  */
589
735
  declare const VALIDATION_MODE_ENV = "CRUST_INTERNAL_VALIDATE_ONLY";
590
736
  /**
737
+ * Companion to {@link VALIDATION_MODE_ENV}. When set to `"1"` _alongside_
738
+ * `VALIDATION_MODE_ENV`, `.execute()` calls `process.exit()` after the
739
+ * validation pipeline completes — ensuring any code that follows
740
+ * `await app.execute()` in the user's entrypoint does not run during
741
+ * `crust build`'s pre-compile validation subprocess.
742
+ *
743
+ * Without this flag, `.execute()` only sets `process.exitCode` and returns,
744
+ * matching the rest of `.execute()`'s error handling. This is the path
745
+ * in-process callers (tests that toggle `VALIDATION_MODE_ENV`, programmatic
746
+ * embedders) take so the host event loop is not terminated.
747
+ */
748
+ declare const VALIDATION_FORCE_EXIT_ENV = "CRUST_INTERNAL_VALIDATE_FORCE_EXIT";
749
+ /**
591
750
  * Chainable builder for defining CLI commands with full type inference.
592
751
  *
593
752
  * Generic parameters:
@@ -645,14 +804,20 @@ declare class Crust<
645
804
  * Set metadata (description, usage) for this command.
646
805
  *
647
806
  * The command name is already set by the builder source (constructor,
648
- * `.sub()`, or the child builder passed into `.command(name, cb)`), so
649
- * only `description` and `usage` can be provided here.
807
+ * `.sub()`, or the child builder passed into `.command(name, cb)`).
808
+ * Provide `description`, `usage`, and/or `aliases` here.
650
809
  *
651
810
  * Returns a new builder with updated metadata. The original builder
652
811
  * is not mutated.
653
812
  *
654
- * @param meta - Metadata fields to set (description, usage)
813
+ * @param meta - Metadata fields to set (description, usage, aliases)
655
814
  * @returns A new `Crust` instance with updated metadata
815
+ * @example
816
+ * ```ts
817
+ * .command("issue", (cmd) =>
818
+ * cmd.meta({ aliases: ["issues", "i"] }).run(() => {})
819
+ * )
820
+ * ```
656
821
  */
657
822
  meta(meta: Omit<CommandMeta, "name">): Crust<Inherited, Local, A, Eff>;
658
823
  /**
@@ -789,6 +954,23 @@ declare class Crust<
789
954
  */
790
955
  command(builder: Crust<any, any, any>): Crust<Inherited, Local, A, Eff>;
791
956
  /**
957
+ * Build a frozen, validated copy of the command tree after running plugin
958
+ * `setup()` hooks. Does not mutate this builder or call command handlers.
959
+ *
960
+ * Use for documentation generators (e.g. man pages) that need the same
961
+ * tree shape as runtime, including flags injected by plugins.
962
+ *
963
+ * @param options - Optional synthetic `argv` passed to `setup()` (defaults to `[]`)
964
+ * @returns The cloned root node and any plugin-setup warnings
965
+ * @throws {CrustError} When the tree fails validation (same as `execute()`)
966
+ */
967
+ prepareCommandTree(options?: {
968
+ argv?: readonly string[];
969
+ }): Promise<{
970
+ root: CommandNode;
971
+ warnings: readonly string[];
972
+ }>;
973
+ /**
792
974
  * Parse `process.argv`, resolve subcommands, run plugins and middleware,
793
975
  * and execute the matched command handler.
794
976
  *
@@ -910,4 +1092,4 @@ declare function parseArgs<
910
1092
  * @throws {CrustError} On missing required args or flags
911
1093
  */
912
1094
  declare function validateParsed(command: CommandNode, parsed: ParseResult): void;
913
- export { validateParsed, resolveCommand, parseArgs, ValueType, ValidateVariadicArgs, ValidateNoPrefixedFlags, ValidateFlagAliases, ValidateCrossCollisions, VALIDATION_MODE_ENV, SetupContext, SetupActions, PluginMiddleware, ParseResult, MiddlewareContext, MergeFlags, InheritableFlags, InferFlags, InferArgs, FlagsDef, FlagDef, EffectiveFlags, CrustPlugin, CrustErrorCode, CrustError, CrustCommandContext, Crust, CommandRoute, CommandNode, CommandMeta, ArgsDef, ArgDef };
1095
+ export { validateParsed, resolveCommand, parseArgs, ValueType, ValidateVariadicArgs, ValidateNoPrefixedFlags, ValidateFlagAliases, ValidateCrossCollisions, VALIDATION_MODE_ENV, VALIDATION_FORCE_EXIT_ENV, SetupContext, SetupActions, PluginMiddleware, ParseResult, MiddlewareContext, MergeFlags, InheritableFlags, InferFlags, InferArgs, FlagsDef, FlagDef, EffectiveFlags, CrustPlugin, CrustErrorCode, CrustError, CrustCommandContext, Crust, CommandRoute, CommandNode, CommandMeta, ArgsDef, ArgDef };
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{a as A,b as $,c as B,d as S}from"./shared/chunk-vt64gs69.js";function I(j){return{meta:{name:j},localFlags:{},effectiveFlags:{},args:void 0,subCommands:{},plugins:[],preRun:void 0,run:void 0,postRun:void 0}}function X(j,q){let J={};for(let[Q,G]of Object.entries(j))if(G.inherit===!0)J[Q]=G;for(let[Q,G]of Object.entries(q))J[Q]=G;return J}function D(j,q){let J=[j.meta.name],Q=j,G=q;while(G.length>0){let H=Q.subCommands;if(!H||Object.keys(H).length===0)break;let Z=G[0];if(!Z||Z.startsWith("-"))break;if(Z in H&&H[Z]){Q=H[Z],J.push(Z),G=G.slice(1);continue}if(Q.run)break;let Y=Object.keys(H);throw new $("COMMAND_NOT_FOUND",`Unknown command "${Z}".`,{input:Z,available:Y,commandPath:[...J],parentCommand:Q})}return{command:Q,argv:G,commandPath:J}}function F(j){for(let[q,J]of Object.entries(j)){if(q.startsWith("no-")){let Q=q.slice(3);throw new $("DEFINITION",`Flag "--${q}" must not use "no-" prefix; define "${Q}" and negate with "--no-${Q}"`)}if(J.short?.startsWith("no-"))throw new $("DEFINITION",`Short alias "-${J.short}" on "--${q}" must not use "no-" prefix (reserved for negation)`);if(J.aliases){for(let Q of J.aliases)if(Q.startsWith("no-"))throw new $("DEFINITION",`Alias "--${Q}" on "--${q}" must not use "no-" prefix (reserved for negation)`)}}}var P="CRUST_INTERNAL_VALIDATE_ONLY",_=130,k="__CRUST_VALIDATE_RESULT__";function w(){let j=new Map;return{get(q){return j.get(q)},has(q){return j.has(q)},set(q,J){j.set(q,J)},delete(q){return j.delete(q)}}}function L(j){if(!(j instanceof Error))return!1;return j.name==="CancelledError"}function O(j,q){j.effectiveFlags=X(q,j.localFlags);for(let J of Object.values(j.subCommands))O(J,j.effectiveFlags)}function N(j){return{addFlag(q,J,Q){if(J in q.effectiveFlags)j?.push(`Plugin flag "--${J}" on "${q.meta.name}" overrides existing flag`);q.effectiveFlags[J]=Q},addSubCommand(q,J,Q){if(!J.trim())throw new $("DEFINITION","addSubCommand: name must be a non-empty string");if(q.subCommands[J]){j?.push(`Plugin subcommand "${J}" on "${q.meta.name}" skipped (already exists)`);return}O(Q,q.effectiveFlags),q.subCommands[J]=Q}}}async function b(j,q,J){for(let Q of j){if(!Q.setup)continue;await Q.setup(q,J)}}async function T(j,q,J){let Q=j.map((Z)=>Z.middleware).filter((Z)=>Boolean(Z)),G=-1,H=async(Z)=>{if(Z<=G)throw new $("DEFINITION","Plugin middleware called next() multiple times");if(G=Z,Z===Q.length){await J();return}let Y=Q[Z];if(!Y)throw new $("DEFINITION","Plugin middleware stack is invalid");await Y(q,()=>H(Z+1))};await H(0)}function x(j){let q=[...j.plugins];for(let J of Object.values(j.subCommands))q.push(...x(J));return q}function y(j){if(Object.freeze(j),Object.freeze(j.localFlags),Object.freeze(j.effectiveFlags),Object.freeze(j.meta),Object.freeze(j.plugins),j.args)Object.freeze(j.args);for(let q of Object.values(j.subCommands))y(q);Object.freeze(j.subCommands)}class R{_node;_inheritedFlags;constructor(j){if(!j.trim())throw new $("DEFINITION","meta.name must be a non-empty string");this._node=I(j),this._inheritedFlags={}}static _createChild(j,q){let J=new R(j);return J._inheritedFlags=q,J}_clone(j){let q=Object.create(Object.getPrototypeOf(this)),J={...this._node,localFlags:{...this._node.localFlags},effectiveFlags:{...this._node.effectiveFlags},subCommands:{...this._node.subCommands},plugins:[...this._node.plugins],meta:{...this._node.meta},args:this._node.args?[...this._node.args]:void 0,...j};return q._node=J,q._inheritedFlags=this._inheritedFlags,q}meta(j){return this._clone({meta:{...this._node.meta,...j}})}flags(j){F(j);let q={};for(let[J,Q]of Object.entries(j))q[J]={...Q};return this._clone({localFlags:q,effectiveFlags:X(this._inheritedFlags,q)})}args(j){let q=j.map((J)=>({...J}));return this._clone({args:q})}run(j){return this._clone({run:j})}preRun(j){return this._clone({preRun:j})}postRun(j){return this._clone({postRun:j})}use(j){return this._clone({plugins:[...this._node.plugins,j]})}sub(j){if(!j.trim())throw new $("DEFINITION","Subcommand name must be a non-empty string");let q=X(this._inheritedFlags,this._node.localFlags);return R._createChild(j,q)}command(j,q){if(typeof j==="string"){let H=j;if(!q)throw new $("DEFINITION","command(name, cb) requires a callback");if(!H.trim())throw new $("DEFINITION","Subcommand name must be a non-empty string");if(this._node.subCommands[H])throw new $("DEFINITION",`Subcommand "${H}" is already registered`);let Z=X(this._inheritedFlags,this._node.localFlags),Y=R._createChild(H,Z),z=q(Y),W={...z._node,effectiveFlags:X(z._inheritedFlags,z._node.localFlags)};return this._clone({subCommands:{...this._node.subCommands,[H]:W}})}let J=j,Q=J._node.meta.name;if(!Q.trim())throw new $("DEFINITION","Subcommand name must be a non-empty string");if(this._node.subCommands[Q])throw new $("DEFINITION",`Subcommand "${Q}" is already registered`);let G={...J._node,effectiveFlags:X(J._inheritedFlags,J._node.localFlags)};return this._clone({subCommands:{...this._node.subCommands,[Q]:G}})}async execute(j){let q=j?.argv??process.argv.slice(2),J=this._node,Q=x(J),G=[],H=w(),Z={argv:[...q],rootCommand:J,state:H},Y=N(G);try{await b(Q,Z,Y)}catch(W){if(L(W)){process.exitCode=_;return}if(W instanceof $){console.error(`Error: ${W.message}`),process.exitCode=1;return}let K=W instanceof Error?W.message:String(W);console.error(`Error: ${K}`),process.exitCode=1;return}if(y(J),process.env[P]==="1"){let W=(async()=>{try{let{validateCommandTree:K}=await import("./shared/chunk-5apf3vnv.js");K(J);for(let U of G)console.warn(`Warning: ${U}`);return{ok:!0}}catch(K){let U=K instanceof Error?K.message:String(K);return console.error(U),process.exitCode=1,{ok:!1,error:K}}})();return globalThis[k]=W,await W,process.exit(process.exitCode??0)}for(let W of G)console.warn(`Warning: ${W}`);let z={argv:[...q],rootCommand:J,state:H,route:null,input:null};try{let W,K;try{let U=D(J,[...q]);z.route=U,W=U.command,K=B(W,U.argv),z.input=K}catch(U){await T(Q,z,async()=>{throw U});return}await T(Q,z,async()=>{if(S(W,K),!W.run)return;let U={args:K.args,flags:K.flags,rawArgs:K.rawArgs,command:W},V;try{if(W.preRun)await W.preRun(U);await W.run(U)}catch(M){V=M}if(W.postRun)try{await W.postRun(U)}catch(M){if(!V)V=M;else console.error(`Error in postRun: ${M instanceof Error?M.message:String(M)}`)}if(V)throw V})}catch(W){if(L(W)){process.exitCode=_;return}if(W instanceof $){console.error(`Error: ${W.message}`),process.exitCode=1;return}if(W instanceof Error){let K=new $("EXECUTION",W.message).withCause(W);console.error(`Error: ${K.message}`),process.exitCode=1;return}console.error(`Error: ${String(W)}`),process.exitCode=1}}}export{S as validateParsed,D as resolveCommand,B as parseArgs,P as VALIDATION_MODE_ENV,$ as CrustError,R as Crust};
2
+ import{a as O,b as K,c as T,d as I,f as B}from"./shared/chunk-w6ydwhzx.js";function P(j){return{meta:{name:j},localFlags:{},effectiveFlags:{},args:void 0,subCommands:{},plugins:[],preRun:void 0,run:void 0,postRun:void 0}}function X(j,J){let q={};for(let[Q,Z]of Object.entries(j))if(Z.inherit===!0)q[Q]=Z;for(let[Q,Z]of Object.entries(J))q[Q]=Z;return q}function E(j,J){for(let[q,Q]of Object.entries(j)){let Z=Q.meta.aliases;if(!Z)continue;if(Z.includes(J))return{canonicalName:q,node:Q}}return null}function D(j,J){let q=[j.meta.name],Q=j,Z=J;while(Z.length>0){let $=Q.subCommands;if(!$||Object.keys($).length===0)break;let G=Z[0];if(!G||G.startsWith("-"))break;if(G in $&&$[G]){Q=$[G],q.push(G),Z=Z.slice(1);continue}let H=E($,G);if(H){Q=H.node,q.push(H.canonicalName),Z=Z.slice(1);continue}if(Q.run)break;throw new K("COMMAND_NOT_FOUND",`Unknown command "${G}".`,{input:G,available:Object.keys($),commandPath:[...q],parentCommand:Q})}return{command:Q,argv:Z,commandPath:q}}function f(j){for(let[J,q]of Object.entries(j)){if(J.startsWith("no-")){let Q=J.slice(3);throw new K("DEFINITION",`Flag "--${J}" must not use "no-" prefix; define "${Q}" and negate with "--no-${Q}"`)}if(q.short?.startsWith("no-"))throw new K("DEFINITION",`Short alias "-${q.short}" on "--${J}" must not use "no-" prefix (reserved for negation)`);if(q.aliases){for(let Q of q.aliases)if(Q.startsWith("no-"))throw new K("DEFINITION",`Alias "--${Q}" on "--${J}" must not use "no-" prefix (reserved for negation)`)}}}var N="CRUST_INTERNAL_VALIDATE_ONLY",b="CRUST_INTERNAL_VALIDATE_FORCE_EXIT",x=130,C="__CRUST_VALIDATE_RESULT__";function k(){let j=new Map;return{get(J){return j.get(J)},has(J){return j.has(J)},set(J,q){j.set(J,q)},delete(J){return j.delete(J)}}}function L(j){if(!(j instanceof Error))return!1;return j.name==="CancelledError"}function h(j,J){j.effectiveFlags=X(J,j.localFlags);for(let q of Object.values(j.subCommands))h(q,j.effectiveFlags)}function y(j){return{addFlag(J,q,Q){if(q in J.effectiveFlags)j?.push(`Plugin flag "--${q}" on "${J.meta.name}" overrides existing flag`);J.effectiveFlags[q]=Q},addSubCommand(J,q,Q){if(!q.trim())throw new K("DEFINITION","addSubCommand: name must be a non-empty string");if(J.subCommands[q]){j?.push(`Plugin subcommand "${q}" on "${J.meta.name}" skipped (already exists)`);return}try{B({canonicalName:q,aliases:Q.meta.aliases},J.subCommands,q)}catch(Z){let $=Z instanceof Error?Z.message:String(Z);j?.push(`Plugin subcommand "${q}" on "${J.meta.name}" skipped: ${$}`);return}h(Q,J.effectiveFlags),J.subCommands[q]=Q}}}async function F(j,J,q){for(let Q of j){if(!Q.setup)continue;await Q.setup(J,q)}}async function A(j,J,q){let Q=j.map((G)=>G.middleware).filter((G)=>Boolean(G)),Z=-1,$=async(G)=>{if(G<=Z)throw new K("DEFINITION","Plugin middleware called next() multiple times");if(Z=G,G===Q.length){await q();return}let H=Q[G];if(!H)throw new K("DEFINITION","Plugin middleware stack is invalid");await H(J,()=>$(G+1))};await $(0)}function S(j){let J=[...j.plugins];for(let q of Object.values(j.subCommands))J.push(...S(q));return J}function w(j){let J={};for(let[q,Q]of Object.entries(j))J[q]={...Q,aliases:Q.aliases?[...Q.aliases]:void 0};return J}function v(j){let J={};for(let[q,Q]of Object.entries(j.subCommands))J[q]=v(Q);return{meta:{...j.meta},localFlags:w(j.localFlags),effectiveFlags:w(j.effectiveFlags),args:j.args?j.args.map((q)=>({...q})):void 0,subCommands:J,plugins:[...j.plugins],preRun:j.preRun,run:j.run,postRun:j.postRun}}function _(j){if(Object.freeze(j),Object.freeze(j.localFlags),Object.freeze(j.effectiveFlags),Object.freeze(j.meta),Object.freeze(j.plugins),j.args)Object.freeze(j.args);for(let J of Object.values(j.subCommands))_(J);Object.freeze(j.subCommands)}class M{_node;_inheritedFlags;constructor(j){if(!j.trim())throw new K("DEFINITION","meta.name must be a non-empty string");this._node=P(j),this._inheritedFlags={}}static _createChild(j,J){let q=new M(j);return q._inheritedFlags=J,q}_clone(j){let J=Object.create(Object.getPrototypeOf(this)),q={...this._node,localFlags:{...this._node.localFlags},effectiveFlags:{...this._node.effectiveFlags},subCommands:{...this._node.subCommands},plugins:[...this._node.plugins],meta:{...this._node.meta},args:this._node.args?[...this._node.args]:void 0,...j};return J._node=q,J._inheritedFlags=this._inheritedFlags,J}meta(j){return this._clone({meta:{...this._node.meta,...j}})}flags(j){f(j);let J={};for(let[q,Q]of Object.entries(j))J[q]={...Q};return this._clone({localFlags:J,effectiveFlags:X(this._inheritedFlags,J)})}args(j){let J=j.map((q)=>({...q}));return this._clone({args:J})}run(j){return this._clone({run:j})}preRun(j){return this._clone({preRun:j})}postRun(j){return this._clone({postRun:j})}use(j){return this._clone({plugins:[...this._node.plugins,j]})}sub(j){if(!j.trim())throw new K("DEFINITION","Subcommand name must be a non-empty string");let J=X(this._inheritedFlags,this._node.localFlags);return M._createChild(j,J)}command(j,J){if(typeof j==="string"){let $=j;if(!J)throw new K("DEFINITION","command(name, cb) requires a callback");if(!$.trim())throw new K("DEFINITION","Subcommand name must be a non-empty string");if(this._node.subCommands[$])throw new K("DEFINITION",`Subcommand "${$}" is already registered`);let G=X(this._inheritedFlags,this._node.localFlags),H=M._createChild($,G),z=J(H);B({canonicalName:$,aliases:z._node.meta.aliases},this._node.subCommands,$);let W={...z._node,effectiveFlags:X(z._inheritedFlags,z._node.localFlags)};return this._clone({subCommands:{...this._node.subCommands,[$]:W}})}let q=j,Q=q._node.meta.name;if(!Q.trim())throw new K("DEFINITION","Subcommand name must be a non-empty string");if(this._node.subCommands[Q])throw new K("DEFINITION",`Subcommand "${Q}" is already registered`);B({canonicalName:Q,aliases:q._node.meta.aliases},this._node.subCommands,Q);let Z={...q._node,effectiveFlags:X(q._inheritedFlags,q._node.localFlags)};return this._clone({subCommands:{...this._node.subCommands,[Q]:Z}})}async prepareCommandTree(j){let J=j?.argv??[],q=v(this._node),Q=S(q),Z=[],$=k(),G={argv:[...J],rootCommand:q,state:$},H=y(Z);try{await F(Q,G,H)}catch(W){if(L(W))throw W;if(W instanceof K)throw W;if(W instanceof Error)throw W;throw new K("DEFINITION",String(W))}_(q);let{validateCommandTree:z}=await import("./shared/chunk-w4s4rg66.js");return z(q),{root:q,warnings:Z}}async execute(j){let J=j?.argv??process.argv.slice(2),q=this._node,Q=S(q),Z=[],$=k(),G={argv:[...J],rootCommand:q,state:$},H=y(Z);try{await F(Q,G,H)}catch(W){if(L(W)){process.exitCode=x;return}if(W instanceof K){console.error(`Error: ${W.message}`),process.exitCode=1;return}let U=W instanceof Error?W.message:String(W);console.error(`Error: ${U}`),process.exitCode=1;return}if(_(q),process.env[N]==="1"){let W=(async()=>{try{let{validateCommandTree:U}=await import("./shared/chunk-w4s4rg66.js");U(q);for(let Y of Z)console.warn(`Warning: ${Y}`);return{ok:!0}}catch(U){let Y=U instanceof Error?U.message:String(U);return console.error(Y),process.exitCode=1,{ok:!1,error:U}}})();if(globalThis[C]=W,await W,process.env[b]==="1")return process.exit(process.exitCode??0);return}for(let W of Z)console.warn(`Warning: ${W}`);let z={argv:[...J],rootCommand:q,state:$,route:null,input:null};try{let W,U;try{let Y=D(q,[...J]);z.route=Y,W=Y.command,U=T(W,Y.argv),z.input=U}catch(Y){await A(Q,z,async()=>{throw Y});return}await A(Q,z,async()=>{if(I(W,U),!W.run)return;let Y={args:U.args,flags:U.flags,rawArgs:U.rawArgs,command:W},R;try{if(W.preRun)await W.preRun(Y);await W.run(Y)}catch(V){R=V}if(W.postRun)try{await W.postRun(Y)}catch(V){if(!R)R=V;else console.error(`Error in postRun: ${V instanceof Error?V.message:String(V)}`)}if(R)throw R})}catch(W){if(L(W)){process.exitCode=x;return}if(W instanceof K){console.error(`Error: ${W.message}`),process.exitCode=1;return}if(W instanceof Error){let U=new K("EXECUTION",W.message).withCause(W);console.error(`Error: ${U.message}`),process.exitCode=1;return}console.error(`Error: ${String(W)}`),process.exitCode=1}}}export{I as validateParsed,D as resolveCommand,T as parseArgs,N as VALIDATION_MODE_ENV,b as VALIDATION_FORCE_EXIT_ENV,K as CrustError,M as Crust};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import{e as a,f as b,g as c}from"./chunk-w6ydwhzx.js";export{b as validateIncomingAliases,c as validateCommandTree,a as validateAliasString};
@@ -0,0 +1,3 @@
1
+ // @bun
2
+ var j=import.meta.require;class Y extends Error{code;details;cause;constructor(B,J,...H){super(J);this.name="CrustError",this.code=B,this.details=H[0]}is(B){return this.code===B}withCause(B){return this.cause=B,this}}import{parseArgs as F}from"util";function P(B){let J={},H={};if(!B)return{options:J,aliasToName:H};let K=new Map;for(let z of Object.keys(B))K.set(z,z);for(let[z,G]of Object.entries(B)){if(z.startsWith("no-")){let X=z.slice(3);throw new Y("DEFINITION",`Flag "--${z}" must not use "no-" prefix; define "${X}" and negate with "--no-${X}"`)}let Q=G.type==="boolean"?"boolean":"string",W={type:Q};if(G.multiple)W.multiple=!0;if(G.short){if(G.short.startsWith("no-"))throw new Y("DEFINITION",`Short alias "-${G.short}" on "--${z}" must not use "no-" prefix (reserved for negation)`);let X=K.get(G.short);if(X)throw new Y("DEFINITION",`Alias collision: "-${G.short}" is used by both "--${X}" and "--${z}"`);K.set(G.short,z),H[G.short]=z,W.short=G.short}if(G.aliases)for(let X of G.aliases){if(X.startsWith("no-"))throw new Y("DEFINITION",`Alias "--${X}" on "--${z}" must not use "no-" prefix (reserved for negation)`);let Z=K.get(X);if(Z)throw new Y("DEFINITION",`Alias collision: "${X.length===1?"-":"--"}${X}" is used by both "--${Z}" and "--${z}"`);K.set(X,z),H[X]=z;let q={type:Q};if(G.multiple)q.multiple=!0;J[X]=q}J[z]=W}return{options:J,aliasToName:H}}function U(B,J,H){if(J==="number"){let K=Number(B);if(Number.isNaN(K))throw new Y("PARSE",`Expected number for ${H}, got "${B}"`);return K}if(J==="boolean")return B==="true"||B==="1";return B}function S(B,J,H){let K=`--${B}`;if(J.multiple&&Array.isArray(H))return J.type==="boolean"?H.filter((z)=>typeof z==="boolean"):H.map((z)=>U(z,J.type,K));if(J.type==="boolean"){if(typeof H==="boolean")return H;throw new Y("PARSE",`Expected boolean value for flag "${K}", got ${typeof H}`)}if(typeof H==="string")return U(H,J.type,K);if(H===!0)return J.default??void 0;return H}function h(B,J,H){let K={};for(let z in B){let G=J[z]??z;if(!(G in H))continue;let Q=B[z],W=K[G];if(W!==void 0&&Array.isArray(W)&&Array.isArray(Q))W.push(...Q);else K[G]=Q}return K}function R(B,J,H){if(!B)return{};let K=h(J,H,B),z={};for(let[G,Q]of Object.entries(B)){let W=K[G];if(W!==void 0){z[G]=S(G,Q,W);continue}z[G]=Q.default??void 0}return z}function w(B,J){if(!B)return;for(let[H,K]of Object.entries(B))if(K.required===!0&&K.default===void 0){if(J[H]===void 0)throw new Y("VALIDATION",`Missing required flag "--${H}"`)}}function A(B,J){if(!B)return{};let H={},K=0;for(let z of B){let{name:G}=z;if(z.variadic){let Q=J.slice(K);H[G]=z.type==="string"?Q:Q.map((W)=>U(W,z.type,`<${G}>`)),K=J.length}else if(K<J.length)H[G]=U(J[K],z.type,`<${G}>`),K++;else H[G]=z.default??void 0}return H}function k(B,J,H){if(!J)return;for(let K of B){if(K==="--")return;if(!K.startsWith("--no-"))continue;let z=K.indexOf("="),G=z===-1?K.slice(5):K.slice(5,z);if(!G)continue;let Q=H[G];if(!Q)continue;if(Q===G)continue;if(J[Q]?.type!=="boolean")continue;throw new Y("PARSE",`Cannot negate alias "--no-${G}"; use "--no-${Q}" instead`)}}function M(B,J){let{args:H,effectiveFlags:K}=B,{options:z,aliasToName:G}=P(K);k(J,K,G);let Q;try{Q=F({args:J,options:z,strict:!0,allowPositionals:!0,allowNegative:!0,tokens:!0})}catch(_){if(_ instanceof Error){let $=_.message.match(/Unknown option '(.+?)'/);if($)throw new Y("PARSE",`Unknown flag "${$[1]}"`).withCause(_)}throw new Y("PARSE","Failed to parse command arguments").withCause(_)}let W=[],X=[];if(Q.tokens){let _=!1;for(let $ of Q.tokens){if($.kind==="option-terminator"){_=!0;continue}if($.kind==="positional")(_?W:X).push($.value??"")}}else X.push(...Q.positionals);let Z=R(K,Q.values,G);return{args:A(H,X),flags:Z,rawArgs:W}}function I(B,J){let{args:H,effectiveFlags:K}=B,z=J.args,G=J.flags;if(H)for(let Q of H){let{name:W}=Q,X=`argument "<${W}>"`,Z=z[W];if(Q.required===!0&&Q.default===void 0){if(Q.variadic){if(!Array.isArray(Z)||Z.length===0)throw new Y("VALIDATION",`Missing required ${X}`)}else if(Z===void 0)throw new Y("VALIDATION",`Missing required ${X}`)}}w(K,G)}function y(B,J,H){if(typeof B!=="string"||B.length===0)throw new Y("DEFINITION",`Subcommand "${H}" has an invalid alias: must be a non-empty string`);if(/\s/.test(B))throw new Y("DEFINITION",`Subcommand "${H}" alias "${B}" must not contain whitespace`);if(B.startsWith("-"))throw new Y("DEFINITION",`Subcommand "${H}" alias "${B}" must not start with "-" (reserved for flags)`);if(B===J)throw new Y("DEFINITION",`Subcommand "${H}" alias "${B}" must not equal its own canonical name`)}function x(B,J,H){let{canonicalName:K,aliases:z}=B;if(z){let G=new Set;for(let Q of z){if(y(Q,K,H),G.has(Q))throw new Y("DEFINITION",`Subcommand "${H}" lists alias "${Q}" more than once`);G.add(Q)}}for(let[G,Q]of Object.entries(J)){let W=Q.meta.aliases;if(W?.includes(K))throw new Y("DEFINITION",`Subcommand "${H}" canonical name "${K}" collides with alias of sibling "${G}"`);if(!z)continue;for(let X of z){if(X===G)throw new Y("DEFINITION",`Subcommand "${H}" alias "${X}" collides with sibling canonical name "${G}"`);if(W?.includes(X))throw new Y("DEFINITION",`Subcommand "${H}" alias "${X}" collides with alias of sibling "${G}"`)}}}function O(B){switch(B.type){case"number":return"1";case"boolean":return"true";default:return"sample"}}function T(B){let J=[],H=B.effectiveFlags;for(let[z,G]of Object.entries(H)){if(G.required!==!0||G.default!==void 0)continue;if(J.push(`--${z}`),G.type!=="boolean")J.push(O(G))}let K=B.args;if(K)for(let z of K){if(z.required!==!0||z.default!==void 0)continue;J.push(O(z))}return J}function b(B){let J=[{command:B,path:[B.meta.name]}],H=new Set;while(J.length>0){let K=J.pop();if(!K)break;let{command:z,path:G}=K;if(H.has(z))continue;H.add(z);try{let W=M(z,T(z));I(z,W)}catch(W){let X=W instanceof Error?W.message:"Unknown validation error";throw new Y("DEFINITION",`Command "${G.join(" ")}" failed runtime validation: ${X}`).withCause(W)}let Q={};for(let[W,X]of Object.entries(z.subCommands))x({canonicalName:W,aliases:X.meta.aliases},Q,[...G,W].join(" ")),Q[W]=X;for(let[W,X]of Object.entries(z.subCommands))J.push({command:X,path:[...G,W]})}}
3
+ export{j as a,Y as b,M as c,I as d,y as e,x as f,b as g};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crustjs/core",
3
- "version": "0.0.15",
3
+ "version": "0.0.17",
4
4
  "description": "Core library for the Crust CLI framework",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -43,9 +43,9 @@
43
43
  },
44
44
  "devDependencies": {
45
45
  "@crustjs/config": "0.0.0",
46
- "bunup": "^0.16.29"
46
+ "bunup": "^0.16.31"
47
47
  },
48
48
  "peerDependencies": {
49
- "typescript": "^5"
49
+ "typescript": "^6.0.3"
50
50
  }
51
51
  }
@@ -1,2 +0,0 @@
1
- // @bun
2
- import{b as Q,c as S,d as W}from"./chunk-vt64gs69.js";function M(B){switch(B.type){case"number":return"1";case"boolean":return"true";default:return"sample"}}function X(B){let z=[],K=B.effectiveFlags;for(let[j,G]of Object.entries(K)){if(G.required!==!0||G.default!==void 0)continue;if(z.push(`--${j}`),G.type!=="boolean")z.push(M(G))}let J=B.args;if(J)for(let j of J){if(j.required!==!0||j.default!==void 0)continue;z.push(M(j))}return z}function _(B){let z=[{command:B,path:[B.meta.name]}],K=new Set;while(z.length>0){let J=z.pop();if(!J)break;let{command:j,path:G}=J;if(K.has(j))continue;K.add(j);try{let H=S(j,X(j));W(j,H)}catch(H){let L=H instanceof Error?H.message:"Unknown validation error";throw new Q("DEFINITION",`Command "${G.join(" ")}" failed runtime validation: ${L}`).withCause(H)}for(let[H,L]of Object.entries(j.subCommands))z.push({command:L,path:[...G,H]})}}export{_ as validateCommandTree};
@@ -1,3 +0,0 @@
1
- // @bun
2
- var A=import.meta.require;class W extends Error{code;details;cause;constructor(B,J,...G){super(J);this.name="CrustError",this.code=B,this.details=G[0]}is(B){return this.code===B}withCause(B){return this.cause=B,this}}import{parseArgs as U}from"util";function q(B){let J={},G={};if(!B)return{options:J,aliasToName:G};let z=new Map;for(let j of Object.keys(B))z.set(j,j);for(let[j,H]of Object.entries(B)){if(j.startsWith("no-")){let L=j.slice(3);throw new W("DEFINITION",`Flag "--${j}" must not use "no-" prefix; define "${L}" and negate with "--no-${L}"`)}let K=H.type==="boolean"?"boolean":"string",Q={type:K};if(H.multiple)Q.multiple=!0;if(H.short){if(H.short.startsWith("no-"))throw new W("DEFINITION",`Short alias "-${H.short}" on "--${j}" must not use "no-" prefix (reserved for negation)`);let L=z.get(H.short);if(L)throw new W("DEFINITION",`Alias collision: "-${H.short}" is used by both "--${L}" and "--${j}"`);z.set(H.short,j),G[H.short]=j,Q.short=H.short}if(H.aliases)for(let L of H.aliases){if(L.startsWith("no-"))throw new W("DEFINITION",`Alias "--${L}" on "--${j}" must not use "no-" prefix (reserved for negation)`);let X=z.get(L);if(X)throw new W("DEFINITION",`Alias collision: "${L.length===1?"-":"--"}${L}" is used by both "--${X}" and "--${j}"`);z.set(L,j),G[L]=j;let $={type:K};if(H.multiple)$.multiple=!0;J[L]=$}J[j]=Q}return{options:J,aliasToName:G}}function _(B,J,G){if(J==="number"){let z=Number(B);if(Number.isNaN(z))throw new W("PARSE",`Expected number for ${G}, got "${B}"`);return z}if(J==="boolean")return B==="true"||B==="1";return B}function I(B,J,G){let z=`--${B}`;if(J.multiple&&Array.isArray(G))return J.type==="boolean"?G.filter((j)=>typeof j==="boolean"):G.map((j)=>_(j,J.type,z));if(J.type==="boolean"){if(typeof G==="boolean")return G;throw new W("PARSE",`Expected boolean value for flag "${z}", got ${typeof G}`)}if(typeof G==="string")return _(G,J.type,z);if(G===!0)return J.default??void 0;return G}function M(B,J,G){let z={};for(let j in B){let H=J[j]??j;if(!(H in G))continue;let K=B[j],Q=z[H];if(Q!==void 0&&Array.isArray(Q)&&Array.isArray(K))Q.push(...K);else z[H]=K}return z}function h(B,J,G){if(!B)return{};let z=M(J,G,B),j={};for(let[H,K]of Object.entries(B)){let Q=z[H];if(Q!==void 0){j[H]=I(H,K,Q);continue}j[H]=K.default??void 0}return j}function O(B,J){if(!B)return;for(let[G,z]of Object.entries(B))if(z.required===!0&&z.default===void 0){if(J[G]===void 0)throw new W("VALIDATION",`Missing required flag "--${G}"`)}}function P(B,J){if(!B)return{};let G={},z=0;for(let j of B){let{name:H}=j;if(j.variadic){let K=J.slice(z);G[H]=j.type==="string"?K:K.map((Q)=>_(Q,j.type,`<${H}>`)),z=J.length}else if(z<J.length)G[H]=_(J[z],j.type,`<${H}>`),z++;else G[H]=j.default??void 0}return G}function S(B,J,G){if(!J)return;for(let z of B){if(z==="--")return;if(!z.startsWith("--no-"))continue;let j=z.indexOf("="),H=j===-1?z.slice(5):z.slice(5,j);if(!H)continue;let K=G[H];if(!K)continue;if(K===H)continue;if(J[K]?.type!=="boolean")continue;throw new W("PARSE",`Cannot negate alias "--no-${H}"; use "--no-${K}" instead`)}}function b(B,J){let{args:G,effectiveFlags:z}=B,{options:j,aliasToName:H}=q(z);S(J,z,H);let K;try{K=U({args:J,options:j,strict:!0,allowPositionals:!0,allowNegative:!0,tokens:!0})}catch(Y){if(Y instanceof Error){let Z=Y.message.match(/Unknown option '(.+?)'/);if(Z)throw new W("PARSE",`Unknown flag "${Z[1]}"`).withCause(Y)}throw new W("PARSE","Failed to parse command arguments").withCause(Y)}let Q=[],L=[];if(K.tokens){let Y=!1;for(let Z of K.tokens){if(Z.kind==="option-terminator"){Y=!0;continue}if(Z.kind==="positional")(Y?Q:L).push(Z.value??"")}}else L.push(...K.positionals);let X=h(z,K.values,H);return{args:P(G,L),flags:X,rawArgs:Q}}function E(B,J){let{args:G,effectiveFlags:z}=B,j=J.args,H=J.flags;if(G)for(let K of G){let{name:Q}=K,L=`argument "<${Q}>"`,X=j[Q];if(K.required===!0&&K.default===void 0){if(K.variadic){if(!Array.isArray(X)||X.length===0)throw new W("VALIDATION",`Missing required ${L}`)}else if(X===void 0)throw new W("VALIDATION",`Missing required ${L}`)}}O(z,H)}
3
- export{A as a,W as b,b as c,E as d};