@crustjs/core 0.3.5 → 0.4.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.
|
@@ -478,6 +478,10 @@ interface FlagSnapshot {
|
|
|
478
478
|
readonly choices?: readonly string[];
|
|
479
479
|
/** Declared default value; `URL` defaults are serialized to their `href` string. */
|
|
480
480
|
readonly default?: unknown;
|
|
481
|
+
/** Declared environment binding; never contains the variable's value. */
|
|
482
|
+
readonly env?: Readonly<NonNullable<FlagDef["env"]>>;
|
|
483
|
+
/** Delimiter that splits string argv values of a repeatable flag into occurrences. */
|
|
484
|
+
readonly delimiter?: string;
|
|
481
485
|
}
|
|
482
486
|
/**
|
|
483
487
|
* A readonly, serializable description of a command, exposed across public
|
|
@@ -1625,16 +1629,42 @@ interface FlagDefBase {
|
|
|
1625
1629
|
/** Not supported with core value options — see {@link SchemaStringFlagDef} */
|
|
1626
1630
|
schema?: never;
|
|
1627
1631
|
}
|
|
1628
|
-
/**
|
|
1629
|
-
interface
|
|
1632
|
+
/** Environment fallback for terminal parsing; structured `run()` never reads it. */
|
|
1633
|
+
interface FlagEnvBinding {
|
|
1634
|
+
/** Variable consulted only when argv omits the flag; help shows its name, never its value. */
|
|
1635
|
+
name: string;
|
|
1636
|
+
/** Split environment text into occurrences; independent of the argv delimiter, repeatable flags only. */
|
|
1637
|
+
delimiter?: string;
|
|
1638
|
+
}
|
|
1639
|
+
/** Occurrence fields of a single-value flag — `multiple` and `delimiter` must be omitted. */
|
|
1640
|
+
interface SingleOccurrenceFields {
|
|
1641
|
+
/** Environment fallback; argv wins over env, which wins over the default. */
|
|
1642
|
+
env?: FlagEnvBinding & {
|
|
1643
|
+
delimiter?: never;
|
|
1644
|
+
};
|
|
1630
1645
|
/** Must be omitted for single-value flags — set to `true` for multi-value */
|
|
1631
1646
|
multiple?: never;
|
|
1647
|
+
/** Only repeatable flags split values — see {@link RepeatableOccurrenceFields} */
|
|
1648
|
+
delimiter?: never;
|
|
1632
1649
|
}
|
|
1633
|
-
/**
|
|
1634
|
-
interface
|
|
1650
|
+
/** Occurrence fields of a repeatable flag — `multiple` is required as `true`. */
|
|
1651
|
+
interface RepeatableOccurrenceFields {
|
|
1652
|
+
/** Environment fallback; text is one occurrence unless `env.delimiter` is set. */
|
|
1653
|
+
env?: FlagEnvBinding;
|
|
1635
1654
|
/** Collect repeated values into an array */
|
|
1636
1655
|
multiple: true;
|
|
1656
|
+
/**
|
|
1657
|
+
* Split each string argv value into separate occurrences
|
|
1658
|
+
* (`--tags a,b` with `","` is two occurrences). Empty segments are dropped.
|
|
1659
|
+
* Boolean argv switches stay booleans. Environment text uses `env.delimiter`.
|
|
1660
|
+
* Opt-in with no default; structured `run()` arrays are never split.
|
|
1661
|
+
*/
|
|
1662
|
+
delimiter?: string;
|
|
1637
1663
|
}
|
|
1664
|
+
/** Base for single-value flags — `multiple` must be omitted */
|
|
1665
|
+
interface SingleFlagBase extends FlagDefBase, SingleOccurrenceFields {}
|
|
1666
|
+
/** Base for multi-value flags — `multiple` is required as `true` */
|
|
1667
|
+
interface MultiFlagBase extends FlagDefBase, RepeatableOccurrenceFields {}
|
|
1638
1668
|
type StringFlagFields<Default, ParseOutput> = {
|
|
1639
1669
|
/** Default string value, or string array for a multi-value flag. */
|
|
1640
1670
|
default?: Default;
|
|
@@ -1688,23 +1718,19 @@ interface SchemaFlagBase extends Omit<FlagDefBase, "schema" | "required"> {
|
|
|
1688
1718
|
* `string[] | undefined` with `multiple: true`) and exclusively owns coercion,
|
|
1689
1719
|
* defaults, requiredness, and validation. `type` declares token consumption only.
|
|
1690
1720
|
*/
|
|
1691
|
-
|
|
1721
|
+
type SchemaStringFlagDef = SchemaFlagBase & {
|
|
1692
1722
|
type: "string";
|
|
1693
|
-
/** When `true`, the schema receives `string[]` when present, or `undefined` when omitted. */
|
|
1694
|
-
multiple?: true;
|
|
1695
1723
|
noNegate?: never;
|
|
1696
|
-
}
|
|
1724
|
+
} & (SingleOccurrenceFields | RepeatableOccurrenceFields);
|
|
1697
1725
|
/**
|
|
1698
1726
|
* A schema-backed toggle flag (no value token). The schema receives the raw
|
|
1699
1727
|
* `boolean | undefined` (or `boolean[] | undefined` with `multiple: true`).
|
|
1700
1728
|
*/
|
|
1701
|
-
|
|
1729
|
+
type SchemaBooleanFlagDef = SchemaFlagBase & {
|
|
1702
1730
|
type: "boolean";
|
|
1703
|
-
/** When `true`, the schema receives `boolean[]` when present, or `undefined` when omitted. */
|
|
1704
|
-
multiple?: true;
|
|
1705
1731
|
/** When `true`, reject `--no-{name}` (and negated aliases) at parse time and hide the generated help label */
|
|
1706
1732
|
noNegate?: true;
|
|
1707
|
-
}
|
|
1733
|
+
} & (SingleOccurrenceFields | RepeatableOccurrenceFields);
|
|
1708
1734
|
/**
|
|
1709
1735
|
* Defines a single named flag for a CLI command.
|
|
1710
1736
|
*
|
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-
|
|
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";
|
|
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. */
|
|
@@ -7,13 +7,13 @@ type OmitName<T> = T extends {
|
|
|
7
7
|
} ? Omit<T, "name"> : never;
|
|
8
8
|
/** A positional argument definition without its name — the `defineArg` input shape. */
|
|
9
9
|
type UnnamedArgDef = OmitName<ArgDef>;
|
|
10
|
-
type Frozen<T> = { readonly [K in keyof T]: K extends "aliases" | "choices" | (T extends {
|
|
10
|
+
type Frozen<T> = { readonly [K in keyof T]: K extends "aliases" | "choices" | "env" | (T extends {
|
|
11
11
|
multiple: true;
|
|
12
12
|
} ? "default" : never) ? Readonly<T[K]> : T[K]; };
|
|
13
13
|
type Named<N extends string, D> = D extends unknown ? Frozen<{
|
|
14
14
|
name: N;
|
|
15
15
|
} & D> : never;
|
|
16
|
-
/** Define and own one flag locally; attachment checks destination collisions. */
|
|
16
|
+
/** Define and own one flag locally, including its readonly env binding; attachment checks destination collisions. */
|
|
17
17
|
export declare function defineFlag<const N extends string, const D extends FlagDef>(name: N & LocalFlagNameBrand<N>, def: D & LocalFlagBrand<{
|
|
18
18
|
name: N;
|
|
19
19
|
} & D>): Named<N, D>;
|
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-
|
|
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";
|
|
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. */
|
|
@@ -115,9 +115,16 @@ function ownDefinition(def) {
|
|
|
115
115
|
...def,
|
|
116
116
|
..."aliases" in def && def.aliases ? { aliases: Object.freeze([...def.aliases]) } : {},
|
|
117
117
|
...def.choices ? { choices: Object.freeze([...def.choices]) } : {},
|
|
118
|
+
..."env" in def && def.env ? { env: Object.freeze({
|
|
119
|
+
name: def.env.name,
|
|
120
|
+
delimiter: def.env.delimiter
|
|
121
|
+
}) } : {},
|
|
118
122
|
..."multiple" in def && def.multiple && Array.isArray(def.default) ? { default: Object.freeze([...def.default]) } : {}
|
|
119
123
|
});
|
|
120
124
|
}
|
|
125
|
+
function isEnvBinding(value) {
|
|
126
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && "name" in value && typeof value.name === "string" && (!("delimiter" in value) || value.delimiter === void 0 || typeof value.delimiter === "string");
|
|
127
|
+
}
|
|
121
128
|
function normalizeFlag(name, def) {
|
|
122
129
|
assertUsableSpelling(name, "canonical");
|
|
123
130
|
if (def.short !== void 0) assertUsableSpelling(def.short, "short");
|
|
@@ -129,6 +136,29 @@ function normalizeFlag(name, def) {
|
|
|
129
136
|
reason: "flag-collision"
|
|
130
137
|
});
|
|
131
138
|
if (def.short !== void 0 && def.short.length !== 1) throw new CrustError("DEFINITION", "Short flags must be one character");
|
|
139
|
+
if (def.env !== void 0 && !isEnvBinding(def.env)) throw new CrustError("DEFINITION", `Flag "${name}" env must be an object with a string name and optional string delimiter`, {
|
|
140
|
+
subject: "flag",
|
|
141
|
+
name,
|
|
142
|
+
reason: "invalid-env"
|
|
143
|
+
});
|
|
144
|
+
if (def.env?.name === "") throw new CrustError("DEFINITION", `Flag "${name}" env variable name must be non-empty`, {
|
|
145
|
+
subject: "flag",
|
|
146
|
+
name,
|
|
147
|
+
reason: "empty-env"
|
|
148
|
+
});
|
|
149
|
+
for (const [field, delimiter] of [["delimiter", def.delimiter], ["env.delimiter", def.env?.delimiter]]) {
|
|
150
|
+
if (delimiter === void 0) continue;
|
|
151
|
+
if (!def.multiple) throw new CrustError("DEFINITION", `Flag "${name}" ${field} requires multiple: true`, {
|
|
152
|
+
subject: "flag",
|
|
153
|
+
name,
|
|
154
|
+
reason: "delimiter-without-multiple"
|
|
155
|
+
});
|
|
156
|
+
if (delimiter === "") throw new CrustError("DEFINITION", `Flag "${name}" ${field} must be non-empty`, {
|
|
157
|
+
subject: "flag",
|
|
158
|
+
name,
|
|
159
|
+
reason: "empty-delimiter"
|
|
160
|
+
});
|
|
161
|
+
}
|
|
132
162
|
return ownDefinition(def);
|
|
133
163
|
}
|
|
134
164
|
function normalizeArg(def) {
|
|
@@ -814,6 +844,60 @@ function resolveAliases(tokens, spellings) {
|
|
|
814
844
|
}
|
|
815
845
|
return canonical;
|
|
816
846
|
}
|
|
847
|
+
/** Split repeatable occurrences on the declared delimiter, dropping empty segments. */
|
|
848
|
+
function splitOccurrences(values, delimiter) {
|
|
849
|
+
if (delimiter === void 0) return [...values];
|
|
850
|
+
return values.flatMap((value) => value.split(delimiter)).filter((value) => value !== "");
|
|
851
|
+
}
|
|
852
|
+
/**
|
|
853
|
+
* Convert an environment value into the shape argv tokens produce, so the
|
|
854
|
+
* shared coercion path (`choices`, `parse`, type conversion, schemas) runs
|
|
855
|
+
* identically. Booleans use the positional spelling rule (`true`/`1`);
|
|
856
|
+
* a `noNegate` flag rejects a false value like it rejects `--no-<name>`.
|
|
857
|
+
*/
|
|
858
|
+
function envFlagValue(name, def, raw) {
|
|
859
|
+
const occurrences = def.multiple ? splitOccurrences([raw], def.env?.delimiter) : [raw];
|
|
860
|
+
if (def.multiple && occurrences.length === 0) return void 0;
|
|
861
|
+
if (def.type !== "boolean") return {
|
|
862
|
+
kind: "string",
|
|
863
|
+
value: def.multiple ? occurrences : raw
|
|
864
|
+
};
|
|
865
|
+
const values = occurrences.map(coerceBooleanString);
|
|
866
|
+
if ("noNegate" in def && def.noNegate && values.includes(false)) throw new CrustError("PARSE", `Flag "--${name}" does not support negation (from ${def.env?.name})`);
|
|
867
|
+
return {
|
|
868
|
+
kind: "boolean",
|
|
869
|
+
value: def.multiple ? values : values[0]
|
|
870
|
+
};
|
|
871
|
+
}
|
|
872
|
+
/**
|
|
873
|
+
* Select each flag's source: argv > `env` > `default`.
|
|
874
|
+
*
|
|
875
|
+
* Source selection looks at explicit argv presence *before* delimiter
|
|
876
|
+
* splitting, so `--tags ""` stays an argv value (zero occurrences, then
|
|
877
|
+
* default/required rules) instead of letting a stale environment variable
|
|
878
|
+
* override an explicit request. Environment lookup is argv-only; structured
|
|
879
|
+
* `run()` input never reaches this function.
|
|
880
|
+
*/
|
|
881
|
+
function applyEnvAndDelimiter(flagsDef, argvValues, env) {
|
|
882
|
+
const values = {};
|
|
883
|
+
for (const [name, def] of Object.entries(flagsDef)) {
|
|
884
|
+
const argvValue = Object.hasOwn(argvValues, name) ? argvValues[name] : void 0;
|
|
885
|
+
if (argvValue !== void 0) {
|
|
886
|
+
if (def.delimiter !== void 0 && argvValue.kind === "string" && Array.isArray(argvValue.value)) {
|
|
887
|
+
const occurrences = splitOccurrences(argvValue.value, def.delimiter);
|
|
888
|
+
values[name] = occurrences.length === 0 ? void 0 : {
|
|
889
|
+
kind: "string",
|
|
890
|
+
value: occurrences
|
|
891
|
+
};
|
|
892
|
+
} else values[name] = argvValue;
|
|
893
|
+
continue;
|
|
894
|
+
}
|
|
895
|
+
if (def.env === void 0 || !Object.hasOwn(env, def.env.name)) continue;
|
|
896
|
+
const raw = env[def.env.name];
|
|
897
|
+
if (raw !== void 0) values[name] = envFlagValue(name, def, raw);
|
|
898
|
+
}
|
|
899
|
+
return values;
|
|
900
|
+
}
|
|
817
901
|
/**
|
|
818
902
|
* Resolve all flag definitions against the canonical parsed values.
|
|
819
903
|
* Handles coercion and default values.
|
|
@@ -990,12 +1074,13 @@ function bind(command, positionals, flagValues, coerceArg, coerceFlag) {
|
|
|
990
1074
|
*
|
|
991
1075
|
* @param command - The command whose arg/flag definitions drive the parsing
|
|
992
1076
|
* @param argv - The argv array to parse (typically `process.argv.slice(2)`)
|
|
1077
|
+
* @param env - Environment consulted for `FlagDef.env` fallbacks; pass `{}` to parse without one
|
|
993
1078
|
* @returns Parsed args, flags, excessArgs (positionals before `--` not consumed by a declared argument), and rawArgs (everything after `--`)
|
|
994
1079
|
* @throws {CrustError} On unknown flags or type coercion failure
|
|
995
1080
|
*/
|
|
996
|
-
function parseArgs$1(command, argv) {
|
|
1081
|
+
function parseArgs$1(command, argv, env = process.env) {
|
|
997
1082
|
const { positionals, flagValues, rawArgs } = tokenizeArgv(command, argv);
|
|
998
|
-
const { args, flags, consumed } = bind(command, positionals, flagValues, coerceArgToken, coerceFlagValue);
|
|
1083
|
+
const { args, flags, consumed } = bind(command, positionals, applyEnvAndDelimiter(command.effectiveFlags, flagValues, env), coerceArgToken, coerceFlagValue);
|
|
999
1084
|
return {
|
|
1000
1085
|
args,
|
|
1001
1086
|
flags,
|
|
@@ -1178,7 +1263,12 @@ function snapshotFlag(def) {
|
|
|
1178
1263
|
negatable: isFlagNegatable(def),
|
|
1179
1264
|
noNegate: "noNegate" in def ? def.noNegate : void 0,
|
|
1180
1265
|
choices: def.choices ? Object.freeze([...def.choices]) : void 0,
|
|
1181
|
-
default: serializableDefault(def.default)
|
|
1266
|
+
default: serializableDefault(def.default),
|
|
1267
|
+
env: def.env ? freezeCompact({
|
|
1268
|
+
name: def.env.name,
|
|
1269
|
+
delimiter: def.env.delimiter
|
|
1270
|
+
}) : void 0,
|
|
1271
|
+
delimiter: def.delimiter
|
|
1182
1272
|
});
|
|
1183
1273
|
}
|
|
1184
1274
|
/**
|
package/dist/tooling.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Tt as FlagSnapshot, g as DeclaredDefault, jt as ExtensionId, m as CommandSection, wt as CommandSnapshot } from "./context-
|
|
1
|
+
import { Tt as FlagSnapshot, g as DeclaredDefault, jt as ExtensionId, m as CommandSection, wt as CommandSnapshot } from "./context-B1ck_WZ-.js";
|
|
2
2
|
import { BUILD_OUT_DIR_ENV } from "@crustjs/utils/artifacts";
|
|
3
3
|
//#region src/command/invocation.d.ts
|
|
4
4
|
/**
|
|
@@ -17,8 +17,11 @@ export declare const SNAPSHOT_PATH_ENV = "CRUST_INTERNAL_SNAPSHOT_PATH";
|
|
|
17
17
|
//#region src/command/documentation.d.ts
|
|
18
18
|
/** Format a declared default value for command documentation. */
|
|
19
19
|
export declare function formatDefault(value: DeclaredDefault): string;
|
|
20
|
-
/**
|
|
21
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Format a definition's description and optional env/default/choice annotations.
|
|
22
|
+
* `env` is the variable *name* only; renderers never see its value.
|
|
23
|
+
*/
|
|
24
|
+
export declare function formatDescription(description: string | undefined, defaultValue: DeclaredDefault, choices: readonly string[] | undefined, formatAnnotation?: (annotation: string) => string, env?: string): string;
|
|
22
25
|
/**
|
|
23
26
|
* Presentation-ready view of one positional argument.
|
|
24
27
|
*
|
|
@@ -90,6 +93,10 @@ interface DocumentationFlag {
|
|
|
90
93
|
readonly choices?: readonly string[];
|
|
91
94
|
/** Default value used when the flag is omitted, e.g. `false`. */
|
|
92
95
|
readonly default?: unknown;
|
|
96
|
+
/** Declared environment binding; never contains the variable's value. */
|
|
97
|
+
readonly env?: FlagSnapshot["env"];
|
|
98
|
+
/** Delimiter that splits string argv values of a repeatable flag into occurrences. */
|
|
99
|
+
readonly delimiter?: string;
|
|
93
100
|
}
|
|
94
101
|
/**
|
|
95
102
|
* One renderer-colorable piece of a usage line. `custom` is the sole segment
|
package/dist/tooling.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as sectionsFor, l as visibleSectionsFor, s as isListed, t as SNAPSHOT_PATH_ENV } from "./invocation-
|
|
1
|
+
import { c as sectionsFor, l as visibleSectionsFor, s as isListed, t as SNAPSHOT_PATH_ENV } from "./invocation-ka-BNJKZ.js";
|
|
2
2
|
import { BUILD_OUT_DIR_ENV } from "@crustjs/utils/artifacts";
|
|
3
3
|
//#region src/command/documentation.ts
|
|
4
4
|
function isNonFiniteNumber(value) {
|
|
@@ -10,9 +10,13 @@ function formatDefault(value) {
|
|
|
10
10
|
if (Array.isArray(value)) return value.map(String).join(", ");
|
|
11
11
|
return JSON.stringify(value) ?? String(value);
|
|
12
12
|
}
|
|
13
|
-
/**
|
|
14
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Format a definition's description and optional env/default/choice annotations.
|
|
15
|
+
* `env` is the variable *name* only; renderers never see its value.
|
|
16
|
+
*/
|
|
17
|
+
function formatDescription(description, defaultValue, choices, formatAnnotation = (annotation) => annotation, env) {
|
|
15
18
|
const parts = description ? [description] : [];
|
|
19
|
+
if (env !== void 0) parts.push(formatAnnotation(`[env: ${env}]`));
|
|
16
20
|
if (defaultValue !== void 0) parts.push(formatAnnotation(`[default: ${formatDefault(defaultValue)}]`));
|
|
17
21
|
if (choices?.length) parts.push(formatAnnotation(`[choices: ${choices.join(", ")}]`));
|
|
18
22
|
return parts.join(" ");
|
|
@@ -39,7 +43,9 @@ function documentationFlags(flags) {
|
|
|
39
43
|
required: def.required === true,
|
|
40
44
|
multiple: def.multiple === true,
|
|
41
45
|
choices: def.choices,
|
|
42
|
-
default: def.default
|
|
46
|
+
default: def.default,
|
|
47
|
+
env: def.env,
|
|
48
|
+
delimiter: def.delimiter
|
|
43
49
|
});
|
|
44
50
|
});
|
|
45
51
|
}
|