ttsc 0.12.4 → 0.13.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.
- package/README.md +3 -0
- package/cmd/ttsc/api_compile.go +15 -2
- package/cmd/ttsc/api_transform.go +15 -2
- package/cmd/ttsc/build.go +34 -4
- package/cmd/ttsc/filter.go +70 -0
- package/cmd/ttsc/filter_strips_unknown_forwarded_flag_test.go +61 -0
- package/cmd/ttsc/flags_gen.go +30 -0
- package/driver/program.go +105 -4
- package/driver/rewrite.go +39 -4
- package/lib/compiler/internal/project/resolveProjectConfig.js +18 -0
- package/lib/compiler/internal/project/resolveProjectConfig.js.map +1 -1
- package/lib/compiler/internal/runBuild.d.ts +5 -4
- package/lib/compiler/internal/runBuild.js +358 -51
- package/lib/compiler/internal/runBuild.js.map +1 -1
- package/lib/flags/parser.d.ts +63 -0
- package/lib/flags/parser.js +254 -0
- package/lib/flags/parser.js.map +1 -0
- package/lib/flags/schema.d.ts +146 -0
- package/lib/flags/schema.js +423 -0
- package/lib/flags/schema.js.map +1 -0
- package/lib/launcher/internal/prepareExecution.js +3 -0
- package/lib/launcher/internal/prepareExecution.js.map +1 -1
- package/lib/launcher/internal/runTtsc.js +71 -147
- package/lib/launcher/internal/runTtsc.js.map +1 -1
- package/lib/launcher/internal/runTtsx.js +104 -72
- package/lib/launcher/internal/runTtsx.js.map +1 -1
- package/lib/plugin/internal/loadProjectPlugins.js +58 -23
- package/lib/plugin/internal/loadProjectPlugins.js.map +1 -1
- package/lib/structures/ITtscPlugin.d.ts +24 -0
- package/lib/structures/ITtscPluginCapabilities.d.ts +40 -0
- package/lib/structures/ITtscPluginCapabilities.js +3 -0
- package/lib/structures/ITtscPluginCapabilities.js.map +1 -0
- package/lib/structures/index.d.ts +1 -0
- package/lib/structures/index.js +1 -0
- package/lib/structures/index.js.map +1 -1
- package/lib/structures/internal/ITtscLoadedNativePlugin.d.ts +5 -0
- package/lib/structures/internal/TtscCommonOptions.d.ts +19 -0
- package/package.json +9 -9
- package/shim/ast/lint.go +6 -0
- package/src/compiler/internal/project/resolveProjectConfig.ts +20 -0
- package/src/compiler/internal/runBuild.ts +463 -56
- package/src/flags/parser.ts +367 -0
- package/src/flags/schema.ts +589 -0
- package/src/launcher/internal/prepareExecution.ts +3 -0
- package/src/launcher/internal/runTtsc.ts +78 -136
- package/src/launcher/internal/runTtsx.ts +116 -74
- package/src/plugin/internal/loadProjectPlugins.ts +74 -27
- package/src/structures/ITtscPlugin.ts +26 -0
- package/src/structures/ITtscPluginCapabilities.ts +41 -0
- package/src/structures/index.ts +1 -0
- package/src/structures/internal/ITtscLoadedNativePlugin.ts +5 -0
- package/src/structures/internal/TtscCommonOptions.ts +19 -0
- package/utility/flags_gen.go +30 -0
- package/utility/host.go +43 -33
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { AnySubcommand, ValueValidator } from "./schema";
|
|
2
|
+
/**
|
|
3
|
+
* Per-subcommand parse result. `values` is keyed by the canonical flag
|
|
4
|
+
* name (e.g. `"--singleThreaded"`); boolean flags resolve to `true`/`false`,
|
|
5
|
+
* value flags to the parsed value type. Callers narrow with the helpers
|
|
6
|
+
* below (`getBoolean`, `getString`, `getNumber`).
|
|
7
|
+
*/
|
|
8
|
+
export interface ParseResult {
|
|
9
|
+
/** Canonical flag name → resolved value. */
|
|
10
|
+
readonly values: ReadonlyMap<string, string | boolean | number>;
|
|
11
|
+
/** Flags the engine did not consume — forwarded to tsgo. */
|
|
12
|
+
readonly passthrough: readonly string[];
|
|
13
|
+
/** Bare non-flag positional arguments, in original order. */
|
|
14
|
+
readonly positional: readonly string[];
|
|
15
|
+
/**
|
|
16
|
+
* Tokens that arrived after the `forwardAfterFirstPositional` sentinel.
|
|
17
|
+
* These are intended for the user's program (e.g. ttsx's entry-file argv);
|
|
18
|
+
* they are NOT forwarded to tsgo. Always empty when
|
|
19
|
+
* `forwardAfterFirstPositional` is false.
|
|
20
|
+
*/
|
|
21
|
+
readonly tail: readonly string[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Options controlling a single `parseFlags` invocation.
|
|
25
|
+
*/
|
|
26
|
+
export interface ParseOptions {
|
|
27
|
+
/** Which subcommand's flag subset to accept. */
|
|
28
|
+
readonly subcommand: AnySubcommand;
|
|
29
|
+
/** Argv tail (the launcher has already split off the subcommand). */
|
|
30
|
+
readonly argv: readonly string[];
|
|
31
|
+
/**
|
|
32
|
+
* Error prefix used when the parser throws (`"ttsc:"` or `"ttsx:"`). The
|
|
33
|
+
* engine itself is product-neutral; the caller controls the brand.
|
|
34
|
+
*/
|
|
35
|
+
readonly errorPrefix: string;
|
|
36
|
+
/**
|
|
37
|
+
* `true` to treat the FIRST positional token as a sentinel that switches
|
|
38
|
+
* the engine to "forward everything after" mode (ttsx's entry-file
|
|
39
|
+
* behaviour: tokens after the entry are runtime argv, not tsgo flags).
|
|
40
|
+
* The sentinel itself is still recorded as a positional argument.
|
|
41
|
+
*/
|
|
42
|
+
readonly forwardAfterFirstPositional?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Optional `"--"` separator handling: when present in argv, every token
|
|
45
|
+
* after `--` is appended to `passthrough` as-is (ttsx already does this).
|
|
46
|
+
*/
|
|
47
|
+
readonly honorDoubleDashSeparator?: boolean;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Parse `argv` according to FLAG_SCHEMA filtered by `subcommand`. Returns a
|
|
51
|
+
* `ParseResult`. Throws `Error` (with the configured prefix) on invalid
|
|
52
|
+
* input — unknown subcommand-only flag, missing required value, value that
|
|
53
|
+
* fails its validator.
|
|
54
|
+
*/
|
|
55
|
+
export declare function parseFlags(opts: ParseOptions): ParseResult;
|
|
56
|
+
/** Return the boolean value of `flag` or `undefined` if not present. */
|
|
57
|
+
export declare function getBoolean(result: ParseResult, flag: string): boolean | undefined;
|
|
58
|
+
/** Return the string value of `flag` or `undefined` if not present. */
|
|
59
|
+
export declare function getString(result: ParseResult, flag: string): string | undefined;
|
|
60
|
+
/** Return the numeric value of `flag` or `undefined` if not present. */
|
|
61
|
+
export declare function getNumber(result: ParseResult, flag: string): number | undefined;
|
|
62
|
+
/** Marker type so docs callers can name the validator without an import dance. */
|
|
63
|
+
export type { ValueValidator };
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Schema-driven CLI parser used by both `runTtsc.ts` and `runTtsx.ts`.
|
|
3
|
+
//
|
|
4
|
+
// One engine, one schema. Each subcommand picks the subset of FLAG_SCHEMA it
|
|
5
|
+
// accepts and feeds it through `parseFlags`. The engine returns:
|
|
6
|
+
//
|
|
7
|
+
// * `values` — typed values for every consumed flag.
|
|
8
|
+
// * `passthrough` — flags ttsc did not consume but must forward verbatim
|
|
9
|
+
// to tsgo (or to native sidecars via `--tsgo-args`).
|
|
10
|
+
// * `positional` — bare non-flag tokens (file paths, entry files, …).
|
|
11
|
+
//
|
|
12
|
+
// The schema is the spec; behaviour at every layer boundary is determined by
|
|
13
|
+
// the FlagSpec attributes, not by ad-hoc `if (arg === "--foo")` branches.
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.parseFlags = parseFlags;
|
|
16
|
+
exports.getBoolean = getBoolean;
|
|
17
|
+
exports.getString = getString;
|
|
18
|
+
exports.getNumber = getNumber;
|
|
19
|
+
const schema_1 = require("./schema");
|
|
20
|
+
/**
|
|
21
|
+
* Parse `argv` according to FLAG_SCHEMA filtered by `subcommand`. Returns a
|
|
22
|
+
* `ParseResult`. Throws `Error` (with the configured prefix) on invalid
|
|
23
|
+
* input — unknown subcommand-only flag, missing required value, value that
|
|
24
|
+
* fails its validator.
|
|
25
|
+
*/
|
|
26
|
+
function parseFlags(opts) {
|
|
27
|
+
const accepted = new Map();
|
|
28
|
+
for (const flag of (0, schema_1.flagsForSubcommand)(opts.subcommand)) {
|
|
29
|
+
// A flag enters the launcher's `accepted` set only when its
|
|
30
|
+
// `consumedBy` includes `"launcher"`. Flags consumed solely by tsgo
|
|
31
|
+
// or by native sidecars (e.g. `--showConfig`, `--listFilesOnly`)
|
|
32
|
+
// must fall through to `forwardKnownButUnaccepted` so the launcher
|
|
33
|
+
// forwards them verbatim instead of storing them in `values` where
|
|
34
|
+
// no consumer reads them back out. The previous shape — filter on
|
|
35
|
+
// `subcommands` only — silently dropped every tsgo-only terminal
|
|
36
|
+
// flag at the launcher boundary (the RC-1 / RC-2 class the schema
|
|
37
|
+
// is meant to make impossible).
|
|
38
|
+
if (!flag.consumedBy.includes("launcher"))
|
|
39
|
+
continue;
|
|
40
|
+
accepted.set(flag.name, flag);
|
|
41
|
+
for (const alias of flag.aliases ?? [])
|
|
42
|
+
accepted.set(alias, flag);
|
|
43
|
+
}
|
|
44
|
+
const values = new Map();
|
|
45
|
+
const passthrough = [];
|
|
46
|
+
const positional = [];
|
|
47
|
+
const tail = [];
|
|
48
|
+
let remainder = null;
|
|
49
|
+
if (opts.honorDoubleDashSeparator === true) {
|
|
50
|
+
const separator = opts.argv.indexOf("--");
|
|
51
|
+
if (separator !== -1) {
|
|
52
|
+
remainder = [...opts.argv.slice(separator + 1)];
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const head = [
|
|
56
|
+
...(remainder === null ? opts.argv : opts.argv.slice(0, indexOfSeparator(opts.argv))),
|
|
57
|
+
];
|
|
58
|
+
let forwardingTail = false;
|
|
59
|
+
while (head.length !== 0) {
|
|
60
|
+
const current = head.shift();
|
|
61
|
+
if (forwardingTail) {
|
|
62
|
+
// Post-sentinel tokens belong to the user's program (e.g. the typia.ts
|
|
63
|
+
// entry's own argv: `ttsx typia.ts generate --input X`). They MUST NOT
|
|
64
|
+
// be forwarded to tsgo — the caller distinguishes `tail` from
|
|
65
|
+
// `passthrough` so script args never reach tsgo's option parser.
|
|
66
|
+
tail.push(current);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
// `--foo=value` / `-p=value` form: split before resolving against the
|
|
70
|
+
// schema. Both long (`--foo`) and short (`-p`) aliases support the
|
|
71
|
+
// inline-value shape — without splitting the short form, `-p=value`
|
|
72
|
+
// would fall through as an unknown token and be forwarded to tsgo,
|
|
73
|
+
// bypassing the launcher's own consumer (e.g. plugin discovery against
|
|
74
|
+
// the wrong project root).
|
|
75
|
+
const equalsIndex = current.startsWith("-") ? current.indexOf("=") : -1;
|
|
76
|
+
const token = equalsIndex === -1 ? current : current.slice(0, equalsIndex);
|
|
77
|
+
const inlineValue = equalsIndex === -1 ? undefined : current.slice(equalsIndex + 1);
|
|
78
|
+
const flag = accepted.get(token);
|
|
79
|
+
if (flag !== undefined) {
|
|
80
|
+
consumeFlag(values, flag, token, inlineValue, head, opts.errorPrefix);
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
// Token IS a known flag but is not accepted by THIS subcommand. The
|
|
84
|
+
// engine forwards it to tsgo just like an unknown flag — the same
|
|
85
|
+
// policy the bare-lane parser applied (RC-1 prevention).
|
|
86
|
+
const globalFlag = schema_1.FLAG_BY_NAME.get(token);
|
|
87
|
+
if (globalFlag !== undefined) {
|
|
88
|
+
forwardKnownButUnaccepted(passthrough, globalFlag, current, inlineValue, head);
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
// Truly unknown `-`-prefixed token: forward to tsgo verbatim. This
|
|
92
|
+
// is what makes `ttsc --strict file.ts` work — ttsc does not need to
|
|
93
|
+
// re-implement every tsgo flag.
|
|
94
|
+
if (current.startsWith("-")) {
|
|
95
|
+
passthrough.push(current);
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
// Bare token: positional argument (file / entry / project path).
|
|
99
|
+
positional.push(current);
|
|
100
|
+
if (opts.forwardAfterFirstPositional === true &&
|
|
101
|
+
positional.length === 1) {
|
|
102
|
+
forwardingTail = true;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (remainder !== null) {
|
|
106
|
+
// `--` separator: everything after goes to the user program when we are
|
|
107
|
+
// in tail mode (ttsx after the entry), otherwise to tsgo as passthrough.
|
|
108
|
+
const sink = forwardingTail ? tail : passthrough;
|
|
109
|
+
for (const token of remainder)
|
|
110
|
+
sink.push(token);
|
|
111
|
+
}
|
|
112
|
+
return { values, passthrough, positional, tail };
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Pull the value for `flag` from either `inlineValue` (`--flag=value`) or
|
|
116
|
+
* the next argv token (`--flag value`), validate it per the schema, and
|
|
117
|
+
* write it to the result map.
|
|
118
|
+
*/
|
|
119
|
+
function consumeFlag(values, flag, token, inlineValue, rest, errorPrefix) {
|
|
120
|
+
if (flag.kind === "boolean") {
|
|
121
|
+
if (inlineValue !== undefined) {
|
|
122
|
+
// `--flag=false` / `--flag=true` inline form. Anything other than
|
|
123
|
+
// a recognised literal stays loud: `--singleThreaded=yes` silently
|
|
124
|
+
// becoming `true` is the kind of footgun the RCA's RC-4 class
|
|
125
|
+
// covers. Mirrors `validatePositiveInt`'s style.
|
|
126
|
+
const literal = parseBooleanLiteral(inlineValue);
|
|
127
|
+
if (literal === undefined) {
|
|
128
|
+
throw new Error(`${errorPrefix} ${token} expects \`true\` or \`false\`, got ${JSON.stringify(inlineValue)}`);
|
|
129
|
+
}
|
|
130
|
+
values.set(flag.name, literal);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
// Space form `--flag true` / `--flag false`: peek the next token and
|
|
134
|
+
// consume it only when it parses as a boolean literal. tsgo accepts
|
|
135
|
+
// this shape natively; the launcher must mirror it so `ttsc --noEmit
|
|
136
|
+
// false` does not corrupt argv (positional sink getting `false`,
|
|
137
|
+
// tsgo seeing it as a stray input file).
|
|
138
|
+
if (rest.length > 0) {
|
|
139
|
+
const peek = parseBooleanLiteral(rest[0]);
|
|
140
|
+
if (peek !== undefined) {
|
|
141
|
+
rest.shift();
|
|
142
|
+
values.set(flag.name, peek);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
values.set(flag.name, true);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
const raw = inlineValue !== undefined ? inlineValue : takeValueToken(token, rest, errorPrefix);
|
|
150
|
+
if (flag.validator === "positiveInt") {
|
|
151
|
+
values.set(flag.name, validatePositiveInt(token, raw, errorPrefix));
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
values.set(flag.name, raw);
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Read the value token that follows `flag`. Throws if argv ends here OR if
|
|
158
|
+
* the next token looks like another flag (`-` prefix). Without the
|
|
159
|
+
* "looks like a flag" guard `ttsc --cwd --strict src/main.ts` would silently
|
|
160
|
+
* consume `--strict` as the value of `--cwd`, leaving `--strict` lost and
|
|
161
|
+
* `cwd` set to a junk path. Mirrors the symmetric guard already in
|
|
162
|
+
* `forwardKnownButUnaccepted` (RC-1 fairness — the two value-resolution
|
|
163
|
+
* paths must agree on what counts as "a missing value").
|
|
164
|
+
*/
|
|
165
|
+
function takeValueToken(flag, rest, errorPrefix) {
|
|
166
|
+
const value = rest.shift();
|
|
167
|
+
if (value === undefined) {
|
|
168
|
+
throw new Error(`${errorPrefix} ${flag} requires a value`);
|
|
169
|
+
}
|
|
170
|
+
if (value.startsWith("-")) {
|
|
171
|
+
// Put it back so the next loop iteration parses it as its own flag.
|
|
172
|
+
rest.unshift(value);
|
|
173
|
+
throw new Error(`${errorPrefix} ${flag} requires a value (next token ${JSON.stringify(value)} starts with "-")`);
|
|
174
|
+
}
|
|
175
|
+
return value;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Parse a CLI boolean literal — `true`/`false` only (case-sensitive to
|
|
179
|
+
* match tsgo's parser). Returns `undefined` for any other token so the
|
|
180
|
+
* caller knows to throw or treat as a non-value.
|
|
181
|
+
*/
|
|
182
|
+
function parseBooleanLiteral(raw) {
|
|
183
|
+
if (raw === "true")
|
|
184
|
+
return true;
|
|
185
|
+
if (raw === "false")
|
|
186
|
+
return false;
|
|
187
|
+
return undefined;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Validate a `positiveInt` value. Mirrors tsgo's `--checkers minValue:1`
|
|
191
|
+
* constraint so a typo fails loudly at the launcher rather than reaching
|
|
192
|
+
* tsgo with an invalid argument.
|
|
193
|
+
*/
|
|
194
|
+
function validatePositiveInt(flag, raw, errorPrefix) {
|
|
195
|
+
const value = Number(raw);
|
|
196
|
+
if (!Number.isInteger(value) || value < 1) {
|
|
197
|
+
throw new Error(`${errorPrefix} ${flag} expects a positive integer, got ${JSON.stringify(raw)}`);
|
|
198
|
+
}
|
|
199
|
+
return value;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Forward a flag the schema knows about but the current subcommand does
|
|
203
|
+
* not accept. The launcher will hand it to tsgo (or to native sidecars
|
|
204
|
+
* via `--tsgo-args`); without this branch the parser would lose the
|
|
205
|
+
* value token of a `--flag value` pair.
|
|
206
|
+
*/
|
|
207
|
+
function forwardKnownButUnaccepted(passthrough, flag, original, inlineValue, rest) {
|
|
208
|
+
passthrough.push(original);
|
|
209
|
+
// Boolean flags carry no value. `--foo=value` already encodes the value
|
|
210
|
+
// inline. Otherwise the next argv token is the flag's value: keep it
|
|
211
|
+
// adjacent so tsgo receives the pair intact.
|
|
212
|
+
if (flag.kind === "boolean" || inlineValue !== undefined) {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
if (rest.length === 0)
|
|
216
|
+
return;
|
|
217
|
+
if (rest[0].startsWith("-"))
|
|
218
|
+
return;
|
|
219
|
+
passthrough.push(rest.shift());
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Return the index of the `--` separator in `argv`, or `argv.length` when
|
|
223
|
+
* absent. The parser slices on this index when honorDoubleDashSeparator.
|
|
224
|
+
*/
|
|
225
|
+
function indexOfSeparator(argv) {
|
|
226
|
+
const index = argv.indexOf("--");
|
|
227
|
+
return index === -1 ? argv.length : index;
|
|
228
|
+
}
|
|
229
|
+
// -----------------------------------------------------------------------------
|
|
230
|
+
// Typed accessors. The parser stores raw values (string | boolean | number) so
|
|
231
|
+
// the engine stays untyped; callers pick the shape per flag.
|
|
232
|
+
// -----------------------------------------------------------------------------
|
|
233
|
+
/** Return the boolean value of `flag` or `undefined` if not present. */
|
|
234
|
+
function getBoolean(result, flag) {
|
|
235
|
+
const value = result.values.get(flag);
|
|
236
|
+
if (typeof value === "boolean")
|
|
237
|
+
return value;
|
|
238
|
+
return undefined;
|
|
239
|
+
}
|
|
240
|
+
/** Return the string value of `flag` or `undefined` if not present. */
|
|
241
|
+
function getString(result, flag) {
|
|
242
|
+
const value = result.values.get(flag);
|
|
243
|
+
if (typeof value === "string")
|
|
244
|
+
return value;
|
|
245
|
+
return undefined;
|
|
246
|
+
}
|
|
247
|
+
/** Return the numeric value of `flag` or `undefined` if not present. */
|
|
248
|
+
function getNumber(result, flag) {
|
|
249
|
+
const value = result.values.get(flag);
|
|
250
|
+
if (typeof value === "number")
|
|
251
|
+
return value;
|
|
252
|
+
return undefined;
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/flags/parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subcommands the ttsc CLI dispatches to. The bare `"ttsc"` entry covers the
|
|
3
|
+
* default lane (no explicit subcommand, e.g. `ttsc -p tsconfig.json`).
|
|
4
|
+
*/
|
|
5
|
+
export type TtscSubcommand = "ttsc" | "build" | "check" | "fix" | "format" | "prepare" | "clean";
|
|
6
|
+
/**
|
|
7
|
+
* Subcommands the ttsx CLI dispatches to. ttsx exposes a single lane today but
|
|
8
|
+
* the schema mirrors ttsc's shape so future subcommands plug in without a
|
|
9
|
+
* second engine.
|
|
10
|
+
*/
|
|
11
|
+
export type TtsxSubcommand = "ttsx";
|
|
12
|
+
export type AnySubcommand = TtscSubcommand | TtsxSubcommand;
|
|
13
|
+
/**
|
|
14
|
+
* Layers a flag can be consumed by. The order reflects the runtime pipeline:
|
|
15
|
+
*
|
|
16
|
+
* Launcher → runBuild → tsgo / native sidecars (host, lint).
|
|
17
|
+
*
|
|
18
|
+
* A flag must declare at least one consumer. `forwardTo` declares where the
|
|
19
|
+
* flag travels when the consuming layer does not absorb it (e.g. ttsc-owned
|
|
20
|
+
* flags that the JS launcher consumes and re-emits as different tsgo flags).
|
|
21
|
+
*/
|
|
22
|
+
export type FlagLayer = "launcher" | "runBuild" | "tsgo" | "host" | "lint";
|
|
23
|
+
/**
|
|
24
|
+
* Argument shape of a flag.
|
|
25
|
+
*
|
|
26
|
+
* - `boolean` — `--flag` / `--flag=true` / `--flag=false`. No value token is
|
|
27
|
+
* consumed.
|
|
28
|
+
* - `value` — `--flag value` or `--flag=value`. Required value.
|
|
29
|
+
* - `valueOptional` — `--flag` standalone is allowed; if followed by a non-flag
|
|
30
|
+
* token that token is consumed as the value. (Currently unused — declared for
|
|
31
|
+
* future flags like `--watch [path]`.)
|
|
32
|
+
*/
|
|
33
|
+
export type FlagKind = "boolean" | "value" | "valueOptional";
|
|
34
|
+
/**
|
|
35
|
+
* Validation predicate for `value`-kind flags. `none` is the default (accept
|
|
36
|
+
* any string).
|
|
37
|
+
*/
|
|
38
|
+
export type ValueValidator = "none" | "positiveInt";
|
|
39
|
+
/**
|
|
40
|
+
* One CLI flag's complete contract. Every layer's behaviour is structural —
|
|
41
|
+
* which subcommands accept the flag, where it is consumed, where it is
|
|
42
|
+
* forwarded, whether it is terminal (prints and exits) — so the next layer
|
|
43
|
+
* never silently drops the flag.
|
|
44
|
+
*/
|
|
45
|
+
export interface FlagSpec {
|
|
46
|
+
/**
|
|
47
|
+
* Canonical flag name including leading dashes (`"--singleThreaded"`). The
|
|
48
|
+
* generator uses this as the map key in the Go allow-list and as the first
|
|
49
|
+
* column of the docs table.
|
|
50
|
+
*/
|
|
51
|
+
readonly name: string;
|
|
52
|
+
/**
|
|
53
|
+
* Alternative spellings (`"-p"`, `"--project"` for `--tsconfig`). The parsing
|
|
54
|
+
* engine treats every alias as an equivalent of `name`.
|
|
55
|
+
*/
|
|
56
|
+
readonly aliases?: readonly string[];
|
|
57
|
+
/** Argument shape: boolean / required value / optional value. */
|
|
58
|
+
readonly kind: FlagKind;
|
|
59
|
+
/**
|
|
60
|
+
* For `value` flags: optional validator. `positiveInt` mirrors the
|
|
61
|
+
* `--checkers minValue:1` constraint tsgo enforces.
|
|
62
|
+
*/
|
|
63
|
+
readonly validator?: ValueValidator;
|
|
64
|
+
/** Subcommands that accept this flag. */
|
|
65
|
+
readonly subcommands: readonly AnySubcommand[];
|
|
66
|
+
/**
|
|
67
|
+
* Layers that read the flag into a typed option. Order matters only for
|
|
68
|
+
* documentation; the parsing engine merges across layers.
|
|
69
|
+
*/
|
|
70
|
+
readonly consumedBy: readonly FlagLayer[];
|
|
71
|
+
/**
|
|
72
|
+
* Where the flag travels when the consuming layer does not absorb it. Default
|
|
73
|
+
* for any flag a layer does not consume is `"tsgo"` — i.e. the launcher
|
|
74
|
+
* forwards an unknown flag to tsgo via passthrough. Setting this to
|
|
75
|
+
* `undefined` while `consumedBy: ["launcher"]` is set means the flag is
|
|
76
|
+
* intentionally consumed-not-forwarded (e.g. ttsc-internal `--binary`).
|
|
77
|
+
*/
|
|
78
|
+
readonly forwardTo?: FlagLayer;
|
|
79
|
+
/**
|
|
80
|
+
* Terminal flags ask the underlying tool to print something and exit
|
|
81
|
+
* (`--help`, `--version`, `--showConfig`, `--listFilesOnly`, `--all`,
|
|
82
|
+
* `--init`). ttsc must not wrap them in a pre-emit pass — that is how the
|
|
83
|
+
* `--showConfig prints twice` bug appeared (RC-2).
|
|
84
|
+
*/
|
|
85
|
+
readonly terminal?: boolean;
|
|
86
|
+
/**
|
|
87
|
+
* `true` when ttsc may add this flag to tsgo internally and post-process the
|
|
88
|
+
* output. If the user also forwards the same flag, ttsc keeps the
|
|
89
|
+
* user-visible behaviour (no double-print, no swallowed output). The shadow
|
|
90
|
+
* check is structural rather than `passthrough.includes("…")`.
|
|
91
|
+
*
|
|
92
|
+
* Currently true for `--listEmittedFiles`, `--noEmit`, `--pretty`.
|
|
93
|
+
*/
|
|
94
|
+
readonly internalShadow?: boolean;
|
|
95
|
+
/**
|
|
96
|
+
* Native sidecar capability that must be declared before ttsc sends this flag
|
|
97
|
+
* as a bare CLI argument. Everything else routes through `--tsgo-args` or
|
|
98
|
+
* stays in the JS launcher.
|
|
99
|
+
*/
|
|
100
|
+
readonly nativeCapability?: "diagnosticsTiming" | "threadingArgs";
|
|
101
|
+
/** Human description for `--help` and the docs table. */
|
|
102
|
+
readonly description: string;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Single source of truth for every flag the ttsc / ttsx CLI accepts. New flags
|
|
106
|
+
* are added here and only here; the generator rebuilds the parsers and the Go
|
|
107
|
+
* allow-lists from this table.
|
|
108
|
+
*
|
|
109
|
+
* Constraints enforced by the parser and the generator:
|
|
110
|
+
*
|
|
111
|
+
* 1. Every flag is uniquely identified by `name`; aliases must not collide with
|
|
112
|
+
* other flags' `name` or `aliases`.
|
|
113
|
+
* 2. A flag listed in `consumedBy: ["launcher"]` without a `forwardTo`
|
|
114
|
+
* consumes-not-forwards. The generator flags this in the docs and the Go
|
|
115
|
+
* allow-list so the boundary is explicit.
|
|
116
|
+
* 3. A flag with `subcommands` covering `clean` or `prepare` is parsed by the
|
|
117
|
+
* project-args lane; the parsing engine accepts the same flag in build /
|
|
118
|
+
* check / fix / format without a separate parser.
|
|
119
|
+
*/
|
|
120
|
+
export declare const FLAG_SCHEMA: readonly FlagSpec[];
|
|
121
|
+
/**
|
|
122
|
+
* Lookup of `name` and every alias → its canonical FlagSpec. Built once at
|
|
123
|
+
* module load so the parsing engine has O(1) flag resolution.
|
|
124
|
+
*/
|
|
125
|
+
export declare const FLAG_BY_NAME: ReadonlyMap<string, FlagSpec>;
|
|
126
|
+
/**
|
|
127
|
+
* Terminal flags as a derived set. Used by `runBuild.ts` to skip the pre-emit
|
|
128
|
+
* pass when one is present.
|
|
129
|
+
*/
|
|
130
|
+
export declare const TERMINAL_FLAGS: ReadonlySet<string>;
|
|
131
|
+
/**
|
|
132
|
+
* `internalShadow: true` flags as a derived set. Used by `runBuild.ts` to
|
|
133
|
+
* detect a user-forwarded copy of a flag ttsc adds internally so the
|
|
134
|
+
* post-processor does not eat the user's output.
|
|
135
|
+
*/
|
|
136
|
+
export declare const INTERNAL_SHADOW_FLAGS: ReadonlySet<string>;
|
|
137
|
+
/** Tokens (canonical name + aliases) accepted in `subcommand`. */
|
|
138
|
+
export declare function flagsForSubcommand(subcommand: AnySubcommand): FlagSpec[];
|
|
139
|
+
/**
|
|
140
|
+
* Allow-list map for the Go layer named `layer` (`"host"` or `"lint"`):
|
|
141
|
+
* flag-name (no leading dashes) → whether the flag takes a value token. The
|
|
142
|
+
* generator emits a literal Go map with the same shape, but this function is
|
|
143
|
+
* the runtime equivalent — used in tests to verify the generated Go matches the
|
|
144
|
+
* schema.
|
|
145
|
+
*/
|
|
146
|
+
export declare function buildGoAllowList(layer: "host" | "lint"): Map<string, boolean>;
|