ttsc 0.27.0 → 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.
Files changed (73) hide show
  1. package/cmd/graphbench/main.go +26 -16
  2. package/cmd/graphdump/main.go +37 -12
  3. package/cmd/graphdump/run_declares_the_capability_its_output_carries_test.go +137 -0
  4. package/cmd/graphdump/run_reports_an_unknown_flag_without_exiting_the_process_test.go +56 -0
  5. package/cmd/graphdump/run_reports_an_unloadable_project_without_printing_a_dump_test.go +46 -0
  6. package/cmd/ttsc/api_transform.go +17 -6
  7. package/cmd/ttscgraph/dump.go +43 -11
  8. package/cmd/ttscgraph/run_dump_claims_artifacts_only_when_it_asked_test.go +135 -0
  9. package/cmd/ttscgraph/run_dump_declares_the_capability_its_output_carries_test.go +96 -0
  10. package/cmd/ttscgraph/serve.go +253 -25
  11. package/cmd/ttscgraph/serve_adopts_a_republished_artifact_set_test.go +348 -0
  12. package/cmd/ttscgraph/serve_projects_an_artifact_no_source_owns_test.go +90 -0
  13. package/cmd/ttscgraph/serve_shards.go +31 -9
  14. package/driver/config_discovery.go +121 -0
  15. package/driver/emit_plugin.go +57 -8
  16. package/driver/plugins.go +125 -14
  17. package/driver/transform_dependencies.go +283 -0
  18. package/driver/transform_dependencies_declares_every_file_without_a_contributor_test.go +28 -0
  19. package/driver/transform_dependencies_drops_a_self_reported_dependency_test.go +21 -0
  20. package/driver/transform_dependencies_keys_a_reported_path_like_the_envelope_test.go +46 -0
  21. package/driver/transform_dependencies_requires_every_contributor_to_declare_test.go +38 -0
  22. package/driver/transform_dependencies_stays_silent_for_an_undeclared_contributor_test.go +23 -0
  23. package/driver/transform_dependencies_withdraws_completeness_after_an_unusable_dependency_test.go +37 -0
  24. package/internal/graph/artifacts.go +230 -0
  25. package/internal/graph/artifacts_index_what_a_plugin_published_test.go +154 -0
  26. package/internal/graph/artifacts_survive_a_partial_rebuild_test.go +89 -0
  27. package/internal/graph/build.go +35 -0
  28. package/internal/graph/build_releases_the_scratch_it_no_longer_reads_test.go +118 -0
  29. package/internal/graph/doc_refs_are_the_use_the_checker_already_counts_test.go +93 -0
  30. package/internal/graph/doc_refs_resolve_documentation_links_test.go +335 -0
  31. package/internal/graph/doc_tags.go +416 -0
  32. package/internal/graph/doc_tags_are_claimed_before_they_are_read_test.go +131 -0
  33. package/internal/graph/doc_tags_capture_every_unrecognized_tag_test.go +165 -0
  34. package/internal/graph/doc_tags_read_only_what_the_parser_attached_test.go +97 -0
  35. package/internal/graph/doc_tags_stop_at_the_external_boundary_test.go +59 -0
  36. package/internal/graph/doc_tags_survive_line_endings_and_repeated_blocks_test.go +146 -0
  37. package/internal/graph/dump.go +60 -13
  38. package/internal/graph/dump_checkout_paths_are_stable_test.go +2 -2
  39. package/internal/graph/dump_paths.go +2 -2
  40. package/internal/graph/dump_paths_are_portable_and_injective_test.go +1 -1
  41. package/internal/graph/edge_kinds_names_every_declared_kind_test.go +49 -0
  42. package/internal/graph/edges.go +1 -0
  43. package/internal/graph/graph.go +79 -4
  44. package/internal/graph/provenance.go +29 -2
  45. package/lib/compiler/internal/project/createNativeProjectContextArgs.d.ts +9 -0
  46. package/lib/compiler/internal/project/createNativeProjectContextArgs.js +16 -4
  47. package/lib/compiler/internal/project/createNativeProjectContextArgs.js.map +1 -1
  48. package/lib/index.d.ts +1 -0
  49. package/lib/index.js +1 -0
  50. package/lib/index.js.map +1 -1
  51. package/lib/launcher/internal/runtimeHooks.d.ts +10 -2
  52. package/lib/launcher/internal/runtimeHooks.js +93 -2
  53. package/lib/launcher/internal/runtimeHooks.js.map +1 -1
  54. package/lib/plugin/internal/capabilityResolutionCache.d.ts +76 -0
  55. package/lib/plugin/internal/capabilityResolutionCache.js +224 -0
  56. package/lib/plugin/internal/capabilityResolutionCache.js.map +1 -0
  57. package/lib/plugin/resolveCapabilityPlugins.d.ts +55 -0
  58. package/lib/plugin/resolveCapabilityPlugins.js +118 -0
  59. package/lib/plugin/resolveCapabilityPlugins.js.map +1 -0
  60. package/lib/structures/ITtscCompilerTransformation.d.ts +7 -0
  61. package/package.json +8 -8
  62. package/shim/ast/parent.go +16 -3
  63. package/shim/checker/enums_gen.go +11 -0
  64. package/shim/checker/shim.go +3 -0
  65. package/shim/compiler/emithook.go +10 -0
  66. package/src/compiler/internal/project/createNativeProjectContextArgs.ts +19 -4
  67. package/src/index.ts +1 -0
  68. package/src/launcher/internal/runtimeHooks.ts +111 -2
  69. package/src/plugin/internal/capabilityResolutionCache.ts +305 -0
  70. package/src/plugin/resolveCapabilityPlugins.ts +171 -0
  71. package/src/structures/ITtscCompilerTransformation.ts +7 -0
  72. package/tools/shim_audit/baseline.json +0 -1
  73. package/utility/host.go +15 -6
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilityResolutionCache.js","sourceRoot":"","sources":["../../../src/plugin/internal/capabilityResolutionCache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * One plugin that declared the requested capability.
3
+ *
4
+ * `manifest` is the `--plugins-json` payload its sidecar needs to find its own
5
+ * configured entry. Without it the sidecar loads an empty rule configuration
6
+ * and answers as though the project declared nothing — an empty answer that
7
+ * looks exactly like a project which genuinely publishes none.
8
+ */
9
+ export interface ITtscCapabilityPlugin {
10
+ binary: string;
11
+ manifest: string;
12
+ /**
13
+ * The `--project-context-json` payload, or `undefined` when the plugin's
14
+ * descriptor does not declare it wants one.
15
+ *
16
+ * A sidecar is handed a project root, not asked to derive one. Without this a
17
+ * rule that resolves its own inputs — the documents an evidence claim reads,
18
+ * a Prisma schema, an OpenAPI file — has no base to resolve them against, and
19
+ * answers with an empty set rather than an error, because "this project
20
+ * declares nothing" is a legitimate answer it cannot distinguish from "I was
21
+ * not told where the project is".
22
+ */
23
+ projectContext?: string;
24
+ }
25
+ /**
26
+ * The built sidecars of a project's configured plugins that declare one
27
+ * capability.
28
+ *
29
+ * This is the seam a consumer outside the compiler needs to ask a plugin a
30
+ * question the plugin declared it can answer. `ttscserver` already does this
31
+ * for `capabilities.lsp`, but it does it from inside the launcher; a separate
32
+ * tool — `@ttsc/graph`, an editor integration, a script — had no way to reach
33
+ * the same answer without reimplementing plugin discovery, descriptor
34
+ * evaluation, and the Go source build cache.
35
+ *
36
+ * It is contributor-agnostic by construction: the caller names a capability,
37
+ * not a package. A project that configures no plugin, or none declaring that
38
+ * capability, gets an empty array — which is an answer, not a failure, and is
39
+ * the common case.
40
+ *
41
+ * Building a plugin is not free the first time. The Go source build is cached
42
+ * by content, so a warm project pays a lookup; a cold one pays the build the
43
+ * next `ttsc` invocation would have paid anyway.
44
+ *
45
+ * @param options.capability - Capability flag the plugin descriptor must
46
+ * declare.
47
+ * @param options.cwd - Project root. Defaults to the current directory.
48
+ * @param options.tsconfig - Project tsconfig path, relative to `cwd`.
49
+ * @returns One entry per declaring plugin, in configured plugin order.
50
+ */
51
+ export declare function resolveCapabilityPlugins(options: {
52
+ capability: string;
53
+ cwd?: string;
54
+ tsconfig?: string;
55
+ }): ITtscCapabilityPlugin[];
@@ -0,0 +1,118 @@
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.resolveCapabilityPlugins = resolveCapabilityPlugins;
7
+ const node_fs_1 = __importDefault(require("node:fs"));
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ const createNativeProjectContextArgs_1 = require("../compiler/internal/project/createNativeProjectContextArgs");
10
+ const resolveBinary_1 = require("../compiler/internal/resolveBinary");
11
+ const capabilityResolutionCache_1 = require("./internal/capabilityResolutionCache");
12
+ const loadProjectPlugins_1 = require("./internal/loadProjectPlugins");
13
+ /**
14
+ * The built sidecars of a project's configured plugins that declare one
15
+ * capability.
16
+ *
17
+ * This is the seam a consumer outside the compiler needs to ask a plugin a
18
+ * question the plugin declared it can answer. `ttscserver` already does this
19
+ * for `capabilities.lsp`, but it does it from inside the launcher; a separate
20
+ * tool — `@ttsc/graph`, an editor integration, a script — had no way to reach
21
+ * the same answer without reimplementing plugin discovery, descriptor
22
+ * evaluation, and the Go source build cache.
23
+ *
24
+ * It is contributor-agnostic by construction: the caller names a capability,
25
+ * not a package. A project that configures no plugin, or none declaring that
26
+ * capability, gets an empty array — which is an answer, not a failure, and is
27
+ * the common case.
28
+ *
29
+ * Building a plugin is not free the first time. The Go source build is cached
30
+ * by content, so a warm project pays a lookup; a cold one pays the build the
31
+ * next `ttsc` invocation would have paid anyway.
32
+ *
33
+ * @param options.capability - Capability flag the plugin descriptor must
34
+ * declare.
35
+ * @param options.cwd - Project root. Defaults to the current directory.
36
+ * @param options.tsconfig - Project tsconfig path, relative to `cwd`.
37
+ * @returns One entry per declaring plugin, in configured plugin order.
38
+ */
39
+ function resolveCapabilityPlugins(options) {
40
+ const cwd = node_path_1.default.resolve(options.cwd ?? process.cwd());
41
+ const tsconfig = options.tsconfig ?? "tsconfig.json";
42
+ const cached = (0, capabilityResolutionCache_1.readCapabilityResolution)({ cwd, tsconfig, version });
43
+ if (cached !== null)
44
+ return select(cached, options.capability);
45
+ const binary = (0, resolveBinary_1.resolveBinary)();
46
+ if (binary === null || binary === undefined)
47
+ return [];
48
+ try {
49
+ const loaded = (0, loadProjectPlugins_1.loadProjectPlugins)({
50
+ binary,
51
+ cwd: options.cwd,
52
+ tsconfig: options.tsconfig,
53
+ });
54
+ // The manifest carries every configured plugin, not only the declaring one.
55
+ // A sidecar reads its OWN entry out of it — that entry is where its config
56
+ // file lives — and a manifest narrowed to the caller's capability would hand
57
+ // it a project it does not recognize, which is an empty answer rather than an
58
+ // error. This is the same string `runBuild` passes for a check-stage plugin.
59
+ const manifest = JSON.stringify(loaded.nativePlugins.map((plugin) => ({
60
+ config: plugin.config,
61
+ name: plugin.name,
62
+ stage: plugin.stage,
63
+ })));
64
+ const wantsContext = loaded.nativePlugins.some((plugin) => plugin.capabilities
65
+ ?.projectContextArgs === true);
66
+ const answer = {
67
+ hostInputs: loaded.hostInputs,
68
+ manifest,
69
+ plugins: loaded.nativePlugins.map((plugin) => ({
70
+ binary: plugin.binary,
71
+ capabilities: Object.fromEntries(Object.entries(plugin.capabilities ?? {}).map(([name, declared]) => [name, declared === true])),
72
+ source: plugin.source,
73
+ })),
74
+ projectContext: wantsContext
75
+ ? (0, createNativeProjectContextArgs_1.createNativeProjectContextJson)(loaded.project)
76
+ : null,
77
+ };
78
+ (0, capabilityResolutionCache_1.writeCapabilityResolution)({ cwd, tsconfig, version }, answer);
79
+ return select(answer, options.capability);
80
+ }
81
+ catch {
82
+ // A project whose plugin configuration does not load is a project the user
83
+ // already sees an error for, from the command that compiles it. Failing here
84
+ // would turn "your lint config has a typo" into "the graph is broken", and
85
+ // the caller's own degraded answer is the honest one.
86
+ return [];
87
+ }
88
+ }
89
+ /** The declaring plugins, from a resolution however it was obtained. */
90
+ function select(resolution, capability) {
91
+ return resolution.plugins
92
+ .filter((plugin) => plugin.binary !== "" && plugin.capabilities[capability] === true)
93
+ .map((plugin) => ({
94
+ binary: plugin.binary,
95
+ manifest: resolution.manifest,
96
+ ...(plugin.capabilities.projectContextArgs === true &&
97
+ resolution.projectContext !== null
98
+ ? { projectContext: resolution.projectContext }
99
+ : {}),
100
+ }));
101
+ }
102
+ /**
103
+ * This build, as the resolution cache's key material.
104
+ *
105
+ * A ttsc upgrade can change what discovery finds — a new descriptor field, a
106
+ * different resolution order — so an entry written by another build is not this
107
+ * build's answer.
108
+ */
109
+ const version = (() => {
110
+ try {
111
+ const manifest = JSON.parse(node_fs_1.default.readFileSync(node_path_1.default.resolve(__dirname, "..", "..", "package.json"), "utf8"));
112
+ return typeof manifest.version === "string" ? manifest.version : "0.0.0";
113
+ }
114
+ catch {
115
+ return "0.0.0";
116
+ }
117
+ })();
118
+ //# sourceMappingURL=resolveCapabilityPlugins.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveCapabilityPlugins.js","sourceRoot":"","sources":["../../src/plugin/resolveCapabilityPlugins.ts"],"names":[],"mappings":"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"}
@@ -118,6 +118,13 @@ export declare namespace ITtscCompilerTransformation {
118
118
  * declares completeness should stamp {@link graph} too; without it a listed
119
119
  * file retains no universal input at all.
120
120
  *
121
+ * Ttsc's own hosts stamp it for what they can prove: their source-to-source
122
+ * output is a syntactic re-print, so the built-in native host and the
123
+ * linked-plugin host list a file once every linked plugin able to
124
+ * contribute to it has declared its own contribution complete — which,
125
+ * where no plugin is active at all, is every file. An executable sidecar
126
+ * prints its own envelope and decides for itself.
127
+ *
121
128
  * Optional, and never required for correctness: an envelope without this
122
129
  * field keeps the sound host-owned bound. A file that is both listed here
123
130
  * and in {@link volatile} keeps the union, since the two claims contradict
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ttsc",
3
- "version": "0.27.0",
3
+ "version": "0.28.0",
4
4
  "description": "General-purpose TypeScript-Go compiler, runtime, plugin host, and LSP host.",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -43,13 +43,13 @@
43
43
  "typescript": "^7.0.2"
44
44
  },
45
45
  "optionalDependencies": {
46
- "@ttsc/linux-x64": "0.27.0",
47
- "@ttsc/linux-arm64": "0.27.0",
48
- "@ttsc/darwin-arm64": "0.27.0",
49
- "@ttsc/darwin-x64": "0.27.0",
50
- "@ttsc/linux-arm": "0.27.0",
51
- "@ttsc/win32-arm64": "0.27.0",
52
- "@ttsc/win32-x64": "0.27.0"
46
+ "@ttsc/linux-arm": "0.28.0",
47
+ "@ttsc/darwin-x64": "0.28.0",
48
+ "@ttsc/linux-x64": "0.28.0",
49
+ "@ttsc/win32-x64": "0.28.0",
50
+ "@ttsc/win32-arm64": "0.28.0",
51
+ "@ttsc/darwin-arm64": "0.28.0",
52
+ "@ttsc/linux-arm64": "0.28.0"
53
53
  },
54
54
  "sideEffects": [
55
55
  "./lib/register.js",
@@ -6,9 +6,17 @@ import innerast "github.com/microsoft/typescript-go/internal/ast"
6
6
  // its containing node.
7
7
  //
8
8
  // A transform that splices freshly built (synthetic) nodes onto a SourceFile
9
- // must call this before emit: passes that walk parents — e.g. the emit
10
- // resolver's reference marking (MarkLinkedReferencesRecursively) — dereference
11
- // Parent and would hit nil on a synthetic node otherwise.
9
+ // must call this before emit, because the passes that then walk the spliced tree
10
+ // dereference Parent and would hit nil on a synthetic node. The printer is the
11
+ // example that holds up: getContainingNodeArray reads node.Parent unguarded for
12
+ // a parameter, template span, decorator, and heritage clause.
13
+ //
14
+ // Two earlier examples were dropped rather than the rule. The emit resolver's
15
+ // reference marking no longer walks the spliced tree at all in ttsc's plugin
16
+ // emit lane, which builds the builtin chain from the parse tree (see
17
+ // driver.EmitWithPluginTransformers). The module transform's own Parent reads
18
+ // carry upstream //nolint:customlint notes saying they deliberately inspect
19
+ // parse-tree parents.
12
20
  func SetParentInChildren(node *Node) {
13
21
  innerast.SetParentInChildren(node)
14
22
  }
@@ -20,6 +28,11 @@ func SetParentInChildren(node *Node) {
20
28
  // kept verbatim while sibling statements were rewritten) makes tsgo's
21
29
  // runtime-syntax/printer mis-resolve the declaration and drop it from emit.
22
30
  // Only freshly built (synthetic) nodes need a parent wired, and those start nil.
31
+ //
32
+ // This is the form ttsc's plugin emit lane calls. How much it currently carries
33
+ // is unproven: stubbing the call out leaves the whole driver suite green, which
34
+ // measures the suite's coverage of parent-dependent emit rather than the hazard.
35
+ // Keep it for the reason above, not on the strength of a failing test.
23
36
  func SetParentInChildrenUnset(node *Node) {
24
37
  node.ForEachChild(func(child *Node) bool {
25
38
  if child.Parent == nil {
@@ -77,6 +77,17 @@ const (
77
77
  ObjectFlagsSingleSignatureType = innerchecker.ObjectFlagsSingleSignatureType
78
78
  ObjectFlagsTuple = innerchecker.ObjectFlagsTuple
79
79
  ObjectFlagsUnresolvedMembers = innerchecker.ObjectFlagsUnresolvedMembers
80
+ SignatureFlagsCallChainFlags = innerchecker.SignatureFlagsCallChainFlags
81
+ SignatureFlagsConstruct = innerchecker.SignatureFlagsConstruct
82
+ SignatureFlagsHasLiteralTypes = innerchecker.SignatureFlagsHasLiteralTypes
83
+ SignatureFlagsHasRestParameter = innerchecker.SignatureFlagsHasRestParameter
84
+ SignatureFlagsIsInnerCallChain = innerchecker.SignatureFlagsIsInnerCallChain
85
+ SignatureFlagsIsNonInferrable = innerchecker.SignatureFlagsIsNonInferrable
86
+ SignatureFlagsIsOuterCallChain = innerchecker.SignatureFlagsIsOuterCallChain
87
+ SignatureFlagsIsSignatureCandidateForOverloadFailure = innerchecker.SignatureFlagsIsSignatureCandidateForOverloadFailure
88
+ SignatureFlagsIsUntypedSignatureInJSFile = innerchecker.SignatureFlagsIsUntypedSignatureInJSFile
89
+ SignatureFlagsNone = innerchecker.SignatureFlagsNone
90
+ SignatureFlagsPropagatingFlags = innerchecker.SignatureFlagsPropagatingFlags
80
91
  SignatureKindConstruct = innerchecker.SignatureKindConstruct
81
92
  TypeFlagsAnyOrUnknown = innerchecker.TypeFlagsAnyOrUnknown
82
93
  TypeFlagsBigInt = innerchecker.TypeFlagsBigInt
@@ -20,6 +20,7 @@ import (
20
20
  type Checker = innerchecker.Checker
21
21
  type IndexInfo = innerchecker.IndexInfo
22
22
  type Signature = innerchecker.Signature
23
+ type SignatureFlags = innerchecker.SignatureFlags
23
24
  type SignatureKind = innerchecker.SignatureKind
24
25
  type Type = innerchecker.Type
25
26
  type TypeMapper = innerchecker.TypeMapper
@@ -216,6 +217,8 @@ func Checker_isSymbolAccessibleAsValue(recv *innerchecker.Checker, symbol *inner
216
217
  }
217
218
 
218
219
  const (
220
+ SignatureFlagsAbstract = innerchecker.SignatureFlagsAbstract
221
+
219
222
  SignatureKindCall = innerchecker.SignatureKindCall
220
223
 
221
224
  TypeMapperKindUnknown = innerchecker.TypeMapperKindUnknown
@@ -18,5 +18,15 @@ import (
18
18
  // (type-erase, import-elision, runtime-syntax, module-transform, ...) for one
19
19
  // source file, linked from the internal package via go:linkname.
20
20
  //
21
+ // `sourceFile` is the marking target, not the file that gets transformed.
22
+ // Upstream reads it for two per-file constants (in-JS-file, JSX language
23
+ // variant) and then hands it to emitResolver.MarkLinkedReferencesRecursively,
24
+ // whose marks the import-elision transformer later reads back through
25
+ // EmitContext.ParseNode. A caller that runs a plugin pass first must therefore
26
+ // pass the PARSE tree here and the transformed tree to TransformSourceFile;
27
+ // upstream's own emitter passes one file to both only because it has nothing in
28
+ // between. Re-check this when the pin moves: a new use of the parameter inside
29
+ // getScriptTransformers could make the two roles diverge further.
30
+ //
21
31
  //go:linkname GetScriptTransformers github.com/microsoft/typescript-go/internal/compiler.getScriptTransformers
22
32
  func GetScriptTransformers(emitContext *innerprinter.EmitContext, host innerprinter.EmitHost, sourceFile *innerast.SourceFile) []*innertransformers.Transformer
@@ -7,9 +7,24 @@ export function createNativeProjectContextArgs(
7
7
  ): string[] {
8
8
  return [
9
9
  "--project-context-json=" +
10
- JSON.stringify({
11
- ...project.identity,
12
- ...(pluginConfigOrigin === undefined ? {} : { pluginConfigOrigin }),
13
- }),
10
+ createNativeProjectContextJson(project, pluginConfigOrigin),
14
11
  ];
15
12
  }
13
+
14
+ /**
15
+ * The identity payload itself, for a caller that spawns a sidecar without going
16
+ * through the compiler's own argument list.
17
+ *
18
+ * Split from the flag so there is still exactly one place that decides what a
19
+ * sidecar is told about the project. A second caller assembling the same JSON,
20
+ * or slicing it back out of the flag, is how the two drift.
21
+ */
22
+ export function createNativeProjectContextJson(
23
+ project: ITtscParsedProjectConfig,
24
+ pluginConfigOrigin?: string,
25
+ ): string {
26
+ return JSON.stringify({
27
+ ...project.identity,
28
+ ...(pluginConfigOrigin === undefined ? {} : { pluginConfigOrigin }),
29
+ });
30
+ }
package/src/index.ts CHANGED
@@ -7,6 +7,7 @@
7
7
  * package surface remains small and stable.
8
8
  */
9
9
 
10
+ export * from "./plugin/resolveCapabilityPlugins";
10
11
  export * from "./TtscCompiler";
11
12
  export * from "./TtscService";
12
13
  export * from "./structures/index";
@@ -274,8 +274,16 @@ export interface RuntimeHookOptions {
274
274
  * `require()` made from inside a CommonJS module that was itself reached
275
275
  * through an ESM `import` (the interop translator loads it on the raw CJS
276
276
  * path). The ESM graph goes through `registerHooks`; the CommonJS `require`
277
- * graph goes through `Module._extensions` — the canonical loader extension
278
- * point `ts-node`/`tsx` use for the same reason.
277
+ * graph goes through `Module._extensions` and `Module._resolveFilename` — the
278
+ * canonical loader extension points `ts-node`/`tsx` use for the same reason.
279
+ *
280
+ * Both halves of that second graph are required, and they answer different
281
+ * questions. `_extensions` decides how a file that was _found_ is compiled, and
282
+ * Node reuses its keys when it probes an extensionless request, so
283
+ * `require("./x")` reaches `x.ts` for free. Nothing there resolves a request
284
+ * that already carries an extension: `require("./x.js")` backed only by `x.ts`
285
+ * is a resolution failure before any compiler is consulted, which is why the
286
+ * rescue is installed on `_resolveFilename` as well (samchon/ttsc#1280).
279
287
  */
280
288
  export function installRuntimeHooks(options: RuntimeHookOptions = {}): void {
281
289
  if (options.prepareEntry !== undefined) {
@@ -295,6 +303,7 @@ export function installRuntimeHooks(options: RuntimeHookOptions = {}): void {
295
303
  }
296
304
  registerHooks({ load, resolve });
297
305
  installCommonJsHook();
306
+ installCommonJsResolveHook();
298
307
  }
299
308
 
300
309
  /**
@@ -339,6 +348,106 @@ function installCommonJsHook(): void {
339
348
  }
340
349
  }
341
350
 
351
+ /**
352
+ * Map a JavaScript spelling back to its TypeScript source on the CommonJS
353
+ * resolution path, so `require("./x.js")` finds `x.ts` when nothing emitted
354
+ * `x.js`.
355
+ *
356
+ * TypeScript asks authors to write the emitted `.js` extension in a relative
357
+ * specifier, so this spelling is the documented one rather than a mistake, and
358
+ * the ESM `resolve` hook has always rescued it. The CommonJS graph could not,
359
+ * and on Node 22 that graph is reached by every `require()` inside a CommonJS
360
+ * module the ESM loader evaluated — `module.registerHooks` sees the `import()`
361
+ * of that module and nothing within it. Node 24 routes the same `require`
362
+ * through the hooks, which is why the gap was only ever visible on the oldest
363
+ * runtime ttsx supports (`engines.node` is `>=22.15.0`).
364
+ *
365
+ * The wrapper only ever answers a request Node's own resolver already refused,
366
+ * so a resolution that succeeds is never perturbed, and a request no candidate
367
+ * satisfies rethrows Node's original error with its `MODULE_NOT_FOUND` code and
368
+ * `requireStack` intact. `require.resolve` shares this entry point and is
369
+ * rescued with it, except in its `{ paths }` form, which resolves against the
370
+ * caller's list rather than the parent this reads.
371
+ */
372
+ function installCommonJsResolveHook(): void {
373
+ const internals = Module as unknown as {
374
+ _resolveFilename(
375
+ request: string,
376
+ parent: { filename?: string | null } | null | undefined,
377
+ isMain: boolean,
378
+ options?: unknown,
379
+ ): string;
380
+ };
381
+ const original = internals._resolveFilename;
382
+ internals._resolveFilename = function resolveFilename(
383
+ this: unknown,
384
+ request: string,
385
+ parent: { filename?: string | null } | null | undefined,
386
+ isMain: boolean,
387
+ options?: unknown,
388
+ ): string {
389
+ try {
390
+ return original.call(this, request, parent, isMain, options);
391
+ } catch (error) {
392
+ const rescued = rescueCommonJsRequest(request, parent, options);
393
+ if (rescued === null) {
394
+ throw error;
395
+ }
396
+ return rescued;
397
+ }
398
+ };
399
+ }
400
+
401
+ /**
402
+ * The TypeScript source a refused CommonJS request names, or `null`.
403
+ *
404
+ * Only a relative or absolute request can be rescued: a bare specifier is a
405
+ * package lookup, whose own resolver already probed every extension the
406
+ * installed `_extensions` keys declare.
407
+ *
408
+ * Two shapes decline before that. `_resolveFilename` is an internal entry point
409
+ * anything may call, so a non-string request reaches here as readily as a
410
+ * specifier does, and reading it would replace Node's own argument error with a
411
+ * `TypeError` from this file. And `require.resolve(request, { paths })`
412
+ * resolves against the caller's list, which this rescue does not consult, so
413
+ * answering it from the parent's directory would be a different question's
414
+ * answer.
415
+ */
416
+ function rescueCommonJsRequest(
417
+ request: string,
418
+ parent: { filename?: string | null } | null | undefined,
419
+ options?: unknown,
420
+ ): string | null {
421
+ if (typeof request !== "string") {
422
+ return null;
423
+ }
424
+ if (
425
+ typeof options === "object" &&
426
+ options !== null &&
427
+ Array.isArray((options as { paths?: unknown }).paths)
428
+ ) {
429
+ return null;
430
+ }
431
+ let base: string;
432
+ if (path.isAbsolute(request)) {
433
+ base = request;
434
+ } else if (isRelativeSpecifier(request)) {
435
+ const from = parent?.filename;
436
+ if (typeof from !== "string") {
437
+ return null;
438
+ }
439
+ base = path.resolve(path.dirname(from), request);
440
+ } else {
441
+ return null;
442
+ }
443
+ for (const candidate of typescriptSourcesForJavaScriptSpecifier(base)) {
444
+ if (isFile(candidate)) {
445
+ return candidate;
446
+ }
447
+ }
448
+ return null;
449
+ }
450
+
342
451
  /**
343
452
  * The module format of the entry source file, derived from the entry project's
344
453
  * compiler options (via the runtime manifest) the same way the served files are