@crustjs/core 0.4.1 → 0.5.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.
@@ -223,7 +223,7 @@ type ValidateContextNames<Ctx extends ContextMap, Cs extends readonly AnyContext
223
223
  type InstanceNames<P extends readonly unknown[]> = P extends readonly [infer H, ...infer T extends readonly unknown[]] ? DefName<H> | InstanceNames<T> : never;
224
224
  /** Statically known names of an Extension's provided Contexts; widened Extensions opt out. */
225
225
  type ExtensionProvidedNames<E> = DefiningOf<E> extends {
226
- readonly provides?: infer P extends readonly unknown[];
226
+ readonly provide?: infer P extends readonly unknown[];
227
227
  } ? InstanceNames<P> : never;
228
228
  type ExtensionContextBrand<E, Existing extends string> = CollisionBrand<ExtensionProvidedNames<E>, Existing, "FIX_DUPLICATE_CONTEXT", "Extension-provided Context ", " is already provided on this command path">;
229
229
  type ValidateExtensionProvidesWorker<Es extends readonly unknown[], Existing extends string> = Es extends readonly [infer H, ...infer T extends readonly unknown[]] ? readonly [H & ExtensionContextBrand<H, Existing>, ...ValidateExtensionProvidesWorker<T, Existing | ExtensionProvidedNames<H>>] : Es;
@@ -246,9 +246,10 @@ type MismatchedDependencyBrand<C, KnownValues> = MismatchedDependencyNames<Provi
246
246
  type ValidateContextDeps<Ctx extends ContextMap, Cs extends readonly AnyContextInstance[], Known extends string = (keyof Ctx & string) | DefName<Cs[number]>, KnownValues extends ContextMap = Ctx & ContextsOutput<Cs>> = { [I in keyof Cs]: Cs[I] & MissingDependencyBrand<Cs[I], Known> & MismatchedDependencyBrand<Cs[I], KnownValues>; };
247
247
  /** Dependency closure carried by command definitions and Extensions. */
248
248
  type IsAny<T> = 0 extends 1 & T ? true : false;
249
- type DeclaredDepsOf<T> = IsAny<T> extends true ? Record<string, ContextValue> : CommandDefinitionData<DefiningOf<T>> extends {
249
+ type DeclaredDepsOfMember<T> = IsAny<T> extends true ? Record<string, ContextValue> : CommandDefinitionData<DefiningOf<T>> extends {
250
250
  readonly _deps?: infer D extends ContextMap;
251
251
  } ? IsAny<D> extends true ? Record<string, ContextValue> : D : {};
252
+ type DeclaredDepsOf<T> = (T extends unknown ? (deps: DeclaredDepsOfMember<T>) => void : never) extends ((deps: infer Deps extends ContextMap) => void) ? Deps : {};
252
253
  /** Missing-dependency brand shared by `ValidateDeclaredDeps` and inline `.command()`. */
253
254
  type MissingDeclaredDependencyBrand<T, Known extends string> = string extends keyof DeclaredDepsOf<T> ? {} : Exclude<keyof DeclaredDepsOf<T> & string, Known> extends (infer Missing extends string) ? [Missing] extends [never] ? {} : {
254
255
  readonly FIX_MISSING_DEPENDENCY: `Uses Context "${Missing}" which is not provided`;
@@ -341,7 +342,7 @@ type ExtensionFlagDefsOf<E> = [E] extends [never] ? readonly [] : DefiningOf<E>
341
342
  type ProvidedContextSpellings<P extends readonly unknown[]> = P extends readonly [infer H, ...infer T extends readonly unknown[]] ? LocalSpellingsOf<ContextOwnedFlags<H>> | ProvidedContextSpellings<T> : [P[number]] extends [never] ? never : LocalSpellingsOf<ContextOwnedFlags<P[number]>>;
342
343
  /** All statically known flag spellings an Extension contributes: declared flags plus provided Context-owned flags. */
343
344
  type ExtensionSpellings<E> = AttachedSpellings<ExtensionFlagDefsOf<E>> | ([E] extends [never] ? never : DefiningOf<E> extends {
344
- readonly provides?: infer P extends readonly unknown[];
345
+ readonly provide?: infer P extends readonly unknown[];
345
346
  } ? ProvidedContextSpellings<P> : never);
346
347
  type ExtensionFlagCollisionBrand<E, Existing extends string> = CollisionBrand<ExtensionSpellings<E>, Existing, "FIX_ALIAS_COLLISION", "Extension flag spelling ", " collides with an existing flag">;
347
348
  /**
@@ -668,7 +669,7 @@ type KnownDefinitionTree<Ds extends readonly unknown[], CF extends FlagsDef> = I
668
669
  type ExtensionCheckAt<Checks, I> = I extends keyof Checks ? Checks[I] : never;
669
670
  type ExtensionCommands<Es extends readonly AnyExtension[]> = Es extends readonly [infer H, ...infer T extends readonly AnyExtension[]] ? readonly [...ExtensionCommandDefs<H>, ...ExtensionCommands<T>] : ExtensionCommandDefs<Es[number]>[number] extends never ? readonly [] : readonly CommandDefinition<any, any, any, any>[];
670
671
  type ExtensionProviders<E> = [E] extends [never] ? [] : DefiningOf<E> extends {
671
- provides?: infer P extends readonly AnyContextInstance[];
672
+ provide?: infer P extends readonly AnyContextInstance[];
672
673
  } ? P : [];
673
674
  type ExtensionOwnDefs<E> = [E] extends [never] ? [] : DefiningOf<E> extends {
674
675
  _flagDefs?: infer F extends readonly NamedFlagDef[];
@@ -763,9 +764,8 @@ type AfterAction<Flags extends FlagsDef, A extends ArgsDef, Ctx extends ContextM
763
764
  }, Awaited<R>, Meta, string, Caps>;
764
765
  type AfterExtend<Flags extends FlagsDef, A extends ArgsDef, Ctx extends ContextMap, Sibs extends string, Sp extends string, Tree extends object, CtxFlags extends FlagsDef, CollisionSp extends AnyCollisionSpellings, Result, Es extends readonly AnyExtension[], Meta extends RootCommandMeta | undefined, Caps extends "app" | "recipe"> = Crust<MergeFlags<Flags, ExtensionFlags<Es>>, A, MergeProviders<Ctx, ExtensionsProvidesOutput<Es>>, Sibs | ExtensionsCommandSpellings<Es>, Sp | ExtensionsSpellings<Es>, ExtendedTree<Tree, Es, RecursiveExtensionFlags<Es>, CtxFlags>, MergeFlags<CtxFlags, RecursiveExtensionFlags<Es>>, CollisionSpellings<CollisionSp["extension"] | ExtensionsSpellings<Es>, CollisionSp["tree"] | DefinitionTreeSpellings<ExtensionCommands<Es>>, CollisionSp["demands"] & ExtensionDemandValues<Es>, CollisionSp["pending"] | DefinitionTreeSpellings<ExtensionCommands<Es>>, RecipeDepsOf<CollisionSp>, MergeProviders<ProvidersOf<CollisionSp>, ExtensionsProvidesOutput<Es>>, ActionDepsOf<CollisionSp>>, Result, Meta, string, Caps>;
765
766
  type AfterAdd<Flags extends FlagsDef, A extends ArgsDef, Ctx extends ContextMap, Sibs extends string, Sp extends string, Tree extends object, CtxFlags extends FlagsDef, CollisionSp extends AnyCollisionSpellings, Result, Ds extends readonly CommandDefinition<any, any, any, any>[], Meta extends RootCommandMeta | undefined, Caps extends "app" | "recipe"> = Crust<Flags, A, Ctx, Sibs | AttachedCommandSpellings<Ds>, Sp, Tree & DefinitionsTree<Ds, CtxFlags>, CtxFlags, CollisionSpellings<CollisionSp["extension"], CollisionSp["tree"] | DefinitionTreeSpellings<Ds>, CollisionSp["demands"], CollisionSp["pending"], RecipeDepsOf<CollisionSp>, ProvidersOf<CollisionSp>, ActionDepsOf<CollisionSp>>, Result, Meta, string, Caps>;
766
- type ExtensionDemandValues<Es extends readonly AnyExtension[]> = UnionToIntersection<DefiningOf<Es[number]> extends {
767
- readonly _hookDeps?: infer H extends ContextMap;
768
- } ? H : Record<string, ContextValue>> extends (infer D extends ContextMap) ? D : {};
767
+ type ExtensionHookDemand<E> = E extends AnyExtension ? (deps: NonNullable<DefiningOf<E>["_hookDeps"]>) => void : never;
768
+ type ExtensionDemandValues<Es extends readonly AnyExtension[]> = ExtensionHookDemand<Es[number]> extends ((deps: infer D extends ContextMap) => void) ? D : {};
769
769
  type DescendantShapeValuesBrand<S, Deps> = S extends CommandShape ? DeclaredDependencyValuesBrand<Deps, NonNullable<S[typeof commandProviders]>> & DescendantValuesBrand<S["children"], Deps> : {};
770
770
  type DescendantValuesBrand<Tree, Deps> = keyof Deps extends never ? {} : UnionToIntersection<Tree extends unknown ? keyof Tree extends never ? {} : { [K in keyof Tree]: DescendantShapeValuesBrand<Tree[K], Deps>; }[keyof Tree] : never>;
771
771
  type DefinitionDescendantValuesBrand<Ds extends readonly CommandDefinition<any, any, any, any>[], Deps> = DescendantValuesBrand<DefinitionsTree<Ds>, Deps>;
@@ -851,6 +851,8 @@ declare class Crust<Flags extends FlagsDef = {}, A extends ArgsDef = [], Ctx ext
851
851
  * reverse construction order after post-run hooks. TypeScript rejects known Context-owned flag collisions, including pending
852
852
  * Extension commands. Consuming operations throw `DEFINITION` for actual collisions.
853
853
  *
854
+ * Context `sections` document only this command, never descendants. Preparation throws
855
+ * `DEFINITION` when one repeats a section title already on this command.
854
856
  */
855
857
  provide<const Cs extends readonly AnyContextInstance[] = never>(...instances: KnownContextInstances<Cs> & ProvideChecks<Sp | CollisionSp["pending"], Cs> & ValidateContextNames<Caps extends "recipe" ? ProvidersOf<CollisionSp> : Ctx, Cs> & ValidateContextDeps<Ctx, Cs> & DeclaredDependencyValuesBrand<CollisionSp["demands"] & RecipeDepsOf<CollisionSp> & ActionDepsOf<CollisionSp>, ContextsOutput<NoInfer<Cs>>>): AfterProvide<Flags, A, Ctx, Sibs, Sp, Tree, CtxFlags, CollisionSp, Result, Cs, Meta, Caps>;
856
858
  /**
@@ -1021,11 +1023,25 @@ interface DefinitionErrorDetails {
1021
1023
  readonly name?: string;
1022
1024
  readonly reason?: string;
1023
1025
  }
1026
+ /** One environment variable that failed; its value is never recorded. */
1027
+ interface EnvIssue {
1028
+ /** Variable name as declared. */
1029
+ readonly name: string;
1030
+ /** Declared expectation, e.g. `"number"` or `"one of: debug, info"`. */
1031
+ readonly expected: string;
1032
+ /** Whether the variable was unset or held a value that failed parsing or validation. */
1033
+ readonly received: "missing" | "invalid";
1034
+ }
1035
+ /** Every missing or invalid variable of one `@crustjs/env` definition. */
1036
+ interface EnvErrorDetails {
1037
+ readonly issues: readonly EnvIssue[];
1038
+ }
1024
1039
  interface CrustErrorDetailsMap {
1025
1040
  DEFINITION: DefinitionErrorDetails | undefined;
1026
1041
  VALIDATION: ValidationErrorDetails | undefined;
1027
1042
  PARSE: ParseErrorDetails | undefined;
1028
1043
  COMMAND_NOT_FOUND: CommandNotFoundErrorDetails;
1044
+ ENV: EnvErrorDetails;
1029
1045
  }
1030
1046
  /**
1031
1047
  * All possible error codes emitted by Crust.
@@ -1034,6 +1050,7 @@ interface CrustErrorDetailsMap {
1034
1050
  * - `VALIDATION` — Missing required arguments or flags
1035
1051
  * - `PARSE` — Argv parsing failures (unknown flags, type coercion)
1036
1052
  * - `COMMAND_NOT_FOUND` — Unrecognised subcommand at the current level
1053
+ * - `ENV` — Missing or invalid `@crustjs/env` variables (values redacted)
1037
1054
  *
1038
1055
  * @example
1039
1056
  * ```ts
@@ -1284,67 +1301,100 @@ type ExtensionSectionContribution = RuntimeCommandSectionInput & {
1284
1301
  readonly command: readonly string[];
1285
1302
  };
1286
1303
  type CommandDefinitionsDependencies<Commands extends readonly CommandDefinition<any, any, any, any>[]> = Commands extends readonly [infer H extends CommandDefinition<any, any, any, any>, ...infer T extends readonly CommandDefinition<any, any, any, any>[]] ? ([H] extends [never] ? {} : DeclaredDepsOf<H>) & CommandDefinitionsDependencies<T> : Commands extends readonly [] ? {} : Record<string, ContextValue>;
1287
- interface ExtensionConfig<Defs extends readonly NamedExtensionFlagDef[] = readonly NamedExtensionFlagDef[], Uses extends readonly AnyContextFactory[] = readonly AnyContextFactory[], Provides extends readonly AnyContextInstance[] = readonly AnyContextInstance[], Commands extends readonly CommandDefinition<any, any, any, any>[] = readonly CommandDefinition<any, any, any, any>[], MetaKeys extends RootMetaKey = never> {
1288
- readonly flags?: Defs;
1289
- readonly commands?: Commands;
1290
- readonly uses?: Uses;
1291
- readonly provides?: Provides;
1292
- readonly sections?: (snapshot: RootCommandSnapshot<MetaKeys>) => readonly ExtensionSectionContribution[];
1293
- readonly build?: (ctx: ExtensionBuildContext<MetaKeys>) => Awaitable<BuildArtifacts>;
1294
- readonly hooks?: ExtensionHooks<Defs, ContextDependencies<Uses>, MetaKeys>;
1295
- }
1296
- type ValidateExtensionConfig<Defs extends readonly NamedExtensionFlagDef[], Provides extends readonly AnyContextInstance[], Commands extends readonly CommandDefinition<any, any, any, any>[], Uses extends readonly AnyContextFactory[]> = {
1297
- readonly uses?: Uses;
1298
- readonly commands?: ValidateCommandDefinitions<Commands>;
1299
- readonly flags?: ValidateLocalFlagDefs<Defs, ProvidedContextSpellings<Provides>>;
1300
- readonly provides?: KnownContextInstances<Provides> & ProvideChecks<never, Provides>;
1301
- };
1304
+ type ExtensionDeps<Use extends readonly AnyContextFactory[], Provide extends readonly AnyContextInstance[], Commands extends readonly CommandDefinition<any, any, any, any>[]> = ContextDependencies<Use> & ContextsDependencies<Provide> & CommandDefinitionsDependencies<Commands>;
1305
+ /** Flag spellings an Extension already owns: declared flags plus provided Context-owned flags. */
1306
+ type DeclaredSpellings<Defs extends readonly NamedExtensionFlagDef[], Provide extends readonly AnyContextInstance[]> = AttachedSpellings<Defs> | ProvidedContextSpellings<Provide>;
1302
1307
  declare const extensionHookProof: unique symbol;
1303
- interface Extension<Deps extends ContextMap = ContextMap, Provides extends readonly AnyContextInstance[] = readonly AnyContextInstance[], FlagDefs extends readonly NamedExtensionFlagDef[] = readonly NamedExtensionFlagDef[], Commands extends readonly CommandDefinition<any, any, any, any>[] = readonly CommandDefinition<any, any, any, any>[], out MetaKeys extends RootMetaKey = never, HookDeps extends ContextMap = Deps> extends Defining<Extension<Deps, Provides, FlagDefs, Commands, MetaKeys, HookDeps>> {
1308
+ /**
1309
+ * @internal Sealed runtime record behind an {@link Extension} handle. Runtime
1310
+ * consumers read it through `definingOf`, so structural copies of a handle keep
1311
+ * the declaration proofs `.extend()` checks.
1312
+ */
1313
+ interface ExtensionData<Deps extends ContextMap = ContextMap, Provide extends readonly AnyContextInstance[] = readonly AnyContextInstance[], FlagDefs extends readonly NamedExtensionFlagDef[] = readonly NamedExtensionFlagDef[], Commands extends readonly CommandDefinition<any, any, any, any>[] = readonly CommandDefinition<any, any, any, any>[], out MetaKeys extends RootMetaKey = never, HookDeps extends ContextMap = Deps> {
1304
1314
  /** @internal Hook demands are distinct from command/provider attachment dependencies. */
1305
1315
  readonly _hookDeps?: HookDeps;
1306
1316
  readonly [extensionHookProof]?: (deps: HookDeps) => void;
1307
1317
  readonly id: ExtensionId;
1308
- readonly flags?: Readonly<Record<string, ExtensionFlagDef>>;
1318
+ readonly flags: Readonly<Record<string, ExtensionFlagDef>>;
1309
1319
  /** @internal — phantom carrying declared flag literals for extend-time collision checks */
1310
1320
  readonly _flagDefs?: FlagDefs;
1311
- readonly commands?: Commands;
1312
- readonly uses: readonly AnyContextFactory[];
1313
- readonly provides?: Provides;
1321
+ readonly commands: Commands;
1322
+ readonly use: readonly AnyContextFactory[];
1323
+ readonly provide: Provide;
1314
1324
  readonly sections?: (snapshot: RootCommandSnapshot<MetaKeys>) => readonly ExtensionSectionContribution[];
1315
1325
  readonly build?: (ctx: ExtensionBuildContext<MetaKeys>) => Awaitable<BuildArtifacts>;
1316
- readonly hooks?: ExtensionHooks<any, Deps, MetaKeys>;
1326
+ readonly hooks: ExtensionHooks<any, Deps, MetaKeys>;
1317
1327
  readonly _deps?: Deps;
1318
1328
  }
1329
+ /**
1330
+ * An Extension handle accepted by `.extend()`. Contribution parameters default to
1331
+ * open sets; holders keep the private dependency and hook-demand proofs.
1332
+ */
1333
+ interface Extension<Deps extends ContextMap = ContextMap, Provide extends readonly AnyContextInstance[] = readonly AnyContextInstance[], FlagDefs extends readonly NamedExtensionFlagDef[] = readonly NamedExtensionFlagDef[], Commands extends readonly CommandDefinition<any, any, any, any>[] = readonly CommandDefinition<any, any, any, any>[], out MetaKeys extends RootMetaKey = never, HookDeps extends ContextMap = Deps> extends Defining<ExtensionData<Deps, Provide, FlagDefs, Commands, MetaKeys, HookDeps>> {
1334
+ readonly id: ExtensionId;
1335
+ }
1319
1336
  /** @internal Broad Extension constraint; contravariance requires the full metadata key set. */
1320
1337
  type AnyExtension = Extension<any, any, any, any, RootMetaKey>;
1321
- type ExtensionProvidesOutput<E> = DefiningOf<E> extends Extension<any, infer Provides, any, any, RootMetaKey> ? ContextsOutput<Provides> : {};
1322
- type ExtensionsProvidesOutput<Es extends readonly AnyExtension[]> = Es extends readonly [infer H, ...infer T extends readonly AnyExtension[]] ? MergeProviders<ExtensionProvidesOutput<H>, ExtensionsProvidesOutput<T>> : Es extends readonly [] ? {} : Es[number] extends Extension<any, infer P, any, any, RootMetaKey> ? P[number] extends never ? {} : Record<string, ContextValue> : {};
1338
+ type ExtensionProvidesOutput<E> = DefiningOf<E> extends ExtensionData<any, infer Provide, any, any, RootMetaKey> ? ContextsOutput<Provide> : {};
1339
+ type ExtensionsProvidesOutput<Es extends readonly AnyExtension[]> = Es extends readonly [infer H, ...infer T extends readonly AnyExtension[]] ? MergeProviders<ExtensionProvidesOutput<H>, ExtensionsProvidesOutput<T>> : Es extends readonly [] ? {} : DefiningOf<Es[number]> extends ExtensionData<any, infer P, any, any, RootMetaKey> ? P[number] extends never ? {} : Record<string, ContextValue> : {};
1323
1340
  /**
1324
1341
  * A callable Extension constructor whose identity is also a section consumer.
1325
1342
  * Contribution parameters default to closed sets. Use `ContextMap`,
1326
1343
  * `readonly AnyContextInstance[]`, `readonly NamedExtensionFlagDef[]`, or
1327
1344
  * `readonly CommandDefinition<any, any, any, any>[]` to keep a namespace open.
1328
1345
  */
1329
- type ExtensionFactory<Args extends readonly unknown[] = [], Deps extends ContextMap = {}, Provides extends readonly AnyContextInstance[] = [], Defs extends readonly NamedExtensionFlagDef[] = [], Commands extends readonly CommandDefinition<any, any, any, any>[] = [], MetaKeys extends RootMetaKey = never, HookDeps extends ContextMap = Deps> = ((...args: Args) => Extension<Deps, Provides, Defs, Commands, MetaKeys, HookDeps>) & {
1346
+ type ExtensionFactory<Args extends readonly unknown[] = [], Deps extends ContextMap = {}, Provide extends readonly AnyContextInstance[] = [], Defs extends readonly NamedExtensionFlagDef[] = [], Commands extends readonly CommandDefinition<any, any, any, any>[] = [], MetaKeys extends RootMetaKey = never, HookDeps extends ContextMap = Deps> = ((...args: Args) => Extension<Deps, Provide, Defs, Commands, MetaKeys, HookDeps>) & {
1330
1347
  readonly id: ExtensionId;
1331
1348
  };
1332
- /** Curried Extension definer: explicit metadata keys leave all other types inferred. */
1333
- interface DefineExtensionWith<MetaKeys extends RootMetaKey> {
1334
- <Args extends readonly unknown[], const Defs extends readonly NamedExtensionFlagDef[] = [], const Uses extends readonly AnyContextFactory[] = [], const Provides extends readonly AnyContextInstance[] = [], const Commands extends readonly CommandDefinition<any, any, any, any>[] = []>(id: ExtensionId, factory: (...args: Args) => ExtensionConfig<Defs, Uses, Provides, Commands, MetaKeys> & ValidateExtensionConfig<Defs, Provides, Commands, Uses>): ExtensionFactory<Args, ContextDependencies<Uses> & ContextsDependencies<Provides> & CommandDefinitionsDependencies<Commands>, Provides, Defs, Commands, MetaKeys, ContextDependencies<Uses>>;
1335
- <const Defs extends readonly NamedExtensionFlagDef[] = [], const Uses extends readonly AnyContextFactory[] = [], const Provides extends readonly AnyContextInstance[] = [], const Commands extends readonly CommandDefinition<any, any, any, any>[] = []>(id: ExtensionId, config?: ExtensionConfig<Defs, Uses, Provides, Commands, MetaKeys> & ValidateExtensionConfig<Defs, Provides, Commands, Uses>): Extension<ContextDependencies<Uses> & ContextsDependencies<Provides> & CommandDefinitionsDependencies<Commands>, Provides, Defs, Commands, MetaKeys, ContextDependencies<Uses>>;
1349
+ type ExtensionFactoryOf<Args extends readonly unknown[], E> = E extends Defining<ExtensionData<infer Deps, infer Provide, infer Defs, infer Commands, infer MetaKeys, infer HookDeps>> ? ExtensionFactory<Args, Deps, Provide, Defs, Commands, MetaKeys, HookDeps> : never;
1350
+ type ExtensionHook<Name extends keyof ExtensionHooks, Use extends readonly AnyContextFactory[], Defs extends readonly NamedExtensionFlagDef[], MetaKeys extends RootMetaKey> = NonNullable<ExtensionHooks<Defs, ContextDependencies<Use>, MetaKeys>[Name]>;
1351
+ /**
1352
+ * Immutable fluent Extension authoring handle returned by {@link defineExtension}.
1353
+ * Every method returns a new handle. Collection methods (`use`, `provide`,
1354
+ * `flags`, `add`) append; lifecycle setters (`preRun`, `postRun`, `onError`,
1355
+ * `sections`, `build`) replace the previous callback. Callbacks are typed by the
1356
+ * declarations made before them.
1357
+ */
1358
+ interface ExtensionBuilder<Use extends readonly AnyContextFactory[] = [], Provide extends readonly AnyContextInstance[] = [], Defs extends readonly NamedExtensionFlagDef[] = [], Commands extends readonly CommandDefinition<any, any, any, any>[] = [], MetaKeys extends RootMetaKey = never> extends Extension<ExtensionDeps<Use, Provide, Commands>, Provide, Defs, Commands, MetaKeys, ContextDependencies<Use>> {
1359
+ /**
1360
+ * Declare Contexts the hooks read from `ctx`. This consumes only: the
1361
+ * application (or `.provide()`) must supply each Context.
1362
+ */
1363
+ use<const Fs extends readonly [AnyContextFactory, ...AnyContextFactory[]]>(...factories: Fs): ExtensionBuilder<readonly [...Use, ...Fs], Provide, Defs, Commands, MetaKeys>;
1364
+ /**
1365
+ * Provide Contexts application-wide, regardless of chain position. Provided
1366
+ * Contexts are not exposed to this Extension's hooks unless also declared with `.use()`.
1367
+ */
1368
+ provide<const Cs extends readonly AnyContextInstance[]>(...instances: KnownContextInstances<Cs> & ProvideChecks<DeclaredSpellings<Defs, Provide>, Cs>): ExtensionBuilder<Use, readonly [...Provide, ...Cs], Defs, Commands, MetaKeys>;
1369
+ /** Own flags; `recursive` (default `true`) contributes a flag to every command. */
1370
+ flags<const Fs extends readonly NamedExtensionFlagDef[]>(...defs: ValidateLocalFlagDefs<Fs, DeclaredSpellings<Defs, Provide>>): ExtensionBuilder<Use, Provide, readonly [...Defs, ...Fs], Commands, MetaKeys>;
1371
+ /** Contribute root commands; they replace same-named application commands. */
1372
+ add<const Ds extends readonly CommandDefinition<any, any, any, any>[]>(...definitions: Ds & ValidateCommandDefinitions<Ds, AttachedCommandSpellings<Commands>>): ExtensionBuilder<Use, Provide, Defs, readonly [...Commands, ...Ds], MetaKeys>;
1373
+ /** See {@link ExtensionHooks.preRun}. */
1374
+ preRun(hook: ExtensionHook<"preRun", Use, Defs, MetaKeys>): ExtensionBuilder<Use, Provide, Defs, Commands, MetaKeys>;
1375
+ /** See {@link ExtensionHooks.postRun}. */
1376
+ postRun(hook: ExtensionHook<"postRun", Use, Defs, MetaKeys>): ExtensionBuilder<Use, Provide, Defs, Commands, MetaKeys>;
1377
+ /** See {@link ExtensionHooks.onError}. */
1378
+ onError(hook: ExtensionHook<"onError", Use, Defs, MetaKeys>): ExtensionBuilder<Use, Provide, Defs, Commands, MetaKeys>;
1379
+ /** Contribute documentation sections computed from the prepared root snapshot. */
1380
+ sections(contribute: (snapshot: RootCommandSnapshot<MetaKeys>) => readonly ExtensionSectionContribution[]): ExtensionBuilder<Use, Provide, Defs, Commands, MetaKeys>;
1381
+ /** Generate build artifacts; build tooling writes the returned files. */
1382
+ build(generate: (ctx: ExtensionBuildContext<MetaKeys>) => Awaitable<BuildArtifacts>): ExtensionBuilder<Use, Provide, Defs, Commands, MetaKeys>;
1383
+ /**
1384
+ * Make a configurable Extension: each call passes this handle and the call
1385
+ * arguments to `define`, which must return an Extension with this handle's id.
1386
+ */
1387
+ factory<Args extends readonly unknown[], E extends AnyExtension>(define: (extension: ExtensionBuilder<Use, Provide, Defs, Commands, MetaKeys>, ...args: Args) => E): ExtensionFactoryOf<Args, E>;
1336
1388
  }
1337
1389
  /**
1338
- * Define an Extension, or a factory that builds one from config on each call.
1390
+ * Start an immutable fluent Extension definition.
1339
1391
  *
1340
1392
  * Extensions apply to the whole application and own the flags and commands
1341
- * they contribute. Factories expose the same identity for section audiences.
1342
- * `defineExtension<"version">()(id, configOrFactory)` declares required root
1343
- * metadata keys without preventing inference of flags, Contexts, or commands.
1393
+ * they contribute. `defineExtension<"version">(id)` requires root metadata keys
1394
+ * without preventing inference of flags, Contexts, or commands; chain
1395
+ * `.factory()` for a configurable Extension whose identity is a section consumer.
1344
1396
  */
1345
- declare function defineExtension<MetaKeys extends RootMetaKey = never>(): DefineExtensionWith<MetaKeys>;
1346
- declare function defineExtension<Args extends readonly unknown[], const Defs extends readonly NamedExtensionFlagDef[] = [], const Uses extends readonly AnyContextFactory[] = [], const Provides extends readonly AnyContextInstance[] = [], const Commands extends readonly CommandDefinition<any, any, any, any>[] = []>(id: ExtensionId, factory: (...args: Args) => ExtensionConfig<Defs, Uses, Provides, Commands> & ValidateExtensionConfig<Defs, Provides, Commands, Uses>): ExtensionFactory<Args, ContextDependencies<Uses> & ContextsDependencies<Provides> & CommandDefinitionsDependencies<Commands>, Provides, Defs, Commands, never, ContextDependencies<Uses>>;
1347
- declare function defineExtension<const Defs extends readonly NamedExtensionFlagDef[] = [], const Uses extends readonly AnyContextFactory[] = [], const Provides extends readonly AnyContextInstance[] = [], const Commands extends readonly CommandDefinition<any, any, any, any>[] = []>(id: ExtensionId, config?: ExtensionConfig<Defs, Uses, Provides, Commands> & ValidateExtensionConfig<Defs, Provides, Commands, Uses>): Extension<ContextDependencies<Uses> & ContextsDependencies<Provides> & CommandDefinitionsDependencies<Commands>, Provides, Defs, Commands, never, ContextDependencies<Uses>>;
1397
+ declare function defineExtension<MetaKeys extends RootMetaKey = never>(id: ExtensionId): ExtensionBuilder<[], [], [], [], MetaKeys>;
1348
1398
  //#endregion
1349
1399
  //#region src/parsing/spellings.d.ts
1350
1400
  /**
@@ -1392,10 +1442,12 @@ interface CommandNode {
1392
1442
  subCommands: Record<string, CommandNode>;
1393
1443
  /** Contexts available to this command in provide order (construction order is pull-driven). */
1394
1444
  contexts: CommandContext[];
1445
+ /** Contexts `.provide()`d on this command itself; preparation installs their sections here. */
1446
+ providedContexts: readonly AnyContextInstance[];
1395
1447
  /** Declared command demands; validated when recipes are materialized. */
1396
1448
  demands: readonly AnyContextFactory[];
1397
1449
  /** Extensions registered via `.extend()` (root builder only) */
1398
- extensions: Extension[];
1450
+ extensions: ExtensionData[];
1399
1451
  /** The Command Action */
1400
1452
  run?: CommandAction;
1401
1453
  }
@@ -1407,6 +1459,22 @@ interface RunInputPayload {
1407
1459
  readonly flags?: Readonly<Record<string, RunInputValue | undefined>>;
1408
1460
  readonly raw?: readonly string[];
1409
1461
  }
1462
+ /** Environment variables consulted by `FlagDef.env`; `process.env` on the terminal path. */
1463
+ type FlagEnvironment = Readonly<Record<string, string | undefined>>;
1464
+ /**
1465
+ * Resolve flags from their `env` bindings alone, as {@link parseArgs} does for an
1466
+ * empty argv: `env.delimiter` splitting, `choices`, `parse`, built-in coercion,
1467
+ * defaults, requiredness, then Standard Schemas. Flags without `env` resolve
1468
+ * to their defaults.
1469
+ *
1470
+ * @param flags - Flag definitions keyed by result name; each `env.name` selects its variable
1471
+ * @param env - Raw variable text; only own properties are read
1472
+ * @throws {CrustError} `DEFINITION` for a definition `defineFlag` rejects (e.g. a
1473
+ * `__proto__` key or a default outside `choices`); `PARSE` or `VALIDATION` on the first
1474
+ * coercion or requiredness failure, or `VALIDATION` aggregating schema issues. Messages
1475
+ * may quote raw values.
1476
+ */
1477
+ declare function parseFlagValues<F extends FlagsDef>(flags: F, env: FlagEnvironment): Promise<InferFlags<F>>;
1410
1478
  //#endregion
1411
1479
  //#region src/types.d.ts
1412
1480
  /** Injectable output callbacks threaded through one invocation. */
@@ -2048,29 +2116,17 @@ declare const contextSources: unique symbol;
2048
2116
  type ContextBag<Deps extends ContextMap = {}> = { readonly [K in keyof Deps]: Promise<Deps[K]>; } & {
2049
2117
  readonly [contextSources]?: readonly (AnyContextFactory | AnyContextInstance)[];
2050
2118
  };
2051
- interface ContextConfig {
2052
- readonly flags?: readonly NamedFlagDef[];
2053
- readonly uses?: readonly AnyContextFactory[];
2054
- }
2055
- type ValidateContextConfig<R extends ContextConfig> = {
2056
- readonly flags?: R["flags"] extends readonly NamedFlagDef[] ? ValidateLocalFlagDefs<R["flags"], never> : "flags" extends keyof R ? {} : never;
2057
- readonly uses?: R["uses"] extends readonly AnyContextFactory[] ? R["uses"] : "uses" extends keyof R ? {} : never;
2058
- };
2059
- interface ContextSetupInput<OF extends FlagsDef = FlagsDef> extends InvocationIO {
2060
- readonly signal: AbortSignal;
2061
- readonly flags: InferFlags<OF>;
2062
- readonly ctx: ContextBag<ContextMap>;
2063
- readonly defer: (cleanup: () => void | PromiseLike<void>) => void;
2064
- }
2065
2119
  interface ContextInstance<Name extends string = string, Value = unknown, OF extends FlagsDef = FlagsDef, Deps extends ContextMap = Record<string, ContextValue>> extends Defining<ContextInstance<Name, Value, OF, Deps>> {
2066
2120
  readonly [contextProof]?: string extends keyof OF | keyof Deps ? unknown : (state: [OF, Deps]) => void;
2067
2121
  readonly name: Name;
2068
2122
  readonly ownedFlags: FlagsDef;
2123
+ /** Validated {@link ContextBuilder.sections}, frozen at declaration. */
2124
+ readonly sections: readonly CommandSection[];
2069
2125
  /** @internal — declared direct dependency factories */
2070
- readonly uses: readonly AnyContextFactory[];
2126
+ readonly use: readonly AnyContextFactory[];
2071
2127
  /** @internal defining factory, for adapters that identify Contexts by factory */
2072
2128
  readonly factory: AnyContextFactory;
2073
- setup(input: ContextSetupInput<OF>): Awaitable<Value>;
2129
+ setup(input: ContextSetup<OF, ContextMap>): Awaitable<Value>;
2074
2130
  readonly _ownedFlags?: OF;
2075
2131
  /** @internal — phantom carrying the transitive dependency closure */
2076
2132
  readonly _deps?: Deps;
@@ -2079,8 +2135,8 @@ interface ContextInstance<Name extends string = string, Value = unknown, OF exte
2079
2135
  type AnyContextInstance = ContextInstance<string, unknown, any, any>;
2080
2136
  /** Whatever a Context setup produces, erased at the runtime registry. */
2081
2137
  type ContextValue = Awaited<ReturnType<AnyContextInstance["setup"]>>;
2082
- interface ContextSetup<Options, OF extends FlagsDef = {}, Deps extends ContextMap = {}> extends InvocationIO {
2083
- readonly options: Options;
2138
+ /** Invocation input passed to a Context's `.setup()` callback; factory options arrive as its second parameter. */
2139
+ interface ContextSetup<OF extends FlagsDef = {}, Deps extends ContextMap = {}> extends InvocationIO {
2084
2140
  /** The invocation's cancellation signal; pass it to cancellable setup work. */
2085
2141
  readonly signal: AbortSignal;
2086
2142
  readonly flags: InferFlags<OF>;
@@ -2092,10 +2148,11 @@ interface ContextSetup<Options, OF extends FlagsDef = {}, Deps extends ContextMa
2092
2148
  readonly defer: (cleanup: () => void | PromiseLike<void>) => void;
2093
2149
  }
2094
2150
  interface ContextFactory<Name extends string, Options, Value, OF extends FlagsDef = {}, Deps extends ContextMap = {}> extends Defining<ContextFactory<Name, Options, Value, OF, Deps>> {
2095
- (options: Options): ContextInstance<Name, Value, OF, Deps>;
2151
+ /** Options may be omitted when their type accepts `undefined` (including no-option `void`). */
2152
+ (...options: undefined extends Options ? [options?: Options] : [options: Options]): ContextInstance<Name, Value, OF, Deps>;
2096
2153
  readonly contextName: Name;
2097
2154
  /** @internal — declared direct dependency factories */
2098
- readonly uses: readonly AnyContextFactory[];
2155
+ readonly use: readonly AnyContextFactory[];
2099
2156
  of(value: Value): ContextInstance<Name, Value, OF, {}>;
2100
2157
  readonly _deps?: Deps;
2101
2158
  }
@@ -2108,20 +2165,40 @@ type FactoryOutput<F> = F extends AnyContextFactory ? DefiningOf<F> extends Cont
2108
2165
  type FactoriesOutput<Fs extends readonly AnyContextFactory[]> = Fs extends readonly [infer H, ...infer T extends readonly AnyContextFactory[]] ? FactoryOutput<H> & FactoriesOutput<T> : {};
2109
2166
  type FactoryDeps<F> = F extends AnyContextFactory ? DefiningOf<F> extends ContextFactory<any, any, any, any, infer Deps> ? Deps : {} : {};
2110
2167
  type FactoriesDeps<Fs extends readonly AnyContextFactory[]> = Fs extends readonly [infer H, ...infer T extends readonly AnyContextFactory[]] ? FactoryDeps<H> & FactoriesDeps<T> : {};
2111
- type ContextDependencies<Uses extends readonly AnyContextFactory[]> = IsStaticTuple<Uses> extends true ? FactoriesOutput<Uses> & FactoriesDeps<Uses> : Record<string, ContextValue>;
2168
+ type ContextDependencies<Use extends readonly AnyContextFactory[]> = IsStaticTuple<Use> extends true ? FactoriesOutput<Use> & FactoriesDeps<Use> : Record<string, ContextValue>;
2112
2169
  type ContextDepsOf<C> = C extends AnyContextInstance ? DefiningOf<C> extends {
2113
2170
  readonly _deps?: infer Deps extends ContextMap;
2114
2171
  } ? Deps : {} : {};
2115
2172
  type ContextsDependencies<Cs extends readonly AnyContextInstance[]> = Cs extends readonly [infer H, ...infer T extends readonly AnyContextInstance[]] ? ContextDepsOf<H> & ContextsDependencies<T> : {};
2116
- type OwnedFlagsOf<R extends ContextConfig> = R extends {
2117
- flags: infer F extends readonly NamedFlagDef[];
2118
- } ? AttachedFlags<F> : "flags" extends keyof R ? FlagsDef : {};
2119
- type UsesOf<R extends ContextConfig> = R extends {
2120
- uses: infer Uses extends readonly AnyContextFactory[];
2121
- } ? Uses : "uses" extends keyof R ? readonly AnyContextFactory[] : readonly [];
2122
- /** Define a named, lazy command dependency. Declared `uses` are exposed on `ctx`. */
2123
- declare function defineContext<Name extends string, Value, Options = void>(name: Name, setup: (input: ContextSetup<Options>) => Awaitable<Value>): ContextFactory<Name, Options, Value>;
2124
- declare function defineContext<Name extends string, const R extends ContextConfig, Value, Options = void>(name: Name, config: R & ValidateContextConfig<R> & ContextConfig, setup: (input: ContextSetup<Options, OwnedFlagsOf<R>, ContextDependencies<UsesOf<R>>>) => Awaitable<Value>): ContextFactory<Name, Options, Value, OwnedFlagsOf<R>, ContextDependencies<UsesOf<R>>>;
2173
+ /** Factory options inferred from a setup callback's optional second parameter. */
2174
+ type ContextOptionsOf<Args extends readonly unknown[]> = Args extends readonly [] ? void : Args[0];
2175
+ /**
2176
+ * Immutable fluent Context authoring handle returned by {@link defineContext}.
2177
+ * `use`, `flags`, and `sections` append and return a new handle; `setup` ends the chain and
2178
+ * returns the callable {@link ContextFactory}. Callbacks are typed by the
2179
+ * declarations made before them.
2180
+ */
2181
+ interface ContextBuilder<Name extends string, Use extends readonly AnyContextFactory[] = [], Defs extends readonly NamedFlagDef[] = []> {
2182
+ /** Declare Contexts setup reads from `ctx`; consumers must provide their transitive closure. */
2183
+ use<const Fs extends readonly AnyContextFactory[]>(...factories: Fs): ContextBuilder<Name, readonly [...Use, ...Fs], Defs>;
2184
+ /** Own flags parsed wherever this Context is provided; setup reads them from `flags`. */
2185
+ flags<const Fs extends readonly NamedFlagDef[]>(...defs: ValidateLocalFlagDefs<Fs, AttachedSpellings<Defs>>): ContextBuilder<Name, Use, readonly [...Defs, ...Fs]>;
2186
+ /** Document only the providing command (the root for Extension-provided Contexts). */
2187
+ sections<const S extends readonly RuntimeCommandSectionInput[]>(...sections: S & LocalSectionsBrand<{
2188
+ sections: S;
2189
+ }>["sections"]): ContextBuilder<Name, Use, Defs>;
2190
+ /**
2191
+ * Finish the definition. `setup` runs lazily, once per invocation, when a
2192
+ * consumer first reads the Context. Annotate its optional second parameter to
2193
+ * accept factory options: `.setup((input, options: { url: string }) => …)`.
2194
+ */
2195
+ setup<Value, Args extends readonly [options?: unknown] = []>(setup: (input: ContextSetup<AttachedFlags<Defs>, ContextDependencies<Use>>, ...args: Args) => Awaitable<Value>): ContextFactory<Name, ContextOptionsOf<Args>, Value, AttachedFlags<Defs>, ContextDependencies<Use>>;
2196
+ }
2197
+ /**
2198
+ * Start an immutable fluent Context definition: a named, lazy command
2199
+ * dependency. Chain `.use()`, `.flags()`, and `.sections()`, then `.setup()` for the factory.
2200
+ */
2201
+ declare function defineContext<Name extends string>(name: Name): ContextBuilder<Name>;
2125
2202
  type FactoryValueOf<F extends AnyContextFactory> = F extends ContextFactory<any, any, infer Value, any, any> ? Awaited<Value> : never;
2126
2203
  //#endregion
2127
- export { CrustErrorCode as $, SectionConsumer as A, MergeContext as At, ExtensionContext as B, InvocationOptions as C, ArgSnapshot as Ct, ParsedArgValue as D, LocalFlagNameBrand as Dt, ParseResult as E, LocalFlagBrand as Et, BuildReport as F, Finished as G, ExtensionFlagDef as H, DefineExtensionWith as I, NamedExtensionFlagDef as J, InferExtensionFlags as K, Extension as L, ValueType as M, defineExtensionId as Mt, BuildArtifacts as N, ParsedFlagValue as O, EmptyArgNameBrand as Ot, BuildFile as P, CrustError as Q, ExtensionBuildContext as R, InvocationIO as S, defineCommand as St, NamedFlagDef as T, FlagSnapshot as Tt, ExtensionHooks as U, ExtensionFactory as V, ExtensionSectionContribution as W, defineExtension as X, RootMetaKey as Y, CommandNotFoundErrorDetails as Z, ExecuteOptions as _, RootCommandMeta as _t, ContextInstance as a, ValidationErrorDetails as at, InputArgs as b, RunInputArguments as bt, FactoryValueOf as c, CommandDefinition as ct, ArgDef as d, CommandPath as dt, CrustErrorDetails as et, ArgsDef as f, CommandShape as ft, DeclaredDefault as g, CrustCommandContext as gt, CommandSectionInput as h, Crust as ht, ContextFactory as i, ParseErrorDetails as it, ValidatedInput as j, ExtensionId as jt, SectionAudience as k, LocalValueBrand as kt, contextSources as l, CommandDefinitionBuilder as lt, CommandSection as m, CommandTree as mt, ContextBag as n, CrustErrorJson as nt, ContextMap as o, AnyCrust as ot, CommandMeta as p, CommandShapeAt as pt, InvocationOutcome as q, ContextConfig as r, DefinitionErrorDetails as rt, ContextSetup as s, CommandConfig as st, AnyContextFactory as t, CrustErrorDetailsMap as tt, defineContext as u, CommandHandle as ut, FlagDef as v, RunArguments as vt, MergeFlags as w, CommandSnapshot as wt, InputFlags as x, RunOutcome as xt, FlagsDef as y, RunInput as yt, ExtensionConfig as z };
2204
+ export { CrustError as $, SectionConsumer as A, LocalFlagNameBrand as At, ExtensionBuilder as B, InvocationOptions as C, RunInputArguments as Ct, ParsedArgValue as D, CommandSnapshot as Dt, ParseResult as E, ArgSnapshot as Et, BuildArtifacts as F, defineExtensionId as Ft, ExtensionSectionContribution as G, ExtensionFactory as H, BuildFile as I, InvocationOutcome as J, Finished as K, BuildReport as L, ValueType as M, LocalValueBrand as Mt, FlagEnvironment as N, MergeContext as Nt, ParsedFlagValue as O, FlagSnapshot as Ot, parseFlagValues as P, ExtensionId as Pt, CommandNotFoundErrorDetails as Q, Extension as R, InvocationIO as S, RunInput as St, NamedFlagDef as T, defineCommand as Tt, ExtensionFlagDef as U, ExtensionContext as V, ExtensionHooks as W, RootMetaKey as X, NamedExtensionFlagDef as Y, defineExtension as Z, ExecuteOptions as _, CommandTree as _t, ContextInstance as a, EnvErrorDetails as at, InputArgs as b, RootCommandMeta as bt, FactoryValueOf as c, ValidationErrorDetails as ct, ArgDef as d, CommandDefinition as dt, CrustErrorCode as et, ArgsDef as f, CommandDefinitionBuilder as ft, DeclaredDefault as g, CommandShapeAt as gt, CommandSectionInput as h, CommandShape as ht, ContextFactory as i, DefinitionErrorDetails as it, ValidatedInput as j, EmptyArgNameBrand as jt, SectionAudience as k, LocalFlagBrand as kt, contextSources as l, AnyCrust as lt, CommandSection as m, CommandPath as mt, ContextBag as n, CrustErrorDetailsMap as nt, ContextMap as o, EnvIssue as ot, CommandMeta as p, CommandHandle as pt, InferExtensionFlags as q, ContextBuilder as r, CrustErrorJson as rt, ContextSetup as s, ParseErrorDetails as st, AnyContextFactory as t, CrustErrorDetails as tt, defineContext as u, CommandConfig as ut, FlagDef as v, Crust as vt, MergeFlags as w, RunOutcome as wt, InputFlags as x, RunArguments as xt, FlagsDef as y, CrustCommandContext as yt, ExtensionBuildContext as z };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as CrustErrorCode, A as SectionConsumer, At as MergeContext, B as ExtensionContext, C as InvocationOptions, Ct as ArgSnapshot, D as ParsedArgValue, Dt as LocalFlagNameBrand, E as ParseResult, Et as LocalFlagBrand, F as BuildReport, G as Finished, H as ExtensionFlagDef, I as DefineExtensionWith, J as NamedExtensionFlagDef, K as InferExtensionFlags, L as Extension, M as ValueType, Mt as defineExtensionId, N as BuildArtifacts, O as ParsedFlagValue, Ot as EmptyArgNameBrand, P as BuildFile, Q as CrustError, R as ExtensionBuildContext, S as InvocationIO, St as defineCommand, T as NamedFlagDef, Tt as FlagSnapshot, U as ExtensionHooks, V as ExtensionFactory, W as ExtensionSectionContribution, X as defineExtension, Y as RootMetaKey, Z as CommandNotFoundErrorDetails, _ as ExecuteOptions, _t as RootCommandMeta, a as ContextInstance, at as ValidationErrorDetails, b as InputArgs, bt as RunInputArguments, c as FactoryValueOf, ct as CommandDefinition, d as ArgDef, dt as CommandPath, et as CrustErrorDetails, f as ArgsDef, ft as CommandShape, gt as CrustCommandContext, h as CommandSectionInput, ht as Crust, i as ContextFactory, it as ParseErrorDetails, j as ValidatedInput, jt as ExtensionId, k as SectionAudience, kt as LocalValueBrand, l as contextSources, lt as CommandDefinitionBuilder, m as CommandSection, mt as CommandTree, n as ContextBag, nt as CrustErrorJson, o as ContextMap, ot as AnyCrust, p as CommandMeta, pt as CommandShapeAt, q as InvocationOutcome, r as ContextConfig, rt as DefinitionErrorDetails, s as ContextSetup, st as CommandConfig, t as AnyContextFactory, tt as CrustErrorDetailsMap, u as defineContext, ut as CommandHandle, v as FlagDef, vt as RunArguments, w as MergeFlags, wt as CommandSnapshot, x as InputFlags, xt as RunOutcome, y as FlagsDef, yt as RunInput, z as ExtensionConfig } from "./context-B1ck_WZ-.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-WQZg1zaQ.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. */
@@ -20,4 +20,4 @@ export declare function defineFlag<const N extends string, const D extends FlagD
20
20
  /** Define and own one positional argument; layout belongs to its consuming command. */
21
21
  export declare function defineArg<const N extends string, const D extends UnnamedArgDef>(name: N & EmptyArgNameBrand<N>, def: D & LocalValueBrand<D>): Named<N, D>;
22
22
  //#endregion
23
- export { type AnyContextFactory, type AnyCrust, type ArgDef, type ArgSnapshot, type ArgsDef, type BuildArtifacts, type BuildFile, type BuildReport, type CommandConfig, type CommandDefinition, type CommandDefinitionBuilder, type CommandHandle, type CommandMeta, type CommandNotFoundErrorDetails, type CommandPath, type CommandSection, type CommandSectionInput, type CommandShape, type CommandShapeAt, type CommandSnapshot, type CommandTree, type ContextBag, type ContextConfig, type ContextFactory, type ContextInstance, type ContextMap, type ContextSetup, Crust, type CrustCommandContext, CrustError, type CrustErrorCode, type CrustErrorDetails, type CrustErrorDetailsMap, type CrustErrorJson, type DefineExtensionWith, type DefinitionErrorDetails, type ExecuteOptions, type Extension, type ExtensionBuildContext, type ExtensionConfig, type ExtensionContext, type ExtensionFactory, type ExtensionFlagDef, type ExtensionHooks, type ExtensionId, type ExtensionSectionContribution, type FactoryValueOf, type Finished, type FlagDef, type FlagSnapshot, type FlagsDef, type InferExtensionFlags, type InputArgs, type InputFlags, type InvocationIO, type InvocationOptions, type InvocationOutcome, type MergeContext, type MergeFlags, type NamedExtensionFlagDef, type NamedFlagDef, type ParseErrorDetails, type ParseResult, type ParsedArgValue, type ParsedFlagValue, type RootCommandMeta, type RootMetaKey, type RunArguments, type RunInput, type RunInputArguments, type RunOutcome, type SectionAudience, type SectionConsumer, type UnnamedArgDef, type ValidatedInput, type ValidationErrorDetails, type ValueType, contextSources, defineCommand, defineContext, defineExtension, defineExtensionId, resolveArtifactDir };
23
+ export { type AnyContextFactory, type AnyCrust, type ArgDef, type ArgSnapshot, type ArgsDef, type BuildArtifacts, type BuildFile, type BuildReport, type CommandConfig, type CommandDefinition, type CommandDefinitionBuilder, type CommandHandle, type CommandMeta, type CommandNotFoundErrorDetails, type CommandPath, type CommandSection, type CommandSectionInput, type CommandShape, type CommandShapeAt, type CommandSnapshot, type CommandTree, type ContextBag, type ContextBuilder, type ContextFactory, type ContextInstance, type ContextMap, type ContextSetup, Crust, type CrustCommandContext, CrustError, type CrustErrorCode, type CrustErrorDetails, type CrustErrorDetailsMap, type CrustErrorJson, type DefinitionErrorDetails, type EnvErrorDetails, type EnvIssue, type ExecuteOptions, type Extension, type ExtensionBuildContext, type ExtensionBuilder, type ExtensionContext, type ExtensionFactory, type ExtensionFlagDef, type ExtensionHooks, type ExtensionId, type ExtensionSectionContribution, type FactoryValueOf, type Finished, type FlagDef, type FlagSnapshot, type FlagsDef, type InferExtensionFlags, type InputArgs, type InputFlags, type InvocationIO, type InvocationOptions, type InvocationOutcome, type MergeContext, type MergeFlags, type NamedExtensionFlagDef, type NamedFlagDef, type ParseErrorDetails, type ParseResult, type ParsedArgValue, type ParsedFlagValue, type RootCommandMeta, type RootMetaKey, type RunArguments, type RunInput, type RunInputArguments, type RunOutcome, type SectionAudience, type SectionConsumer, type UnnamedArgDef, type ValidatedInput, type ValidationErrorDetails, type ValueType, contextSources, defineCommand, defineContext, defineExtension, defineExtensionId, resolveArtifactDir };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { C as CrustError, S as normalizeFlag, _ as contextSources, a as runInvocation, b as validateContextAvailability, d as cloneFlagRegistry, f as installExtensionContexts, g as defineExtension, h as registerFlag, i as resolveTypedPath, m as createCommandNode, n as executeInvocation, o as snapshotCommand, p as validateCommandSections, r as prepareInvocation, u as cloneCommandNode, v as defineContext, x as normalizeArg, y as definingOf } from "./invocation-ka-BNJKZ.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-ljkrw2dt.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. */
@@ -161,7 +161,8 @@ var Crust = class {
161
161
  validateContextAvailability([...this._node.contexts.map(({ instance }) => instance), ...instances], instances);
162
162
  const cloned = this._clone({
163
163
  ...cloneFlagRegistry(this._node),
164
- contexts: [...this._node.contexts, ...instances.map((instance) => ({ instance }))]
164
+ contexts: [...this._node.contexts, ...instances.map((instance) => ({ instance }))],
165
+ providedContexts: [...this._node.providedContexts, ...instances]
165
166
  });
166
167
  for (const instance of instances) for (const [name, definition] of Object.entries(instance.ownedFlags)) registerFlag(cloned._node, name, definition, "owned");
167
168
  return cloned;
@@ -187,7 +188,7 @@ var Crust = class {
187
188
  const extensions = inputs.map(definingOf);
188
189
  const activeExtensions = dedupeExtensions([...this._node.extensions, ...extensions]);
189
190
  const node = installExtensionContexts(this._node, activeExtensions, new Set(extensions.map((extension) => extension.id)));
190
- validateContextAvailability(node.contexts.map(({ instance }) => instance), activeExtensions.flatMap((extension) => [...extension.uses, ...extension.provides ?? []]));
191
+ validateContextAvailability(node.contexts.map(({ instance }) => instance), activeExtensions.flatMap((extension) => [...extension.use, ...extension.provide]));
191
192
  return this._clone({
192
193
  ...node,
193
194
  extensions: activeExtensions