@crustjs/core 0.0.19 → 0.2.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.
@@ -0,0 +1,160 @@
1
+ import { D as CommandSnapshot, O as FlagSnapshot, V as ExtensionId, i as CommandSection, o as DeclaredDefault } from "./types-DjMHz7M6.js";
2
+ //#region src/command/invocation.d.ts
3
+ /**
4
+ * Snapshot subprocess protocol used by first-party build tooling.
5
+ *
6
+ * When set to a non-empty file path, `.execute()` prepares the command tree,
7
+ * validates its documentation sections, optionally runs Extension build hooks when the
8
+ * build output directory is set, writes its final JSON snapshot and Build Report, and exits
9
+ * without dispatching a Command Action. In-process callers use `Crust.snapshot()`.
10
+ */
11
+ export declare const SNAPSHOT_PATH_ENV = "CRUST_INTERNAL_SNAPSHOT_PATH";
12
+ export declare const BUILD_OUT_DIR_ENV = "CRUST_INTERNAL_BUILD_OUT_DIR";
13
+ //#endregion
14
+ //#region src/command/documentation.d.ts
15
+ /** Format a declared default value for command documentation. */
16
+ export declare function formatDefault(value: DeclaredDefault): string;
17
+ /** Format a definition's description and optional default/choice annotations. */
18
+ export declare function formatDescription(description: string | undefined, defaultValue: DeclaredDefault, choices: readonly string[] | undefined, formatAnnotation?: (annotation: string) => string): string;
19
+ /**
20
+ * Presentation-ready view of one positional argument.
21
+ *
22
+ * Same data as {@link ArgSnapshot} but normalized for renderers: booleans are
23
+ * always present (never `undefined`) and the display token is pre-formatted.
24
+ */
25
+ interface DocumentationArg {
26
+ /** Argument name as defined, e.g. `"file"`. */
27
+ readonly name: string;
28
+ /**
29
+ * Pre-formatted usage token: `<name>` if required, `[name]` if optional,
30
+ * with `...` appended when variadic — e.g. `"<file>"`, `"[files...]"`.
31
+ */
32
+ readonly token: string;
33
+ /** Value type (`"string"`, `"number"`, …); `undefined` for schema-backed args. */
34
+ readonly type?: CommandSnapshot["args"][number]["type"];
35
+ /** Human-readable description from the arg definition. */
36
+ readonly description?: string;
37
+ /** `true` when parsing fails if the argument is missing. */
38
+ readonly required: boolean;
39
+ /** `true` when the argument collects all remaining positionals into an array. */
40
+ readonly variadic: boolean;
41
+ /** Static enum of accepted values, e.g. `["json", "text"]`, if declared. */
42
+ readonly choices?: readonly string[];
43
+ /** Default value used when the argument is omitted, e.g. `3000`. */
44
+ readonly default?: unknown;
45
+ }
46
+ /**
47
+ * Presentation-ready view of one flag.
48
+ *
49
+ * @example
50
+ * For `{ output: { type: "string", short: "o", aliases: ["out"] } }`:
51
+ * ```ts
52
+ * {
53
+ * name: "output",
54
+ * spellings: ["-o", "--output", "--out"],
55
+ * short: "o",
56
+ * aliases: ["out"],
57
+ * negatable: false,
58
+ * type: "string",
59
+ * required: false,
60
+ * multiple: false,
61
+ * }
62
+ * ```
63
+ */
64
+ interface DocumentationFlag {
65
+ /** Canonical flag name (the key in the flags definition), e.g. `"output"`. */
66
+ readonly name: string;
67
+ /**
68
+ * All accepted CLI spellings with dashes, ordered short, canonical, aliases,
69
+ * then negations — e.g. `["-v", "--verbose", "--no-verbose"]`.
70
+ */
71
+ readonly spellings: readonly string[];
72
+ /** Single-character short alias without the dash, e.g. `"v"` for `-v`. */
73
+ readonly short?: string;
74
+ /** Additional long aliases without dashes, e.g. `["out"]` for `--out`. */
75
+ readonly aliases: readonly string[];
76
+ /** `true` for boolean flags that also accept `--no-<name>` (i.e. `noNegate` unset). */
77
+ readonly negatable: boolean;
78
+ /** Value type, e.g. `"boolean"`, `"string"`, `"number"`. */
79
+ readonly type: FlagSnapshot["type"];
80
+ /** Human-readable description from the flag definition. */
81
+ readonly description?: string;
82
+ /** `true` when parsing fails if the flag is not provided. */
83
+ readonly required: boolean;
84
+ /** `true` when the flag can repeat and collects values into an array. */
85
+ readonly multiple: boolean;
86
+ /** Static enum of accepted values, e.g. `["debug", "info", "error"]`, if declared. */
87
+ readonly choices?: readonly string[];
88
+ /** Default value used when the flag is omitted, e.g. `false`. */
89
+ readonly default?: unknown;
90
+ }
91
+ /**
92
+ * One renderer-colorable piece of a usage line. `custom` is the sole segment
93
+ * when the author supplied `meta.usage`; generated usage lines are composed
94
+ * of the other kinds so renderers can style parts without re-deriving the
95
+ * assembly policy (when `<command>`/`[options]` appear, argument ordering).
96
+ */
97
+ type UsageSegment = {
98
+ readonly kind: "path";
99
+ readonly text: string;
100
+ } | {
101
+ readonly kind: "command";
102
+ readonly text: "<command>";
103
+ } | {
104
+ readonly kind: "arg";
105
+ readonly text: string;
106
+ readonly required: boolean;
107
+ } | {
108
+ readonly kind: "options";
109
+ readonly text: "[options]";
110
+ } | {
111
+ readonly kind: "custom";
112
+ readonly text: string;
113
+ };
114
+ /**
115
+ * Presentation-neutral documentation model for one command (and, via
116
+ * `children`, its visible subtree). Renderers (help, man pages, …) consume
117
+ * this instead of re-deriving usage/spelling policy from raw definitions.
118
+ */
119
+ interface CommandDocumentation {
120
+ /** Canonical command name, e.g. `"add"`. */
121
+ readonly name: string;
122
+ /** Full invocation path from the root CLI, e.g. `["mycli", "remote", "add"]`. */
123
+ readonly path: readonly string[];
124
+ /** Human-readable description from `meta.description`. */
125
+ readonly description?: string;
126
+ /** Alternative names that route to this command, e.g. `["i"]` for `install`. */
127
+ readonly aliases: readonly string[];
128
+ /**
129
+ * Plain usage line: `usageSegments` texts joined with spaces —
130
+ * e.g. `"mycli remote add <name> [url] [options]"`.
131
+ */
132
+ readonly usage: string;
133
+ /** Structured pieces of `usage` so renderers can color parts individually. */
134
+ readonly usageSegments: readonly UsageSegment[];
135
+ /** `true` when the command has its own action (not just a subcommand container). */
136
+ readonly hasAction: boolean;
137
+ /** Positional arguments in declaration order. */
138
+ readonly args: readonly DocumentationArg[];
139
+ /** Effective flags (Context-owned + local), in definition order. */
140
+ readonly flags: readonly DocumentationFlag[];
141
+ /** Unfiltered command-authored and Extension-contributed documentation sections. */
142
+ readonly sections: readonly CommandSection[];
143
+ /** Visible children only; hidden commands remain invocable but are not documentation. */
144
+ readonly children: readonly CommandDocumentation[];
145
+ }
146
+ /** Build the presentation-neutral documentation model for a full command tree. */
147
+ export declare function buildCommandDocumentation(command: CommandSnapshot, path?: readonly string[]): CommandDocumentation;
148
+ //#endregion
149
+ //#region src/sections.d.ts
150
+ /** Whether a command belongs in user-facing listings. */
151
+ export declare function isListed(command: CommandSnapshot): boolean;
152
+ /** Select and merge sections visible to the given consumer. */
153
+ export declare function sectionsFor(sections: readonly CommandSection[] | undefined, consumer: ExtensionId): readonly CommandSection[];
154
+ /** Collect section-bearing visible commands in canonical path order. The root path is `[]`. */
155
+ export declare function visibleSectionsFor(snapshot: CommandSnapshot, consumer: ExtensionId): readonly {
156
+ readonly path: readonly string[];
157
+ readonly sections: readonly CommandSection[];
158
+ }[];
159
+ //#endregion
160
+ export type { CommandDocumentation, CommandSnapshot, DocumentationArg, DocumentationFlag, UsageSegment };
@@ -0,0 +1,96 @@
1
+ import { c as sectionsFor, l as visibleSectionsFor, n as SNAPSHOT_PATH_ENV, s as isListed, t as BUILD_OUT_DIR_ENV } from "./invocation-DcA5FqF7.js";
2
+ //#region src/command/documentation.ts
3
+ function isNonFiniteNumber(value) {
4
+ return typeof value === "number" && !Number.isFinite(value);
5
+ }
6
+ /** Format a declared default value for command documentation. */
7
+ function formatDefault(value) {
8
+ if (isNonFiniteNumber(value)) return String(value);
9
+ if (Array.isArray(value)) return value.map(String).join(", ");
10
+ return JSON.stringify(value) ?? String(value);
11
+ }
12
+ /** Format a definition's description and optional default/choice annotations. */
13
+ function formatDescription(description, defaultValue, choices, formatAnnotation = (annotation) => annotation) {
14
+ const parts = description ? [description] : [];
15
+ if (defaultValue !== void 0) parts.push(formatAnnotation(`[default: ${formatDefault(defaultValue)}]`));
16
+ if (choices?.length) parts.push(formatAnnotation(`[choices: ${choices.join(", ")}]`));
17
+ return parts.join(" ");
18
+ }
19
+ function argToken(arg) {
20
+ const name = arg.variadic ? `${arg.name}...` : arg.name;
21
+ return arg.required ? `<${name}>` : `[${name}]`;
22
+ }
23
+ function documentationFlags(flags) {
24
+ return Object.entries(flags).map(([name, def]) => {
25
+ const long = [name, ...def.aliases ?? []];
26
+ return Object.freeze({
27
+ name,
28
+ spellings: Object.freeze([
29
+ ...def.short ? [`-${def.short}`] : [],
30
+ ...long.map((spelling) => `--${spelling}`),
31
+ ...def.negatable ? long.map((spelling) => `--no-${spelling}`) : []
32
+ ]),
33
+ short: def.short,
34
+ aliases: Object.freeze([...def.aliases ?? []]),
35
+ negatable: def.negatable,
36
+ type: def.type,
37
+ description: def.description,
38
+ required: def.required === true,
39
+ multiple: def.multiple === true,
40
+ choices: def.choices,
41
+ default: def.default
42
+ });
43
+ });
44
+ }
45
+ function buildNode(command, path) {
46
+ const args = command.args.map((arg) => Object.freeze({
47
+ ...arg,
48
+ token: argToken(arg),
49
+ required: arg.required === true,
50
+ variadic: arg.variadic === true
51
+ }));
52
+ const children = Object.entries(command.subCommands).flatMap(([name, child]) => isListed(child) ? [buildNode(child, [...path, name])] : []);
53
+ const flags = documentationFlags(command.flags);
54
+ const usageSegments = command.meta.usage ? [{
55
+ kind: "custom",
56
+ text: command.meta.usage
57
+ }] : [
58
+ {
59
+ kind: "path",
60
+ text: path.join(" ")
61
+ },
62
+ ...children.length > 0 && !command.hasAction ? [{
63
+ kind: "command",
64
+ text: "<command>"
65
+ }] : [],
66
+ ...args.map((arg) => ({
67
+ kind: "arg",
68
+ text: arg.token,
69
+ required: arg.required
70
+ })),
71
+ ...flags.length > 0 ? [{
72
+ kind: "options",
73
+ text: "[options]"
74
+ }] : []
75
+ ];
76
+ const usage = usageSegments.map((segment) => segment.text).join(" ");
77
+ return Object.freeze({
78
+ name: command.meta.name,
79
+ path: Object.freeze([...path]),
80
+ description: command.meta.description,
81
+ aliases: Object.freeze([...command.meta.aliases ?? []]),
82
+ usage,
83
+ usageSegments: Object.freeze(usageSegments.map((segment) => Object.freeze(segment))),
84
+ hasAction: command.hasAction,
85
+ args: Object.freeze(args),
86
+ flags: Object.freeze(flags),
87
+ sections: Object.freeze([...command.meta.sections ?? []]),
88
+ children: Object.freeze(children)
89
+ });
90
+ }
91
+ /** Build the presentation-neutral documentation model for a full command tree. */
92
+ function buildCommandDocumentation(command, path = [command.meta.name]) {
93
+ return buildNode(command, path);
94
+ }
95
+ //#endregion
96
+ export { BUILD_OUT_DIR_ENV, SNAPSHOT_PATH_ENV, buildCommandDocumentation, formatDefault, formatDescription, isListed, sectionsFor, visibleSectionsFor };