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
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
|
|
4
|
+
import { createNativeProjectContextJson } from "../compiler/internal/project/createNativeProjectContextArgs";
|
|
5
|
+
import { resolveBinary } from "../compiler/internal/resolveBinary";
|
|
6
|
+
import {
|
|
7
|
+
readCapabilityResolution,
|
|
8
|
+
writeCapabilityResolution,
|
|
9
|
+
} from "./internal/capabilityResolutionCache";
|
|
10
|
+
import { loadProjectPlugins } from "./internal/loadProjectPlugins";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* One plugin that declared the requested capability.
|
|
14
|
+
*
|
|
15
|
+
* `manifest` is the `--plugins-json` payload its sidecar needs to find its own
|
|
16
|
+
* configured entry. Without it the sidecar loads an empty rule configuration
|
|
17
|
+
* and answers as though the project declared nothing — an empty answer that
|
|
18
|
+
* looks exactly like a project which genuinely publishes none.
|
|
19
|
+
*/
|
|
20
|
+
export interface ITtscCapabilityPlugin {
|
|
21
|
+
binary: string;
|
|
22
|
+
manifest: string;
|
|
23
|
+
/**
|
|
24
|
+
* The `--project-context-json` payload, or `undefined` when the plugin's
|
|
25
|
+
* descriptor does not declare it wants one.
|
|
26
|
+
*
|
|
27
|
+
* A sidecar is handed a project root, not asked to derive one. Without this a
|
|
28
|
+
* rule that resolves its own inputs — the documents an evidence claim reads,
|
|
29
|
+
* a Prisma schema, an OpenAPI file — has no base to resolve them against, and
|
|
30
|
+
* answers with an empty set rather than an error, because "this project
|
|
31
|
+
* declares nothing" is a legitimate answer it cannot distinguish from "I was
|
|
32
|
+
* not told where the project is".
|
|
33
|
+
*/
|
|
34
|
+
projectContext?: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* The built sidecars of a project's configured plugins that declare one
|
|
39
|
+
* capability.
|
|
40
|
+
*
|
|
41
|
+
* This is the seam a consumer outside the compiler needs to ask a plugin a
|
|
42
|
+
* question the plugin declared it can answer. `ttscserver` already does this
|
|
43
|
+
* for `capabilities.lsp`, but it does it from inside the launcher; a separate
|
|
44
|
+
* tool — `@ttsc/graph`, an editor integration, a script — had no way to reach
|
|
45
|
+
* the same answer without reimplementing plugin discovery, descriptor
|
|
46
|
+
* evaluation, and the Go source build cache.
|
|
47
|
+
*
|
|
48
|
+
* It is contributor-agnostic by construction: the caller names a capability,
|
|
49
|
+
* not a package. A project that configures no plugin, or none declaring that
|
|
50
|
+
* capability, gets an empty array — which is an answer, not a failure, and is
|
|
51
|
+
* the common case.
|
|
52
|
+
*
|
|
53
|
+
* Building a plugin is not free the first time. The Go source build is cached
|
|
54
|
+
* by content, so a warm project pays a lookup; a cold one pays the build the
|
|
55
|
+
* next `ttsc` invocation would have paid anyway.
|
|
56
|
+
*
|
|
57
|
+
* @param options.capability - Capability flag the plugin descriptor must
|
|
58
|
+
* declare.
|
|
59
|
+
* @param options.cwd - Project root. Defaults to the current directory.
|
|
60
|
+
* @param options.tsconfig - Project tsconfig path, relative to `cwd`.
|
|
61
|
+
* @returns One entry per declaring plugin, in configured plugin order.
|
|
62
|
+
*/
|
|
63
|
+
export function resolveCapabilityPlugins(options: {
|
|
64
|
+
capability: string;
|
|
65
|
+
cwd?: string;
|
|
66
|
+
tsconfig?: string;
|
|
67
|
+
}): ITtscCapabilityPlugin[] {
|
|
68
|
+
const cwd = path.resolve(options.cwd ?? process.cwd());
|
|
69
|
+
const tsconfig = options.tsconfig ?? "tsconfig.json";
|
|
70
|
+
const cached = readCapabilityResolution({ cwd, tsconfig, version });
|
|
71
|
+
if (cached !== null) return select(cached, options.capability);
|
|
72
|
+
|
|
73
|
+
const binary = resolveBinary();
|
|
74
|
+
if (binary === null || binary === undefined) return [];
|
|
75
|
+
try {
|
|
76
|
+
const loaded = loadProjectPlugins({
|
|
77
|
+
binary,
|
|
78
|
+
cwd: options.cwd,
|
|
79
|
+
tsconfig: options.tsconfig,
|
|
80
|
+
});
|
|
81
|
+
// The manifest carries every configured plugin, not only the declaring one.
|
|
82
|
+
// A sidecar reads its OWN entry out of it — that entry is where its config
|
|
83
|
+
// file lives — and a manifest narrowed to the caller's capability would hand
|
|
84
|
+
// it a project it does not recognize, which is an empty answer rather than an
|
|
85
|
+
// error. This is the same string `runBuild` passes for a check-stage plugin.
|
|
86
|
+
const manifest = JSON.stringify(
|
|
87
|
+
loaded.nativePlugins.map((plugin) => ({
|
|
88
|
+
config: plugin.config,
|
|
89
|
+
name: plugin.name,
|
|
90
|
+
stage: plugin.stage,
|
|
91
|
+
})),
|
|
92
|
+
);
|
|
93
|
+
const wantsContext = loaded.nativePlugins.some(
|
|
94
|
+
(plugin) =>
|
|
95
|
+
(plugin.capabilities as Record<string, unknown> | undefined)
|
|
96
|
+
?.projectContextArgs === true,
|
|
97
|
+
);
|
|
98
|
+
const answer = {
|
|
99
|
+
hostInputs: loaded.hostInputs,
|
|
100
|
+
manifest,
|
|
101
|
+
plugins: loaded.nativePlugins.map((plugin) => ({
|
|
102
|
+
binary: plugin.binary,
|
|
103
|
+
capabilities: Object.fromEntries(
|
|
104
|
+
Object.entries(
|
|
105
|
+
(plugin.capabilities as Record<string, unknown> | undefined) ?? {},
|
|
106
|
+
).map(([name, declared]) => [name, declared === true] as const),
|
|
107
|
+
),
|
|
108
|
+
source: plugin.source,
|
|
109
|
+
})),
|
|
110
|
+
projectContext: wantsContext
|
|
111
|
+
? createNativeProjectContextJson(loaded.project)
|
|
112
|
+
: null,
|
|
113
|
+
};
|
|
114
|
+
writeCapabilityResolution({ cwd, tsconfig, version }, answer);
|
|
115
|
+
return select(answer, options.capability);
|
|
116
|
+
} catch {
|
|
117
|
+
// A project whose plugin configuration does not load is a project the user
|
|
118
|
+
// already sees an error for, from the command that compiles it. Failing here
|
|
119
|
+
// would turn "your lint config has a typo" into "the graph is broken", and
|
|
120
|
+
// the caller's own degraded answer is the honest one.
|
|
121
|
+
return [];
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** The declaring plugins, from a resolution however it was obtained. */
|
|
126
|
+
function select(
|
|
127
|
+
resolution: {
|
|
128
|
+
manifest: string;
|
|
129
|
+
projectContext: string | null;
|
|
130
|
+
plugins: readonly {
|
|
131
|
+
binary: string;
|
|
132
|
+
capabilities: Record<string, boolean>;
|
|
133
|
+
}[];
|
|
134
|
+
},
|
|
135
|
+
capability: string,
|
|
136
|
+
): ITtscCapabilityPlugin[] {
|
|
137
|
+
return resolution.plugins
|
|
138
|
+
.filter(
|
|
139
|
+
(plugin) =>
|
|
140
|
+
plugin.binary !== "" && plugin.capabilities[capability] === true,
|
|
141
|
+
)
|
|
142
|
+
.map((plugin) => ({
|
|
143
|
+
binary: plugin.binary,
|
|
144
|
+
manifest: resolution.manifest,
|
|
145
|
+
...(plugin.capabilities.projectContextArgs === true &&
|
|
146
|
+
resolution.projectContext !== null
|
|
147
|
+
? { projectContext: resolution.projectContext }
|
|
148
|
+
: {}),
|
|
149
|
+
}));
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* This build, as the resolution cache's key material.
|
|
154
|
+
*
|
|
155
|
+
* A ttsc upgrade can change what discovery finds — a new descriptor field, a
|
|
156
|
+
* different resolution order — so an entry written by another build is not this
|
|
157
|
+
* build's answer.
|
|
158
|
+
*/
|
|
159
|
+
const version = ((): string => {
|
|
160
|
+
try {
|
|
161
|
+
const manifest = JSON.parse(
|
|
162
|
+
fs.readFileSync(
|
|
163
|
+
path.resolve(__dirname, "..", "..", "package.json"),
|
|
164
|
+
"utf8",
|
|
165
|
+
),
|
|
166
|
+
) as { version?: unknown };
|
|
167
|
+
return typeof manifest.version === "string" ? manifest.version : "0.0.0";
|
|
168
|
+
} catch {
|
|
169
|
+
return "0.0.0";
|
|
170
|
+
}
|
|
171
|
+
})();
|
package/src/register.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
|
|
4
|
+
import { prepareExecution } from "./launcher/internal/prepareExecution";
|
|
5
|
+
import {
|
|
6
|
+
type RuntimeManifest,
|
|
7
|
+
installRuntimeHooks,
|
|
8
|
+
} from "./launcher/internal/runtimeHooks";
|
|
9
|
+
|
|
10
|
+
const cleanupDirectories = new Set<string>();
|
|
11
|
+
let runtimeSequence = 0;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Prepare one TypeScript root with the same checked compiler pipeline as ttsx,
|
|
15
|
+
* then expose its transient emit to the already-installed runtime hooks.
|
|
16
|
+
*/
|
|
17
|
+
function prepareEntry(filename: string): RuntimeManifest {
|
|
18
|
+
const execution = prepareExecution(filename, {
|
|
19
|
+
runtimeCacheKey: `register-${process.pid}-${++runtimeSequence}`,
|
|
20
|
+
});
|
|
21
|
+
cleanupDirectories.add(execution.cleanupDir);
|
|
22
|
+
return {
|
|
23
|
+
depCacheDir: path.join(execution.cleanupDir, "deps"),
|
|
24
|
+
emitDir: execution.emitDir,
|
|
25
|
+
emittedFiles: execution.emittedFiles,
|
|
26
|
+
entryFile: execution.entryFile,
|
|
27
|
+
entrySource: execution.entrySource,
|
|
28
|
+
moduleOptions: execution.moduleOptions,
|
|
29
|
+
projectRoot: execution.projectRoot,
|
|
30
|
+
rootDir: execution.rootDir,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Remove every register-owned transient emit when the JavaScript host exits. */
|
|
35
|
+
function cleanupRuntimeOutputs(): void {
|
|
36
|
+
for (const directory of cleanupDirectories) {
|
|
37
|
+
try {
|
|
38
|
+
fs.rmSync(directory, { force: true, recursive: true });
|
|
39
|
+
} catch {
|
|
40
|
+
// Best effort: cleanup must not replace the host process exit status.
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
cleanupDirectories.clear();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
process.once("exit", cleanupRuntimeOutputs);
|
|
47
|
+
installRuntimeHooks({ prepareEntry });
|
|
@@ -76,11 +76,14 @@ export interface ITtscCompilerContext {
|
|
|
76
76
|
binary?: string;
|
|
77
77
|
|
|
78
78
|
/**
|
|
79
|
-
* Additional environment variables for child compiler
|
|
79
|
+
* Additional environment variables for child compiler and plugin-descriptor
|
|
80
|
+
* processes.
|
|
80
81
|
*
|
|
81
82
|
* Values are merged over `process.env` before ttsc starts TypeScript-Go,
|
|
82
|
-
* native plugin binaries,
|
|
83
|
-
*
|
|
83
|
+
* native plugin binaries, isolated descriptor evaluators (including the
|
|
84
|
+
* `ttsx` fallback), or the native compiler host used by
|
|
85
|
+
* {@link TtscCompiler.compile}. Descriptor output is diagnostic text and is
|
|
86
|
+
* forwarded to stderr so it cannot corrupt compiler/API protocol stdout.
|
|
84
87
|
*/
|
|
85
88
|
env?: NodeJS.ProcessEnv;
|
|
86
89
|
|
|
@@ -65,6 +65,17 @@ export namespace ITtscCompilerTransformation {
|
|
|
65
65
|
* the same observation on the wire and after decoding.
|
|
66
66
|
*/
|
|
67
67
|
candidates?: Record<string, string[]>;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* SHA-256/null states returned by the compiler filesystem while this graph
|
|
71
|
+
* was being resolved, keyed in the same vocabulary as {@link edges}.
|
|
72
|
+
* Persistent hosts use them to reject a graph whose external file or
|
|
73
|
+
* superseding candidate changed during compilation.
|
|
74
|
+
*/
|
|
75
|
+
inputHashes?: Record<string, string | null>;
|
|
76
|
+
|
|
77
|
+
/** Compiler-time physical identities paired with {@link inputHashes}. */
|
|
78
|
+
inputRealpaths?: Record<string, string | null>;
|
|
68
79
|
}
|
|
69
80
|
|
|
70
81
|
/** Successful source-to-source transformation result. */
|
|
@@ -122,6 +133,13 @@ export namespace ITtscCompilerTransformation {
|
|
|
122
133
|
* declares completeness should stamp {@link graph} too; without it a listed
|
|
123
134
|
* file retains no universal input at all.
|
|
124
135
|
*
|
|
136
|
+
* Ttsc's own hosts stamp it for what they can prove: their source-to-source
|
|
137
|
+
* output is a syntactic re-print, so the built-in native host and the
|
|
138
|
+
* linked-plugin host list a file once every linked plugin able to
|
|
139
|
+
* contribute to it has declared its own contribution complete — which,
|
|
140
|
+
* where no plugin is active at all, is every file. An executable sidecar
|
|
141
|
+
* prints its own envelope and decides for itself.
|
|
142
|
+
*
|
|
125
143
|
* Optional, and never required for correctness: an envelope without this
|
|
126
144
|
* field keeps the sound host-owned bound. A file that is both listed here
|
|
127
145
|
* and in {@link volatile} keeps the union, since the two claims contradict
|
|
@@ -140,6 +158,25 @@ export namespace ITtscCompilerTransformation {
|
|
|
140
158
|
*/
|
|
141
159
|
graph?: IReferenceGraph;
|
|
142
160
|
|
|
161
|
+
/**
|
|
162
|
+
* Host-wide files consulted before the native transform starts, such as
|
|
163
|
+
* JavaScript plugin descriptors and explicitly selected plugin config
|
|
164
|
+
* files. Unlike {@link dependencies}, these affect every transformed file.
|
|
165
|
+
* Bundler adapters register and validate them as universal inputs without
|
|
166
|
+
* treating arbitrary unclassified project files as configuration.
|
|
167
|
+
*/
|
|
168
|
+
hostInputs?: string[];
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* SHA-256 fingerprints captured by the plugin loader at the instant each
|
|
172
|
+
* host input influenced this generation. Internal cache validators use
|
|
173
|
+
* these to reject a result raced by a concurrent config/module change.
|
|
174
|
+
*/
|
|
175
|
+
hostInputHashes?: Record<string, string | null>;
|
|
176
|
+
|
|
177
|
+
/** Evaluation-time physical identities paired with {@link hostInputs}. */
|
|
178
|
+
hostInputRealpaths?: Record<string, string | null>;
|
|
179
|
+
|
|
143
180
|
/**
|
|
144
181
|
* Transformed files (keyed like {@link typescript}) whose output depends on
|
|
145
182
|
* non-file inputs (environment, time, network) as declared by the transform
|
|
@@ -188,6 +225,15 @@ export namespace ITtscCompilerTransformation {
|
|
|
188
225
|
*/
|
|
189
226
|
graph?: IReferenceGraph;
|
|
190
227
|
|
|
228
|
+
/** Host-wide transform inputs; same contract as {@link ISuccess.hostInputs}. */
|
|
229
|
+
hostInputs?: string[];
|
|
230
|
+
|
|
231
|
+
/** Generation-time host-input fingerprints. */
|
|
232
|
+
hostInputHashes?: Record<string, string | null>;
|
|
233
|
+
|
|
234
|
+
/** Generation-time physical host-input identities. */
|
|
235
|
+
hostInputRealpaths?: Record<string, string | null>;
|
|
236
|
+
|
|
191
237
|
/**
|
|
192
238
|
* Volatile transformed files. Same shape and semantics as
|
|
193
239
|
* {@link ISuccess.volatile}.
|
|
@@ -22,6 +22,42 @@ export interface ITtscPlugin {
|
|
|
22
22
|
*/
|
|
23
23
|
name?: string;
|
|
24
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Absolute files whose contents or presence influence this descriptor or its
|
|
27
|
+
* native transform for every project file.
|
|
28
|
+
*
|
|
29
|
+
* Ttsc automatically records the descriptor's CommonJS module graph, tsconfig
|
|
30
|
+
* ancestry, package-discovery manifest, and an explicit `configFile`. Use
|
|
31
|
+
* this field for additional implicit config discovery and for files a native
|
|
32
|
+
* plugin reads outside the TypeScript reference graph. Missing paths are
|
|
33
|
+
* valid: they represent higher-priority discovery candidates whose later
|
|
34
|
+
* creation must invalidate a resident transform.
|
|
35
|
+
*/
|
|
36
|
+
hostInputs?: string[];
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Evaluation-time SHA-256 fingerprints for entries in {@link hostInputs}.
|
|
40
|
+
*
|
|
41
|
+
* Use a lowercase 64-digit digest for a file observed during descriptor
|
|
42
|
+
* evaluation and `null` for a missing candidate. Ttsc's generated resolution
|
|
43
|
+
* loaders also digest the stable kind marker for an existing directory
|
|
44
|
+
* candidate, so replacing that directory with a file invalidates the
|
|
45
|
+
* generation. The map is optional: ttsc still watches unhashed inputs, but
|
|
46
|
+
* persistent adapters conservatively decline narrow generation reuse because
|
|
47
|
+
* a later host snapshot cannot prove which state produced the descriptor.
|
|
48
|
+
*/
|
|
49
|
+
hostInputHashes?: Record<string, string | null>;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Evaluation-time physical paths for entries in {@link hostInputs}.
|
|
53
|
+
*
|
|
54
|
+
* Use the canonical path returned by `fs.realpathSync.native`, or `null` when
|
|
55
|
+
* the input was missing. Persistent adapters pair this with
|
|
56
|
+
* {@link hostInputHashes} so retargeting a symlink or junction cannot attach
|
|
57
|
+
* output evaluated from one target to equal bytes at another target.
|
|
58
|
+
*/
|
|
59
|
+
hostInputRealpaths?: Record<string, string | null>;
|
|
60
|
+
|
|
25
61
|
/**
|
|
26
62
|
* Go package directory, or a `go.mod` file, that ttsc lazily builds.
|
|
27
63
|
*
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
"ESCAPE|checker|NodeBuilderContext",
|
|
20
20
|
"ESCAPE|checker|ObjectType",
|
|
21
21
|
"ESCAPE|checker|ReverseMappedType",
|
|
22
|
-
"ESCAPE|checker|SignatureFlags",
|
|
23
22
|
"ESCAPE|checker|StringMappingType",
|
|
24
23
|
"ESCAPE|checker|StructuredType",
|
|
25
24
|
"ESCAPE|checker|SubstitutionType",
|
|
@@ -29,7 +28,6 @@
|
|
|
29
28
|
"ESCAPE|checker|TupleType",
|
|
30
29
|
"ESCAPE|checker|TypeFormatFlags",
|
|
31
30
|
"ESCAPE|checker|TypeId",
|
|
32
|
-
"ESCAPE|checker|TypeMapper",
|
|
33
31
|
"ESCAPE|checker|TypeParameter",
|
|
34
32
|
"ESCAPE|checker|TypePredicate",
|
|
35
33
|
"ESCAPE|checker|TypeReference",
|
package/utility/host.go
CHANGED
|
@@ -46,9 +46,18 @@ type hostOptions struct {
|
|
|
46
46
|
// so cache layers can register every file whose content can influence a
|
|
47
47
|
// transformed module without per-plugin reporting.
|
|
48
48
|
type transformResult struct {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
// Dependencies and DependenciesComplete carry what the linked plugins
|
|
50
|
+
// declared about their own contribution to each file; the host prints the
|
|
51
|
+
// parsed AST syntactically, so it adds nothing of its own to either. See
|
|
52
|
+
// driver.Program.TransformDependenciesFor.
|
|
53
|
+
Dependencies map[string][]string `json:"dependencies,omitempty"`
|
|
54
|
+
DependenciesComplete []string `json:"dependenciesComplete,omitempty"`
|
|
55
|
+
Diagnostics []any `json:"diagnostics,omitempty"`
|
|
56
|
+
Graph *driver.TransformGraph `json:"graph,omitempty"`
|
|
57
|
+
HostInputs []string `json:"hostInputs,omitempty"`
|
|
58
|
+
HostInputHashes map[string]*string `json:"hostInputHashes,omitempty"`
|
|
59
|
+
HostInputRealpaths map[string]*string `json:"hostInputRealpaths,omitempty"`
|
|
60
|
+
TypeScript map[string]string `json:"typescript"`
|
|
52
61
|
}
|
|
53
62
|
|
|
54
63
|
// RunCheck validates the project and linked plugin configuration without
|
|
@@ -150,6 +159,12 @@ func RunTransformWithIO(args []string, stdout, stderr io.Writer) int {
|
|
|
150
159
|
text := shimprinter.EmitSourceFile(printer, file)
|
|
151
160
|
out.TypeScript[apiOutputKey(opts.cwd, file.FileName())] = text
|
|
152
161
|
}
|
|
162
|
+
dependencies := prog.TransformDependenciesFor(opts.cwd)
|
|
163
|
+
out.Dependencies = dependencies.Dependencies
|
|
164
|
+
out.DependenciesComplete = dependencies.Complete
|
|
165
|
+
out.HostInputs = prog.PluginHostInputs()
|
|
166
|
+
out.HostInputHashes = prog.PluginHostInputHashes()
|
|
167
|
+
out.HostInputRealpaths = prog.PluginHostInputRealpaths()
|
|
153
168
|
data, _ := json.Marshal(out)
|
|
154
169
|
fmt.Fprintln(opts.stdout, string(data))
|
|
155
170
|
return 0
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.assertSafeExplicitCacheDirectory = assertSafeExplicitCacheDirectory;
|
|
7
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
-
/**
|
|
9
|
-
* Refuse an explicit cache directory whose wholesale removal could delete the
|
|
10
|
-
* project or an entire filesystem volume.
|
|
11
|
-
*/
|
|
12
|
-
function assertSafeExplicitCacheDirectory(projectRoot, cacheDirectory) {
|
|
13
|
-
const project = node_path_1.default.resolve(projectRoot);
|
|
14
|
-
const cache = node_path_1.default.resolve(cacheDirectory);
|
|
15
|
-
if (cache === node_path_1.default.parse(cache).root) {
|
|
16
|
-
throw new Error(`ttsc: refusing to clean cache directory ${JSON.stringify(cache)} because filesystem roots are never valid cache directories`);
|
|
17
|
-
}
|
|
18
|
-
const relative = node_path_1.default.relative(cache, project);
|
|
19
|
-
if (relative === "" ||
|
|
20
|
-
(relative !== ".." &&
|
|
21
|
-
!relative.startsWith(`..${node_path_1.default.sep}`) &&
|
|
22
|
-
!node_path_1.default.isAbsolute(relative))) {
|
|
23
|
-
throw new Error(`ttsc: refusing to clean cache directory ${JSON.stringify(cache)} because it equals or contains project root ${JSON.stringify(project)}; choose a dedicated cache directory`);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
//# sourceMappingURL=assertSafeExplicitCacheDirectory.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"assertSafeExplicitCacheDirectory.js","sourceRoot":"","sources":["../../src/internal/assertSafeExplicitCacheDirectory.ts"],"names":[],"mappings":";;;;;;AAAA,0DAA6B;AAE7B;;;GAGG;AACH,0CACE,WAAmB,EACnB,cAAsB;IAEtB,MAAM,OAAO,GAAG,mBAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,mBAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IAC3C,IAAI,KAAK,KAAK,mBAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CACb,2CAA2C,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,6DAA6D,CAC9H,CAAC;IACJ,CAAC;IACD,MAAM,QAAQ,GAAG,mBAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC/C,IACE,QAAQ,KAAK,EAAE;QACf,CAAC,QAAQ,KAAK,IAAI;YAChB,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,mBAAI,CAAC,GAAG,EAAE,CAAC;YACrC,CAAC,mBAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,EAC7B,CAAC;QACD,MAAM,IAAI,KAAK,CACb,2CAA2C,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,+CAA+C,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,sCAAsC,CAC7K,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Refuse an explicit cache directory whose wholesale removal could delete the
|
|
5
|
-
* project or an entire filesystem volume.
|
|
6
|
-
*/
|
|
7
|
-
export function assertSafeExplicitCacheDirectory(
|
|
8
|
-
projectRoot: string,
|
|
9
|
-
cacheDirectory: string,
|
|
10
|
-
): void {
|
|
11
|
-
const project = path.resolve(projectRoot);
|
|
12
|
-
const cache = path.resolve(cacheDirectory);
|
|
13
|
-
if (cache === path.parse(cache).root) {
|
|
14
|
-
throw new Error(
|
|
15
|
-
`ttsc: refusing to clean cache directory ${JSON.stringify(cache)} because filesystem roots are never valid cache directories`,
|
|
16
|
-
);
|
|
17
|
-
}
|
|
18
|
-
const relative = path.relative(cache, project);
|
|
19
|
-
if (
|
|
20
|
-
relative === "" ||
|
|
21
|
-
(relative !== ".." &&
|
|
22
|
-
!relative.startsWith(`..${path.sep}`) &&
|
|
23
|
-
!path.isAbsolute(relative))
|
|
24
|
-
) {
|
|
25
|
-
throw new Error(
|
|
26
|
-
`ttsc: refusing to clean cache directory ${JSON.stringify(cache)} because it equals or contains project root ${JSON.stringify(project)}; choose a dedicated cache directory`,
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
}
|