ttsc 0.26.2 → 0.28.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.
- package/README.md +9 -0
- package/cmd/graphbench/main.go +26 -16
- package/cmd/graphdump/main.go +37 -12
- package/cmd/graphdump/run_declares_the_capability_its_output_carries_test.go +137 -0
- package/cmd/graphdump/run_reports_an_unknown_flag_without_exiting_the_process_test.go +56 -0
- package/cmd/graphdump/run_reports_an_unloadable_project_without_printing_a_dump_test.go +46 -0
- package/cmd/ttsc/api_transform.go +28 -3
- package/cmd/ttscgraph/auxiliary_identity_state_tracks_retargets_not_source_contents_test.go +85 -0
- package/cmd/ttscgraph/disk_realpath_other.go +16 -0
- package/cmd/ttscgraph/disk_realpath_windows.go +56 -0
- package/cmd/ttscgraph/dump.go +43 -11
- package/cmd/ttscgraph/run_dump_claims_artifacts_only_when_it_asked_test.go +135 -0
- package/cmd/ttscgraph/run_dump_declares_the_capability_its_output_carries_test.go +96 -0
- package/cmd/ttscgraph/serve.go +357 -60
- package/cmd/ttscgraph/serve_adopts_a_republished_artifact_set_test.go +348 -0
- package/cmd/ttscgraph/serve_projects_an_artifact_no_source_owns_test.go +90 -0
- package/cmd/ttscgraph/serve_shards.go +31 -9
- package/driver/config_discovery.go +121 -0
- package/driver/emit_plugin.go +77 -11
- package/driver/graph.go +64 -11
- package/driver/input_observation.go +273 -0
- package/driver/input_observation_test.go +149 -0
- package/driver/plugins.go +506 -15
- package/driver/program.go +54 -1
- package/driver/resolution_candidates.go +13 -5
- package/driver/rewrite.go +45 -2
- package/driver/transform_dependencies.go +283 -0
- package/driver/transform_dependencies_declares_every_file_without_a_contributor_test.go +28 -0
- package/driver/transform_dependencies_drops_a_self_reported_dependency_test.go +21 -0
- package/driver/transform_dependencies_keys_a_reported_path_like_the_envelope_test.go +46 -0
- package/driver/transform_dependencies_requires_every_contributor_to_declare_test.go +38 -0
- package/driver/transform_dependencies_stays_silent_for_an_undeclared_contributor_test.go +23 -0
- package/driver/transform_dependencies_withdraws_completeness_after_an_unusable_dependency_test.go +37 -0
- package/internal/graph/artifacts.go +230 -0
- package/internal/graph/artifacts_index_what_a_plugin_published_test.go +154 -0
- package/internal/graph/artifacts_survive_a_partial_rebuild_test.go +89 -0
- package/internal/graph/build.go +35 -0
- package/internal/graph/build_releases_the_scratch_it_no_longer_reads_test.go +118 -0
- package/internal/graph/doc_refs_are_the_use_the_checker_already_counts_test.go +93 -0
- package/internal/graph/doc_refs_resolve_documentation_links_test.go +335 -0
- package/internal/graph/doc_tags.go +416 -0
- package/internal/graph/doc_tags_are_claimed_before_they_are_read_test.go +131 -0
- package/internal/graph/doc_tags_capture_every_unrecognized_tag_test.go +165 -0
- package/internal/graph/doc_tags_read_only_what_the_parser_attached_test.go +97 -0
- package/internal/graph/doc_tags_stop_at_the_external_boundary_test.go +59 -0
- package/internal/graph/doc_tags_survive_line_endings_and_repeated_blocks_test.go +146 -0
- package/internal/graph/dump.go +60 -13
- package/internal/graph/dump_checkout_paths_are_stable_test.go +2 -2
- package/internal/graph/dump_paths.go +2 -2
- package/internal/graph/dump_paths_are_portable_and_injective_test.go +1 -1
- package/internal/graph/edge_kinds_names_every_declared_kind_test.go +49 -0
- package/internal/graph/edges.go +1 -0
- package/internal/graph/graph.go +79 -4
- package/internal/graph/provenance.go +29 -2
- package/lib/TtscCompiler.d.ts +12 -11
- package/lib/TtscCompiler.js +44 -29
- package/lib/TtscCompiler.js.map +1 -1
- package/lib/compiler/internal/captureProcessOutput.js +2 -2
- package/lib/compiler/internal/captureProcessOutput.js.map +1 -1
- package/lib/compiler/internal/compileProjectInMemory.js +4 -3
- package/lib/compiler/internal/compileProjectInMemory.js.map +1 -1
- package/lib/compiler/internal/project/createNativeProjectContextArgs.d.ts +9 -0
- package/lib/compiler/internal/project/createNativeProjectContextArgs.js +16 -4
- package/lib/compiler/internal/project/createNativeProjectContextArgs.js.map +1 -1
- package/lib/compiler/internal/resolveEmittedJavaScript.d.ts +2 -0
- package/lib/compiler/internal/resolveEmittedJavaScript.js +3 -0
- package/lib/compiler/internal/resolveEmittedJavaScript.js.map +1 -1
- package/lib/compiler/internal/runBuild.d.ts +1 -1
- package/lib/compiler/internal/runBuild.js +80 -34
- package/lib/compiler/internal/runBuild.js.map +1 -1
- package/lib/compiler/internal/runSingleFileEmit.js +2 -2
- package/lib/compiler/internal/runSingleFileEmit.js.map +1 -1
- package/lib/compiler/internal/sharedHostHelpers.d.ts +28 -0
- package/lib/compiler/internal/sharedHostHelpers.js +39 -0
- package/lib/compiler/internal/sharedHostHelpers.js.map +1 -1
- package/lib/compiler/internal/startResidentTransform.js +12 -4
- package/lib/compiler/internal/startResidentTransform.js.map +1 -1
- package/lib/compiler/internal/transformProjectInMemory.d.ts +3 -0
- package/lib/compiler/internal/transformProjectInMemory.js +239 -35
- package/lib/compiler/internal/transformProjectInMemory.js.map +1 -1
- package/lib/flags/schema.js +12 -5
- package/lib/flags/schema.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/internal/createCanonicalTempDirectory.d.ts +17 -0
- package/lib/internal/createCanonicalTempDirectory.js +42 -0
- package/lib/internal/createCanonicalTempDirectory.js.map +1 -0
- package/lib/internal/projectInputPathIdentity.d.ts +3 -0
- package/lib/internal/projectInputPathIdentity.js +11 -5
- package/lib/internal/projectInputPathIdentity.js.map +1 -1
- package/lib/internal/resolveNodeBinary.d.ts +14 -0
- package/lib/internal/resolveNodeBinary.js +150 -0
- package/lib/internal/resolveNodeBinary.js.map +1 -0
- package/lib/internal/resolveSafeCacheCleanupTargets.d.ts +15 -0
- package/lib/internal/resolveSafeCacheCleanupTargets.js +61 -0
- package/lib/internal/resolveSafeCacheCleanupTargets.js.map +1 -0
- package/lib/launcher/internal/prepareExecution.d.ts +3 -0
- package/lib/launcher/internal/prepareExecution.js +42 -14
- package/lib/launcher/internal/prepareExecution.js.map +1 -1
- package/lib/launcher/internal/runTtsc.js +25 -13
- package/lib/launcher/internal/runTtsc.js.map +1 -1
- package/lib/launcher/internal/runTtscserver.js +18 -3
- package/lib/launcher/internal/runTtscserver.js.map +1 -1
- package/lib/launcher/internal/runTtsx.js +2 -0
- package/lib/launcher/internal/runTtsx.js.map +1 -1
- package/lib/launcher/internal/runtimeHooks.d.ts +47 -3
- package/lib/launcher/internal/runtimeHooks.js +746 -64
- package/lib/launcher/internal/runtimeHooks.js.map +1 -1
- package/lib/plugin/internal/buildSourcePlugin.d.ts +62 -8
- package/lib/plugin/internal/buildSourcePlugin.js +754 -72
- package/lib/plugin/internal/buildSourcePlugin.js.map +1 -1
- package/lib/plugin/internal/capabilityResolutionCache.d.ts +76 -0
- package/lib/plugin/internal/capabilityResolutionCache.js +224 -0
- package/lib/plugin/internal/capabilityResolutionCache.js.map +1 -0
- package/lib/plugin/internal/loadProjectPlugins.d.ts +17 -5
- package/lib/plugin/internal/loadProjectPlugins.js +1339 -77
- package/lib/plugin/internal/loadProjectPlugins.js.map +1 -1
- package/lib/plugin/resolveCapabilityPlugins.d.ts +55 -0
- package/lib/plugin/resolveCapabilityPlugins.js +118 -0
- package/lib/plugin/resolveCapabilityPlugins.js.map +1 -0
- package/lib/register.d.ts +1 -0
- package/lib/register.js +46 -0
- package/lib/register.js.map +1 -0
- package/lib/structures/ITtscCompilerContext.d.ts +6 -3
- package/lib/structures/ITtscCompilerTransformation.d.ts +38 -0
- package/lib/structures/ITtscPlugin.d.ts +33 -0
- package/package.json +16 -9
- package/shim/ast/parent.go +16 -3
- package/shim/checker/enums_gen.go +11 -0
- package/shim/checker/go.mod +9 -0
- package/shim/checker/go.sum +22 -0
- package/shim/checker/shim.go +78 -0
- package/shim/compiler/emithook.go +10 -0
- package/shim/compiler/incremental.go +45 -8
- package/src/TtscCompiler.ts +55 -33
- package/src/compiler/internal/captureProcessOutput.ts +3 -2
- package/src/compiler/internal/compileProjectInMemory.ts +4 -3
- package/src/compiler/internal/project/createNativeProjectContextArgs.ts +19 -4
- package/src/compiler/internal/resolveEmittedJavaScript.ts +6 -0
- package/src/compiler/internal/runBuild.ts +102 -39
- package/src/compiler/internal/runSingleFileEmit.ts +2 -2
- package/src/compiler/internal/sharedHostHelpers.ts +44 -0
- package/src/compiler/internal/startResidentTransform.ts +12 -3
- package/src/compiler/internal/transformProjectInMemory.ts +410 -39
- package/src/flags/schema.ts +12 -5
- package/src/index.ts +1 -0
- package/src/internal/createCanonicalTempDirectory.ts +53 -0
- package/src/internal/projectInputPathIdentity.ts +17 -4
- package/src/internal/resolveNodeBinary.ts +173 -0
- package/src/internal/resolveSafeCacheCleanupTargets.ts +85 -0
- package/src/launcher/internal/prepareExecution.ts +50 -14
- package/src/launcher/internal/runTtsc.ts +24 -13
- package/src/launcher/internal/runTtscserver.ts +18 -3
- package/src/launcher/internal/runTtsx.ts +2 -0
- package/src/launcher/internal/runtimeHooks.ts +934 -68
- package/src/plugin/internal/buildSourcePlugin.ts +984 -79
- package/src/plugin/internal/capabilityResolutionCache.ts +305 -0
- package/src/plugin/internal/loadProjectPlugins.ts +1718 -104
- package/src/plugin/resolveCapabilityPlugins.ts +171 -0
- package/src/register.ts +47 -0
- package/src/structures/ITtscCompilerContext.ts +6 -3
- package/src/structures/ITtscCompilerTransformation.ts +46 -0
- package/src/structures/ITtscPlugin.ts +36 -0
- package/tools/shim_audit/baseline.json +0 -2
- package/utility/host.go +18 -3
- package/lib/internal/assertSafeExplicitCacheDirectory.d.ts +0 -5
- package/lib/internal/assertSafeExplicitCacheDirectory.js +0 -26
- package/lib/internal/assertSafeExplicitCacheDirectory.js.map +0 -1
- package/src/internal/assertSafeExplicitCacheDirectory.ts +0 -29
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
|
|
3
|
+
import { resolveNodeBinary } from "../../internal/resolveNodeBinary";
|
|
3
4
|
import {
|
|
4
|
-
|
|
5
|
+
collectProjectHostInputs,
|
|
6
|
+
hashHostInputPaths,
|
|
5
7
|
loadProjectPlugins,
|
|
8
|
+
realpathHostInputPaths,
|
|
6
9
|
} from "../../plugin/internal/loadProjectPlugins";
|
|
7
10
|
import type { ITtscCompilerContext } from "../../structures/ITtscCompilerContext";
|
|
8
11
|
import type { ITtscCompilerDiagnostic } from "../../structures/ITtscCompilerDiagnostic";
|
|
@@ -13,12 +16,13 @@ import type { TtscBuildResult } from "../../structures/internal/TtscBuildResult"
|
|
|
13
16
|
import { buildNativeCompiler } from "./buildNativeCompiler";
|
|
14
17
|
import { packageRootDir } from "./paths";
|
|
15
18
|
import { createNativeProjectContextArgs } from "./project/createNativeProjectContextArgs";
|
|
16
|
-
import { readProjectConfig } from "./project/readProjectConfig";
|
|
17
19
|
import { resolveBinary } from "./resolveBinary";
|
|
18
20
|
import { resolveTsgo } from "./resolveTsgo";
|
|
19
21
|
import { appendBuildOutput, normalizeBuildOutput } from "./runBuild";
|
|
20
22
|
import {
|
|
21
23
|
assertSharedHostCompatibility,
|
|
24
|
+
clearInheritedTsgoArgs,
|
|
25
|
+
inheritedSidecarEnv,
|
|
22
26
|
linkedTransformPlugins,
|
|
23
27
|
resolvePluginConfigDir,
|
|
24
28
|
selectSharedHostPlugin,
|
|
@@ -44,28 +48,28 @@ export function transformProjectInMemory(options: ITtscCompilerContext): {
|
|
|
44
48
|
dependencies?: Record<string, string[]>;
|
|
45
49
|
dependenciesComplete?: string[];
|
|
46
50
|
graph?: ITtscCompilerTransformation.IReferenceGraph;
|
|
51
|
+
hostInputHashes?: Record<string, string | null>;
|
|
52
|
+
hostInputRealpaths?: Record<string, string | null>;
|
|
53
|
+
hostInputs?: string[];
|
|
47
54
|
result: TtscBuildResult;
|
|
48
55
|
typescript: Record<string, string>;
|
|
49
56
|
volatile?: string[];
|
|
50
57
|
} {
|
|
51
58
|
const cwd = path.resolve(options.cwd ?? process.cwd());
|
|
52
|
-
const
|
|
59
|
+
const loaded = loadProjectPlugins({
|
|
60
|
+
binary: resolveBinary(options) ?? "",
|
|
61
|
+
cacheDir: options.cacheDir ?? options.env?.TTSC_CACHE_DIR,
|
|
53
62
|
cwd,
|
|
63
|
+
entries: options.plugins,
|
|
64
|
+
env: inheritedSidecarEnv(options.env),
|
|
65
|
+
pluginConfigDir: options.pluginConfigDir,
|
|
54
66
|
projectRoot: options.projectRoot,
|
|
55
67
|
tsconfig: options.tsconfig,
|
|
56
68
|
});
|
|
57
|
-
if (
|
|
58
|
-
return transformProjectWithPlugins(options,
|
|
69
|
+
if (loaded.nativePlugins.length !== 0) {
|
|
70
|
+
return transformProjectWithPlugins(options, loaded);
|
|
59
71
|
}
|
|
60
|
-
return transformProjectWithNativeHost(options, project);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/** Return true when the project or the call-level options declare any plugins. */
|
|
64
|
-
function hasConfiguredPlugins(
|
|
65
|
-
options: ITtscCompilerContext,
|
|
66
|
-
project: ITtscParsedProjectConfig,
|
|
67
|
-
): boolean {
|
|
68
|
-
return hasProjectPluginEntries(project, options.plugins);
|
|
72
|
+
return transformProjectWithNativeHost(options, loaded.project, loaded);
|
|
69
73
|
}
|
|
70
74
|
|
|
71
75
|
/**
|
|
@@ -76,14 +80,47 @@ function hasConfiguredPlugins(
|
|
|
76
80
|
function transformProjectWithNativeHost(
|
|
77
81
|
options: ITtscCompilerContext,
|
|
78
82
|
project: ITtscParsedProjectConfig,
|
|
83
|
+
baseline?: {
|
|
84
|
+
hostInputHashes: Readonly<Record<string, string | null>>;
|
|
85
|
+
hostInputRealpaths: Readonly<Record<string, string | null>>;
|
|
86
|
+
hostInputs: readonly string[];
|
|
87
|
+
},
|
|
79
88
|
): {
|
|
80
89
|
dependencies?: Record<string, string[]>;
|
|
81
90
|
dependenciesComplete?: string[];
|
|
82
91
|
graph?: ITtscCompilerTransformation.IReferenceGraph;
|
|
92
|
+
hostInputHashes?: Record<string, string | null>;
|
|
93
|
+
hostInputRealpaths?: Record<string, string | null>;
|
|
94
|
+
hostInputs?: string[];
|
|
83
95
|
result: TtscBuildResult;
|
|
84
96
|
typescript: Record<string, string>;
|
|
85
97
|
volatile?: string[];
|
|
86
98
|
} {
|
|
99
|
+
// Capture the project inputs before the native host observes them. Pairing a
|
|
100
|
+
// post-build hash with an earlier result can bless a torn generation when a
|
|
101
|
+
// config changes during the child process.
|
|
102
|
+
// Plugin discovery already ran in loadProjectPlugins. The native host only
|
|
103
|
+
// consumes the resolved config chain here, so dependency package manifests
|
|
104
|
+
// must not become per-project universal inputs a second time.
|
|
105
|
+
const projectHostInputs = collectProjectHostInputs(project, false);
|
|
106
|
+
const projectHostInputHashes = hashHostInputPaths(projectHostInputs);
|
|
107
|
+
const projectHostInputRealpaths = realpathHostInputPaths(projectHostInputs);
|
|
108
|
+
const observedHostInputs = mergeHostInputs(
|
|
109
|
+
baseline?.hostInputs,
|
|
110
|
+
projectHostInputs,
|
|
111
|
+
);
|
|
112
|
+
const observedHostInputHashes = mergeCompatibleHostInputHashes(
|
|
113
|
+
baseline?.hostInputHashes ?? {},
|
|
114
|
+
projectHostInputHashes,
|
|
115
|
+
baseline?.hostInputs ?? [],
|
|
116
|
+
projectHostInputs,
|
|
117
|
+
);
|
|
118
|
+
const observedHostInputRealpaths = mergeCompatibleHostInputHashes(
|
|
119
|
+
baseline?.hostInputRealpaths ?? {},
|
|
120
|
+
projectHostInputRealpaths,
|
|
121
|
+
baseline?.hostInputs ?? [],
|
|
122
|
+
projectHostInputs,
|
|
123
|
+
);
|
|
87
124
|
const binary = buildNativeCompiler({
|
|
88
125
|
cacheBaseDir: project.root,
|
|
89
126
|
cacheDir: options.cacheDir ?? options.env?.TTSC_CACHE_DIR,
|
|
@@ -94,7 +131,7 @@ function transformProjectWithNativeHost(
|
|
|
94
131
|
["api-transform", "--cwd", project.root, "--tsconfig", project.path],
|
|
95
132
|
{
|
|
96
133
|
cwd: project.root,
|
|
97
|
-
env:
|
|
134
|
+
env: inheritedSidecarEnv(options.env),
|
|
98
135
|
},
|
|
99
136
|
);
|
|
100
137
|
if (res.error) {
|
|
@@ -107,8 +144,37 @@ function transformProjectWithNativeHost(
|
|
|
107
144
|
outputText(res.stdout),
|
|
108
145
|
outputText(res.stderr),
|
|
109
146
|
);
|
|
147
|
+
const finalObservedHostInputHashes = revalidateHostInputHashes(
|
|
148
|
+
observedHostInputHashes,
|
|
149
|
+
observedHostInputs,
|
|
150
|
+
);
|
|
151
|
+
const finalOutputHostInputHashes = revalidateHostInputHashes(
|
|
152
|
+
output.hostInputHashes ?? {},
|
|
153
|
+
output.hostInputs ?? [],
|
|
154
|
+
);
|
|
155
|
+
const finalObservedHostInputRealpaths = revalidateHostInputRealpaths(
|
|
156
|
+
observedHostInputRealpaths,
|
|
157
|
+
observedHostInputs,
|
|
158
|
+
);
|
|
159
|
+
const finalOutputHostInputRealpaths = revalidateHostInputRealpaths(
|
|
160
|
+
output.hostInputRealpaths ?? {},
|
|
161
|
+
output.hostInputs ?? [],
|
|
162
|
+
);
|
|
110
163
|
return {
|
|
111
164
|
...envelopeSideChannels(output),
|
|
165
|
+
hostInputHashes: mergeCompatibleHostInputHashes(
|
|
166
|
+
finalObservedHostInputHashes,
|
|
167
|
+
finalOutputHostInputHashes,
|
|
168
|
+
observedHostInputs,
|
|
169
|
+
output.hostInputs,
|
|
170
|
+
),
|
|
171
|
+
hostInputRealpaths: mergeCompatibleHostInputHashes(
|
|
172
|
+
finalObservedHostInputRealpaths,
|
|
173
|
+
finalOutputHostInputRealpaths,
|
|
174
|
+
observedHostInputs,
|
|
175
|
+
output.hostInputs,
|
|
176
|
+
),
|
|
177
|
+
hostInputs: mergeHostInputs(observedHostInputs, output.hostInputs),
|
|
112
178
|
result: {
|
|
113
179
|
diagnostics: output.diagnostics,
|
|
114
180
|
status: res.status ?? 1,
|
|
@@ -121,26 +187,19 @@ function transformProjectWithNativeHost(
|
|
|
121
187
|
|
|
122
188
|
function transformProjectWithPlugins(
|
|
123
189
|
options: ITtscCompilerContext,
|
|
124
|
-
|
|
125
|
-
project: ITtscParsedProjectConfig,
|
|
190
|
+
loaded: ReturnType<typeof loadProjectPlugins>,
|
|
126
191
|
): {
|
|
127
192
|
dependencies?: Record<string, string[]>;
|
|
128
193
|
dependenciesComplete?: string[];
|
|
129
194
|
graph?: ITtscCompilerTransformation.IReferenceGraph;
|
|
195
|
+
hostInputHashes?: Record<string, string | null>;
|
|
196
|
+
hostInputRealpaths?: Record<string, string | null>;
|
|
197
|
+
hostInputs?: string[];
|
|
130
198
|
result: TtscBuildResult;
|
|
131
199
|
typescript: Record<string, string>;
|
|
132
200
|
volatile?: string[];
|
|
133
201
|
} {
|
|
134
|
-
const
|
|
135
|
-
binary: resolveBinary(options) ?? "",
|
|
136
|
-
cacheDir: options.cacheDir ?? options.env?.TTSC_CACHE_DIR,
|
|
137
|
-
cwd,
|
|
138
|
-
entries: options.plugins,
|
|
139
|
-
env: { ...process.env, ...options.env },
|
|
140
|
-
pluginConfigDir: options.pluginConfigDir,
|
|
141
|
-
projectRoot: options.projectRoot,
|
|
142
|
-
tsconfig: project.path,
|
|
143
|
-
});
|
|
202
|
+
const { project } = loaded;
|
|
144
203
|
const checks = loaded.nativePlugins.filter(
|
|
145
204
|
(plugin) => plugin.stage === "check",
|
|
146
205
|
);
|
|
@@ -160,14 +219,44 @@ function transformProjectWithPlugins(
|
|
|
160
219
|
);
|
|
161
220
|
if (checked.status !== 0) {
|
|
162
221
|
return {
|
|
222
|
+
hostInputHashes: revalidateHostInputHashes(
|
|
223
|
+
loaded.hostInputHashes,
|
|
224
|
+
loaded.hostInputs,
|
|
225
|
+
),
|
|
226
|
+
hostInputRealpaths: revalidateHostInputRealpaths(
|
|
227
|
+
loaded.hostInputRealpaths,
|
|
228
|
+
loaded.hostInputs,
|
|
229
|
+
),
|
|
230
|
+
hostInputs: loaded.hostInputs,
|
|
163
231
|
result: checked,
|
|
164
232
|
typescript: {},
|
|
165
233
|
};
|
|
166
234
|
}
|
|
167
235
|
if (transformers.length === 0) {
|
|
168
236
|
const transformed = transformProjectWithNativeHost(options, project);
|
|
237
|
+
const finalLoadedHostInputHashes = revalidateHostInputHashes(
|
|
238
|
+
loaded.hostInputHashes,
|
|
239
|
+
loaded.hostInputs,
|
|
240
|
+
);
|
|
241
|
+
const finalLoadedHostInputRealpaths = revalidateHostInputRealpaths(
|
|
242
|
+
loaded.hostInputRealpaths,
|
|
243
|
+
loaded.hostInputs,
|
|
244
|
+
);
|
|
169
245
|
return {
|
|
170
246
|
...envelopeSideChannels(transformed),
|
|
247
|
+
hostInputHashes: mergeCompatibleHostInputHashes(
|
|
248
|
+
finalLoadedHostInputHashes,
|
|
249
|
+
transformed.hostInputHashes,
|
|
250
|
+
loaded.hostInputs,
|
|
251
|
+
transformed.hostInputs,
|
|
252
|
+
),
|
|
253
|
+
hostInputRealpaths: mergeCompatibleHostInputHashes(
|
|
254
|
+
finalLoadedHostInputRealpaths,
|
|
255
|
+
transformed.hostInputRealpaths,
|
|
256
|
+
loaded.hostInputs,
|
|
257
|
+
transformed.hostInputs,
|
|
258
|
+
),
|
|
259
|
+
hostInputs: mergeHostInputs(loaded.hostInputs, transformed.hostInputs),
|
|
171
260
|
result: appendBuildOutput(checked, transformed.result),
|
|
172
261
|
typescript: transformed.typescript,
|
|
173
262
|
};
|
|
@@ -184,7 +273,13 @@ function transformProjectWithPlugins(
|
|
|
184
273
|
),
|
|
185
274
|
{
|
|
186
275
|
cwd: project.root,
|
|
187
|
-
env: nativePluginEnv(
|
|
276
|
+
env: nativePluginEnv(
|
|
277
|
+
options,
|
|
278
|
+
project.root,
|
|
279
|
+
tsgoBinary,
|
|
280
|
+
loaded.nativePlugins,
|
|
281
|
+
plugin,
|
|
282
|
+
),
|
|
188
283
|
},
|
|
189
284
|
);
|
|
190
285
|
if (res.error) {
|
|
@@ -202,13 +297,76 @@ function transformProjectWithPlugins(
|
|
|
202
297
|
stdout: "",
|
|
203
298
|
stderr: outputText(res.stderr),
|
|
204
299
|
};
|
|
300
|
+
const finalLoadedHostInputHashes = revalidateHostInputHashes(
|
|
301
|
+
loaded.hostInputHashes,
|
|
302
|
+
loaded.hostInputs,
|
|
303
|
+
);
|
|
304
|
+
const finalOutputHostInputHashes = revalidateHostInputHashes(
|
|
305
|
+
output.hostInputHashes ?? {},
|
|
306
|
+
output.hostInputs ?? [],
|
|
307
|
+
);
|
|
308
|
+
const finalLoadedHostInputRealpaths = revalidateHostInputRealpaths(
|
|
309
|
+
loaded.hostInputRealpaths,
|
|
310
|
+
loaded.hostInputs,
|
|
311
|
+
);
|
|
312
|
+
const finalOutputHostInputRealpaths = revalidateHostInputRealpaths(
|
|
313
|
+
output.hostInputRealpaths ?? {},
|
|
314
|
+
output.hostInputs ?? [],
|
|
315
|
+
);
|
|
205
316
|
return {
|
|
206
317
|
...envelopeSideChannels(output),
|
|
318
|
+
hostInputHashes: mergeCompatibleHostInputHashes(
|
|
319
|
+
finalLoadedHostInputHashes,
|
|
320
|
+
finalOutputHostInputHashes,
|
|
321
|
+
loaded.hostInputs,
|
|
322
|
+
output.hostInputs,
|
|
323
|
+
),
|
|
324
|
+
hostInputRealpaths: mergeCompatibleHostInputHashes(
|
|
325
|
+
finalLoadedHostInputRealpaths,
|
|
326
|
+
finalOutputHostInputRealpaths,
|
|
327
|
+
loaded.hostInputs,
|
|
328
|
+
output.hostInputs,
|
|
329
|
+
),
|
|
330
|
+
hostInputs: mergeHostInputs(loaded.hostInputs, output.hostInputs),
|
|
207
331
|
result: appendBuildOutput(checked, result),
|
|
208
332
|
typescript: output.typescript,
|
|
209
333
|
};
|
|
210
334
|
}
|
|
211
335
|
|
|
336
|
+
/** Keep evaluation proof only when the same input still has the same state. */
|
|
337
|
+
function revalidateHostInputHashes(
|
|
338
|
+
initial: Readonly<Record<string, string | null>>,
|
|
339
|
+
inputs: readonly string[],
|
|
340
|
+
): Record<string, string | null> {
|
|
341
|
+
const current = hashHostInputPaths(inputs);
|
|
342
|
+
return Object.fromEntries(
|
|
343
|
+
inputs.flatMap((input) => {
|
|
344
|
+
const absolute = path.resolve(input);
|
|
345
|
+
return Object.prototype.hasOwnProperty.call(initial, absolute) &&
|
|
346
|
+
initial[absolute] === current[absolute]
|
|
347
|
+
? ([[absolute, current[absolute]!]] as const)
|
|
348
|
+
: [];
|
|
349
|
+
}),
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/** Keep evaluation proof only while each lexical path selects the same target. */
|
|
354
|
+
function revalidateHostInputRealpaths(
|
|
355
|
+
initial: Readonly<Record<string, string | null>>,
|
|
356
|
+
inputs: readonly string[],
|
|
357
|
+
): Record<string, string | null> {
|
|
358
|
+
const current = realpathHostInputPaths(inputs);
|
|
359
|
+
return Object.fromEntries(
|
|
360
|
+
inputs.flatMap((input) => {
|
|
361
|
+
const absolute = path.resolve(input);
|
|
362
|
+
return Object.prototype.hasOwnProperty.call(initial, absolute) &&
|
|
363
|
+
initial[absolute] === current[absolute]
|
|
364
|
+
? ([[absolute, current[absolute]!]] as const)
|
|
365
|
+
: [];
|
|
366
|
+
}),
|
|
367
|
+
);
|
|
368
|
+
}
|
|
369
|
+
|
|
212
370
|
/**
|
|
213
371
|
* Collect the optional advisory envelope fields (`dependencies`,
|
|
214
372
|
* `dependenciesComplete`, `graph`, `volatile`) into a spreadable object,
|
|
@@ -238,6 +396,73 @@ function envelopeSideChannels(output: {
|
|
|
238
396
|
};
|
|
239
397
|
}
|
|
240
398
|
|
|
399
|
+
/** Merge JavaScript- and native-host universal inputs by absolute path. */
|
|
400
|
+
function mergeHostInputs(
|
|
401
|
+
...groups: readonly (readonly string[] | undefined)[]
|
|
402
|
+
): string[] {
|
|
403
|
+
return [
|
|
404
|
+
...new Set(
|
|
405
|
+
groups.flatMap((group) =>
|
|
406
|
+
(group ?? []).map((file) => path.resolve(file)),
|
|
407
|
+
),
|
|
408
|
+
),
|
|
409
|
+
].sort();
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/** Keep only native/descriptor fingerprints that agree on shared paths. */
|
|
413
|
+
function mergeCompatibleHostInputHashes(
|
|
414
|
+
first: Readonly<Record<string, string | null>>,
|
|
415
|
+
second: Readonly<Record<string, string | null>> | undefined,
|
|
416
|
+
firstInputs: readonly string[],
|
|
417
|
+
secondInputs: readonly string[] | undefined,
|
|
418
|
+
): Record<string, string | null> {
|
|
419
|
+
const firstDeclared = new Set(
|
|
420
|
+
firstInputs.map((input) => path.resolve(input)),
|
|
421
|
+
);
|
|
422
|
+
const secondDeclared = new Set(
|
|
423
|
+
(secondInputs ?? []).map((input) => path.resolve(input)),
|
|
424
|
+
);
|
|
425
|
+
const output = Object.fromEntries(
|
|
426
|
+
Object.entries(first).flatMap(([file, hash]) => {
|
|
427
|
+
const absolute = path.resolve(file);
|
|
428
|
+
return firstDeclared.has(absolute) ? [[absolute, hash] as const] : [];
|
|
429
|
+
}),
|
|
430
|
+
);
|
|
431
|
+
const unproven = new Set<string>();
|
|
432
|
+
for (const input of firstInputs) {
|
|
433
|
+
const absolute = path.resolve(input);
|
|
434
|
+
if (!Object.prototype.hasOwnProperty.call(first, absolute)) {
|
|
435
|
+
delete output[absolute];
|
|
436
|
+
unproven.add(absolute);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
for (const input of secondInputs ?? []) {
|
|
440
|
+
const absolute = path.resolve(input);
|
|
441
|
+
if (!Object.prototype.hasOwnProperty.call(second ?? {}, absolute)) {
|
|
442
|
+
delete output[absolute];
|
|
443
|
+
unproven.add(absolute);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
for (const [file, hash] of Object.entries(second ?? {})) {
|
|
447
|
+
const absolute = path.resolve(file);
|
|
448
|
+
if (!secondDeclared.has(absolute)) continue;
|
|
449
|
+
if (unproven.has(absolute)) continue;
|
|
450
|
+
if (
|
|
451
|
+
Object.prototype.hasOwnProperty.call(output, absolute) &&
|
|
452
|
+
output[absolute] !== hash
|
|
453
|
+
) {
|
|
454
|
+
// Two evaluation stages observed different states. Dropping proof makes
|
|
455
|
+
// persistent adapters replace the generation without turning advisory
|
|
456
|
+
// cache metadata into a user-facing compile failure.
|
|
457
|
+
delete output[absolute];
|
|
458
|
+
unproven.add(absolute);
|
|
459
|
+
continue;
|
|
460
|
+
}
|
|
461
|
+
output[absolute] = hash;
|
|
462
|
+
}
|
|
463
|
+
return output;
|
|
464
|
+
}
|
|
465
|
+
|
|
241
466
|
/**
|
|
242
467
|
* Run every check-stage plugin in sequence, short-circuiting on the first
|
|
243
468
|
* failure. Returns the aggregated `TtscBuildResult` (status 0 when all pass).
|
|
@@ -266,7 +491,13 @@ function runNativeChecks(
|
|
|
266
491
|
),
|
|
267
492
|
{
|
|
268
493
|
cwd: project.root,
|
|
269
|
-
env: nativePluginEnv(
|
|
494
|
+
env: nativePluginEnv(
|
|
495
|
+
options,
|
|
496
|
+
project.root,
|
|
497
|
+
tsgoBinary,
|
|
498
|
+
nativePlugins,
|
|
499
|
+
plugin,
|
|
500
|
+
),
|
|
270
501
|
},
|
|
271
502
|
);
|
|
272
503
|
if (res.error) {
|
|
@@ -358,6 +589,7 @@ function serializeNativePlugins(
|
|
|
358
589
|
*/
|
|
359
590
|
function nativePluginEnv(
|
|
360
591
|
options: ITtscCompilerContext,
|
|
592
|
+
projectRoot: string,
|
|
361
593
|
tsgoBinary: string,
|
|
362
594
|
nativePlugins?: readonly ITtscLoadedNativePlugin[],
|
|
363
595
|
plugin?: ITtscLoadedNativePlugin,
|
|
@@ -365,7 +597,6 @@ function nativePluginEnv(
|
|
|
365
597
|
const pluginConfigDir = resolvePluginConfigDir(options);
|
|
366
598
|
const env: NodeJS.ProcessEnv = {
|
|
367
599
|
...process.env,
|
|
368
|
-
TTSC_NODE_BINARY: process.env.TTSC_NODE_BINARY ?? process.execPath,
|
|
369
600
|
...(pluginConfigDir === undefined
|
|
370
601
|
? {}
|
|
371
602
|
: { TTSC_PLUGIN_CONFIG_DIR: pluginConfigDir }),
|
|
@@ -375,6 +606,9 @@ function nativePluginEnv(
|
|
|
375
606
|
path.join(__dirname, "..", "..", "launcher", "ttsx.js"),
|
|
376
607
|
...options.env,
|
|
377
608
|
};
|
|
609
|
+
const node = resolveNodeBinary(env, projectRoot);
|
|
610
|
+
if (node === undefined) delete env.TTSC_NODE_BINARY;
|
|
611
|
+
else env.TTSC_NODE_BINARY = node;
|
|
378
612
|
// The anchor is per-invocation state owned by this host: when this run
|
|
379
613
|
// declared none (and the caller's env does not name one), drop any value
|
|
380
614
|
// inherited from an ancestor ttsc process so a nested build never
|
|
@@ -385,6 +619,9 @@ function nativePluginEnv(
|
|
|
385
619
|
) {
|
|
386
620
|
delete env.TTSC_PLUGIN_CONFIG_DIR;
|
|
387
621
|
}
|
|
622
|
+
// This lane forwards no tsgo argv of its own, so anything inherited belongs
|
|
623
|
+
// to an outer ttsc run and must not reach these sidecars.
|
|
624
|
+
clearInheritedTsgoArgs(env, options.env);
|
|
388
625
|
if (plugin?.stage === "transform") {
|
|
389
626
|
const linked = linkedTransformPlugins(nativePlugins ?? []);
|
|
390
627
|
if (linked.length !== 0) {
|
|
@@ -418,6 +655,9 @@ function parseNativeTransformOutput(
|
|
|
418
655
|
dependenciesComplete?: string[];
|
|
419
656
|
diagnostics: ITtscCompilerDiagnostic[];
|
|
420
657
|
graph?: ITtscCompilerTransformation.IReferenceGraph;
|
|
658
|
+
hostInputHashes?: Record<string, string | null>;
|
|
659
|
+
hostInputRealpaths?: Record<string, string | null>;
|
|
660
|
+
hostInputs?: string[];
|
|
421
661
|
typescript: Record<string, string>;
|
|
422
662
|
volatile?: string[];
|
|
423
663
|
} {
|
|
@@ -427,6 +667,9 @@ function parseNativeTransformOutput(
|
|
|
427
667
|
dependenciesComplete?: string[];
|
|
428
668
|
diagnostics?: ITtscCompilerDiagnostic[];
|
|
429
669
|
graph?: ITtscCompilerTransformation.IReferenceGraph;
|
|
670
|
+
hostInputHashes?: Record<string, string | null>;
|
|
671
|
+
hostInputRealpaths?: Record<string, string | null>;
|
|
672
|
+
hostInputs?: string[];
|
|
430
673
|
typescript?: Record<string, string>;
|
|
431
674
|
volatile?: string[];
|
|
432
675
|
};
|
|
@@ -438,11 +681,19 @@ function parseNativeTransformOutput(
|
|
|
438
681
|
const dependencies = parseDependencyLists(parsed.dependencies);
|
|
439
682
|
const dependenciesComplete = parseFileList(parsed.dependenciesComplete);
|
|
440
683
|
const graph = parseReferenceGraph(parsed.graph);
|
|
684
|
+
const hostInputHashes = parseHostInputHashes(parsed.hostInputHashes);
|
|
685
|
+
const hostInputRealpaths = parseHostInputRealpaths(
|
|
686
|
+
parsed.hostInputRealpaths,
|
|
687
|
+
);
|
|
688
|
+
const hostInputs = parseFileList(parsed.hostInputs);
|
|
441
689
|
const volatile = parseFileList(parsed.volatile);
|
|
442
690
|
return {
|
|
443
691
|
...(dependencies === undefined ? {} : { dependencies }),
|
|
444
692
|
...(dependenciesComplete === undefined ? {} : { dependenciesComplete }),
|
|
445
693
|
...(graph === undefined ? {} : { graph }),
|
|
694
|
+
...(hostInputHashes === undefined ? {} : { hostInputHashes }),
|
|
695
|
+
...(hostInputRealpaths === undefined ? {} : { hostInputRealpaths }),
|
|
696
|
+
...(hostInputs === undefined ? {} : { hostInputs }),
|
|
446
697
|
...(volatile === undefined ? {} : { volatile }),
|
|
447
698
|
diagnostics: Array.isArray(parsed.diagnostics) ? parsed.diagnostics : [],
|
|
448
699
|
typescript: parsed.typescript,
|
|
@@ -458,6 +709,49 @@ function parseNativeTransformOutput(
|
|
|
458
709
|
}
|
|
459
710
|
}
|
|
460
711
|
|
|
712
|
+
/** Parse native evaluation-time SHA-256/null host-input fingerprints. */
|
|
713
|
+
function parseHostInputHashes(
|
|
714
|
+
value: unknown,
|
|
715
|
+
): Record<string, string | null> | undefined {
|
|
716
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
717
|
+
return undefined;
|
|
718
|
+
}
|
|
719
|
+
const output: Record<string, string | null> = {};
|
|
720
|
+
for (const [file, hash] of Object.entries(value)) {
|
|
721
|
+
if (
|
|
722
|
+
!path.isAbsolute(file) ||
|
|
723
|
+
(hash !== null &&
|
|
724
|
+
(typeof hash !== "string" || !/^[0-9a-f]{64}$/.test(hash)))
|
|
725
|
+
) {
|
|
726
|
+
continue;
|
|
727
|
+
}
|
|
728
|
+
output[path.resolve(file)] = hash;
|
|
729
|
+
}
|
|
730
|
+
return Object.keys(output).length === 0 ? undefined : output;
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
/** Parse native evaluation-time realpath/null host-input identities. */
|
|
734
|
+
function parseHostInputRealpaths(
|
|
735
|
+
value: unknown,
|
|
736
|
+
): Record<string, string | null> | undefined {
|
|
737
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
738
|
+
return undefined;
|
|
739
|
+
}
|
|
740
|
+
const output: Record<string, string | null> = {};
|
|
741
|
+
for (const [file, realpath] of Object.entries(value)) {
|
|
742
|
+
if (
|
|
743
|
+
!path.isAbsolute(file) ||
|
|
744
|
+
(realpath !== null &&
|
|
745
|
+
(typeof realpath !== "string" || !path.isAbsolute(realpath)))
|
|
746
|
+
) {
|
|
747
|
+
continue;
|
|
748
|
+
}
|
|
749
|
+
output[path.resolve(file)] =
|
|
750
|
+
realpath === null ? null : path.resolve(realpath as string);
|
|
751
|
+
}
|
|
752
|
+
return Object.keys(output).length === 0 ? undefined : output;
|
|
753
|
+
}
|
|
754
|
+
|
|
461
755
|
/**
|
|
462
756
|
* Normalize the optional `dependencies` envelope field into a record of string
|
|
463
757
|
* arrays, or `undefined` when absent or carrying nothing usable.
|
|
@@ -483,11 +777,37 @@ function parseDependencyLists(
|
|
|
483
777
|
return Object.keys(output).length === 0 ? undefined : output;
|
|
484
778
|
}
|
|
485
779
|
|
|
780
|
+
/**
|
|
781
|
+
* Normalize graph adjacency while retaining every well-formed node key.
|
|
782
|
+
*
|
|
783
|
+
* A leaf is intentionally encoded as an empty target array. Its key still
|
|
784
|
+
* declares graph membership and lets persistent hosts bind the compiler-time
|
|
785
|
+
* input proof for that source. A node needs a non-empty source key and an array
|
|
786
|
+
* value; invalid array members are filtered without erasing a valid node.
|
|
787
|
+
*/
|
|
788
|
+
function parseGraphEdges(value: unknown): Record<string, string[]> | undefined {
|
|
789
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
790
|
+
return undefined;
|
|
791
|
+
}
|
|
792
|
+
const output: Record<string, string[]> = {};
|
|
793
|
+
for (const [key, entries] of Object.entries(value)) {
|
|
794
|
+
if (key.length === 0 || !Array.isArray(entries)) {
|
|
795
|
+
continue;
|
|
796
|
+
}
|
|
797
|
+
output[key] = entries.filter(
|
|
798
|
+
(entry): entry is string => typeof entry === "string",
|
|
799
|
+
);
|
|
800
|
+
}
|
|
801
|
+
return Object.keys(output).length === 0 ? undefined : output;
|
|
802
|
+
}
|
|
803
|
+
|
|
486
804
|
/**
|
|
487
805
|
* Normalize the optional `graph` envelope section with the same tolerance as
|
|
488
|
-
* `dependencies`: non-object sections are dropped,
|
|
489
|
-
*
|
|
490
|
-
*
|
|
806
|
+
* `dependencies`: non-object sections are dropped, empty source keys and edge
|
|
807
|
+
* entries that are not arrays are dropped, and non-string list members are
|
|
808
|
+
* filtered. Empty arrays remain as graph nodes because leaf membership binds
|
|
809
|
+
* compiler input proof. A section carrying nothing usable collapses to
|
|
810
|
+
* `undefined`.
|
|
491
811
|
*
|
|
492
812
|
* `candidates` is the one optional member, so an empty one is left off the
|
|
493
813
|
* result instead of being materialized as `{}`. The host omits the key when it
|
|
@@ -506,11 +826,15 @@ function parseReferenceGraph(
|
|
|
506
826
|
configs?: unknown;
|
|
507
827
|
edges?: unknown;
|
|
508
828
|
globals?: unknown;
|
|
829
|
+
inputHashes?: unknown;
|
|
830
|
+
inputRealpaths?: unknown;
|
|
509
831
|
};
|
|
510
832
|
const candidates = parseDependencyLists(section.candidates) ?? {};
|
|
511
|
-
const edges =
|
|
833
|
+
const edges = parseGraphEdges(section.edges) ?? {};
|
|
512
834
|
const globals = parseFileList(section.globals) ?? [];
|
|
513
835
|
const configs = parseFileList(section.configs) ?? [];
|
|
836
|
+
const inputHashes = parseGraphInputHashes(section.inputHashes);
|
|
837
|
+
const inputRealpaths = parseGraphInputRealpaths(section.inputRealpaths);
|
|
514
838
|
if (
|
|
515
839
|
Object.keys(candidates).length === 0 &&
|
|
516
840
|
Object.keys(edges).length === 0 &&
|
|
@@ -519,15 +843,62 @@ function parseReferenceGraph(
|
|
|
519
843
|
) {
|
|
520
844
|
return undefined;
|
|
521
845
|
}
|
|
522
|
-
return
|
|
523
|
-
? {
|
|
524
|
-
|
|
846
|
+
return {
|
|
847
|
+
...(Object.keys(candidates).length === 0 ? {} : { candidates }),
|
|
848
|
+
configs,
|
|
849
|
+
edges,
|
|
850
|
+
globals,
|
|
851
|
+
...(inputHashes === undefined ? {} : { inputHashes }),
|
|
852
|
+
...(inputRealpaths === undefined ? {} : { inputRealpaths }),
|
|
853
|
+
};
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
/** Parse graph-keyed compiler-time content/null observations. */
|
|
857
|
+
function parseGraphInputHashes(
|
|
858
|
+
value: unknown,
|
|
859
|
+
): Record<string, string | null> | undefined {
|
|
860
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
861
|
+
return undefined;
|
|
862
|
+
}
|
|
863
|
+
const output: Record<string, string | null> = {};
|
|
864
|
+
for (const [file, hash] of Object.entries(value)) {
|
|
865
|
+
if (
|
|
866
|
+
file.length === 0 ||
|
|
867
|
+
(hash !== null &&
|
|
868
|
+
(typeof hash !== "string" || !/^[0-9a-f]{64}$/.test(hash)))
|
|
869
|
+
) {
|
|
870
|
+
continue;
|
|
871
|
+
}
|
|
872
|
+
output[file] = hash;
|
|
873
|
+
}
|
|
874
|
+
return Object.keys(output).length === 0 ? undefined : output;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
/** Parse graph-keyed compiler-time physical/null identities. */
|
|
878
|
+
function parseGraphInputRealpaths(
|
|
879
|
+
value: unknown,
|
|
880
|
+
): Record<string, string | null> | undefined {
|
|
881
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
882
|
+
return undefined;
|
|
883
|
+
}
|
|
884
|
+
const output: Record<string, string | null> = {};
|
|
885
|
+
for (const [file, realpath] of Object.entries(value)) {
|
|
886
|
+
if (
|
|
887
|
+
file.length === 0 ||
|
|
888
|
+
(realpath !== null &&
|
|
889
|
+
(typeof realpath !== "string" || !path.isAbsolute(realpath)))
|
|
890
|
+
) {
|
|
891
|
+
continue;
|
|
892
|
+
}
|
|
893
|
+
output[file] = realpath === null ? null : path.resolve(realpath);
|
|
894
|
+
}
|
|
895
|
+
return Object.keys(output).length === 0 ? undefined : output;
|
|
525
896
|
}
|
|
526
897
|
|
|
527
898
|
/**
|
|
528
899
|
* Normalize an optional string-list envelope field (`dependenciesComplete`,
|
|
529
|
-
* `volatile`, and the `globals`/`configs` graph sections), or
|
|
530
|
-
* absent or carrying nothing usable.
|
|
900
|
+
* `hostInputs`, `volatile`, and the `globals`/`configs` graph sections), or
|
|
901
|
+
* `undefined` when absent or carrying nothing usable.
|
|
531
902
|
*/
|
|
532
903
|
function parseFileList(value: unknown): string[] | undefined {
|
|
533
904
|
if (!Array.isArray(value)) {
|
package/src/flags/schema.ts
CHANGED
|
@@ -635,10 +635,17 @@ export const FLAG_SCHEMA: readonly FlagSpec[] = [
|
|
|
635
635
|
},
|
|
636
636
|
|
|
637
637
|
// -------------------------------------------------------------------------
|
|
638
|
-
// `--tsgo-args` — JSON-encoded passthrough envelope
|
|
639
|
-
//
|
|
640
|
-
//
|
|
641
|
-
//
|
|
638
|
+
// `--tsgo-args` — JSON-encoded passthrough envelope a native sidecar decodes
|
|
639
|
+
// back into the tsgo argv. Listed here so the schema describes every flag
|
|
640
|
+
// the Go layers accept, not just the user-facing ones.
|
|
641
|
+
//
|
|
642
|
+
// The launcher no longer emits it. A CLI flag is fatal to any host whose
|
|
643
|
+
// `flag.FlagSet` does not declare it, and this one was added to a plugin
|
|
644
|
+
// protocol third-party hosts had already frozen, so every forwarded compiler
|
|
645
|
+
// flag exited 2 on a typia/nestia-shaped sidecar (issue #1188). The payload
|
|
646
|
+
// now rides the `TTSC_TSGO_ARGS` environment variable, which an unaware host
|
|
647
|
+
// simply ignores. ttsc's own hosts still accept the flag so an older
|
|
648
|
+
// launcher, or an embedder that composes sidecar argv itself, keeps working.
|
|
642
649
|
// -------------------------------------------------------------------------
|
|
643
650
|
{
|
|
644
651
|
name: "--tsgo-args",
|
|
@@ -654,7 +661,7 @@ export const FLAG_SCHEMA: readonly FlagSpec[] = [
|
|
|
654
661
|
],
|
|
655
662
|
consumedBy: ["host", "lint"],
|
|
656
663
|
description:
|
|
657
|
-
"JSON-encoded tsgo passthrough argv (internal:
|
|
664
|
+
"JSON-encoded tsgo passthrough argv (internal: accepted by ttsc's own hosts; the launcher forwards it in TTSC_TSGO_ARGS).",
|
|
658
665
|
},
|
|
659
666
|
{
|
|
660
667
|
name: "--plugins-json",
|