@crustjs/core 0.5.0 → 0.5.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.
@@ -579,12 +579,13 @@ type RunOutcome<Result> = {
579
579
  type CommandTree = Record<string, CommandShape>;
580
580
  /** Every valid path through a command tree, including the root path (`[]`). */
581
581
  type CommandPath<Tree extends object, Depth extends readonly unknown[] = readonly []> = Depth["length"] extends 15 ? readonly string[] : string extends keyof Tree ? readonly string[] : readonly [] | { [K in keyof Tree & string]: Tree[K] extends CommandShape ? readonly [K, ...CommandPath<Tree[K]["children"], readonly [...Depth, unknown]>] : never; }[keyof Tree & string];
582
- type KnownCommandPath<Path extends readonly string[], Tree> = string extends keyof Tree ? Path : IsStaticTuple<Path> extends true ? string extends Path[number] ? never : Path : never;
582
+ type CommandPathContinuations<Path extends readonly string[], Tree extends object, Prefix extends readonly string[] = readonly []> = Path extends readonly [infer Head extends string, ...infer Tail extends readonly string[]] ? readonly [...Prefix, Head] extends CommandPath<Tree> ? CommandPathContinuations<Tail, Tree, readonly [...Prefix, Head]> : Extract<CommandPath<Tree>, readonly [...Prefix, ...string[]]> : Extract<CommandPath<Tree>, readonly [...Prefix, ...string[]]>;
583
+ type KnownCommandPath<Path extends readonly string[], Tree extends object> = string extends keyof Tree ? Path : IsStaticTuple<Path> extends true ? string extends Path[number] ? never : [Path] extends [CommandPath<Tree>] ? Path : CommandPathContinuations<Path, Tree> : number extends Path["length"] ? CommandPath<Tree> : never;
583
584
  /** Resolve the command shape at a typed path. */
584
585
  type CommandShapeAt<Shape extends CommandShape, Path extends readonly string[]> = Path extends readonly [infer Head, ...infer Tail extends readonly string[]] ? Head extends keyof Shape["children"] ? Shape["children"][Head] extends (infer Child extends CommandShape) ? CommandShapeAt<Child, Tail> : never : string extends Head ? CommandShape : never : Path extends readonly [] ? Shape : CommandShape;
585
- type RunSection<Name extends string, Values> = keyof Values extends never ? { [K in Name]?: never; } : {} extends Values ? { [K in Name]?: Values; } : { [K in Name]: Values; };
586
+ type RunSection<Name extends string, Values> = keyof Values extends never ? {} : {} extends Values ? { [K in Name]?: Values; } : { [K in Name]: Values; };
586
587
  /** Structured values bound directly against the selected command's definitions; no argv is produced. */
587
- type RunInput<Shape extends CommandShape> = RunSection<"args", ArgsDef extends Shape["args"] ? NonNullable<RunInputPayload["args"]> : InputArgs<Shape["args"]>> & RunSection<"flags", FlagsDef extends Shape["flags"] ? NonNullable<RunInputPayload["flags"]> : InputFlags<Shape["flags"]>> & {
588
+ type RunInput<Shape extends CommandShape> = RunSection<"args", ArgsDef extends Shape["args"] ? NonNullable<RunInputPayload["args"]> : InputArgs<Shape["args"]>> & RunSection<"flags", FlagsDef extends Shape["flags"] ? [keyof Shape["flags"]] extends [never] ? {} : NonNullable<RunInputPayload["flags"]> : InputFlags<Shape["flags"]>> & {
588
589
  readonly raw?: readonly string[];
589
590
  };
590
591
  type CompatibleRunValue<Expected, Actual> = Actual extends Expected ? Actual extends object ? Expected extends unknown ? Actual extends Expected ? Actual & { [K in Exclude<keyof Actual, keyof Expected>]: never; } & { [K in keyof Actual & keyof Expected]: CompatibleRunValue<Expected[K], Actual[K]>; } : never : never : Actual : JsonValue extends Expected ? Actual extends JsonCompatible<Actual> ? Actual : never : Expected extends unknown ? CompatibleRunBranch<Expected, Actual> : never;
@@ -592,6 +593,14 @@ type CompatibleRunBranch<Expected, Actual> = Actual extends Expected ? Actual :
592
593
  type CompatibleRunInput<Shape extends CommandShape, Input> = CompatibleRunValue<RunInput<Shape>, Input>;
593
594
  type RunInputArguments<Shape extends CommandShape> = {} extends RunInput<Shape> ? readonly [input?: RunInput<Shape>] : readonly [input: RunInput<Shape>];
594
595
  type RunArguments<Shape extends CommandShape> = readonly [...RunInputArguments<Shape>, options?: InvocationOptions];
596
+ type KeysOf<T> = T extends unknown ? keyof T : never;
597
+ type UnknownRunKeys<Actual, Known> = { [K in keyof Actual as string extends K ? never : number extends K ? never : K extends Known ? never : K]: Actual[K] extends undefined ? Actual[K] : never; };
598
+ type ClosedRunInput<Shape extends CommandShape, Input> = Input extends unknown ? UnknownRunKeys<Input, keyof RunInput<Shape>> & { [K in keyof Input as K extends ("args" | "flags") & keyof RunInput<Shape> ? K : never]: UnknownRunKeys<NonNullable<Input[K]>, KeysOf<NonNullable<RunInput<Shape>[K & keyof RunInput<Shape>]>>>; } : never;
599
+ type CheckedRunInput<Shape extends CommandShape, Input> = [Input] extends [ClosedRunInput<Shape, Input>] ? NonNullable<RunInputArguments<Shape>[0]> : Input & NoInfer<ClosedRunInput<Shape, Input>>;
600
+ type OmittableRunInput<Shape extends CommandShape> = {} extends RunInput<Shape> ? undefined : never;
601
+ type RunWithoutInputThis<Shape extends CommandShape, This> = [Shape] extends [never] ? This : {} extends RunInput<Shape> ? This : This & {
602
+ readonly FIX_MISSING_INPUT: "Pass the command's required arguments or flags";
603
+ };
595
604
  /**
596
605
  * Typed invoker bound to one command in an app, returned by {@link Crust.at}.
597
606
  *
@@ -601,7 +610,8 @@ type RunArguments<Shape extends CommandShape> = readonly [...RunInputArguments<S
601
610
  interface CommandHandle<Shape extends CommandShape> {
602
611
  /** The typed path this handle was created with (`[]` selects the root). */
603
612
  readonly path: readonly string[];
604
- run(...args: RunArguments<Shape>): Promise<RunOutcome<Shape["result"]>>;
613
+ run(this: RunWithoutInputThis<Shape, unknown>): Promise<RunOutcome<Shape["result"]>>;
614
+ run<const Input extends RunInput<Shape> | OmittableRunInput<Shape> = RunInput<Shape>>(input: CheckedRunInput<Shape, Input> | OmittableRunInput<Shape>, options?: InvocationOptions): Promise<RunOutcome<Shape["result"]>>;
605
615
  run<const Input>(input: Input, ...validation: [Input] extends [CompatibleRunInput<Shape, Input>] ? readonly [options?: InvocationOptions] : readonly [invalidInput: never]): Promise<RunOutcome<Shape["result"]>>;
606
616
  }
607
617
  /** Static configuration for a reusable command definition. */
@@ -899,21 +909,17 @@ declare class Crust<Flags extends FlagsDef = {}, A extends ArgsDef = [], Ctx ext
899
909
  */
900
910
  add<const Ds extends readonly CommandDefinition<any, any, any, any>[] = never>(...definitions: Ds & ValidateCommandDefinitions<Ds, Sibs> & ValidateDeclaredDeps<Ctx, Ds> & DefinitionDescendantValuesBrand<Ds, CollisionSp["demands"]> & ValidateDefinitionFlags<Ds, CollisionSp["extension"] | LocalSpellingsOf<CtxFlags>>): AfterAdd<Flags, A, Ctx, Sibs, Sp, Tree, CtxFlags, CollisionSp, Result, Ds, Meta, Caps>;
901
911
  /**
902
- * Define an app-local leaf subcommand inline (root-only sugar for
903
- * `.add(defineCommand(name, recipe))`).
912
+ * Define a subcommand inline (sugar for `.add(defineCommand(name, recipe))`),
913
+ * on the root or inside another command's recipe.
904
914
  *
905
915
  * The recipe builder is seeded with the Contexts and Context-owned flags
906
- * accumulated on this builder so far — the call site. Contexts provided
907
- * after `.command()` are not visible to it, matching the positional runtime
908
- * semantics of `.provide()`. Extract to `defineCommand` when a command needs
909
- * its own file, reuse, or a package. Recipe builders cannot call this
910
- * root-only method.
916
+ * accumulated on this builder so far — the call site. In a recipe, those are
917
+ * its `.use()` and `.provide()` Contexts. Contexts provided after `.command()`
918
+ * are not visible to it, matching the positional runtime semantics of
919
+ * `.provide()`. Extract to `defineCommand` when a command needs its own file
920
+ * or reuse.
911
921
  */
912
- command<const N extends string, B extends AnyCommandDefinitionBuilder>(this: {
913
- readonly _types: {
914
- readonly caps: "app";
915
- };
916
- }, name: N & CommandNameBrand<N> & CommandCollisionBrand<N, Sibs>, recipe: ((command: CommandDefinitionBuilder<{}, [], Ctx, never, LocalSpellingsOf<CtxFlags>, {}, CtxFlags>) => B & ShapeFlagCollisionBrand<ShapeOfBuilder<B>, CollisionSp["extension"]> & ValidateInlineCommandDeps<Ctx, NoInfer<B>>) & NoInfer<DescendantValuesBrand<{
922
+ command<const N extends string, B extends AnyCommandDefinitionBuilder>(name: N & CommandNameBrand<N> & CommandCollisionBrand<N, Sibs>, recipe: ((command: CommandDefinitionBuilder<{}, [], Ctx, never, LocalSpellingsOf<CtxFlags>, {}, CtxFlags>) => B & ShapeFlagCollisionBrand<ShapeOfBuilder<B>, CollisionSp["extension"]> & ValidateInlineCommandDeps<Ctx, NoInfer<B>>) & NoInfer<DescendantValuesBrand<{
917
923
  child: ShapeOfBuilder<B>;
918
924
  }, CollisionSp["demands"]>>): AfterAdd<Flags, A, Ctx, Sibs, Sp, Tree, CtxFlags, CollisionSp, Result, readonly [CommandDefinition<N, readonly [], ShapeOfBuilder<B>, DepsOfBuilder<B>>], Meta, Caps>;
919
925
  private _addDefinitions;
@@ -940,16 +946,21 @@ declare class Crust<Flags extends FlagsDef = {}, A extends ArgsDef = [], Ctx ext
940
946
  * exposed to Command Actions and Extensions) and an
941
947
  * `AbortSignal` that cancels the invocation
942
948
  */
943
- run<const Path extends CommandPath<Tree>>(this: {
949
+ run<const Path extends readonly string[]>(this: RunWithoutInputThis<CommandShapeAt<CommandShape<A, Flags, Tree, Result>, Path>, {
950
+ readonly _types: {
951
+ readonly caps: "app";
952
+ };
953
+ }>, path: KnownCommandPath<Path, Tree>): Promise<RunOutcome<CommandShapeAt<CommandShape<A, Flags, Tree, Result>, Path>["result"]>>;
954
+ run<const Path extends readonly string[], const Input extends RunInput<CommandShapeAt<CommandShape<A, Flags, Tree, Result>, Path>> | OmittableRunInput<CommandShapeAt<CommandShape<A, Flags, Tree, Result>, Path>> = RunInput<CommandShapeAt<CommandShape<A, Flags, Tree, Result>, Path>>>(this: {
944
955
  readonly _types: {
945
956
  readonly caps: "app";
946
957
  };
947
- }, path: Path & KnownCommandPath<Path, Tree>, ...args: RunArguments<CommandShapeAt<CommandShape<A, Flags, Tree, Result>, Path>>): Promise<RunOutcome<CommandShapeAt<CommandShape<A, Flags, Tree, Result>, Path>["result"]>>;
948
- run<const Path extends CommandPath<Tree>, const Input>(this: {
958
+ }, path: KnownCommandPath<Path, Tree>, input: CheckedRunInput<CommandShapeAt<CommandShape<A, Flags, Tree, Result>, Path>, Input> | OmittableRunInput<CommandShapeAt<CommandShape<A, Flags, Tree, Result>, Path>>, options?: InvocationOptions): Promise<RunOutcome<CommandShapeAt<CommandShape<A, Flags, Tree, Result>, Path>["result"]>>;
959
+ run<const Path extends readonly string[], const Input>(this: {
949
960
  readonly _types: {
950
961
  readonly caps: "app";
951
962
  };
952
- }, path: Path & KnownCommandPath<Path, Tree>, input: Input, ...validation: [Input] extends [CompatibleRunInput<CommandShapeAt<CommandShape<A, Flags, Tree, Result>, NoInfer<Path>>, Input>] ? readonly [options?: InvocationOptions] : readonly [invalidInput: never]): Promise<RunOutcome<CommandShapeAt<CommandShape<A, Flags, Tree, Result>, Path>["result"]>>;
963
+ }, path: KnownCommandPath<Path, Tree>, input: Input, ...validation: [Input] extends [CompatibleRunInput<CommandShapeAt<CommandShape<A, Flags, Tree, Result>, NoInfer<Path>>, Input>] ? readonly [options?: InvocationOptions] : readonly [invalidInput: never]): Promise<RunOutcome<CommandShapeAt<CommandShape<A, Flags, Tree, Result>, Path>["result"]>>;
953
964
  /**
954
965
  * Bind a typed command path into a reusable {@link CommandHandle}.
955
966
  *
@@ -961,11 +972,11 @@ declare class Crust<Flags extends FlagsDef = {}, A extends ArgsDef = [], Ctx ext
961
972
  * @param path - Typed path to the command to bind (`[]` selects the root)
962
973
  * @throws {CrustError} COMMAND_NOT_FOUND when the path does not name a command
963
974
  */
964
- at<const Path extends CommandPath<Tree>>(this: {
975
+ at<const Path extends readonly string[]>(this: {
965
976
  readonly _types: {
966
977
  readonly caps: "app";
967
978
  };
968
- }, path: Path & KnownCommandPath<Path, Tree>): CommandHandle<CommandShapeAt<CommandShape<A, Flags, Tree, Result>, Path>>;
979
+ }, path: KnownCommandPath<Path, Tree>): CommandHandle<CommandShapeAt<CommandShape<A, Flags, Tree, Result>, Path>>;
969
980
  /**
970
981
  * Parse `process.argv`, resolve subcommands, run Extension hooks, and
971
982
  * execute the matched Command Action.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as CrustError, A as SectionConsumer, At as LocalFlagNameBrand, B as ExtensionBuilder, C as InvocationOptions, Ct as RunInputArguments, D as ParsedArgValue, Dt as CommandSnapshot, E as ParseResult, Et as ArgSnapshot, F as BuildArtifacts, Ft as defineExtensionId, G as ExtensionSectionContribution, H as ExtensionFactory, I as BuildFile, J as InvocationOutcome, K as Finished, L as BuildReport, M as ValueType, Mt as LocalValueBrand, Nt as MergeContext, O as ParsedFlagValue, Ot as FlagSnapshot, Pt as ExtensionId, Q as CommandNotFoundErrorDetails, R as Extension, S as InvocationIO, St as RunInput, T as NamedFlagDef, Tt as defineCommand, U as ExtensionFlagDef, V as ExtensionContext, W as ExtensionHooks, X as RootMetaKey, Y as NamedExtensionFlagDef, Z as defineExtension, _ as ExecuteOptions, _t as CommandTree, a as ContextInstance, at as EnvErrorDetails, b as InputArgs, bt as RootCommandMeta, c as FactoryValueOf, ct as ValidationErrorDetails, d as ArgDef, dt as CommandDefinition, et as CrustErrorCode, f as ArgsDef, ft as CommandDefinitionBuilder, gt as CommandShapeAt, h as CommandSectionInput, ht as CommandShape, i as ContextFactory, it as DefinitionErrorDetails, j as ValidatedInput, jt as EmptyArgNameBrand, k as SectionAudience, kt as LocalFlagBrand, l as contextSources, lt as AnyCrust, m as CommandSection, mt as CommandPath, n as ContextBag, nt as CrustErrorDetailsMap, o as ContextMap, ot as EnvIssue, p as CommandMeta, pt as CommandHandle, q as InferExtensionFlags, r as ContextBuilder, rt as CrustErrorJson, s as ContextSetup, st as ParseErrorDetails, t as AnyContextFactory, tt as CrustErrorDetails, u as defineContext, ut as CommandConfig, v as FlagDef, vt as Crust, w as MergeFlags, wt as RunOutcome, x as InputFlags, xt as RunArguments, y as FlagsDef, yt as CrustCommandContext, z as ExtensionBuildContext } from "./context-WQZg1zaQ.js";
1
+ import { $ as CrustError, A as SectionConsumer, At as LocalFlagNameBrand, B as ExtensionBuilder, C as InvocationOptions, Ct as RunInputArguments, D as ParsedArgValue, Dt as CommandSnapshot, E as ParseResult, Et as ArgSnapshot, F as BuildArtifacts, Ft as defineExtensionId, G as ExtensionSectionContribution, H as ExtensionFactory, I as BuildFile, J as InvocationOutcome, K as Finished, L as BuildReport, M as ValueType, Mt as LocalValueBrand, Nt as MergeContext, O as ParsedFlagValue, Ot as FlagSnapshot, Pt as ExtensionId, Q as CommandNotFoundErrorDetails, R as Extension, S as InvocationIO, St as RunInput, T as NamedFlagDef, Tt as defineCommand, U as ExtensionFlagDef, V as ExtensionContext, W as ExtensionHooks, X as RootMetaKey, Y as NamedExtensionFlagDef, Z as defineExtension, _ as ExecuteOptions, _t as CommandTree, a as ContextInstance, at as EnvErrorDetails, b as InputArgs, bt as RootCommandMeta, c as FactoryValueOf, ct as ValidationErrorDetails, d as ArgDef, dt as CommandDefinition, et as CrustErrorCode, f as ArgsDef, ft as CommandDefinitionBuilder, gt as CommandShapeAt, h as CommandSectionInput, ht as CommandShape, i as ContextFactory, it as DefinitionErrorDetails, j as ValidatedInput, jt as EmptyArgNameBrand, k as SectionAudience, kt as LocalFlagBrand, l as contextSources, lt as AnyCrust, m as CommandSection, mt as CommandPath, n as ContextBag, nt as CrustErrorDetailsMap, o as ContextMap, ot as EnvIssue, p as CommandMeta, pt as CommandHandle, q as InferExtensionFlags, r as ContextBuilder, rt as CrustErrorJson, s as ContextSetup, st as ParseErrorDetails, t as AnyContextFactory, tt as CrustErrorDetails, u as defineContext, ut as CommandConfig, v as FlagDef, vt as Crust, w as MergeFlags, wt as RunOutcome, x as InputFlags, xt as RunArguments, y as FlagsDef, yt as CrustCommandContext, z as ExtensionBuildContext } from "./context-9ee4iljp.js";
2
2
  import { resolveArtifactDir } from "@crustjs/utils/artifacts";
3
3
  //#region src/api/flags.d.ts
4
4
  /** Distribute `Omit<_, "name">` over the {@link ArgDef} union. */
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { C as normalizeFlag, S as normalizeArg, _ as validateContextAvailability, a as runInvocation, b as validateCommandSections, c as cloneCommandNode, d as createCommandNode, f as registerFlag, g as definingOf, h as defineContext, i as resolveTypedPath, l as cloneFlagRegistry, m as contextSources, n as executeInvocation, o as snapshotCommand, p as defineExtension, r as prepareInvocation, u as installExtensionContexts, w as CrustError } from "./invocation-ljkrw2dt.js";
1
+ import { C as normalizeFlag, S as normalizeArg, _ as validateContextAvailability, a as runInvocation, b as validateCommandSections, c as cloneCommandNode, d as createCommandNode, f as registerFlag, g as definingOf, h as defineContext, i as resolveTypedPath, l as cloneFlagRegistry, m as contextSources, n as executeInvocation, o as snapshotCommand, p as defineExtension, r as prepareInvocation, u as installExtensionContexts, w as CrustError } from "./invocation-CD299Gic.js";
2
2
  import { resolveArtifactDir } from "@crustjs/utils/artifacts";
3
3
  //#region src/identity.ts
4
4
  /** Mint an Extension identity from any non-blank, trimmed string. */
@@ -307,54 +307,6 @@ function createContextFactory(name, use, ownedFlags, sections, setup) {
307
307
  function defineContext(name) {
308
308
  return createContextBuilder(name, Object.freeze([]), Object.freeze({}), Object.freeze([]));
309
309
  }
310
- function isDisposeCallback(value) {
311
- return typeof value === "function";
312
- }
313
- /**
314
- * Minimal `AsyncDisposableStack` stand-in for runtimes without the global
315
- * (Node 22): LIFO disposal of used resources and deferred callbacks,
316
- * preferring `Symbol.asyncDispose` over `Symbol.dispose`.
317
- *
318
- * ponytail: multiple disposal errors aggregate as `AggregateError` instead of
319
- * the native `SuppressedError` chain; delete this class when Node 22 leaves
320
- * the support floor.
321
- *
322
- * @internal Exported for unit testing and invocation wiring.
323
- */
324
- var FallbackAsyncDisposableStack = class {
325
- #entries = [];
326
- #disposed = false;
327
- #assertPending() {
328
- if (this.#disposed) throw new ReferenceError("AsyncDisposableStack is already disposed");
329
- }
330
- use(value) {
331
- this.#assertPending();
332
- const dispose = hasAsyncDispose(value) ? value[Symbol.asyncDispose] : value[Symbol.dispose];
333
- this.#entries.push(() => dispose.call(value));
334
- return value;
335
- }
336
- defer(onDisposeAsync) {
337
- this.#assertPending();
338
- if (!isDisposeCallback(onDisposeAsync)) throw new TypeError("defer callback is not callable");
339
- this.#entries.push(onDisposeAsync);
340
- }
341
- async [Symbol.asyncDispose]() {
342
- if (this.#disposed) return;
343
- this.#disposed = true;
344
- const errors = [];
345
- for (let index = this.#entries.length - 1; index >= 0; index--) try {
346
- await this.#entries[index]();
347
- } catch (error) {
348
- errors.push(error);
349
- }
350
- if (errors.length === 1) throw errors[0];
351
- if (errors.length > 1) throw new AggregateError(errors, "Disposal failed");
352
- }
353
- };
354
- const DisposalStack = globalThis.AsyncDisposableStack ?? FallbackAsyncDisposableStack;
355
- function hasAsyncDispose(value) {
356
- return typeof value[Symbol.asyncDispose] === "function";
357
- }
358
310
  function isDisposableValue(value) {
359
311
  if (value === null || typeof value !== "object" && typeof value !== "function") return false;
360
312
  const candidate = value;
@@ -1565,62 +1517,6 @@ function resolveCommand(command, argv) {
1565
1517
  };
1566
1518
  }
1567
1519
  //#endregion
1568
- //#region \0@oxc-project+runtime@0.150.0/helpers/esm/usingCtx.js
1569
- function _usingCtx() {
1570
- var r = "function" == typeof SuppressedError ? SuppressedError : function(r, e) {
1571
- var n = Error();
1572
- return n.name = "SuppressedError", n.error = r, n.suppressed = e, n;
1573
- }, e = {}, n = [];
1574
- function using(r, e) {
1575
- if (null != e) {
1576
- if (Object(e) !== e) throw new TypeError("using declarations can only be used with objects, functions, null, or undefined.");
1577
- if (r) var o = e[Symbol.asyncDispose || Symbol["for"]("Symbol.asyncDispose")];
1578
- if (void 0 === o && (o = e[Symbol.dispose || Symbol["for"]("Symbol.dispose")], r)) var t = o;
1579
- if ("function" != typeof o) throw new TypeError("Object is not disposable.");
1580
- t && (o = function o() {
1581
- try {
1582
- t.call(e);
1583
- } catch (r) {
1584
- return Promise.reject(r);
1585
- }
1586
- }), n.push({
1587
- v: e,
1588
- d: o,
1589
- a: r
1590
- });
1591
- } else r && n.push({
1592
- d: e,
1593
- a: r
1594
- });
1595
- return e;
1596
- }
1597
- return {
1598
- e,
1599
- u: using.bind(null, !1),
1600
- a: using.bind(null, !0),
1601
- d: function d() {
1602
- var o, t = this.e, s = 0;
1603
- function next() {
1604
- for (; o = n.pop();) try {
1605
- if (!o.a && 1 === s) return s = 0, n.push(o), Promise.resolve().then(next);
1606
- if (o.d) {
1607
- var r = o.d.call(o.v);
1608
- if (o.a) return s |= 2, Promise.resolve(r).then(next, err);
1609
- } else s |= 1;
1610
- } catch (r) {
1611
- return err(r);
1612
- }
1613
- if (1 === s) return t !== e ? Promise.reject(t) : Promise.resolve();
1614
- if (t !== e) throw t;
1615
- }
1616
- function err(n) {
1617
- return t = t !== e ? new r(n, t) : n, next();
1618
- }
1619
- return next();
1620
- }
1621
- };
1622
- }
1623
- //#endregion
1624
1520
  //#region src/command/invocation.ts
1625
1521
  const ignoreStreamError = () => {};
1626
1522
  /**
@@ -1672,7 +1568,7 @@ function isAbortError(error) {
1672
1568
  return error.name === "AbortError";
1673
1569
  }
1674
1570
  /**
1675
- * Structural: Node 22 bundles down-level `await using` to a plain `Error`
1571
+ * Structural: down-level bundles can implement `await using` with a plain `Error`
1676
1572
  * carrying `error`/`suppressed`, so `instanceof SuppressedError` cannot be used.
1677
1573
  */
1678
1574
  function isSuppressedError(error) {
@@ -1825,98 +1721,91 @@ function resolveStructuredInput(root, path, input) {
1825
1721
  }
1826
1722
  /** Resolve, parse, and run one invocation without rendering failures. */
1827
1723
  async function dispatch(input, prepared, io, signal, onExtensionContext, onFailure) {
1828
- try {
1829
- var _usingCtx$1 = _usingCtx();
1830
- const { rootNode, extensions } = prepared;
1831
- const { argv, route, parsed } = "argv" in input ? resolveArgvInput(rootNode, input.argv) : resolveStructuredInput(rootNode, input.path, input.input);
1832
- const resolvedNode = route.command;
1833
- const disposal = _usingCtx$1.a(new DisposalStack());
1834
- const contexts = resolvedNode.contexts.map(({ instance }) => instance);
1835
- const resolver = createContextResolver(contexts, io, disposal, signal);
1836
- const rootSnapshot = snapshotCommand(rootNode);
1837
- let commandSnapshot = rootSnapshot;
1838
- for (const name of route.commandPath.slice(1)) commandSnapshot = commandSnapshot.subCommands[name];
1839
- const extensionContext = Object.freeze({
1840
- argv: [...argv],
1841
- rootCommand: rootSnapshot,
1842
- command: commandSnapshot,
1843
- commandPath: Object.freeze([...route.commandPath]),
1844
- args: parsed.args,
1845
- flags: parsed.flags,
1724
+ const { rootNode, extensions } = prepared;
1725
+ const { argv, route, parsed } = "argv" in input ? resolveArgvInput(rootNode, input.argv) : resolveStructuredInput(rootNode, input.path, input.input);
1726
+ const resolvedNode = route.command;
1727
+ await using disposal = new AsyncDisposableStack();
1728
+ const contexts = resolvedNode.contexts.map(({ instance }) => instance);
1729
+ const resolver = createContextResolver(contexts, io, disposal, signal);
1730
+ const rootSnapshot = snapshotCommand(rootNode);
1731
+ let commandSnapshot = rootSnapshot;
1732
+ for (const name of route.commandPath.slice(1)) commandSnapshot = commandSnapshot.subCommands[name];
1733
+ const extensionContext = Object.freeze({
1734
+ argv: [...argv],
1735
+ rootCommand: rootSnapshot,
1736
+ command: commandSnapshot,
1737
+ commandPath: Object.freeze([...route.commandPath]),
1738
+ args: parsed.args,
1739
+ flags: parsed.flags,
1740
+ rawArgs: parsed.rawArgs,
1741
+ signal,
1742
+ ctx: resolver.bag(extensions.flatMap((extension) => extension.use)),
1743
+ finish: finishInvocation,
1744
+ stdout: io.stdout,
1745
+ stderr: io.stderr
1746
+ });
1747
+ onExtensionContext?.(extensionContext);
1748
+ const terminal = async () => {
1749
+ validateParsed(resolvedNode, parsed);
1750
+ const validated = await applySchemas(resolvedNode, parsed);
1751
+ resolver.setValidatedFlags(validated.flags);
1752
+ if (!resolvedNode.run) return;
1753
+ const context = {
1754
+ args: validated.args,
1755
+ flags: validated.flags,
1756
+ ctx: resolver.bag(contexts),
1846
1757
  rawArgs: parsed.rawArgs,
1847
1758
  signal,
1848
- ctx: resolver.bag(extensions.flatMap((extension) => extension.use)),
1849
- finish: finishInvocation,
1759
+ command: extensionContext.command,
1760
+ rootCommand: rootSnapshot,
1850
1761
  stdout: io.stdout,
1851
1762
  stderr: io.stderr
1852
- });
1853
- onExtensionContext?.(extensionContext);
1854
- const terminal = async () => {
1855
- validateParsed(resolvedNode, parsed);
1856
- const validated = await applySchemas(resolvedNode, parsed);
1857
- resolver.setValidatedFlags(validated.flags);
1858
- if (!resolvedNode.run) return;
1859
- const context = {
1860
- args: validated.args,
1861
- flags: validated.flags,
1862
- ctx: resolver.bag(contexts),
1863
- rawArgs: parsed.rawArgs,
1864
- signal,
1865
- command: extensionContext.command,
1866
- rootCommand: rootSnapshot,
1867
- stdout: io.stdout,
1868
- stderr: io.stderr
1869
- };
1870
- return await resolvedNode.run(context);
1871
1763
  };
1872
- let result;
1873
- let outcome = { status: "completed" };
1764
+ return await resolvedNode.run(context);
1765
+ };
1766
+ let result;
1767
+ let outcome = { status: "completed" };
1768
+ try {
1874
1769
  try {
1875
- try {
1876
- for (const extension of extensions) if (await extension.hooks?.preRun?.(extensionContext) === finishInvocation()) {
1877
- outcome = {
1878
- status: "finished",
1879
- by: extension.id
1880
- };
1881
- break;
1882
- }
1883
- if (outcome.status !== "finished") result = await terminal();
1884
- } catch (error) {
1885
- const by = await onFailure?.(error, extensionContext);
1770
+ for (const extension of extensions) if (await extension.hooks?.preRun?.(extensionContext) === finishInvocation()) {
1886
1771
  outcome = {
1887
- status: "failed",
1888
- error,
1889
- ...by === void 0 ? {} : { by }
1772
+ status: "finished",
1773
+ by: extension.id
1890
1774
  };
1775
+ break;
1891
1776
  }
1892
- Object.freeze(outcome);
1893
- let postRunFailed = false;
1894
- let postRunError;
1895
- for (const extension of extensions.toReversed()) try {
1896
- await extension.hooks?.postRun?.(extensionContext, outcome);
1897
- } catch (error) {
1898
- if (outcome.status !== "failed" && !postRunFailed) {
1899
- postRunFailed = true;
1900
- postRunError = error;
1901
- }
1777
+ if (outcome.status !== "finished") result = await terminal();
1778
+ } catch (error) {
1779
+ const by = await onFailure?.(error, extensionContext);
1780
+ outcome = {
1781
+ status: "failed",
1782
+ error,
1783
+ ...by === void 0 ? {} : { by }
1784
+ };
1785
+ }
1786
+ Object.freeze(outcome);
1787
+ let postRunFailed = false;
1788
+ let postRunError;
1789
+ for (const extension of extensions.toReversed()) try {
1790
+ await extension.hooks?.postRun?.(extensionContext, outcome);
1791
+ } catch (error) {
1792
+ if (outcome.status !== "failed" && !postRunFailed) {
1793
+ postRunFailed = true;
1794
+ postRunError = error;
1902
1795
  }
1903
- if (outcome.status === "failed") throw outcome.error;
1904
- if (postRunFailed) throw postRunError;
1905
- } finally {
1906
- await resolver.settle();
1907
1796
  }
1908
- return outcome.status === "finished" ? {
1909
- status: "finished",
1910
- by: outcome.by
1911
- } : {
1912
- status: "completed",
1913
- result
1914
- };
1915
- } catch (_) {
1916
- _usingCtx$1.e = _;
1797
+ if (outcome.status === "failed") throw outcome.error;
1798
+ if (postRunFailed) throw postRunError;
1917
1799
  } finally {
1918
- await _usingCtx$1.d();
1800
+ await resolver.settle();
1919
1801
  }
1802
+ return outcome.status === "finished" ? {
1803
+ status: "finished",
1804
+ by: outcome.by
1805
+ } : {
1806
+ status: "completed",
1807
+ result
1808
+ };
1920
1809
  }
1921
1810
  /** Render one failure through Extension onError hooks, ending in Core's default renderer. */
1922
1811
  async function renderFailure(error, argv, prepared, io, signal, extensionContext, silentDefault = false) {
package/dist/tooling.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Dt as CommandSnapshot, N as FlagEnvironment, Ot as FlagSnapshot, P as parseFlagValues, Pt as ExtensionId, g as DeclaredDefault, m as CommandSection } from "./context-WQZg1zaQ.js";
1
+ import { Dt as CommandSnapshot, N as FlagEnvironment, Ot as FlagSnapshot, P as parseFlagValues, Pt as ExtensionId, g as DeclaredDefault, m as CommandSection } from "./context-9ee4iljp.js";
2
2
  import { BUILD_OUT_DIR_ENV } from "@crustjs/utils/artifacts";
3
3
  //#region src/command/invocation.d.ts
4
4
  /**
package/dist/tooling.js CHANGED
@@ -1,4 +1,4 @@
1
- import { s as parseFlagValues, t as SNAPSHOT_PATH_ENV, v as isListed, x as visibleSectionsFor, y as sectionsFor } from "./invocation-ljkrw2dt.js";
1
+ import { s as parseFlagValues, t as SNAPSHOT_PATH_ENV, v as isListed, x as visibleSectionsFor, y as sectionsFor } from "./invocation-CD299Gic.js";
2
2
  import { BUILD_OUT_DIR_ENV } from "@crustjs/utils/artifacts";
3
3
  //#region src/command/documentation.ts
4
4
  function isNonFiniteNumber(value) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crustjs/core",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "Core library for the Crust CLI framework",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -41,11 +41,11 @@
41
41
  "access": "public"
42
42
  },
43
43
  "dependencies": {
44
- "@crustjs/utils": "^0.2.0"
44
+ "@crustjs/utils": "^0.2.1"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@crustjs/config": "0.0.0",
48
- "vite-plus": "1.0.0-rc.0"
48
+ "vite-plus": "1.0.0"
49
49
  },
50
50
  "peerDependencies": {
51
51
  "typescript": "^7.0.0"
@@ -57,7 +57,7 @@
57
57
  },
58
58
  "engines": {
59
59
  "bun": ">=1.4.0",
60
- "node": ">=22",
60
+ "node": ">=24",
61
61
  "deno": ">=2.8"
62
62
  },
63
63
  "scripts": {