ttsc 0.26.1 → 0.27.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 +10 -1
- package/cmd/ttsc/api_transform.go +17 -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/serve.go +104 -35
- package/driver/diagnostics_preamble.go +284 -0
- package/driver/emit_plugin.go +71 -19
- 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 +384 -4
- package/driver/program.go +81 -15
- package/driver/resolution_candidates.go +13 -5
- package/driver/rewrite.go +47 -4
- package/internal/graph/diagnostics.go +4 -3
- package/internal/graph/provenance.go +10 -1
- 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 +11 -3
- package/lib/compiler/internal/compileProjectInMemory.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 +29 -1
- package/lib/compiler/internal/runBuild.js +117 -32
- package/lib/compiler/internal/runBuild.js.map +1 -1
- package/lib/compiler/internal/runSingleFileEmit.js +9 -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 +33 -5
- package/lib/flags/schema.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/assertNoSolutionBuild.d.ts +31 -0
- package/lib/launcher/internal/assertNoSolutionBuild.js +38 -0
- package/lib/launcher/internal/assertNoSolutionBuild.js.map +1 -0
- package/lib/launcher/internal/prepareExecution.d.ts +3 -0
- package/lib/launcher/internal/prepareExecution.js +73 -26
- package/lib/launcher/internal/prepareExecution.js.map +1 -1
- package/lib/launcher/internal/runTtsc.js +27 -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 +4 -0
- package/lib/launcher/internal/runTtsx.js.map +1 -1
- package/lib/launcher/internal/runtimeHooks.d.ts +37 -1
- package/lib/launcher/internal/runtimeHooks.js +660 -62
- 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/loadProjectPlugins.d.ts +17 -5
- package/lib/plugin/internal/loadProjectPlugins.js +1339 -77
- package/lib/plugin/internal/loadProjectPlugins.js.map +1 -1
- 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 +31 -0
- package/lib/structures/ITtscPlugin.d.ts +33 -0
- package/package.json +16 -9
- package/shim/checker/go.mod +9 -0
- package/shim/checker/go.sum +22 -0
- package/shim/checker/shim.go +75 -0
- package/shim/compiler/emit_sourcemap.go +56 -15
- 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 +11 -3
- package/src/compiler/internal/resolveEmittedJavaScript.ts +6 -0
- package/src/compiler/internal/runBuild.ts +172 -36
- package/src/compiler/internal/runSingleFileEmit.ts +9 -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 +35 -5
- 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/assertNoSolutionBuild.ts +40 -0
- package/src/launcher/internal/prepareExecution.ts +78 -26
- package/src/launcher/internal/runTtsc.ts +26 -13
- package/src/launcher/internal/runTtscserver.ts +18 -3
- package/src/launcher/internal/runTtsx.ts +4 -0
- package/src/launcher/internal/runtimeHooks.ts +830 -66
- package/src/plugin/internal/buildSourcePlugin.ts +984 -79
- package/src/plugin/internal/loadProjectPlugins.ts +1718 -104
- package/src/register.ts +47 -0
- package/src/structures/ITtscCompilerContext.ts +6 -3
- package/src/structures/ITtscCompilerTransformation.ts +39 -0
- package/src/structures/ITtscPlugin.ts +36 -0
- package/tools/shim_audit/baseline.json +0 -1
- package/utility/host.go +9 -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
|
@@ -3,12 +3,51 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.TSGO_ARGS_ENV = void 0;
|
|
7
|
+
exports.clearInheritedTsgoArgs = clearInheritedTsgoArgs;
|
|
8
|
+
exports.inheritedSidecarEnv = inheritedSidecarEnv;
|
|
6
9
|
exports.resolvePluginConfigDir = resolvePluginConfigDir;
|
|
7
10
|
exports.isLinkedTransform = isLinkedTransform;
|
|
8
11
|
exports.assertSharedHostCompatibility = assertSharedHostCompatibility;
|
|
9
12
|
exports.selectSharedHostPlugin = selectSharedHostPlugin;
|
|
10
13
|
exports.linkedTransformPlugins = linkedTransformPlugins;
|
|
11
14
|
const node_path_1 = __importDefault(require("node:path"));
|
|
15
|
+
/**
|
|
16
|
+
* Environment channel carrying the JSON-encoded tsgo argv ttsc forwards to a
|
|
17
|
+
* native sidecar. Mirrors `driver.TsgoArgsEnv` on the Go side; see
|
|
18
|
+
* `runBuild.ts::createNativeTsgoArgs` for why the payload is not a CLI flag.
|
|
19
|
+
*/
|
|
20
|
+
exports.TSGO_ARGS_ENV = "TTSC_TSGO_ARGS";
|
|
21
|
+
/**
|
|
22
|
+
* Drop a forwarded-tsgo payload this invocation did not publish itself.
|
|
23
|
+
*
|
|
24
|
+
* Every sidecar env starts from `process.env`, so a ttsc that is itself running
|
|
25
|
+
* inside a plugin sidecar — `@ttsc/lint` evaluating a config file through
|
|
26
|
+
* `ttsx`, for instance — would otherwise hand the outer run's `--strict` to its
|
|
27
|
+
* own sidecars, and `driver.LoadProgram` would apply it. The forwarded argv is
|
|
28
|
+
* per-invocation state the spawning host owns, the same rule
|
|
29
|
+
* `TTSC_PLUGIN_CONFIG_DIR` already follows. A caller that named the variable
|
|
30
|
+
* explicitly keeps it.
|
|
31
|
+
*/
|
|
32
|
+
function clearInheritedTsgoArgs(env, callerEnv) {
|
|
33
|
+
if (callerEnv?.[exports.TSGO_ARGS_ENV] === undefined) {
|
|
34
|
+
delete env[exports.TSGO_ARGS_ENV];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The `{ ...process.env, ...callerEnv }` a child process inherits, minus a
|
|
39
|
+
* forwarded-tsgo payload this lane never published.
|
|
40
|
+
*
|
|
41
|
+
* Use it at every spawn whose child can reach `driver.LoadProgram` — the
|
|
42
|
+
* `api-compile` / `api-transform` hosts, and the plugin loader, whose `ttsx`
|
|
43
|
+
* descriptor evaluation compiles a project of its own. One rule at every site
|
|
44
|
+
* beats four sites each reasoning about whether the variable could be present.
|
|
45
|
+
*/
|
|
46
|
+
function inheritedSidecarEnv(callerEnv) {
|
|
47
|
+
const env = { ...process.env, ...callerEnv };
|
|
48
|
+
clearInheritedTsgoArgs(env, callerEnv);
|
|
49
|
+
return env;
|
|
50
|
+
}
|
|
12
51
|
/**
|
|
13
52
|
* Resolve the caller-declared plugin config anchor to an absolute path, or
|
|
14
53
|
* `undefined` when the caller did not declare one.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sharedHostHelpers.js","sourceRoot":"","sources":["../../../src/compiler/internal/sharedHostHelpers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sharedHostHelpers.js","sourceRoot":"","sources":["../../../src/compiler/internal/sharedHostHelpers.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,0DAA6B;AAI7B;;;;GAIG;AACU,QAAA,aAAa,GAAG,gBAAgB,CAAC;AAE9C;;;;;;;;;;GAUG;AACH,gCACE,GAAsB,EACtB,SAAwC;IAExC,IAAI,SAAS,EAAE,CAAC,QAAA,aAAa,CAAC,KAAK,SAAS,EAAE,CAAC;QAC7C,OAAO,GAAG,CAAC,QAAA,aAAa,CAAC,CAAC;IAC5B,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,6BACE,SAAwC;IAExC,MAAM,GAAG,GAAsB,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,SAAS,EAAE,CAAC;IAChE,sBAAsB,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IACvC,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;;;GAWG;AACH,gCAAuC,OAGtC;IACC,IAAI,OAAO,CAAC,eAAe,KAAK,SAAS,IAAI,OAAO,CAAC,eAAe,KAAK,EAAE,EAAE,CAAC;QAC5E,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,mBAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;AAC7E,CAAC;AAED;;;GAGG;AACH,2BAAkC,MAA+B;IAC/D,OAAO,MAAM,CAAC,KAAK,KAAK,WAAW,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC;AAClE,CAAC;AAED;;;;;;;;;;;GAWG;AACH,uCACE,OAA2C,EAC3C,IAAiC;IAEjC,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACtE,IAAI,QAAQ,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QACzB,OAAO;IACT,CAAC;IACD,MAAM,aAAa,GAAG;QACpB,GAAG,IAAI,GAAG,CACR,OAAO;aACJ,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;aAC9C,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAClC;KACF,CAAC;IACF,IAAI,aAAa,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QAC9B,OAAO;IACT,CAAC;IACD,MAAM,MAAM,GACV,IAAI,KAAK,MAAM;QACb,CAAC,CAAC,8DAA8D;QAChE,CAAC,CAAC,2EAA2E,CAAC;IAClF,MAAM,IAAI,KAAK,CACb,QAAQ;QACN,MAAM;QACN,iEAAiE,CACpE,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,gCACE,OAA2C;IAE3C,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,CAAE,CAAC;AAC7E,CAAC;AAED;;;;GAIG;AACH,gCACE,OAA2C;IAE3C,OAAO,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAC3C,CAAC"}
|
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.startResidentTransform = startResidentTransform;
|
|
7
7
|
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
+
const resolveNodeBinary_1 = require("../../internal/resolveNodeBinary");
|
|
8
9
|
const loadProjectPlugins_1 = require("../../plugin/internal/loadProjectPlugins");
|
|
9
10
|
const readProjectConfig_1 = require("./project/readProjectConfig");
|
|
10
11
|
const residentTransformProcess_1 = require("./residentTransformProcess");
|
|
@@ -38,7 +39,7 @@ function startResidentTransform(context) {
|
|
|
38
39
|
cacheDir: context.cacheDir ?? context.env?.TTSC_CACHE_DIR,
|
|
39
40
|
cwd,
|
|
40
41
|
entries: context.plugins,
|
|
41
|
-
env:
|
|
42
|
+
env: (0, sharedHostHelpers_1.inheritedSidecarEnv)(context.env),
|
|
42
43
|
pluginConfigDir: context.pluginConfigDir,
|
|
43
44
|
projectRoot: context.projectRoot,
|
|
44
45
|
tsconfig: project.path,
|
|
@@ -60,7 +61,7 @@ function startResidentTransform(context) {
|
|
|
60
61
|
],
|
|
61
62
|
binary: host.binary,
|
|
62
63
|
cwd: project.root,
|
|
63
|
-
env: residentEnv(context, tsgoBinary, loaded.nativePlugins),
|
|
64
|
+
env: residentEnv(context, project.root, tsgoBinary, loaded.nativePlugins),
|
|
64
65
|
});
|
|
65
66
|
return { process: resident, projectRoot: project.root };
|
|
66
67
|
}
|
|
@@ -73,11 +74,10 @@ function startResidentTransform(context) {
|
|
|
73
74
|
* wrapper's temp-dir ancestry, and forwards linked transform plugins via
|
|
74
75
|
* `TTSC_LINKED_PLUGINS_JSON`.
|
|
75
76
|
*/
|
|
76
|
-
function residentEnv(context, tsgoBinary, nativePlugins) {
|
|
77
|
+
function residentEnv(context, projectRoot, tsgoBinary, nativePlugins) {
|
|
77
78
|
const pluginConfigDir = (0, sharedHostHelpers_1.resolvePluginConfigDir)(context);
|
|
78
79
|
const env = {
|
|
79
80
|
...process.env,
|
|
80
|
-
TTSC_NODE_BINARY: process.env.TTSC_NODE_BINARY ?? process.execPath,
|
|
81
81
|
...(pluginConfigDir === undefined
|
|
82
82
|
? {}
|
|
83
83
|
: { TTSC_PLUGIN_CONFIG_DIR: pluginConfigDir }),
|
|
@@ -86,6 +86,11 @@ function residentEnv(context, tsgoBinary, nativePlugins) {
|
|
|
86
86
|
node_path_1.default.join(__dirname, "..", "..", "launcher", "ttsx.js"),
|
|
87
87
|
...context.env,
|
|
88
88
|
};
|
|
89
|
+
const node = (0, resolveNodeBinary_1.resolveNodeBinary)(env, projectRoot);
|
|
90
|
+
if (node === undefined)
|
|
91
|
+
delete env.TTSC_NODE_BINARY;
|
|
92
|
+
else
|
|
93
|
+
env.TTSC_NODE_BINARY = node;
|
|
89
94
|
// The anchor is per-invocation state owned by this host: when this run
|
|
90
95
|
// declared none (and the caller's env does not name one), drop any value
|
|
91
96
|
// inherited from an ancestor ttsc process so a nested build never
|
|
@@ -94,6 +99,9 @@ function residentEnv(context, tsgoBinary, nativePlugins) {
|
|
|
94
99
|
context.env?.TTSC_PLUGIN_CONFIG_DIR === undefined) {
|
|
95
100
|
delete env.TTSC_PLUGIN_CONFIG_DIR;
|
|
96
101
|
}
|
|
102
|
+
// This lane forwards no tsgo argv of its own, so anything inherited belongs
|
|
103
|
+
// to an outer ttsc run and must not reach the resident sidecar.
|
|
104
|
+
(0, sharedHostHelpers_1.clearInheritedTsgoArgs)(env, context.env);
|
|
97
105
|
const linked = (0, sharedHostHelpers_1.linkedTransformPlugins)(nativePlugins);
|
|
98
106
|
if (linked.length !== 0) {
|
|
99
107
|
env.TTSC_LINKED_PLUGINS_JSON = serializeNativePlugins(linked);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startResidentTransform.js","sourceRoot":"","sources":["../../../src/compiler/internal/startResidentTransform.ts"],"names":[],"mappings":";;;;;;AAAA,0DAA6B;AAE7B,iFAA8E;AAG9E,mEAAgE;AAChE,yEAAsE;AACtE,mDAAgD;AAChD,+CAA4C;AAC5C,
|
|
1
|
+
{"version":3,"file":"startResidentTransform.js","sourceRoot":"","sources":["../../../src/compiler/internal/startResidentTransform.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,6 +20,9 @@ export declare function transformProjectInMemory(options: ITtscCompilerContext):
|
|
|
20
20
|
dependencies?: Record<string, string[]>;
|
|
21
21
|
dependenciesComplete?: string[];
|
|
22
22
|
graph?: ITtscCompilerTransformation.IReferenceGraph;
|
|
23
|
+
hostInputHashes?: Record<string, string | null>;
|
|
24
|
+
hostInputRealpaths?: Record<string, string | null>;
|
|
25
|
+
hostInputs?: string[];
|
|
23
26
|
result: TtscBuildResult;
|
|
24
27
|
typescript: Record<string, string>;
|
|
25
28
|
volatile?: string[];
|
|
@@ -5,11 +5,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.transformProjectInMemory = transformProjectInMemory;
|
|
7
7
|
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
+
const resolveNodeBinary_1 = require("../../internal/resolveNodeBinary");
|
|
8
9
|
const loadProjectPlugins_1 = require("../../plugin/internal/loadProjectPlugins");
|
|
9
10
|
const buildNativeCompiler_1 = require("./buildNativeCompiler");
|
|
10
11
|
const paths_1 = require("./paths");
|
|
11
12
|
const createNativeProjectContextArgs_1 = require("./project/createNativeProjectContextArgs");
|
|
12
|
-
const readProjectConfig_1 = require("./project/readProjectConfig");
|
|
13
13
|
const resolveBinary_1 = require("./resolveBinary");
|
|
14
14
|
const resolveTsgo_1 = require("./resolveTsgo");
|
|
15
15
|
const runBuild_1 = require("./runBuild");
|
|
@@ -32,26 +32,39 @@ const spawnNative_1 = require("./spawnNative");
|
|
|
32
32
|
*/
|
|
33
33
|
function transformProjectInMemory(options) {
|
|
34
34
|
const cwd = node_path_1.default.resolve(options.cwd ?? process.cwd());
|
|
35
|
-
const
|
|
35
|
+
const loaded = (0, loadProjectPlugins_1.loadProjectPlugins)({
|
|
36
|
+
binary: (0, resolveBinary_1.resolveBinary)(options) ?? "",
|
|
37
|
+
cacheDir: options.cacheDir ?? options.env?.TTSC_CACHE_DIR,
|
|
36
38
|
cwd,
|
|
39
|
+
entries: options.plugins,
|
|
40
|
+
env: (0, sharedHostHelpers_1.inheritedSidecarEnv)(options.env),
|
|
41
|
+
pluginConfigDir: options.pluginConfigDir,
|
|
37
42
|
projectRoot: options.projectRoot,
|
|
38
43
|
tsconfig: options.tsconfig,
|
|
39
44
|
});
|
|
40
|
-
if (
|
|
41
|
-
return transformProjectWithPlugins(options,
|
|
45
|
+
if (loaded.nativePlugins.length !== 0) {
|
|
46
|
+
return transformProjectWithPlugins(options, loaded);
|
|
42
47
|
}
|
|
43
|
-
return transformProjectWithNativeHost(options, project);
|
|
44
|
-
}
|
|
45
|
-
/** Return true when the project or the call-level options declare any plugins. */
|
|
46
|
-
function hasConfiguredPlugins(options, project) {
|
|
47
|
-
return (0, loadProjectPlugins_1.hasProjectPluginEntries)(project, options.plugins);
|
|
48
|
+
return transformProjectWithNativeHost(options, loaded.project, loaded);
|
|
48
49
|
}
|
|
49
50
|
/**
|
|
50
51
|
* Transform via the built-in native compiler host (`cmd/ttsc api-transform`).
|
|
51
52
|
* Used when no user plugins are configured, or as the fallback transformer when
|
|
52
53
|
* check-stage plugins pass and no transform-stage plugins are declared.
|
|
53
54
|
*/
|
|
54
|
-
function transformProjectWithNativeHost(options, project) {
|
|
55
|
+
function transformProjectWithNativeHost(options, project, baseline) {
|
|
56
|
+
// Capture the project inputs before the native host observes them. Pairing a
|
|
57
|
+
// post-build hash with an earlier result can bless a torn generation when a
|
|
58
|
+
// config changes during the child process.
|
|
59
|
+
// Plugin discovery already ran in loadProjectPlugins. The native host only
|
|
60
|
+
// consumes the resolved config chain here, so dependency package manifests
|
|
61
|
+
// must not become per-project universal inputs a second time.
|
|
62
|
+
const projectHostInputs = (0, loadProjectPlugins_1.collectProjectHostInputs)(project, false);
|
|
63
|
+
const projectHostInputHashes = (0, loadProjectPlugins_1.hashHostInputPaths)(projectHostInputs);
|
|
64
|
+
const projectHostInputRealpaths = (0, loadProjectPlugins_1.realpathHostInputPaths)(projectHostInputs);
|
|
65
|
+
const observedHostInputs = mergeHostInputs(baseline?.hostInputs, projectHostInputs);
|
|
66
|
+
const observedHostInputHashes = mergeCompatibleHostInputHashes(baseline?.hostInputHashes ?? {}, projectHostInputHashes, baseline?.hostInputs ?? [], projectHostInputs);
|
|
67
|
+
const observedHostInputRealpaths = mergeCompatibleHostInputHashes(baseline?.hostInputRealpaths ?? {}, projectHostInputRealpaths, baseline?.hostInputs ?? [], projectHostInputs);
|
|
55
68
|
const binary = (0, buildNativeCompiler_1.buildNativeCompiler)({
|
|
56
69
|
cacheBaseDir: project.root,
|
|
57
70
|
cacheDir: options.cacheDir ?? options.env?.TTSC_CACHE_DIR,
|
|
@@ -59,14 +72,21 @@ function transformProjectWithNativeHost(options, project) {
|
|
|
59
72
|
});
|
|
60
73
|
const res = (0, spawnNative_1.spawnNative)(binary, ["api-transform", "--cwd", project.root, "--tsconfig", project.path], {
|
|
61
74
|
cwd: project.root,
|
|
62
|
-
env:
|
|
75
|
+
env: (0, sharedHostHelpers_1.inheritedSidecarEnv)(options.env),
|
|
63
76
|
});
|
|
64
77
|
if (res.error) {
|
|
65
78
|
throw new Error(`ttsc: failed to spawn native compiler host ${binary}: ${res.error.message}`);
|
|
66
79
|
}
|
|
67
80
|
const output = parseNativeTransformOutput((0, spawnNative_1.outputText)(res.stdout), (0, spawnNative_1.outputText)(res.stderr));
|
|
81
|
+
const finalObservedHostInputHashes = revalidateHostInputHashes(observedHostInputHashes, observedHostInputs);
|
|
82
|
+
const finalOutputHostInputHashes = revalidateHostInputHashes(output.hostInputHashes ?? {}, output.hostInputs ?? []);
|
|
83
|
+
const finalObservedHostInputRealpaths = revalidateHostInputRealpaths(observedHostInputRealpaths, observedHostInputs);
|
|
84
|
+
const finalOutputHostInputRealpaths = revalidateHostInputRealpaths(output.hostInputRealpaths ?? {}, output.hostInputs ?? []);
|
|
68
85
|
return {
|
|
69
86
|
...envelopeSideChannels(output),
|
|
87
|
+
hostInputHashes: mergeCompatibleHostInputHashes(finalObservedHostInputHashes, finalOutputHostInputHashes, observedHostInputs, output.hostInputs),
|
|
88
|
+
hostInputRealpaths: mergeCompatibleHostInputHashes(finalObservedHostInputRealpaths, finalOutputHostInputRealpaths, observedHostInputs, output.hostInputs),
|
|
89
|
+
hostInputs: mergeHostInputs(observedHostInputs, output.hostInputs),
|
|
70
90
|
result: {
|
|
71
91
|
diagnostics: output.diagnostics,
|
|
72
92
|
status: res.status ?? 1,
|
|
@@ -76,17 +96,8 @@ function transformProjectWithNativeHost(options, project) {
|
|
|
76
96
|
typescript: output.typescript,
|
|
77
97
|
};
|
|
78
98
|
}
|
|
79
|
-
function transformProjectWithPlugins(options,
|
|
80
|
-
const
|
|
81
|
-
binary: (0, resolveBinary_1.resolveBinary)(options) ?? "",
|
|
82
|
-
cacheDir: options.cacheDir ?? options.env?.TTSC_CACHE_DIR,
|
|
83
|
-
cwd,
|
|
84
|
-
entries: options.plugins,
|
|
85
|
-
env: { ...process.env, ...options.env },
|
|
86
|
-
pluginConfigDir: options.pluginConfigDir,
|
|
87
|
-
projectRoot: options.projectRoot,
|
|
88
|
-
tsconfig: project.path,
|
|
89
|
-
});
|
|
99
|
+
function transformProjectWithPlugins(options, loaded) {
|
|
100
|
+
const { project } = loaded;
|
|
90
101
|
const checks = loaded.nativePlugins.filter((plugin) => plugin.stage === "check");
|
|
91
102
|
const transformers = loaded.nativePlugins.filter((plugin) => plugin.stage === "transform");
|
|
92
103
|
const tsgoBinary = loaded.nativePlugins.length === 0
|
|
@@ -95,14 +106,22 @@ function transformProjectWithPlugins(options, cwd, project) {
|
|
|
95
106
|
const checked = runNativeChecks(options, project, tsgoBinary, loaded.nativePlugins, checks);
|
|
96
107
|
if (checked.status !== 0) {
|
|
97
108
|
return {
|
|
109
|
+
hostInputHashes: revalidateHostInputHashes(loaded.hostInputHashes, loaded.hostInputs),
|
|
110
|
+
hostInputRealpaths: revalidateHostInputRealpaths(loaded.hostInputRealpaths, loaded.hostInputs),
|
|
111
|
+
hostInputs: loaded.hostInputs,
|
|
98
112
|
result: checked,
|
|
99
113
|
typescript: {},
|
|
100
114
|
};
|
|
101
115
|
}
|
|
102
116
|
if (transformers.length === 0) {
|
|
103
117
|
const transformed = transformProjectWithNativeHost(options, project);
|
|
118
|
+
const finalLoadedHostInputHashes = revalidateHostInputHashes(loaded.hostInputHashes, loaded.hostInputs);
|
|
119
|
+
const finalLoadedHostInputRealpaths = revalidateHostInputRealpaths(loaded.hostInputRealpaths, loaded.hostInputs);
|
|
104
120
|
return {
|
|
105
121
|
...envelopeSideChannels(transformed),
|
|
122
|
+
hostInputHashes: mergeCompatibleHostInputHashes(finalLoadedHostInputHashes, transformed.hostInputHashes, loaded.hostInputs, transformed.hostInputs),
|
|
123
|
+
hostInputRealpaths: mergeCompatibleHostInputHashes(finalLoadedHostInputRealpaths, transformed.hostInputRealpaths, loaded.hostInputs, transformed.hostInputs),
|
|
124
|
+
hostInputs: mergeHostInputs(loaded.hostInputs, transformed.hostInputs),
|
|
106
125
|
result: (0, runBuild_1.appendBuildOutput)(checked, transformed.result),
|
|
107
126
|
typescript: transformed.typescript,
|
|
108
127
|
};
|
|
@@ -111,7 +130,7 @@ function transformProjectWithPlugins(options, cwd, project) {
|
|
|
111
130
|
const plugin = (0, sharedHostHelpers_1.selectSharedHostPlugin)(transformers);
|
|
112
131
|
const res = (0, spawnNative_1.spawnNative)(plugin.binary, createNativeTransformArgs(project, transformers, (0, sharedHostHelpers_1.resolvePluginConfigDir)(options)), {
|
|
113
132
|
cwd: project.root,
|
|
114
|
-
env: nativePluginEnv(options, tsgoBinary, loaded.nativePlugins, plugin),
|
|
133
|
+
env: nativePluginEnv(options, project.root, tsgoBinary, loaded.nativePlugins, plugin),
|
|
115
134
|
});
|
|
116
135
|
if (res.error) {
|
|
117
136
|
throw new Error(`ttsc.transform: failed to spawn ${plugin.binary}: ${res.error.message}`);
|
|
@@ -123,12 +142,41 @@ function transformProjectWithPlugins(options, cwd, project) {
|
|
|
123
142
|
stdout: "",
|
|
124
143
|
stderr: (0, spawnNative_1.outputText)(res.stderr),
|
|
125
144
|
};
|
|
145
|
+
const finalLoadedHostInputHashes = revalidateHostInputHashes(loaded.hostInputHashes, loaded.hostInputs);
|
|
146
|
+
const finalOutputHostInputHashes = revalidateHostInputHashes(output.hostInputHashes ?? {}, output.hostInputs ?? []);
|
|
147
|
+
const finalLoadedHostInputRealpaths = revalidateHostInputRealpaths(loaded.hostInputRealpaths, loaded.hostInputs);
|
|
148
|
+
const finalOutputHostInputRealpaths = revalidateHostInputRealpaths(output.hostInputRealpaths ?? {}, output.hostInputs ?? []);
|
|
126
149
|
return {
|
|
127
150
|
...envelopeSideChannels(output),
|
|
151
|
+
hostInputHashes: mergeCompatibleHostInputHashes(finalLoadedHostInputHashes, finalOutputHostInputHashes, loaded.hostInputs, output.hostInputs),
|
|
152
|
+
hostInputRealpaths: mergeCompatibleHostInputHashes(finalLoadedHostInputRealpaths, finalOutputHostInputRealpaths, loaded.hostInputs, output.hostInputs),
|
|
153
|
+
hostInputs: mergeHostInputs(loaded.hostInputs, output.hostInputs),
|
|
128
154
|
result: (0, runBuild_1.appendBuildOutput)(checked, result),
|
|
129
155
|
typescript: output.typescript,
|
|
130
156
|
};
|
|
131
157
|
}
|
|
158
|
+
/** Keep evaluation proof only when the same input still has the same state. */
|
|
159
|
+
function revalidateHostInputHashes(initial, inputs) {
|
|
160
|
+
const current = (0, loadProjectPlugins_1.hashHostInputPaths)(inputs);
|
|
161
|
+
return Object.fromEntries(inputs.flatMap((input) => {
|
|
162
|
+
const absolute = node_path_1.default.resolve(input);
|
|
163
|
+
return Object.prototype.hasOwnProperty.call(initial, absolute) &&
|
|
164
|
+
initial[absolute] === current[absolute]
|
|
165
|
+
? [[absolute, current[absolute]]]
|
|
166
|
+
: [];
|
|
167
|
+
}));
|
|
168
|
+
}
|
|
169
|
+
/** Keep evaluation proof only while each lexical path selects the same target. */
|
|
170
|
+
function revalidateHostInputRealpaths(initial, inputs) {
|
|
171
|
+
const current = (0, loadProjectPlugins_1.realpathHostInputPaths)(inputs);
|
|
172
|
+
return Object.fromEntries(inputs.flatMap((input) => {
|
|
173
|
+
const absolute = node_path_1.default.resolve(input);
|
|
174
|
+
return Object.prototype.hasOwnProperty.call(initial, absolute) &&
|
|
175
|
+
initial[absolute] === current[absolute]
|
|
176
|
+
? [[absolute, current[absolute]]]
|
|
177
|
+
: [];
|
|
178
|
+
}));
|
|
179
|
+
}
|
|
132
180
|
/**
|
|
133
181
|
* Collect the optional advisory envelope fields (`dependencies`,
|
|
134
182
|
* `dependenciesComplete`, `graph`, `volatile`) into a spreadable object,
|
|
@@ -147,6 +195,54 @@ function envelopeSideChannels(output) {
|
|
|
147
195
|
...(output.volatile === undefined ? {} : { volatile: output.volatile }),
|
|
148
196
|
};
|
|
149
197
|
}
|
|
198
|
+
/** Merge JavaScript- and native-host universal inputs by absolute path. */
|
|
199
|
+
function mergeHostInputs(...groups) {
|
|
200
|
+
return [
|
|
201
|
+
...new Set(groups.flatMap((group) => (group ?? []).map((file) => node_path_1.default.resolve(file)))),
|
|
202
|
+
].sort();
|
|
203
|
+
}
|
|
204
|
+
/** Keep only native/descriptor fingerprints that agree on shared paths. */
|
|
205
|
+
function mergeCompatibleHostInputHashes(first, second, firstInputs, secondInputs) {
|
|
206
|
+
const firstDeclared = new Set(firstInputs.map((input) => node_path_1.default.resolve(input)));
|
|
207
|
+
const secondDeclared = new Set((secondInputs ?? []).map((input) => node_path_1.default.resolve(input)));
|
|
208
|
+
const output = Object.fromEntries(Object.entries(first).flatMap(([file, hash]) => {
|
|
209
|
+
const absolute = node_path_1.default.resolve(file);
|
|
210
|
+
return firstDeclared.has(absolute) ? [[absolute, hash]] : [];
|
|
211
|
+
}));
|
|
212
|
+
const unproven = new Set();
|
|
213
|
+
for (const input of firstInputs) {
|
|
214
|
+
const absolute = node_path_1.default.resolve(input);
|
|
215
|
+
if (!Object.prototype.hasOwnProperty.call(first, absolute)) {
|
|
216
|
+
delete output[absolute];
|
|
217
|
+
unproven.add(absolute);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
for (const input of secondInputs ?? []) {
|
|
221
|
+
const absolute = node_path_1.default.resolve(input);
|
|
222
|
+
if (!Object.prototype.hasOwnProperty.call(second ?? {}, absolute)) {
|
|
223
|
+
delete output[absolute];
|
|
224
|
+
unproven.add(absolute);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
for (const [file, hash] of Object.entries(second ?? {})) {
|
|
228
|
+
const absolute = node_path_1.default.resolve(file);
|
|
229
|
+
if (!secondDeclared.has(absolute))
|
|
230
|
+
continue;
|
|
231
|
+
if (unproven.has(absolute))
|
|
232
|
+
continue;
|
|
233
|
+
if (Object.prototype.hasOwnProperty.call(output, absolute) &&
|
|
234
|
+
output[absolute] !== hash) {
|
|
235
|
+
// Two evaluation stages observed different states. Dropping proof makes
|
|
236
|
+
// persistent adapters replace the generation without turning advisory
|
|
237
|
+
// cache metadata into a user-facing compile failure.
|
|
238
|
+
delete output[absolute];
|
|
239
|
+
unproven.add(absolute);
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
output[absolute] = hash;
|
|
243
|
+
}
|
|
244
|
+
return output;
|
|
245
|
+
}
|
|
150
246
|
/**
|
|
151
247
|
* Run every check-stage plugin in sequence, short-circuiting on the first
|
|
152
248
|
* failure. Returns the aggregated `TtscBuildResult` (status 0 when all pass).
|
|
@@ -161,7 +257,7 @@ function runNativeChecks(options, project, tsgoBinary, nativePlugins, checks) {
|
|
|
161
257
|
for (const plugin of checks) {
|
|
162
258
|
const res = (0, spawnNative_1.spawnNative)(plugin.binary, createNativeCheckArgs(project, nativePlugins, plugin, (0, sharedHostHelpers_1.resolvePluginConfigDir)(options)), {
|
|
163
259
|
cwd: project.root,
|
|
164
|
-
env: nativePluginEnv(options, tsgoBinary, nativePlugins, plugin),
|
|
260
|
+
env: nativePluginEnv(options, project.root, tsgoBinary, nativePlugins, plugin),
|
|
165
261
|
});
|
|
166
262
|
if (res.error) {
|
|
167
263
|
throw new Error(`ttsc.transform.check: failed to spawn ${plugin.binary}: ${res.error.message}`);
|
|
@@ -223,11 +319,10 @@ function serializeNativePlugins(plugins) {
|
|
|
223
319
|
* instead of the wrapper's temp-dir ancestry. For transform plugins, also
|
|
224
320
|
* passes `TTSC_LINKED_PLUGINS_JSON` when linked sources are present.
|
|
225
321
|
*/
|
|
226
|
-
function nativePluginEnv(options, tsgoBinary, nativePlugins, plugin) {
|
|
322
|
+
function nativePluginEnv(options, projectRoot, tsgoBinary, nativePlugins, plugin) {
|
|
227
323
|
const pluginConfigDir = (0, sharedHostHelpers_1.resolvePluginConfigDir)(options);
|
|
228
324
|
const env = {
|
|
229
325
|
...process.env,
|
|
230
|
-
TTSC_NODE_BINARY: process.env.TTSC_NODE_BINARY ?? process.execPath,
|
|
231
326
|
...(pluginConfigDir === undefined
|
|
232
327
|
? {}
|
|
233
328
|
: { TTSC_PLUGIN_CONFIG_DIR: pluginConfigDir }),
|
|
@@ -236,6 +331,11 @@ function nativePluginEnv(options, tsgoBinary, nativePlugins, plugin) {
|
|
|
236
331
|
node_path_1.default.join(__dirname, "..", "..", "launcher", "ttsx.js"),
|
|
237
332
|
...options.env,
|
|
238
333
|
};
|
|
334
|
+
const node = (0, resolveNodeBinary_1.resolveNodeBinary)(env, projectRoot);
|
|
335
|
+
if (node === undefined)
|
|
336
|
+
delete env.TTSC_NODE_BINARY;
|
|
337
|
+
else
|
|
338
|
+
env.TTSC_NODE_BINARY = node;
|
|
239
339
|
// The anchor is per-invocation state owned by this host: when this run
|
|
240
340
|
// declared none (and the caller's env does not name one), drop any value
|
|
241
341
|
// inherited from an ancestor ttsc process so a nested build never
|
|
@@ -244,6 +344,9 @@ function nativePluginEnv(options, tsgoBinary, nativePlugins, plugin) {
|
|
|
244
344
|
options.env?.TTSC_PLUGIN_CONFIG_DIR === undefined) {
|
|
245
345
|
delete env.TTSC_PLUGIN_CONFIG_DIR;
|
|
246
346
|
}
|
|
347
|
+
// This lane forwards no tsgo argv of its own, so anything inherited belongs
|
|
348
|
+
// to an outer ttsc run and must not reach these sidecars.
|
|
349
|
+
(0, sharedHostHelpers_1.clearInheritedTsgoArgs)(env, options.env);
|
|
247
350
|
if (plugin?.stage === "transform") {
|
|
248
351
|
const linked = (0, sharedHostHelpers_1.linkedTransformPlugins)(nativePlugins ?? []);
|
|
249
352
|
if (linked.length !== 0) {
|
|
@@ -277,11 +380,17 @@ function parseNativeTransformOutput(stdout, stderr) {
|
|
|
277
380
|
const dependencies = parseDependencyLists(parsed.dependencies);
|
|
278
381
|
const dependenciesComplete = parseFileList(parsed.dependenciesComplete);
|
|
279
382
|
const graph = parseReferenceGraph(parsed.graph);
|
|
383
|
+
const hostInputHashes = parseHostInputHashes(parsed.hostInputHashes);
|
|
384
|
+
const hostInputRealpaths = parseHostInputRealpaths(parsed.hostInputRealpaths);
|
|
385
|
+
const hostInputs = parseFileList(parsed.hostInputs);
|
|
280
386
|
const volatile = parseFileList(parsed.volatile);
|
|
281
387
|
return {
|
|
282
388
|
...(dependencies === undefined ? {} : { dependencies }),
|
|
283
389
|
...(dependenciesComplete === undefined ? {} : { dependenciesComplete }),
|
|
284
390
|
...(graph === undefined ? {} : { graph }),
|
|
391
|
+
...(hostInputHashes === undefined ? {} : { hostInputHashes }),
|
|
392
|
+
...(hostInputRealpaths === undefined ? {} : { hostInputRealpaths }),
|
|
393
|
+
...(hostInputs === undefined ? {} : { hostInputs }),
|
|
285
394
|
...(volatile === undefined ? {} : { volatile }),
|
|
286
395
|
diagnostics: Array.isArray(parsed.diagnostics) ? parsed.diagnostics : [],
|
|
287
396
|
typescript: parsed.typescript,
|
|
@@ -295,6 +404,39 @@ function parseNativeTransformOutput(stdout, stderr) {
|
|
|
295
404
|
"ttsc: native transform host returned no output");
|
|
296
405
|
}
|
|
297
406
|
}
|
|
407
|
+
/** Parse native evaluation-time SHA-256/null host-input fingerprints. */
|
|
408
|
+
function parseHostInputHashes(value) {
|
|
409
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
410
|
+
return undefined;
|
|
411
|
+
}
|
|
412
|
+
const output = {};
|
|
413
|
+
for (const [file, hash] of Object.entries(value)) {
|
|
414
|
+
if (!node_path_1.default.isAbsolute(file) ||
|
|
415
|
+
(hash !== null &&
|
|
416
|
+
(typeof hash !== "string" || !/^[0-9a-f]{64}$/.test(hash)))) {
|
|
417
|
+
continue;
|
|
418
|
+
}
|
|
419
|
+
output[node_path_1.default.resolve(file)] = hash;
|
|
420
|
+
}
|
|
421
|
+
return Object.keys(output).length === 0 ? undefined : output;
|
|
422
|
+
}
|
|
423
|
+
/** Parse native evaluation-time realpath/null host-input identities. */
|
|
424
|
+
function parseHostInputRealpaths(value) {
|
|
425
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
426
|
+
return undefined;
|
|
427
|
+
}
|
|
428
|
+
const output = {};
|
|
429
|
+
for (const [file, realpath] of Object.entries(value)) {
|
|
430
|
+
if (!node_path_1.default.isAbsolute(file) ||
|
|
431
|
+
(realpath !== null &&
|
|
432
|
+
(typeof realpath !== "string" || !node_path_1.default.isAbsolute(realpath)))) {
|
|
433
|
+
continue;
|
|
434
|
+
}
|
|
435
|
+
output[node_path_1.default.resolve(file)] =
|
|
436
|
+
realpath === null ? null : node_path_1.default.resolve(realpath);
|
|
437
|
+
}
|
|
438
|
+
return Object.keys(output).length === 0 ? undefined : output;
|
|
439
|
+
}
|
|
298
440
|
/**
|
|
299
441
|
* Normalize the optional `dependencies` envelope field into a record of string
|
|
300
442
|
* arrays, or `undefined` when absent or carrying nothing usable.
|
|
@@ -315,11 +457,34 @@ function parseDependencyLists(value) {
|
|
|
315
457
|
}
|
|
316
458
|
return Object.keys(output).length === 0 ? undefined : output;
|
|
317
459
|
}
|
|
460
|
+
/**
|
|
461
|
+
* Normalize graph adjacency while retaining every well-formed node key.
|
|
462
|
+
*
|
|
463
|
+
* A leaf is intentionally encoded as an empty target array. Its key still
|
|
464
|
+
* declares graph membership and lets persistent hosts bind the compiler-time
|
|
465
|
+
* input proof for that source. A node needs a non-empty source key and an array
|
|
466
|
+
* value; invalid array members are filtered without erasing a valid node.
|
|
467
|
+
*/
|
|
468
|
+
function parseGraphEdges(value) {
|
|
469
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
470
|
+
return undefined;
|
|
471
|
+
}
|
|
472
|
+
const output = {};
|
|
473
|
+
for (const [key, entries] of Object.entries(value)) {
|
|
474
|
+
if (key.length === 0 || !Array.isArray(entries)) {
|
|
475
|
+
continue;
|
|
476
|
+
}
|
|
477
|
+
output[key] = entries.filter((entry) => typeof entry === "string");
|
|
478
|
+
}
|
|
479
|
+
return Object.keys(output).length === 0 ? undefined : output;
|
|
480
|
+
}
|
|
318
481
|
/**
|
|
319
482
|
* Normalize the optional `graph` envelope section with the same tolerance as
|
|
320
|
-
* `dependencies`: non-object sections are dropped,
|
|
321
|
-
*
|
|
322
|
-
*
|
|
483
|
+
* `dependencies`: non-object sections are dropped, empty source keys and edge
|
|
484
|
+
* entries that are not arrays are dropped, and non-string list members are
|
|
485
|
+
* filtered. Empty arrays remain as graph nodes because leaf membership binds
|
|
486
|
+
* compiler input proof. A section carrying nothing usable collapses to
|
|
487
|
+
* `undefined`.
|
|
323
488
|
*
|
|
324
489
|
* `candidates` is the one optional member, so an empty one is left off the
|
|
325
490
|
* result instead of being materialized as `{}`. The host omits the key when it
|
|
@@ -333,23 +498,62 @@ function parseReferenceGraph(value) {
|
|
|
333
498
|
}
|
|
334
499
|
const section = value;
|
|
335
500
|
const candidates = parseDependencyLists(section.candidates) ?? {};
|
|
336
|
-
const edges =
|
|
501
|
+
const edges = parseGraphEdges(section.edges) ?? {};
|
|
337
502
|
const globals = parseFileList(section.globals) ?? [];
|
|
338
503
|
const configs = parseFileList(section.configs) ?? [];
|
|
504
|
+
const inputHashes = parseGraphInputHashes(section.inputHashes);
|
|
505
|
+
const inputRealpaths = parseGraphInputRealpaths(section.inputRealpaths);
|
|
339
506
|
if (Object.keys(candidates).length === 0 &&
|
|
340
507
|
Object.keys(edges).length === 0 &&
|
|
341
508
|
globals.length === 0 &&
|
|
342
509
|
configs.length === 0) {
|
|
343
510
|
return undefined;
|
|
344
511
|
}
|
|
345
|
-
return
|
|
346
|
-
? {
|
|
347
|
-
|
|
512
|
+
return {
|
|
513
|
+
...(Object.keys(candidates).length === 0 ? {} : { candidates }),
|
|
514
|
+
configs,
|
|
515
|
+
edges,
|
|
516
|
+
globals,
|
|
517
|
+
...(inputHashes === undefined ? {} : { inputHashes }),
|
|
518
|
+
...(inputRealpaths === undefined ? {} : { inputRealpaths }),
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
/** Parse graph-keyed compiler-time content/null observations. */
|
|
522
|
+
function parseGraphInputHashes(value) {
|
|
523
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
524
|
+
return undefined;
|
|
525
|
+
}
|
|
526
|
+
const output = {};
|
|
527
|
+
for (const [file, hash] of Object.entries(value)) {
|
|
528
|
+
if (file.length === 0 ||
|
|
529
|
+
(hash !== null &&
|
|
530
|
+
(typeof hash !== "string" || !/^[0-9a-f]{64}$/.test(hash)))) {
|
|
531
|
+
continue;
|
|
532
|
+
}
|
|
533
|
+
output[file] = hash;
|
|
534
|
+
}
|
|
535
|
+
return Object.keys(output).length === 0 ? undefined : output;
|
|
536
|
+
}
|
|
537
|
+
/** Parse graph-keyed compiler-time physical/null identities. */
|
|
538
|
+
function parseGraphInputRealpaths(value) {
|
|
539
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
540
|
+
return undefined;
|
|
541
|
+
}
|
|
542
|
+
const output = {};
|
|
543
|
+
for (const [file, realpath] of Object.entries(value)) {
|
|
544
|
+
if (file.length === 0 ||
|
|
545
|
+
(realpath !== null &&
|
|
546
|
+
(typeof realpath !== "string" || !node_path_1.default.isAbsolute(realpath)))) {
|
|
547
|
+
continue;
|
|
548
|
+
}
|
|
549
|
+
output[file] = realpath === null ? null : node_path_1.default.resolve(realpath);
|
|
550
|
+
}
|
|
551
|
+
return Object.keys(output).length === 0 ? undefined : output;
|
|
348
552
|
}
|
|
349
553
|
/**
|
|
350
554
|
* Normalize an optional string-list envelope field (`dependenciesComplete`,
|
|
351
|
-
* `volatile`, and the `globals`/`configs` graph sections), or
|
|
352
|
-
* absent or carrying nothing usable.
|
|
555
|
+
* `hostInputs`, `volatile`, and the `globals`/`configs` graph sections), or
|
|
556
|
+
* `undefined` when absent or carrying nothing usable.
|
|
353
557
|
*/
|
|
354
558
|
function parseFileList(value) {
|
|
355
559
|
if (!Array.isArray(value)) {
|