Skip to content

Commit 47b5e98

Browse files
committed
Fix auto discovery of entry points
Resolves #2988
1 parent 73f3dc2 commit 47b5e98

File tree

6 files changed

+100
-77
lines changed

6 files changed

+100
-77
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ title: Changelog
44

55
## Unreleased
66

7+
### Features
8+
9+
- Add support for TypeScript 5.9, #2989.
10+
11+
### Bug Fixes
12+
13+
- Fixed automatic discovery of entry points when not running in packages mode, #2988.
14+
715
## v0.28.8 (2025-07-28)
816

917
### Features

src/lib/application.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ import { Outputs } from "./output/output.js";
4343
import { validateMergeModuleWith } from "./validation/unusedMergeModuleWith.js";
4444
import { diagnostic, diagnostics } from "./utils/loggers.js";
4545
import { ValidatingFileRegistry } from "./utils/ValidatingFileRegistry.js";
46-
import { addInferredDeclarationMapPaths } from "./converter/factories/symbol-id.js";
4746
import { Internationalization } from "./internationalization/internationalization.js";
4847

4948
const packageInfo = JSON.parse(
@@ -822,11 +821,6 @@ export class Application extends AbstractComponent<
822821
continue;
823822
}
824823

825-
addInferredDeclarationMapPaths(
826-
opts.getCompilerOptions(),
827-
opts.getFileNames(),
828-
);
829-
830824
projectsToConvert.push({ dir, options: opts });
831825
}
832826

Lines changed: 3 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
import { ReflectionSymbolId } from "#models";
2-
import { findPackageForPath, getCommonDirectory, getQualifiedName, normalizePath, readFile } from "#node-utils";
3-
import { type NormalizedPath, Validation } from "#utils";
4-
import { existsSync } from "fs";
5-
import { join, relative, resolve } from "node:path";
2+
import { findPackageForPath, getQualifiedName, normalizePath, resolveDeclarationMaps } from "#node-utils";
3+
import { type NormalizedPath } from "#utils";
4+
import { relative } from "node:path";
65
import ts from "typescript";
76

8-
const declarationMapCache = new Map<string, string>();
9-
107
let transientCount = 0;
118
const transientIds = new WeakMap<ts.Symbol, number>();
129

@@ -51,66 +48,3 @@ export function createSymbolIdImpl(symbol: ts.Symbol, declaration?: ts.Declarati
5148

5249
return id;
5350
}
54-
55-
function resolveDeclarationMaps(file: string): string {
56-
if (!/\.d\.[cm]?ts$/.test(file)) return file;
57-
if (declarationMapCache.has(file)) return declarationMapCache.get(file)!;
58-
59-
const mapFile = file + ".map";
60-
if (!existsSync(mapFile)) return file;
61-
62-
let sourceMap: unknown;
63-
try {
64-
sourceMap = JSON.parse(readFile(mapFile)) as unknown;
65-
} catch {
66-
return file;
67-
}
68-
69-
if (
70-
Validation.validate(
71-
{
72-
file: String,
73-
sourceRoot: Validation.optional(String),
74-
sources: [Array, String],
75-
},
76-
sourceMap,
77-
)
78-
) {
79-
// There's a pretty large assumption in here that we only have
80-
// 1 source file per js file. This is a pretty standard typescript approach,
81-
// but people might do interesting things with transpilation that could break this.
82-
let source = sourceMap.sources[0];
83-
84-
// If we have a sourceRoot, trim any leading slash from the source, and join them
85-
// Similar to how it's done at https://github.com/mozilla/source-map/blob/58819f09018d56ef84dc41ba9c93f554e0645169/lib/util.js#L412
86-
if (sourceMap.sourceRoot !== undefined) {
87-
source = source.replace(/^\//, "");
88-
source = join(sourceMap.sourceRoot, source);
89-
}
90-
91-
const result = resolve(mapFile, "..", source);
92-
declarationMapCache.set(file, result);
93-
return result;
94-
}
95-
96-
return file;
97-
}
98-
99-
// See also: inferEntryPoints in entry-point.ts
100-
export function addInferredDeclarationMapPaths(
101-
opts: ts.CompilerOptions,
102-
files: readonly string[],
103-
) {
104-
const rootDir = opts.rootDir || getCommonDirectory(files);
105-
const declDir = opts.declarationDir || opts.outDir || rootDir;
106-
107-
for (const file of files) {
108-
const mapFile = normalizePath(
109-
resolve(declDir, relative(rootDir, file)).replace(
110-
/\.([cm]?[tj]s)x?$/,
111-
".d.$1",
112-
),
113-
);
114-
declarationMapCache.set(mapFile, file);
115-
}
116-
}

src/lib/utils/declaration-maps.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import type ts from "typescript";
2+
import { existsSync } from "fs";
3+
import { readFile } from "./fs.js";
4+
import { Validation } from "#utils";
5+
import { join, relative, resolve } from "path";
6+
import { getCommonDirectory, normalizePath } from "./paths.js";
7+
8+
const declarationMapCache = new Map<string, string>();
9+
10+
export function resolveDeclarationMaps(file: string): string {
11+
if (!/\.d\.[cm]?ts$/.test(file)) return file;
12+
if (declarationMapCache.has(file)) return declarationMapCache.get(file)!;
13+
14+
const mapFile = file + ".map";
15+
if (!existsSync(mapFile)) return file;
16+
17+
let sourceMap: unknown;
18+
try {
19+
sourceMap = JSON.parse(readFile(mapFile)) as unknown;
20+
} catch {
21+
return file;
22+
}
23+
24+
if (
25+
Validation.validate(
26+
{
27+
file: String,
28+
sourceRoot: Validation.optional(String),
29+
sources: [Array, String],
30+
},
31+
sourceMap,
32+
)
33+
) {
34+
// There's a pretty large assumption in here that we only have
35+
// 1 source file per js file. This is a pretty standard typescript approach,
36+
// but people might do interesting things with transpilation that could break this.
37+
let source = sourceMap.sources[0];
38+
39+
// If we have a sourceRoot, trim any leading slash from the source, and join them
40+
// Similar to how it's done at https://github.com/mozilla/source-map/blob/58819f09018d56ef84dc41ba9c93f554e0645169/lib/util.js#L412
41+
if (sourceMap.sourceRoot !== undefined) {
42+
source = source.replace(/^\//, "");
43+
source = join(sourceMap.sourceRoot, source);
44+
}
45+
46+
const result = resolve(mapFile, "..", source);
47+
declarationMapCache.set(file, result);
48+
return result;
49+
}
50+
51+
return file;
52+
}
53+
54+
// See also: inferEntryPoints in entry-point.ts
55+
export function addInferredDeclarationMapPaths(
56+
opts: ts.CompilerOptions,
57+
files: readonly string[],
58+
) {
59+
const rootDir = opts.rootDir || getCommonDirectory(files);
60+
const declDir = opts.declarationDir || opts.outDir || rootDir;
61+
62+
for (const file of files) {
63+
const mapFile = normalizePath(
64+
resolve(declDir, relative(rootDir, file)).replace(
65+
/\.([cm]?[tj]s)x?$/,
66+
".d.$1",
67+
),
68+
);
69+
declarationMapCache.set(mapFile, file);
70+
}
71+
}

src/lib/utils/entry-point.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { deriveRootDir, getCommonDirectory, MinimatchSet, nicePath, normalizePat
66
import type { Options } from "./options/index.js";
77
import { discoverPackageJson, glob, inferPackageEntryPointPaths, isDir } from "./fs.js";
88
import { assertNever, type GlobString, i18n, type Logger, type NormalizedPath } from "#utils";
9+
import { addInferredDeclarationMapPaths, resolveDeclarationMaps } from "./declaration-maps.js";
910

1011
/**
1112
* Defines how entry points are interpreted.
@@ -65,7 +66,7 @@ export function inferEntryPoints(logger: Logger, options: Options, programs?: ts
6566
options,
6667
);
6768

68-
// See also: addInferredDeclarationMapPaths in ReflectionSymbolId
69+
// See also: addInferredDeclarationMapPaths in symbol-id factory
6970
const jsToTsSource = new Map<string, string>();
7071
for (const program of programs) {
7172
const opts = program.getCompilerOptions();
@@ -86,7 +87,7 @@ export function inferEntryPoints(logger: Logger, options: Options, programs?: ts
8687
for (const [name, path] of pathEntries) {
8788
// Strip leading ./ from the display name
8889
const displayName = name.replace(/^\.\/?/, "");
89-
const targetPath = jsToTsSource.get(path) || path;
90+
const targetPath = jsToTsSource.get(path) || resolveDeclarationMaps(path) || path;
9091

9192
const program = programs.find((p) => p.getSourceFile(targetPath));
9293
if (program) {
@@ -107,6 +108,10 @@ export function inferEntryPoints(logger: Logger, options: Options, programs?: ts
107108
return [];
108109
}
109110

111+
logger.verbose(
112+
`Inferred entry points to be:\n\t${entryPoints.map(e => nicePath(e.sourceFile.fileName)).join("\n\t")}`,
113+
);
114+
110115
return entryPoints;
111116
}
112117

@@ -413,6 +418,11 @@ function getEntryPrograms(
413418
projectReferences: options.getProjectReferences(),
414419
});
415420

421+
addInferredDeclarationMapPaths(
422+
options.getCompilerOptions(),
423+
options.getFileNames(),
424+
);
425+
416426
const programs = [rootProgram];
417427
// This might be a solution style tsconfig, in which case we need to add a program for each
418428
// reference so that the converter can look through each of these.
@@ -433,6 +443,11 @@ function getEntryPrograms(
433443
projectReferences: ref.commandLine.projectReferences,
434444
}),
435445
);
446+
447+
addInferredDeclarationMapPaths(
448+
ref.commandLine.options,
449+
ref.commandLine.fileNames,
450+
);
436451
}
437452
}
438453

src/lib/utils/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export type { SortStrategy } from "./sort.js";
4444

4545
export * from "./entry-point.js";
4646

47+
export * from "./declaration-maps.js";
4748
export * from "./highlighter.js";
4849
export * from "./html.js";
4950
export * from "./tsconfig.js";

0 commit comments

Comments
 (0)