@scriptc/compiler 0.1.1 → 0.1.2

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 (209) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +45 -17
  2. package/ambient/scriptc.d.ts +2 -1
  3. package/dist/backend/build-cache.js.map +1 -1
  4. package/dist/backend/c/async.js +24 -2
  5. package/dist/backend/c/async.js.map +1 -1
  6. package/dist/backend/c/c-emitter.d.ts +22 -10
  7. package/dist/backend/c/c-emitter.js +60 -15
  8. package/dist/backend/c/c-emitter.js.map +1 -1
  9. package/dist/backend/c/exprs.js +220 -10
  10. package/dist/backend/c/exprs.js.map +1 -1
  11. package/dist/backend/c/island.js.map +1 -1
  12. package/dist/backend/c/may-throw.js.map +1 -1
  13. package/dist/backend/c/stmts.d.ts +3 -5
  14. package/dist/backend/c/stmts.js +58 -17
  15. package/dist/backend/c/stmts.js.map +1 -1
  16. package/dist/backend/c/types.js.map +1 -1
  17. package/dist/backend/c/walkers.js +31 -5
  18. package/dist/backend/c/walkers.js.map +1 -1
  19. package/dist/backend/external-c.js.map +1 -1
  20. package/dist/backend/linker.js.map +1 -1
  21. package/dist/backend/llvm/blocks.js.map +1 -1
  22. package/dist/backend/llvm/dyn.js +56 -3
  23. package/dist/backend/llvm/dyn.js.map +1 -1
  24. package/dist/backend/llvm/emitter.js +98 -19
  25. package/dist/backend/llvm/emitter.js.map +1 -1
  26. package/dist/backend/llvm/expr-async.js +85 -3
  27. package/dist/backend/llvm/expr-async.js.map +1 -1
  28. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  29. package/dist/backend/llvm/expr-calls.js.map +1 -1
  30. package/dist/backend/llvm/expr-containers.js.map +1 -1
  31. package/dist/backend/llvm/expr-context.d.ts +1 -0
  32. package/dist/backend/llvm/expr-control.js.map +1 -1
  33. package/dist/backend/llvm/expr-dispatch.js.map +1 -1
  34. package/dist/backend/llvm/expr-dynamic.js +6 -3
  35. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  36. package/dist/backend/llvm/expr-island.js.map +1 -1
  37. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  38. package/dist/backend/llvm/expr-records.js.map +1 -1
  39. package/dist/backend/llvm/expr-stream-bridges.js +220 -9
  40. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  41. package/dist/backend/llvm/lib-dispatch.js +2 -0
  42. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  43. package/dist/backend/llvm/lib-shared.js +18 -0
  44. package/dist/backend/llvm/lib-shared.js.map +1 -1
  45. package/dist/backend/llvm/lib-stream.js +6 -3
  46. package/dist/backend/llvm/lib-stream.js.map +1 -1
  47. package/dist/backend/llvm/split.js.map +1 -1
  48. package/dist/backend/llvm/unsupported.js.map +1 -1
  49. package/dist/backend/llvm/walkers.js.map +1 -1
  50. package/dist/backend/native-codegen.js.map +1 -1
  51. package/dist/backend/native-codegen.test.js +2 -0
  52. package/dist/backend/native-codegen.test.js.map +1 -1
  53. package/dist/backend/native-toolchain.js.map +1 -1
  54. package/dist/backend/native-toolchain.test.js.map +1 -1
  55. package/dist/backend/runtime-pack.js.map +1 -1
  56. package/dist/backend/targets.js.map +1 -1
  57. package/dist/backend/vendor-archives.js.map +1 -1
  58. package/dist/compat/fetch-profile.js +4 -2
  59. package/dist/compat/fetch-profile.js.map +1 -1
  60. package/dist/coverage/report.js.map +1 -1
  61. package/dist/coverage/surface-manifest.js +12 -0
  62. package/dist/coverage/surface-manifest.js.map +1 -1
  63. package/dist/diagnostics/diagnostic.d.ts +6 -5
  64. package/dist/diagnostics/diagnostic.js +7 -6
  65. package/dist/diagnostics/diagnostic.js.map +1 -1
  66. package/dist/diagnostics/render.js.map +1 -1
  67. package/dist/ffi/ffi-manifest.js.map +1 -1
  68. package/dist/frontend/cjs-lexer.js.map +1 -1
  69. package/dist/frontend/dts-paths.js.map +1 -1
  70. package/dist/frontend/input-tracker.d.ts +10 -0
  71. package/dist/frontend/input-tracker.js +26 -3
  72. package/dist/frontend/input-tracker.js.map +1 -1
  73. package/dist/frontend/input-tracker.test.js +8 -1
  74. package/dist/frontend/input-tracker.test.js.map +1 -1
  75. package/dist/frontend/lib-contract.js.map +1 -1
  76. package/dist/frontend/lowering/array-values.d.ts +4 -0
  77. package/dist/frontend/lowering/array-values.js +18 -2
  78. package/dist/frontend/lowering/array-values.js.map +1 -1
  79. package/dist/frontend/lowering/callback-arg.js.map +1 -1
  80. package/dist/frontend/lowering/containers/bytes.d.ts +35 -0
  81. package/dist/frontend/lowering/containers/bytes.js +1021 -0
  82. package/dist/frontend/lowering/containers/bytes.js.map +1 -0
  83. package/dist/frontend/lowering/containers/string-and-regexp.d.ts +17 -0
  84. package/dist/frontend/lowering/containers/string-and-regexp.js +345 -0
  85. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -0
  86. package/dist/frontend/lowering/expressions/evaluation-safety.d.ts +13 -0
  87. package/dist/frontend/lowering/expressions/evaluation-safety.js +76 -0
  88. package/dist/frontend/lowering/expressions/evaluation-safety.js.map +1 -0
  89. package/dist/frontend/lowering/expressions/object-literals.d.ts +44 -0
  90. package/dist/frontend/lowering/expressions/object-literals.js +1815 -0
  91. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -0
  92. package/dist/frontend/lowering/expressions/optional-chains.d.ts +31 -0
  93. package/dist/frontend/lowering/expressions/optional-chains.js +382 -0
  94. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -0
  95. package/dist/frontend/lowering/expressions/try-lower-expression.d.ts +7 -0
  96. package/dist/frontend/lowering/expressions/try-lower-expression.js +26 -0
  97. package/dist/frontend/lowering/expressions/try-lower-expression.js.map +1 -0
  98. package/dist/frontend/lowering/lib-boundary.js +7 -2
  99. package/dist/frontend/lowering/lib-boundary.js.map +1 -1
  100. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  101. package/dist/frontend/lowering/lower-async-iteration.d.ts +7 -0
  102. package/dist/frontend/lowering/lower-async-iteration.js +657 -0
  103. package/dist/frontend/lowering/lower-async-iteration.js.map +1 -0
  104. package/dist/frontend/lowering/lower-builtins.d.ts +18 -0
  105. package/dist/frontend/lowering/lower-builtins.js +219 -48
  106. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  107. package/dist/frontend/lowering/lower-calls.d.ts +13 -4
  108. package/dist/frontend/lowering/lower-calls.js +407 -64
  109. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  110. package/dist/frontend/lowering/lower-classes.d.ts +7 -13
  111. package/dist/frontend/lowering/lower-classes.js +128 -35
  112. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  113. package/dist/frontend/lowering/lower-comptime.js.map +1 -1
  114. package/dist/frontend/lowering/lower-containers.d.ts +1 -47
  115. package/dist/frontend/lowering/lower-containers.js +135 -1467
  116. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  117. package/dist/frontend/lowering/lower-event-emitter.js +51 -5
  118. package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
  119. package/dist/frontend/lowering/lower-exprs.d.ts +0 -78
  120. package/dist/frontend/lowering/lower-exprs.js +402 -2351
  121. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  122. package/dist/frontend/lowering/lower-generators.d.ts +18 -3
  123. package/dist/frontend/lowering/lower-generators.js +145 -9
  124. package/dist/frontend/lowering/lower-generators.js.map +1 -1
  125. package/dist/frontend/lowering/lower-inspect.js +3 -3
  126. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  127. package/dist/frontend/lowering/lower-island.d.ts +6 -0
  128. package/dist/frontend/lowering/lower-island.js +37 -5
  129. package/dist/frontend/lowering/lower-island.js.map +1 -1
  130. package/dist/frontend/lowering/lower-modules.js +52 -15
  131. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  132. package/dist/frontend/lowering/lower-node-module.d.ts +18 -0
  133. package/dist/frontend/lowering/lower-node-module.js +302 -0
  134. package/dist/frontend/lowering/lower-node-module.js.map +1 -0
  135. package/dist/frontend/lowering/lower-server.js +1 -1
  136. package/dist/frontend/lowering/lower-server.js.map +1 -1
  137. package/dist/frontend/lowering/lower-stmts.d.ts +5 -24
  138. package/dist/frontend/lowering/lower-stmts.js +519 -253
  139. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  140. package/dist/frontend/lowering/lower-stream.js +4 -4
  141. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  142. package/dist/frontend/lowering/lowerer.d.ts +37 -34
  143. package/dist/frontend/lowering/lowerer.js +143 -57
  144. package/dist/frontend/lowering/lowerer.js.map +1 -1
  145. package/dist/frontend/lowering/optional-arguments.d.ts +9 -0
  146. package/dist/frontend/lowering/optional-arguments.js +57 -0
  147. package/dist/frontend/lowering/optional-arguments.js.map +1 -0
  148. package/dist/frontend/npm-static-declarations.d.ts +35 -0
  149. package/dist/frontend/npm-static-declarations.js +506 -0
  150. package/dist/frontend/npm-static-declarations.js.map +1 -0
  151. package/dist/frontend/npm-static-declarations.test.d.ts +1 -0
  152. package/dist/frontend/npm-static-declarations.test.js +122 -0
  153. package/dist/frontend/npm-static-declarations.test.js.map +1 -0
  154. package/dist/frontend/npm-static.d.ts +2 -0
  155. package/dist/frontend/npm-static.js +26 -10
  156. package/dist/frontend/npm-static.js.map +1 -1
  157. package/dist/frontend/npm.d.ts +60 -0
  158. package/dist/frontend/npm.js +38 -4
  159. package/dist/frontend/npm.js.map +1 -1
  160. package/dist/frontend/npm.test.d.ts +1 -0
  161. package/dist/frontend/npm.test.js +50 -0
  162. package/dist/frontend/npm.test.js.map +1 -0
  163. package/dist/frontend/program.d.ts +3 -2
  164. package/dist/frontend/program.js +495 -68
  165. package/dist/frontend/program.js.map +1 -1
  166. package/dist/frontend/resolve.d.ts +10 -2
  167. package/dist/frontend/resolve.js +90 -14
  168. package/dist/frontend/resolve.js.map +1 -1
  169. package/dist/frontend/resolve.test.js +4 -1
  170. package/dist/frontend/resolve.test.js.map +1 -1
  171. package/dist/frontend/runtime-resolve.d.ts +22 -0
  172. package/dist/frontend/runtime-resolve.js +101 -0
  173. package/dist/frontend/runtime-resolve.js.map +1 -0
  174. package/dist/frontend/runtime-resolve.test.d.ts +1 -0
  175. package/dist/frontend/runtime-resolve.test.js +18 -0
  176. package/dist/frontend/runtime-resolve.test.js.map +1 -0
  177. package/dist/frontend/ts7/adapter.js +12 -13
  178. package/dist/frontend/ts7/adapter.js.map +1 -1
  179. package/dist/frontend/ts7/ast.js.map +1 -1
  180. package/dist/frontend/ts7/census-check.js +3 -3
  181. package/dist/frontend/ts7/census-check.js.map +1 -1
  182. package/dist/frontend/ts7/checker.d.ts +3 -0
  183. package/dist/frontend/ts7/checker.js +12 -3
  184. package/dist/frontend/ts7/checker.js.map +1 -1
  185. package/dist/frontend/ts7/enums.js.map +1 -1
  186. package/dist/frontend/ts7/program-adapter.js +42 -3
  187. package/dist/frontend/ts7/program-adapter.js.map +1 -1
  188. package/dist/frontend/type-mapper.js +120 -7
  189. package/dist/frontend/type-mapper.js.map +1 -1
  190. package/dist/index.js +5 -5
  191. package/dist/index.js.map +1 -1
  192. package/dist/ir/analysis.js.map +1 -1
  193. package/dist/ir/ir.d.ts +60 -30
  194. package/dist/ir/ir.js +57 -6
  195. package/dist/ir/ir.js.map +1 -1
  196. package/dist/ir/validate.js +44 -59
  197. package/dist/ir/validate.js.map +1 -1
  198. package/dist/library/cache-primitives.js.map +1 -1
  199. package/dist/library/cache-reset.test.js.map +1 -1
  200. package/dist/library/compiler-self-identity.js.map +1 -1
  201. package/dist/library/int-infer.js.map +1 -1
  202. package/dist/library/int-infer.test.js.map +1 -1
  203. package/dist/library/library-profile.js.map +1 -1
  204. package/dist/library/sidecar-validate.js.map +1 -1
  205. package/dist/library/sidecar.js.map +1 -1
  206. package/dist/startup-cache.js.map +1 -1
  207. package/dist/wasi-paths.js.map +1 -1
  208. package/package.json +18 -18
  209. package/surface-manifest.json +60 -4
@@ -39,19 +39,20 @@
39
39
  * JSON.parse's wording rather than tsc's, the one message-text delta on
40
40
  * that path (no snapshot pins it). */
41
41
  import { builtinModules } from "node:module";
42
- import { dirname, resolve } from "node:path";
42
+ import { dirname, isAbsolute, resolve } from "node:path";
43
43
  import * as ts from "./ts7/adapter.js";
44
44
  import { commonJsModuleSyntaxDiag, invalidPackageConfigDiag, strictNullChecksFloorDiag, tscPassthroughDiag, unsupportedDiag, } from "../diagnostics/diagnostic.js";
45
- import { isNodeModulesPath, nearestInvalidPackageJsonPath, nearestPackageType, nearestPkgJsonPath, projectDtsRuntimeSibling, resolveBareModule, resolveProjectImport, resolveRelativeModule, resolveTypeDirective, setProjectRealm } from "./resolve.js";
45
+ import { isNodeModulesPath, nearestInvalidPackageJsonPath, nearestPackageType, nearestPkgJsonPath, projectDtsRuntimeSibling, resolveBareModule, resolveProjectModule, resolveTypeDirective, setProjectPathMappings, setProjectRealm } from "./resolve.js";
46
46
  import { probeNodeImportRefusal, probeNodeRequireRefusal } from "./npm.js";
47
- import { isNpmStaticPackage, npmStaticActive, npmStaticFsShadow, npmStaticPackageOfPath, reportNpmStaticOffender, setNpmStaticPackages } from "./npm-static.js";
47
+ import { isNpmStaticPackage, npmStaticActive, npmStaticFsShadow, npmStaticPackageOfPath, reportNpmStaticOffender, setNpmStaticDeclarationOverloads, setNpmStaticPackages } from "./npm-static.js";
48
+ import { npmStaticDeclarationReexports, npmStaticRuntimeClassTargets, parseNpmStaticDeclarationOverloads, parseNpmStaticDeclarationProperties } from "./npm-static-declarations.js";
48
49
  import { provenanceEntryFor, provenancePaths } from "./provenance-registry.js";
49
50
  import { cjsLexerVisibleNames } from "./cjs-lexer.js";
50
51
  import { ambientDtsPath, fallbackDtsPath, isNodeTypesPath, overridesDtsPath, tsgoPath, } from "./dts-paths.js";
51
52
  import { builtinDefaultImportModule, canonicalBuiltinModule, SUPPORTED_NODE_MODULES, unsupportedModuleFeatureOf, } from "./builtin-modules.js";
52
- import { clearWorkspacePackages, isRelativeSpecifier, isWorkspacePackageName, registerWorkspacePackage, workspacePackageOfPath, } from "./workspace-registry.js";
53
+ import { clearWorkspacePackages, isRelativeSpecifier, isWorkspacePackageName, npmPackageNameOf, registerWorkspacePackage, workspacePackageOfPath, } from "./workspace-registry.js";
53
54
  import { ADOPTED_OPTIONS, isJsSourceFileName, JS_ANY_OPERATOR_CODES, JS_RELAXED_TSC_CODES, } from "./tsc-codes.js";
54
- import { trackedFileExists } from "./input-tracker.js";
55
+ import { trackedFileExists, trackedReadFile, trackedRealpath } from "./input-tracker.js";
55
56
  const BASE_OPTIONS = {
56
57
  strict: true,
57
58
  };
@@ -67,7 +68,10 @@ const FORCED_OPTIONS = {
67
68
  // classification is intentionally independent below; this option is only
68
69
  // the binder's scope decision.
69
70
  moduleDetection: ts.ModuleDetectionKind.Force,
70
- lib: ["lib.es2025.d.ts"],
71
+ // Explicit resource management is an ESNext library slice in TS 7 even
72
+ // though Node 24 ships the runtime protocol. Include that focused lib
73
+ // without widening the rest of the standard-library target past ES2025.
74
+ lib: ["lib.es2025.d.ts", "lib.esnext.disposable.d.ts"],
71
75
  types: [],
72
76
  allowImportingTsExtensions: true,
73
77
  allowJs: true,
@@ -142,6 +146,28 @@ function adoptProjectConfig7(host, entryPath) {
142
146
  if (value !== undefined)
143
147
  adopted[key] = value;
144
148
  }
149
+ // TS 7 accepts `paths`, but no longer accepts `baseUrl` as a compiler
150
+ // option. Translate the established baseUrl+paths spelling into absolute
151
+ // targets: the synthesized config lives beside the entry rather than the
152
+ // real config, so preserving relative targets would silently change their
153
+ // meaning. The absolute map is also the own resolver's configuration.
154
+ const rawPaths = parsed.options["paths"];
155
+ if (rawPaths !== undefined && typeof rawPaths === "object" && rawPaths !== null) {
156
+ const configDir = dirname(configFile);
157
+ const rawBaseUrl = parsed.options["baseUrl"];
158
+ const base = typeof rawBaseUrl === "string"
159
+ ? (isAbsolute(rawBaseUrl) ? rawBaseUrl : resolve(configDir, rawBaseUrl))
160
+ : configDir;
161
+ const paths = {};
162
+ for (const [key, targets] of Object.entries(rawPaths)) {
163
+ if (!Array.isArray(targets))
164
+ continue;
165
+ paths[key] = targets
166
+ .filter((target) => typeof target === "string")
167
+ .map((target) => isAbsolute(target) ? target : resolve(base, target));
168
+ }
169
+ adopted["paths"] = paths;
170
+ }
145
171
  const nullChecks = adopted["strictNullChecks"] ?? adopted["strict"] ?? false;
146
172
  if (nullChecks !== true) {
147
173
  diags.push(strictNullChecksFloorDiag(configFile));
@@ -156,6 +182,94 @@ function resolveNodeTypes7(entryPath) {
156
182
  const file = resolveTypeDirective("node", entryPath);
157
183
  return file !== null && isNodeTypesPath(file) ? file : null;
158
184
  }
185
+ function declarationReexportTarget(fromFile, specifier) {
186
+ const base = resolve(dirname(fromFile), specifier);
187
+ const candidates = [];
188
+ const extension = /\.(mjs|cjs|js)$/.exec(base)?.[1];
189
+ if (extension !== undefined) {
190
+ const stem = base.slice(0, -(extension.length + 1));
191
+ if (extension === "mjs")
192
+ candidates.push(`${stem}.d.mts`, `${stem}.d.ts`);
193
+ else if (extension === "cjs")
194
+ candidates.push(`${stem}.d.cts`, `${stem}.d.ts`);
195
+ else
196
+ candidates.push(`${stem}.d.ts`, `${stem}.d.mts`, `${stem}.d.cts`);
197
+ }
198
+ else {
199
+ candidates.push(base, `${base}.d.ts`, `${base}.d.mts`, `${base}.d.cts`);
200
+ }
201
+ candidates.push(resolve(base, "index.d.ts"), resolve(base, "index.d.mts"), resolve(base, "index.d.cts"));
202
+ return candidates.find((candidate) => trackedFileExists(candidate)) ?? null;
203
+ }
204
+ function runtimeReexportTarget(fromFile, specifier) {
205
+ const base = resolve(dirname(fromFile), specifier);
206
+ const candidates = [
207
+ base,
208
+ `${base}.js`,
209
+ `${base}.mjs`,
210
+ `${base}.cjs`,
211
+ resolve(base, "index.js"),
212
+ resolve(base, "index.mjs"),
213
+ resolve(base, "index.cjs"),
214
+ ];
215
+ const target = candidates.find((candidate) => trackedFileExists(candidate) && isJsSourceFileName(candidate));
216
+ return target === undefined ? null : (trackedRealpath(target) ?? target);
217
+ }
218
+ /** Visits an opted package's own declaration entry and relative barrel
219
+ * closure. This is intentionally narrower than TypeScript module
220
+ * resolution: bare edges name other packages and never inherit trust. */
221
+ function visitNpmStaticDeclarationClosure(entryPath, onSource) {
222
+ const seen = new Set();
223
+ const packageJson = nearestPkgJsonPath(entryPath);
224
+ const packageRoot = (packageJson === null ? dirname(entryPath) : dirname(packageJson)).split("\\").join("/");
225
+ const visit = (path) => {
226
+ path = resolve(path);
227
+ const normalized = path.split("\\").join("/");
228
+ if (normalized !== packageRoot && !normalized.startsWith(packageRoot + "/"))
229
+ return;
230
+ if (seen.has(path))
231
+ return;
232
+ seen.add(path);
233
+ const source = trackedReadFile(path);
234
+ if (source === null)
235
+ return;
236
+ onSource(path, source);
237
+ for (const specifier of npmStaticDeclarationReexports(path, source)) {
238
+ const target = declarationReexportTarget(path, specifier);
239
+ if (target !== null)
240
+ visit(target);
241
+ }
242
+ };
243
+ visit(entryPath);
244
+ }
245
+ function npmStaticDeclarationOverloadsOf(entryPath) {
246
+ const classes = new Map();
247
+ visitNpmStaticDeclarationClosure(entryPath, (path, source) => {
248
+ for (const [className, methods] of parseNpmStaticDeclarationOverloads(path, source)) {
249
+ const target = classes.get(className) ?? new Map();
250
+ classes.set(className, target);
251
+ for (const [methodName, signatures] of methods) {
252
+ if (!target.has(methodName))
253
+ target.set(methodName, signatures);
254
+ }
255
+ }
256
+ });
257
+ return classes;
258
+ }
259
+ function npmStaticDeclarationPropertiesOf(entryPath) {
260
+ const classes = new Map();
261
+ visitNpmStaticDeclarationClosure(entryPath, (path, source) => {
262
+ for (const [className, properties] of parseNpmStaticDeclarationProperties(path, source)) {
263
+ const target = classes.get(className) ?? new Map();
264
+ classes.set(className, target);
265
+ for (const [propertyName, type] of properties) {
266
+ if (!target.has(propertyName))
267
+ target.set(propertyName, type);
268
+ }
269
+ }
270
+ });
271
+ return classes;
272
+ }
159
273
  /** True when a coverage mapping names one exact bare host module. TypeScript
160
274
  * gives `paths` keys containing `*` pattern semantics, so accepting one here
161
275
  * would silently broaden the mapping beyond the specifier the caller named. */
@@ -232,6 +346,10 @@ function externalTypeFileClosure7(program, externalTypes) {
232
346
  }
233
347
  function loadProgram7(host, entryPath, externalTypes = new Map()) {
234
348
  const config = adoptProjectConfig7(host, entryPath);
349
+ const configuredPaths = config.options["paths"];
350
+ setProjectPathMappings(configuredPaths !== undefined && typeof configuredPaths === "object" && configuredPaths !== null
351
+ ? configuredPaths
352
+ : null);
235
353
  const nodeTypes = config.configFile ? resolveNodeTypes7(entryPath) : null;
236
354
  // skipLibCheck is FORCED with @types/node in the program: checking a
237
355
  // third-party lib's internals against OUR lib choice (es2025, no dyn) is
@@ -251,7 +369,10 @@ function loadProgram7(host, entryPath, externalTypes = new Map()) {
251
369
  // driver against the package's real TypeScript, not its shipped .d.ts.
252
370
  const provenance = provenancePaths();
253
371
  if (provenance !== null || externalTypes.size > 0) {
254
- const paths = { ...(provenance ?? {}) };
372
+ const paths = {
373
+ ...configuredPaths,
374
+ ...(provenance ?? {}),
375
+ };
255
376
  for (const [specifier, declarationPath] of externalTypes) {
256
377
  paths[specifier] = [declarationPath];
257
378
  }
@@ -303,7 +424,60 @@ export function loadProgram(entryPath, opts) {
303
424
  }
304
425
  externalTypes.set(specifier, declarationPath);
305
426
  }
306
- setNpmStaticPackages(opts?.npmStatic ?? []);
427
+ const npmStaticPackages = [...new Set(opts?.npmStatic ?? [])];
428
+ // Resolve authored declaration entries before enabling the JS-only
429
+ // package resolver. Safe overload metadata binds through the runtime
430
+ // entry to one exact implementation file; it never contributes values
431
+ // or executable module edges.
432
+ const declarationOverloads = new Map();
433
+ const declarationProperties = new Map();
434
+ for (const pkg of npmStaticPackages) {
435
+ const resolved = resolveBareModule(entryPath, pkg, "types-only");
436
+ if (resolved === null ||
437
+ resolved.packageName !== pkg ||
438
+ !/\.d\.(?:ts|mts|cts)$/.test(resolved.typesFile)) {
439
+ continue;
440
+ }
441
+ const overloads = npmStaticDeclarationOverloadsOf(resolved.typesFile);
442
+ const properties = npmStaticDeclarationPropertiesOf(resolved.typesFile);
443
+ const classNames = new Set([...overloads.keys(), ...properties.keys()]);
444
+ if (classNames.size === 0)
445
+ continue;
446
+ const runtime = resolveBareModule(entryPath, pkg, "js-only");
447
+ if (runtime === null || !isJsSourceFileName(runtime.typesFile))
448
+ continue;
449
+ const runtimeSource = trackedReadFile(runtime.typesFile);
450
+ if (runtimeSource === null)
451
+ continue;
452
+ const targets = npmStaticRuntimeClassTargets(runtime.typesFile, runtimeSource, classNames);
453
+ for (const [className, specifier] of targets) {
454
+ const methods = overloads.get(className);
455
+ const fields = properties.get(className);
456
+ if (methods === undefined && fields === undefined)
457
+ continue;
458
+ const target = specifier === null ? runtime.typesFile : runtimeReexportTarget(runtime.typesFile, specifier);
459
+ if (target === null)
460
+ continue;
461
+ const targetPackage = npmPackageNameOf(target);
462
+ const targetNorm = target.split("\\").join("/");
463
+ const insideWorkspace = runtime.workspaceDir !== undefined &&
464
+ targetNorm.startsWith(runtime.workspaceDir.split("\\").join("/") + "/");
465
+ if (targetPackage !== pkg && !insideWorkspace)
466
+ continue;
467
+ if (methods !== undefined) {
468
+ const byClass = new Map(declarationOverloads.get(targetNorm) ?? []);
469
+ byClass.set(className, methods);
470
+ declarationOverloads.set(targetNorm, byClass);
471
+ }
472
+ if (fields !== undefined) {
473
+ const byClass = new Map(declarationProperties.get(targetNorm) ?? []);
474
+ byClass.set(className, fields);
475
+ declarationProperties.set(targetNorm, byClass);
476
+ }
477
+ }
478
+ }
479
+ setNpmStaticPackages(npmStaticPackages);
480
+ setNpmStaticDeclarationOverloads(declarationOverloads, declarationProperties);
307
481
  // Workspace-package registrations reset per load (same discipline as the
308
482
  // npm-static set), then the opted-in names are probed UP FRONT: a
309
483
  // workspace-linked opt-in resolves to files whose realpaths carry no
@@ -1327,7 +1501,7 @@ export function makeCycleAdmission(program, edgesOf) {
1327
1501
  * resolveImport) for the lowering: CommonJS require statements lower to
1328
1502
  * guarded %init calls of exactly the module preflight resolved here. */
1329
1503
  function resolveImport7(program, from, specifier) {
1330
- const resolved = resolveRelativeModule(from.fileName, specifier);
1504
+ const resolved = resolveProjectModule(from.fileName, specifier);
1331
1505
  if (resolved === null)
1332
1506
  return null;
1333
1507
  return program.getSourceFile(resolved) ?? null;
@@ -1342,7 +1516,7 @@ function resolveNpmImport7(fromFileName, specifier) {
1342
1516
  return null;
1343
1517
  }
1344
1518
  // --provenance-sources: a registered specifier is NOT an npm import —
1345
- // its attested source compiles as program modules (resolveProjectImport
1519
+ // its attested source compiles as program modules (resolveProjectModule
1346
1520
  // answers the entry), so no island embed and no .d.ts type surface.
1347
1521
  if (provenanceEntryFor(specifier) !== null)
1348
1522
  return null;
@@ -1888,9 +2062,15 @@ function preflight7(load) {
1888
2062
  pos: stmt.getStart(sf),
1889
2063
  });
1890
2064
  };
2065
+ // Project modules win before npm fallback: this is the source graph
2066
+ // tsgo type-checked for tsconfig paths, package imports/self-references,
2067
+ // and provenance entries. Ordinary packages still answer null here.
2068
+ const projDep = isBare ? resolveImport7(program, sf, spec) : null;
1891
2069
  // "#" specifiers can never name an npm package — they are the
1892
- // imports-field family, resolved below.
1893
- const npm = isBare && !spec.startsWith("#") ? resolveNpmImport7(sf.fileName, spec) : null;
2070
+ // imports-field family, resolved by the project arm above.
2071
+ const npm = isBare && projDep === null && !spec.startsWith("#")
2072
+ ? resolveNpmImport7(sf.fileName, spec)
2073
+ : null;
1894
2074
  if (npm && isNodeTypesPath(npm.typesFile)) {
1895
2075
  diags.push(unsupportedDiag("SC1010", locOf7(stmt), unsupportedModuleFeatureOf(spec)));
1896
2076
  continue;
@@ -1922,19 +2102,13 @@ function preflight7(load) {
1922
2102
  continue;
1923
2103
  }
1924
2104
  }
1925
- // PROJECT imports: package.json-mediated specifiers that resolve to
1926
- // the program's own sources — `#alias` (the imports field) and
1927
- // self-name references (the nearest package.json's name through its
1928
- // exports). A source answer is an ordinary user-module edge, exactly
1929
- // like a relative import (the checker resolved the bindings the same
1930
- // way); a refused resolution is Node's startup crash with Node's
1931
- // exact message; what keeps a compile fence: the unsupported
1932
- // builtin and the types-only resolution (Node-hostable or ambiguous
1933
- // — scriptc's own limitations, named as such).
1934
- let projDep = null;
2105
+ // PROJECT imports: tsconfig paths and package.json-mediated specifiers
2106
+ // that resolve to the program's own sources. A source answer is an
2107
+ // ordinary user-module edge, exactly like a relative import (the
2108
+ // checker resolved the bindings the same way); a refused resolution is
2109
+ // Node's startup crash with Node's exact message; what keeps a compile
2110
+ // fence is unsupported builtin or types-only surface.
1935
2111
  if (isBare && npmStaticDep === null) {
1936
- const resolved = resolveProjectImport(sf.fileName, spec);
1937
- projDep = resolved !== null ? (program.getSourceFile(resolved) ?? null) : null;
1938
2112
  if (projDep !== null && projDep.isDeclarationFile) {
1939
2113
  diags.push(unsupportedDiag("SC1010", locOf7(stmt), `the '${spec}' import (it resolves only to type declarations — there is no runtime implementation to compile)`));
1940
2114
  continue;
@@ -2077,8 +2251,8 @@ function preflight7(load) {
2077
2251
  }
2078
2252
  }
2079
2253
  const isRelative = isRelativeSpecifier(req.spec);
2080
- let dep = null;
2081
- if (!isRelative) {
2254
+ let dep = resolveImport7(program, sf, req.spec);
2255
+ if (dep === null && !isRelative) {
2082
2256
  // --npm-static: a require() of an OPTED-IN package is a
2083
2257
  // program-module edge exactly like the import-declaration
2084
2258
  // form above (bundle dists require their workspace siblings —
@@ -2106,9 +2280,6 @@ function preflight7(load) {
2106
2280
  continue;
2107
2281
  }
2108
2282
  }
2109
- else {
2110
- dep = resolveImport7(program, sf, req.spec);
2111
- }
2112
2283
  if (dep && dep.fileName.endsWith(".json")) {
2113
2284
  diags.push(unsupportedDiag("SC1012", loc, "require() of JSON modules"));
2114
2285
  continue;
@@ -2139,6 +2310,15 @@ function preflight7(load) {
2139
2310
  if (load.externalTypes.has(spec)) {
2140
2311
  continue;
2141
2312
  }
2313
+ const projectDep = resolveImport7(program, sf, spec);
2314
+ if (projectDep !== null) {
2315
+ if (projectDep.fileName.endsWith(".json")) {
2316
+ diags.push(unsupportedDiag("SC1012", loc, "require() of JSON modules"));
2317
+ continue;
2318
+ }
2319
+ deps.push({ dep: projectDep });
2320
+ continue;
2321
+ }
2142
2322
  if (!isRelativeSpecifier(spec)) {
2143
2323
  // --npm-static: opted-in packages ride the program-module edge
2144
2324
  // (the statement-level require branch above).
@@ -2158,13 +2338,6 @@ function preflight7(load) {
2158
2338
  }
2159
2339
  continue;
2160
2340
  }
2161
- const dep = resolveImport7(program, sf, spec);
2162
- if (dep && dep.fileName.endsWith(".json")) {
2163
- diags.push(unsupportedDiag("SC1012", loc, "require() of JSON modules"));
2164
- continue;
2165
- }
2166
- if (dep)
2167
- deps.push({ dep });
2168
2341
  }
2169
2342
  }
2170
2343
  }
@@ -2263,7 +2436,9 @@ function preflight7(load) {
2263
2436
  }
2264
2437
  }
2265
2438
  }
2266
- const linkCrash = resolveCrash !== null ? null : cjsNamedImportLinkCheck(program, entry, order, diags);
2439
+ const linkCrash = resolveCrash !== null
2440
+ ? null
2441
+ : earlierLinkCrash(order, cjsNamedImportLinkCheck(program, entry, order, diags), esmNamedImportLinkCheck(program, entry, order, diags));
2267
2442
  return { diags, moduleOrder: order, startupCrash: resolveCrash ?? linkCrash };
2268
2443
  }
2269
2444
  /** Walks the entry's ESM instantiate graph exactly as V8 does — children
@@ -2278,21 +2453,18 @@ function preflight7(load) {
2278
2453
  * not modeled: those get a pointed fence instead. */
2279
2454
  function cjsNamedImportLinkCheck(program, entry, moduleOrder, diags) {
2280
2455
  const lexMemo = new Map();
2281
- const isRelative = isRelativeSpecifier;
2282
- // Relative specifiers resolve as ever; PROJECT imports (#alias/self-name
2283
- // — the same package.json-mediated edges preflight admits) join them so
2456
+ // Project specifiers resolve as ever; aliases and package.json-mediated
2457
+ // edges (#alias/self-name) join relative imports so
2284
2458
  // a named import THROUGH one of a CommonJS module keeps Node's lexer
2285
2459
  // check. Builtin/npm targets contribute nothing here — except opted-in
2286
2460
  // --npm-static packages, whose CJS entries face Node's lexer exactly
2287
2461
  // like program CJS files (their JS IS the program now).
2288
2462
  const resolveEdge = (from, spec) => {
2289
- if (isRelative(spec))
2290
- return resolveImport7(program, from, spec);
2463
+ const project = resolveImport7(program, from, spec);
2464
+ if (project !== null)
2465
+ return project;
2291
2466
  const npmStatic = npmStaticDepSf7(program, from, spec);
2292
- if (npmStatic !== null)
2293
- return npmStatic;
2294
- const p = resolveProjectImport(from.fileName, spec);
2295
- return p !== null ? (program.getSourceFile(p) ?? null) : null;
2467
+ return npmStatic;
2296
2468
  };
2297
2469
  // Reexport targets union in only when they resolve to CommonJS program
2298
2470
  // files (Node's cjsPreparseModuleExports rule).
@@ -2447,6 +2619,279 @@ function cjsNamedImportLinkCheck(program, entry, moduleOrder, diags) {
2447
2619
  loc,
2448
2620
  };
2449
2621
  }
2622
+ /** Node's strip-only loader exposes an empty `default` export for a default
2623
+ * interface only when the `.ts` file is in an ambiguous (typeless) package
2624
+ * scope. Explicitly ESM files (`.mts` and `.mjs`) and `.ts` files in a
2625
+ * `"type": "module"` package do not get that placeholder. */
2626
+ function hasNodeTsDefaultInterfacePlaceholder7(sf) {
2627
+ return sf.fileName.endsWith(".ts") && nearestPackageType(sf.fileName) === null;
2628
+ }
2629
+ /** Finds the first native-ESM link failure in the static module graph rooted
2630
+ * at `entry`. This is used both for startup linking of the entry graph and
2631
+ * for dynamic imports: a dynamically loaded graph rejects its import promise
2632
+ * at this same link point instead of running any module body. */
2633
+ function analyzeEsmNamedImportLinks(program, entry) {
2634
+ const checker = program.getTypeChecker();
2635
+ const resolveEdge = (from, spec) => {
2636
+ const project = resolveImport7(program, from, spec);
2637
+ if (project !== null)
2638
+ return project;
2639
+ return npmStaticDepSf7(program, from, spec);
2640
+ };
2641
+ const runtimeExport = (dep, name, seenModules = new Set()) => {
2642
+ if (seenModules.has(dep))
2643
+ return undefined;
2644
+ const nextSeen = new Set(seenModules);
2645
+ nextSeen.add(dep);
2646
+ const module = checker.getSymbolAtLocation(dep);
2647
+ const exported = module?.getExports().get(name);
2648
+ if (exported !== undefined) {
2649
+ let resolved = exported;
2650
+ const seenSymbols = new Set();
2651
+ while ((resolved.flags & ts.SymbolFlags.Alias) !== 0 && !seenSymbols.has(resolved)) {
2652
+ seenSymbols.add(resolved);
2653
+ resolved = checker.getAliasedSymbol(resolved);
2654
+ }
2655
+ if (resolved.flags & ts.SymbolFlags.Value)
2656
+ return resolved;
2657
+ // Node's strip-only TypeScript loader materializes a direct `export
2658
+ // default interface X {}` as an empty default export in an ambiguous
2659
+ // `.ts` file. The checker correctly classifies the declaration as
2660
+ // type-only, but the native ESM linker sees the runtime placeholder.
2661
+ if (name === "default" &&
2662
+ hasNodeTsDefaultInterfacePlaceholder7(dep) &&
2663
+ checker.declarationsOf(resolved).some((declaration) => ts.isInterfaceDeclaration(declaration) &&
2664
+ ts.getModifiers(declaration)?.some((modifier) => modifier.kind === ts.SyntaxKind.DefaultKeyword) === true &&
2665
+ ts.getModifiers(declaration)?.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword) === true)) {
2666
+ return resolved;
2667
+ }
2668
+ return undefined;
2669
+ }
2670
+ // TypeScript 7's client-side module symbol exposes the module's own
2671
+ // export table but not names contributed by `export *`. Follow those
2672
+ // source edges explicitly, applying the ESM ambiguity rule: the same
2673
+ // resolved symbol may arrive through multiple stars, while distinct
2674
+ // symbols make the name unavailable. `default` never star-reexports.
2675
+ if (name === "default")
2676
+ return undefined;
2677
+ let starExport;
2678
+ for (const stmt of dep.statements) {
2679
+ if (!ts.isExportDeclaration(stmt) || stmt.isTypeOnly || stmt.exportClause !== undefined)
2680
+ continue;
2681
+ if (stmt.moduleSpecifier === undefined || !ts.isStringLiteral(stmt.moduleSpecifier))
2682
+ continue;
2683
+ const target = resolveEdge(dep, stmt.moduleSpecifier.text);
2684
+ if (target === null || target.fileName.endsWith(".json") || !isNodeEsmFile7(target))
2685
+ continue;
2686
+ const candidate = runtimeExport(target, name, nextSeen);
2687
+ if (candidate === undefined)
2688
+ continue;
2689
+ if (starExport !== undefined && starExport !== candidate)
2690
+ return undefined;
2691
+ starExport = candidate;
2692
+ }
2693
+ return starExport;
2694
+ };
2695
+ const firstMissingOf = (sf) => {
2696
+ const imports = [];
2697
+ for (const stmt of sf.statements) {
2698
+ if (!ts.isImportDeclaration(stmt) || !ts.isStringLiteral(stmt.moduleSpecifier))
2699
+ continue;
2700
+ const clause = stmt.importClause;
2701
+ if (clause === undefined || clause.phaseModifier === ts.SyntaxKind.TypeKeyword)
2702
+ continue;
2703
+ const spec = stmt.moduleSpecifier.text;
2704
+ const dep = resolveEdge(sf, spec);
2705
+ if (dep === null || dep.fileName.endsWith(".json") || !isNodeEsmFile7(dep))
2706
+ continue;
2707
+ if (clause.name !== undefined) {
2708
+ imports.push({ local: clause.name.text, exportName: "default", spec, nameNode: clause.name, dep });
2709
+ }
2710
+ if (clause.namedBindings === undefined || !ts.isNamedImports(clause.namedBindings))
2711
+ continue;
2712
+ for (const element of clause.namedBindings.elements) {
2713
+ if (element.isTypeOnly)
2714
+ continue;
2715
+ const nameNode = element.propertyName ?? element.name;
2716
+ imports.push({
2717
+ local: element.name.text,
2718
+ exportName: nameNode.text,
2719
+ spec,
2720
+ nameNode,
2721
+ dep,
2722
+ });
2723
+ }
2724
+ }
2725
+ // Node checks regular named requests in local-binding order. Keeping the
2726
+ // same order as the CommonJS linker matters when one statement asks for
2727
+ // more than one erased TypeScript export.
2728
+ imports.sort((a, b) => (a.local < b.local ? -1 : a.local > b.local ? 1 : 0));
2729
+ for (const request of imports) {
2730
+ if (runtimeExport(request.dep, request.exportName) === undefined) {
2731
+ return {
2732
+ exportName: request.exportName,
2733
+ spec: request.spec,
2734
+ nameNode: request.nameNode,
2735
+ sf,
2736
+ };
2737
+ }
2738
+ }
2739
+ for (const stmt of sf.statements) {
2740
+ if (!ts.isExportDeclaration(stmt) || stmt.isTypeOnly)
2741
+ continue;
2742
+ const moduleSpecifier = stmt.moduleSpecifier;
2743
+ const exportClause = stmt.exportClause;
2744
+ if (moduleSpecifier === undefined || exportClause === undefined)
2745
+ continue;
2746
+ if (!ts.isStringLiteral(moduleSpecifier) || !ts.isNamedExports(exportClause))
2747
+ continue;
2748
+ const spec = moduleSpecifier.text;
2749
+ const dep = resolveEdge(sf, spec);
2750
+ if (dep === null || dep.fileName.endsWith(".json") || !isNodeEsmFile7(dep))
2751
+ continue;
2752
+ for (const element of exportClause.elements) {
2753
+ if (element.isTypeOnly)
2754
+ continue;
2755
+ const nameNode = element.propertyName ?? element.name;
2756
+ if (runtimeExport(dep, nameNode.text) === undefined) {
2757
+ return { exportName: nameNode.text, spec, nameNode, sf };
2758
+ }
2759
+ }
2760
+ }
2761
+ return null;
2762
+ };
2763
+ // The ESM instantiate graph is the same depth-first graph used by the CJS
2764
+ // linker: dependencies are linked before the importing module, and a
2765
+ // CommonJS/JSON target is a leaf for this native-export check.
2766
+ const visited = new Set();
2767
+ const dfs = (sf) => {
2768
+ if (visited.has(sf))
2769
+ return null;
2770
+ visited.add(sf);
2771
+ for (const stmt of sf.statements) {
2772
+ if (!ts.isImportDeclaration(stmt) && !(ts.isExportDeclaration(stmt) && !stmt.isTypeOnly))
2773
+ continue;
2774
+ if (ts.isImportDeclaration(stmt) && stmt.importClause?.phaseModifier === ts.SyntaxKind.TypeKeyword)
2775
+ continue;
2776
+ const moduleSpecifier = stmt.moduleSpecifier;
2777
+ if (moduleSpecifier === undefined || !ts.isStringLiteral(moduleSpecifier))
2778
+ continue;
2779
+ const dep = resolveEdge(sf, moduleSpecifier.text);
2780
+ if (dep === null || dep.fileName.endsWith(".json") || !isNodeEsmFile7(dep))
2781
+ continue;
2782
+ const bad = dfs(dep);
2783
+ if (bad !== null)
2784
+ return bad;
2785
+ }
2786
+ return firstMissingOf(sf);
2787
+ };
2788
+ // Native ESM linking itself starts only from an ESM entry. The caller
2789
+ // supplies dynamic-only roots here too; each such root gets its own
2790
+ // promise rejection rather than a startup crash.
2791
+ const bad = isNodeEsmFile7(entry) ? dfs(entry) : null;
2792
+ if (bad !== null) {
2793
+ return {
2794
+ crash: {
2795
+ message: `The requested module '${bad.spec}' does not provide an export named '${bad.exportName}'`,
2796
+ className: "%SyntaxError",
2797
+ loc: locOf7(bad.nameNode),
2798
+ },
2799
+ visited,
2800
+ firstMissingOf,
2801
+ };
2802
+ }
2803
+ return { crash: null, visited, firstMissingOf };
2804
+ }
2805
+ export function esmNamedImportLinkCrash(program, entry) {
2806
+ return analyzeEsmNamedImportLinks(program, entry).crash;
2807
+ }
2808
+ function esmNamedImportLinkCheck(program, entry, moduleOrder, diags) {
2809
+ const analysis = analyzeEsmNamedImportLinks(program, entry);
2810
+ if (analysis.crash !== null)
2811
+ return analysis.crash;
2812
+ // A CommonJS entry can synchronously require an ESM graph. Node links that
2813
+ // graph at the require site, after the CommonJS module has already begun
2814
+ // evaluating, so this cannot use startupCrash (which would move the error
2815
+ // before earlier output). Keep the compile-time fence used by the CJS link
2816
+ // checker for the analogous mid-evaluation failure instead.
2817
+ for (const sf of moduleOrder) {
2818
+ if (!isNodeEsmFile7(sf) || analysis.visited.has(sf))
2819
+ continue;
2820
+ const childFailure = analysis.firstMissingOf(sf);
2821
+ if (childFailure !== null) {
2822
+ diags.push(unsupportedDiag("SC1013", locOf7(childFailure.nameNode), "a named import of an unavailable export in an ES module reached through require() (Node throws its SyntaxError mid-evaluation at that require; make the import match the module's runtime exports)"));
2823
+ }
2824
+ }
2825
+ return null;
2826
+ }
2827
+ /** Both named-export link checks run independently because their export
2828
+ * questions are different (Node's CJS lexer versus TypeScript's value
2829
+ * symbols). Their first failures still share one Node instantiate order: the
2830
+ * module postorder established by preflight, then regular named imports by
2831
+ * local binding name, then source-order re-exports. Pick the earlier result
2832
+ * so a native ESM failure in a child cannot be hidden by a CJS failure in a
2833
+ * later parent. */
2834
+ function earlierLinkCrash(moduleOrder, first, second) {
2835
+ if (first === null)
2836
+ return second;
2837
+ if (second === null)
2838
+ return first;
2839
+ const moduleIndex = new Map(moduleOrder.map((sf, index) => [sf.fileName, index]));
2840
+ const firstIndex = moduleIndex.get(first.loc.file) ?? Number.MAX_SAFE_INTEGER;
2841
+ const secondIndex = moduleIndex.get(second.loc.file) ?? Number.MAX_SAFE_INTEGER;
2842
+ if (firstIndex !== secondIndex)
2843
+ return firstIndex < secondIndex ? first : second;
2844
+ if (first.loc.start !== second.loc.start) {
2845
+ const sf = moduleOrder[firstIndex];
2846
+ if (sf === undefined)
2847
+ return first.loc.start < second.loc.start ? first : second;
2848
+ const rank = (crash) => {
2849
+ const entries = [];
2850
+ for (const stmt of sf.statements) {
2851
+ if (ts.isImportDeclaration(stmt) && ts.isStringLiteral(stmt.moduleSpecifier)) {
2852
+ const clause = stmt.importClause;
2853
+ if (clause?.phaseModifier === ts.SyntaxKind.TypeKeyword)
2854
+ continue;
2855
+ if (clause?.namedBindings && ts.isNamedImports(clause.namedBindings)) {
2856
+ for (const element of clause.namedBindings.elements) {
2857
+ if (!element.isTypeOnly) {
2858
+ entries.push({
2859
+ local: element.name.text,
2860
+ start: (element.propertyName ?? element.name).getStart(sf),
2861
+ kind: 0,
2862
+ });
2863
+ }
2864
+ }
2865
+ }
2866
+ }
2867
+ }
2868
+ entries.sort((a, b) => (a.local < b.local ? -1 : a.local > b.local ? 1 : 0));
2869
+ const direct = entries.findIndex((entry) => entry.start === crash.loc.start);
2870
+ if (direct >= 0)
2871
+ return [0, direct];
2872
+ let reexport = 0;
2873
+ for (const stmt of sf.statements) {
2874
+ const exportClause = ts.isExportDeclaration(stmt) ? stmt.exportClause : undefined;
2875
+ if (!ts.isExportDeclaration(stmt) || stmt.isTypeOnly || exportClause === undefined || !ts.isNamedExports(exportClause))
2876
+ continue;
2877
+ for (const element of exportClause.elements) {
2878
+ if (!element.isTypeOnly && (element.propertyName ?? element.name).getStart(sf) === crash.loc.start) {
2879
+ return [1, reexport];
2880
+ }
2881
+ if (!element.isTypeOnly)
2882
+ reexport++;
2883
+ }
2884
+ }
2885
+ return [2, crash.loc.start];
2886
+ };
2887
+ const firstRank = rank(first);
2888
+ const secondRank = rank(second);
2889
+ if (firstRank[0] !== secondRank[0])
2890
+ return firstRank[0] < secondRank[0] ? first : second;
2891
+ return firstRank[1] <= secondRank[1] ? first : second;
2892
+ }
2893
+ return first;
2894
+ }
2450
2895
  /* node's builtin-module name list, for the SC1010 wording decision ("the
2451
2896
  * 'fs' module" vs the generic package message) — shared verbatim with the
2452
2897
  * retired 5.9.3 lane's builtinModules use. */
@@ -2521,16 +2966,11 @@ export function orderedImportsOf(program, sf) {
2521
2966
  if (!stmt.moduleSpecifier || !ts.isStringLiteral(stmt.moduleSpecifier))
2522
2967
  continue;
2523
2968
  const spec = stmt.moduleSpecifier.text;
2524
- const isRelative = isRelativeSpecifier(spec);
2525
- // Relative edges as ever; PROJECT imports (#alias/self-name — the
2526
- // package.json-mediated specifiers preflight admits as user-module
2527
- // edges) resolve to the same dep so the importer's %init header calls
2528
- // theirs. Builtin and npm bare specifiers stay null (resolveProjectImport
2529
- // answers only inside the project) — EXCEPT opted-in --npm-static
2969
+ // Every project edge (relative, tsconfig alias, #alias, or self-name)
2970
+ // resolves to the same dep so the importer's %init header calls theirs.
2971
+ // Builtin and npm bare specifiers stay null — EXCEPT opted-in --npm-static
2530
2972
  // packages, whose entries are program modules the header must init.
2531
- const dep = isRelative
2532
- ? resolveImport7(program, sf, spec)
2533
- : (npmStaticDepSf7(program, sf, spec) ?? resolveProjectImportSf7(program, sf, spec));
2973
+ const dep = resolveImport7(program, sf, spec) ?? npmStaticDepSf7(program, sf, spec);
2534
2974
  const isJson = dep !== null && dep.fileName.endsWith(".json");
2535
2975
  out.push({ stmt, dep: isJson ? null : dep });
2536
2976
  }
@@ -2553,19 +2993,6 @@ export function npmStaticDepSf7(program, sf, spec) {
2553
2993
  return null;
2554
2994
  return program.getSourceFile(npm.typesFile) ?? null;
2555
2995
  }
2556
- /** resolveProjectImport lifted to SourceFile answers: the program's file
2557
- * for a `#alias`/self-name resolution, or null (unresolved, or resolved
2558
- * outside the program — declaration files included; callers that admit
2559
- * d.ts answers probe resolveProjectImport directly). */
2560
- function resolveProjectImportSf7(program, sf, spec) {
2561
- if (spec.startsWith("node:"))
2562
- return null;
2563
- const p = resolveProjectImport(sf.fileName, spec);
2564
- if (p === null)
2565
- return null;
2566
- const dep = program.getSourceFile(p) ?? null;
2567
- return dep !== null && !dep.isDeclarationFile ? dep : null;
2568
- }
2569
2996
  /** True when `expr` is the `module.exports` property access. */
2570
2997
  export function isModuleExportsAccess(expr) {
2571
2998
  return (ts.isPropertyAccessExpression(expr) &&