@openrewrite/rewrite 8.91.0 → 8.91.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.
- package/dist/java/formatting-utils.d.ts +8 -5
- package/dist/java/formatting-utils.d.ts.map +1 -1
- package/dist/java/formatting-utils.js +14 -10
- package/dist/java/formatting-utils.js.map +1 -1
- package/dist/java/type.d.ts +2 -0
- package/dist/java/type.d.ts.map +1 -1
- package/dist/java/type.js +5 -0
- package/dist/java/type.js.map +1 -1
- package/dist/javascript/add-import.d.ts +96 -43
- package/dist/javascript/add-import.d.ts.map +1 -1
- package/dist/javascript/add-import.js +668 -236
- package/dist/javascript/add-import.js.map +1 -1
- package/dist/javascript/amd.d.ts +138 -0
- package/dist/javascript/amd.d.ts.map +1 -0
- package/dist/javascript/amd.js +768 -0
- package/dist/javascript/amd.js.map +1 -0
- package/dist/javascript/assertions.d.ts +7 -0
- package/dist/javascript/assertions.d.ts.map +1 -1
- package/dist/javascript/assertions.js +31 -5
- package/dist/javascript/assertions.js.map +1 -1
- package/dist/javascript/binding.d.ts +94 -0
- package/dist/javascript/binding.d.ts.map +1 -0
- package/dist/javascript/binding.js +335 -0
- package/dist/javascript/binding.js.map +1 -0
- package/dist/javascript/comparator.d.ts +5 -0
- package/dist/javascript/comparator.d.ts.map +1 -1
- package/dist/javascript/comparator.js +34 -9
- package/dist/javascript/comparator.js.map +1 -1
- package/dist/javascript/format/format.d.ts.map +1 -1
- package/dist/javascript/format/format.js +8 -9
- package/dist/javascript/format/format.js.map +1 -1
- package/dist/javascript/format/tabs-and-indents-visitor.d.ts +2 -0
- package/dist/javascript/format/tabs-and-indents-visitor.d.ts.map +1 -1
- package/dist/javascript/format/tabs-and-indents-visitor.js +17 -11
- package/dist/javascript/format/tabs-and-indents-visitor.js.map +1 -1
- package/dist/javascript/index.d.ts +8 -1
- package/dist/javascript/index.d.ts.map +1 -1
- package/dist/javascript/index.js +26 -1
- package/dist/javascript/index.js.map +1 -1
- package/dist/javascript/node-resolution-result.d.ts +19 -1
- package/dist/javascript/node-resolution-result.d.ts.map +1 -1
- package/dist/javascript/node-resolution-result.js +37 -2
- package/dist/javascript/node-resolution-result.js.map +1 -1
- package/dist/javascript/package-exported-types.d.ts.map +1 -1
- package/dist/javascript/package-exported-types.js +56 -72
- package/dist/javascript/package-exported-types.js.map +1 -1
- package/dist/javascript/parser-utils.d.ts.map +1 -1
- package/dist/javascript/parser-utils.js +2 -0
- package/dist/javascript/parser-utils.js.map +1 -1
- package/dist/javascript/parser.d.ts +7 -1
- package/dist/javascript/parser.d.ts.map +1 -1
- package/dist/javascript/parser.js +17 -4
- package/dist/javascript/parser.js.map +1 -1
- package/dist/javascript/recipes/change-import.d.ts +2 -4
- package/dist/javascript/recipes/change-import.d.ts.map +1 -1
- package/dist/javascript/recipes/change-import.js +8 -244
- package/dist/javascript/recipes/change-import.js.map +1 -1
- package/dist/javascript/remove-import.d.ts +2 -28
- package/dist/javascript/remove-import.d.ts.map +1 -1
- package/dist/javascript/remove-import.js +19 -57
- package/dist/javascript/remove-import.js.map +1 -1
- package/dist/javascript/scope.d.ts +49 -0
- package/dist/javascript/scope.d.ts.map +1 -0
- package/dist/javascript/scope.js +324 -0
- package/dist/javascript/scope.js.map +1 -0
- package/dist/javascript/style.d.ts.map +1 -1
- package/dist/javascript/style.js +3 -10
- package/dist/javascript/style.js.map +1 -1
- package/dist/javascript/templating/bindings.d.ts +8 -0
- package/dist/javascript/templating/bindings.d.ts.map +1 -0
- package/dist/javascript/templating/bindings.js +92 -0
- package/dist/javascript/templating/bindings.js.map +1 -0
- package/dist/javascript/templating/comparator.d.ts +10 -0
- package/dist/javascript/templating/comparator.d.ts.map +1 -1
- package/dist/javascript/templating/comparator.js +48 -20
- package/dist/javascript/templating/comparator.js.map +1 -1
- package/dist/javascript/templating/engine.d.ts +34 -10
- package/dist/javascript/templating/engine.d.ts.map +1 -1
- package/dist/javascript/templating/engine.js +109 -55
- package/dist/javascript/templating/engine.js.map +1 -1
- package/dist/javascript/templating/index.d.ts +1 -1
- package/dist/javascript/templating/index.d.ts.map +1 -1
- package/dist/javascript/templating/index.js.map +1 -1
- package/dist/javascript/templating/pattern.d.ts.map +1 -1
- package/dist/javascript/templating/pattern.js +13 -10
- package/dist/javascript/templating/pattern.js.map +1 -1
- package/dist/javascript/templating/placeholder-replacement.d.ts +4 -0
- package/dist/javascript/templating/placeholder-replacement.d.ts.map +1 -1
- package/dist/javascript/templating/placeholder-replacement.js +24 -10
- package/dist/javascript/templating/placeholder-replacement.js.map +1 -1
- package/dist/javascript/templating/precedence.d.ts +12 -4
- package/dist/javascript/templating/precedence.d.ts.map +1 -1
- package/dist/javascript/templating/precedence.js +18 -11
- package/dist/javascript/templating/precedence.js.map +1 -1
- package/dist/javascript/templating/rewrite.d.ts.map +1 -1
- package/dist/javascript/templating/rewrite.js +19 -17
- package/dist/javascript/templating/rewrite.js.map +1 -1
- package/dist/javascript/templating/template.d.ts +14 -0
- package/dist/javascript/templating/template.d.ts.map +1 -1
- package/dist/javascript/templating/template.js +63 -3
- package/dist/javascript/templating/template.js.map +1 -1
- package/dist/javascript/templating/types.d.ts +39 -1
- package/dist/javascript/templating/types.d.ts.map +1 -1
- package/dist/javascript/templating/utils.d.ts +6 -1
- package/dist/javascript/templating/utils.d.ts.map +1 -1
- package/dist/javascript/templating/utils.js +20 -2
- package/dist/javascript/templating/utils.js.map +1 -1
- package/dist/javascript/type-mapping.d.ts +1 -0
- package/dist/javascript/type-mapping.d.ts.map +1 -1
- package/dist/javascript/type-mapping.js +52 -2
- package/dist/javascript/type-mapping.js.map +1 -1
- package/dist/rewrite-javascript-version.txt +1 -1
- package/dist/style.d.ts +2 -0
- package/dist/style.d.ts.map +1 -1
- package/dist/style.js +5 -0
- package/dist/style.js.map +1 -1
- package/dist/test/rewrite-test.d.ts +12 -0
- package/dist/test/rewrite-test.d.ts.map +1 -1
- package/dist/test/rewrite-test.js +40 -3
- package/dist/test/rewrite-test.js.map +1 -1
- package/package.json +2 -2
- package/src/java/formatting-utils.ts +14 -10
- package/src/java/type.ts +5 -0
- package/src/javascript/add-import.ts +751 -247
- package/src/javascript/amd.ts +915 -0
- package/src/javascript/assertions.ts +33 -5
- package/src/javascript/binding.ts +449 -0
- package/src/javascript/comparator.ts +39 -10
- package/src/javascript/format/format.ts +9 -10
- package/src/javascript/format/tabs-and-indents-visitor.ts +18 -12
- package/src/javascript/index.ts +12 -1
- package/src/javascript/node-resolution-result.ts +59 -4
- package/src/javascript/package-exported-types.ts +60 -74
- package/src/javascript/parser-utils.ts +2 -0
- package/src/javascript/parser.ts +23 -3
- package/src/javascript/recipes/change-import.ts +10 -263
- package/src/javascript/remove-import.ts +20 -56
- package/src/javascript/scope.ts +338 -0
- package/src/javascript/style.ts +3 -11
- package/src/javascript/templating/bindings.ts +99 -0
- package/src/javascript/templating/comparator.ts +57 -20
- package/src/javascript/templating/engine.ts +148 -68
- package/src/javascript/templating/index.ts +1 -0
- package/src/javascript/templating/pattern.ts +19 -16
- package/src/javascript/templating/placeholder-replacement.ts +32 -11
- package/src/javascript/templating/precedence.ts +21 -13
- package/src/javascript/templating/rewrite.ts +23 -17
- package/src/javascript/templating/template.ts +84 -9
- package/src/javascript/templating/types.ts +46 -1
- package/src/javascript/templating/utils.ts +21 -2
- package/src/javascript/type-mapping.ts +54 -2
- package/src/style.ts +5 -0
- package/src/test/rewrite-test.ts +61 -3
|
@@ -22,7 +22,6 @@ import {
|
|
|
22
22
|
lastWhitespace,
|
|
23
23
|
normalizeSpaceIndent,
|
|
24
24
|
replaceIndentAfterLastNewline,
|
|
25
|
-
replaceLastWhitespace,
|
|
26
25
|
spaceContainsNewline,
|
|
27
26
|
stripLeadingIndent
|
|
28
27
|
} from "../../java";
|
|
@@ -45,6 +44,11 @@ export class TabsAndIndentsVisitor<P> extends JavaScriptVisitor<P> {
|
|
|
45
44
|
this.useTabCharacter = this.tabsAndIndentsStyle.useTabCharacter;
|
|
46
45
|
}
|
|
47
46
|
|
|
47
|
+
/** Width of existing indent whitespace in the unit {@link indentString} takes, where a tab is one indent. */
|
|
48
|
+
private indentWidth(indent: string): number {
|
|
49
|
+
return [...indent].reduce((width, ch) => width + (ch === "\t" ? this.indentSize : 1), 0);
|
|
50
|
+
}
|
|
51
|
+
|
|
48
52
|
private indentString(indent: number): string {
|
|
49
53
|
if (this.useTabCharacter) {
|
|
50
54
|
return "\t".repeat(Math.floor(indent / this.indentSize));
|
|
@@ -395,12 +399,12 @@ export class TabsAndIndentsVisitor<P> extends JavaScriptVisitor<P> {
|
|
|
395
399
|
}
|
|
396
400
|
|
|
397
401
|
private normalizeBlockEnd(block: J.Block, myIndent: number): J.Block {
|
|
398
|
-
|
|
399
|
-
if (!effectiveLastWs.includes("\n")) {
|
|
402
|
+
if (!spaceContainsNewline(block.end)) {
|
|
400
403
|
return block;
|
|
401
404
|
}
|
|
402
|
-
|
|
403
|
-
|
|
405
|
+
const end = normalizeSpaceIndent(block.end, this.indentString(myIndent), this.indentString(myIndent + this.indentSize));
|
|
406
|
+
return end === block.end ? block : produce(block, draft => {
|
|
407
|
+
draft.end = end;
|
|
404
408
|
});
|
|
405
409
|
}
|
|
406
410
|
|
|
@@ -440,12 +444,14 @@ export class TabsAndIndentsVisitor<P> extends JavaScriptVisitor<P> {
|
|
|
440
444
|
// Normalize the last element's after whitespace (closing delimiter like `)`)
|
|
441
445
|
// The closing delimiter should align with the parent's indent level
|
|
442
446
|
if (container.elements.length > 0) {
|
|
443
|
-
const
|
|
444
|
-
if (
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
447
|
+
const last = container.elements[container.elements.length - 1];
|
|
448
|
+
if (spaceContainsNewline(last.after)) {
|
|
449
|
+
const after = normalizeSpaceIndent(last.after, this.indentString(parentIndent), this.indentString(parentIndent + this.indentSize));
|
|
450
|
+
if (after !== last.after) {
|
|
451
|
+
return produce(container, draft => {
|
|
452
|
+
draft.elements[draft.elements.length - 1].after = after;
|
|
453
|
+
});
|
|
454
|
+
}
|
|
449
455
|
}
|
|
450
456
|
}
|
|
451
457
|
|
|
@@ -646,7 +652,7 @@ export class TabsAndIndentsVisitor<P> extends JavaScriptVisitor<P> {
|
|
|
646
652
|
const idx = ws.lastIndexOf('\n');
|
|
647
653
|
if (idx !== -1) {
|
|
648
654
|
anchorCursor = c;
|
|
649
|
-
anchorIndent = ws.
|
|
655
|
+
anchorIndent = this.indentWidth(ws.substring(idx + 1));
|
|
650
656
|
}
|
|
651
657
|
}
|
|
652
658
|
|
package/src/javascript/index.ts
CHANGED
|
@@ -31,7 +31,18 @@ export * from "./autodetect";
|
|
|
31
31
|
export * from "./tree-debug";
|
|
32
32
|
export * from "./project-parser";
|
|
33
33
|
|
|
34
|
-
export
|
|
34
|
+
export type {Scope} from "./scope";
|
|
35
|
+
export {scopeOf, namesDeclaredIn, bindingNames} from "./scope";
|
|
36
|
+
export type {QuoteChar, AddImportOptions} from "./add-import";
|
|
37
|
+
export {ImportStyle, moduleNameOf, AddImport} from "./add-import";
|
|
38
|
+
// AMD mechanics `recipes-ui5` builds on directly, beyond the `maybeBind` surface below.
|
|
39
|
+
export type {AmdBlock} from "./amd";
|
|
40
|
+
export {
|
|
41
|
+
DEFAULT_AMD_CALLEES, amdBlockOf, dependencyNames, parameterNames, withDependency, withoutDependencyAt,
|
|
42
|
+
RemoveAmdDependency, removeNewlyUnusedAmdBindings
|
|
43
|
+
} from "./amd";
|
|
44
|
+
export type {MaybeBindOptions, MaybeUnbindOptions, MaybeRebindOptions, ModuleBindings} from "./binding";
|
|
45
|
+
export {maybeBind, maybeUnbind, maybeRebind, moduleBindings, isAmdBlock, maybeRemoveImport, maybeAddImport} from "./binding";
|
|
35
46
|
export * from "./remove-import";
|
|
36
47
|
export * from "./cleanup/index";
|
|
37
48
|
export * from "./recipes/index";
|
|
@@ -60,13 +60,65 @@ export interface PackageLockEntry {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
/**
|
|
63
|
-
*
|
|
63
|
+
* Entry in a legacy npm lockfileVersion 1 `dependencies` tree (npm 5/6), with its
|
|
64
|
+
* requirements under `requires` and nested conflicting versions under `dependencies`.
|
|
65
|
+
*/
|
|
66
|
+
export interface LockfileV1Entry {
|
|
67
|
+
readonly version?: string;
|
|
68
|
+
readonly resolved?: string;
|
|
69
|
+
readonly integrity?: string;
|
|
70
|
+
readonly license?: string | string[] | { type?: string; url?: string };
|
|
71
|
+
readonly engines?: Record<string, string> | string[];
|
|
72
|
+
readonly requires?: Record<string, string>;
|
|
73
|
+
readonly dependencies?: Record<string, LockfileV1Entry>;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Parsed package-lock.json content structure. The `packages` map is the modern
|
|
78
|
+
* (lockfileVersion 2/3) shape; `dependencies` is the legacy lockfileVersion 1 tree.
|
|
64
79
|
*/
|
|
65
80
|
export interface PackageLockContent {
|
|
66
81
|
readonly name?: string;
|
|
67
82
|
readonly version?: string;
|
|
68
83
|
readonly lockfileVersion?: number;
|
|
69
84
|
readonly packages?: Record<string, PackageLockEntry>;
|
|
85
|
+
readonly dependencies?: Record<string, LockfileV1Entry>;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Converts a legacy npm lockfileVersion 1 `dependencies` tree into the modern
|
|
90
|
+
* `packages` map keyed by node_modules path, so the resolver can walk transitive
|
|
91
|
+
* dependencies the same way it does for lockfileVersion 2/3 files. Returns
|
|
92
|
+
* undefined when the tree is absent or empty.
|
|
93
|
+
*/
|
|
94
|
+
function convertV1DependencyTree(
|
|
95
|
+
tree: Record<string, LockfileV1Entry> | undefined
|
|
96
|
+
): Record<string, PackageLockEntry> | undefined {
|
|
97
|
+
if (!tree || Object.keys(tree).length === 0) {
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
100
|
+
const packages: Record<string, PackageLockEntry> = {};
|
|
101
|
+
|
|
102
|
+
function walk(deps: Record<string, LockfileV1Entry>, pathPrefix: string): void {
|
|
103
|
+
for (const [name, entry] of Object.entries(deps)) {
|
|
104
|
+
const pkgPath = `${pathPrefix}node_modules/${name}`;
|
|
105
|
+
packages[pkgPath] = {
|
|
106
|
+
version: entry.version,
|
|
107
|
+
resolved: entry.resolved,
|
|
108
|
+
integrity: entry.integrity,
|
|
109
|
+
license: entry.license,
|
|
110
|
+
engines: entry.engines,
|
|
111
|
+
// v1 folds all declared deps into `requires`; the resolver reads `dependencies`.
|
|
112
|
+
dependencies: entry.requires,
|
|
113
|
+
};
|
|
114
|
+
if (entry.dependencies) {
|
|
115
|
+
walk(entry.dependencies, `${pkgPath}/`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
walk(tree, "");
|
|
121
|
+
return packages;
|
|
70
122
|
}
|
|
71
123
|
|
|
72
124
|
/**
|
|
@@ -524,9 +576,12 @@ export function createNodeResolutionResultMarker(
|
|
|
524
576
|
function parseResolutions(
|
|
525
577
|
lockContent: PackageLockContent
|
|
526
578
|
): ResolvedDependency[] {
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
const packages = lockContent.packages
|
|
579
|
+
// Prefer the modern `packages` map; fall back to converting a legacy
|
|
580
|
+
// lockfileVersion 1 `dependencies` tree when no `packages` map is present.
|
|
581
|
+
const packages = lockContent.packages && Object.keys(lockContent.packages).length > 0
|
|
582
|
+
? lockContent.packages
|
|
583
|
+
: convertV1DependencyTree(lockContent.dependencies);
|
|
584
|
+
if (!packages) return [];
|
|
530
585
|
|
|
531
586
|
// First pass: Create all ResolvedDependency placeholders and build path map
|
|
532
587
|
const packageInfos: Array<{ path: string; name: string; version: string; entry: PackageLockEntry }> = [];
|
|
@@ -18,6 +18,8 @@ import * as path from "path";
|
|
|
18
18
|
import {Type} from "../java";
|
|
19
19
|
import {JavaScriptTypeMapping} from "./type-mapping";
|
|
20
20
|
|
|
21
|
+
const TYPESCRIPT_FILE = /\.[cm]?tsx?$/;
|
|
22
|
+
|
|
21
23
|
// Free functions are not exported-type entries; only nominal types (and value modules, which are
|
|
22
24
|
// descended into for nested types) qualify.
|
|
23
25
|
const TYPE_SYMBOL_FLAGS =
|
|
@@ -38,21 +40,13 @@ const TYPE_SYMBOL_FLAGS =
|
|
|
38
40
|
* @param references node_modules roots / sibling packages used only for symbol resolution
|
|
39
41
|
*/
|
|
40
42
|
export function exportedTypes(ownArtifacts: string[], references: string[]): Type.FullyQualified[] {
|
|
41
|
-
const entries: string[] = [];
|
|
42
|
-
for (const artifact of ownArtifacts) {
|
|
43
|
-
const entry = declarationFileEntry(artifact) ?? resolvePackageEntry(artifact);
|
|
44
|
-
if (entry) {
|
|
45
|
-
entries.push(path.normalize(entry));
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
if (entries.length === 0) {
|
|
49
|
-
return [];
|
|
50
|
-
}
|
|
51
|
-
|
|
52
43
|
const compilerOptions: ts.CompilerOptions = {
|
|
53
44
|
target: ts.ScriptTarget.Latest,
|
|
54
|
-
module
|
|
55
|
-
|
|
45
|
+
// Mirrors JavaScriptParser's module resolution, so a dependency's own imports resolve here
|
|
46
|
+
// as they do when its consumers are parsed; the rationale for each option lives there.
|
|
47
|
+
module: ts.ModuleKind.Preserve,
|
|
48
|
+
moduleResolution: ts.ModuleResolutionKind.Bundler,
|
|
49
|
+
customConditions: ["node"],
|
|
56
50
|
noEmit: true,
|
|
57
51
|
allowJs: true,
|
|
58
52
|
checkJs: false,
|
|
@@ -80,6 +74,17 @@ export function exportedTypes(ownArtifacts: string[], references: string[]): Typ
|
|
|
80
74
|
return resolved;
|
|
81
75
|
});
|
|
82
76
|
|
|
77
|
+
const entries: string[] = [];
|
|
78
|
+
for (const artifact of ownArtifacts) {
|
|
79
|
+
const entry = declarationFileEntry(artifact) ?? resolvePackageEntry(artifact, compilerOptions, host);
|
|
80
|
+
if (entry) {
|
|
81
|
+
entries.push(path.normalize(entry));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (entries.length === 0) {
|
|
85
|
+
return [];
|
|
86
|
+
}
|
|
87
|
+
|
|
83
88
|
const program = ts.createProgram(entries, compilerOptions, host);
|
|
84
89
|
const checker = program.getTypeChecker();
|
|
85
90
|
const typeMapping = new JavaScriptTypeMapping(checker);
|
|
@@ -156,7 +161,7 @@ function arity(cls: Type.Class): number {
|
|
|
156
161
|
|
|
157
162
|
/** A TypeScript declaration/source FILE (e.g. a `lib.*.d.ts` of ambient globals), used directly as a program entry. */
|
|
158
163
|
function declarationFileEntry(artifact: string): string | undefined {
|
|
159
|
-
return ts.sys.fileExists(artifact) &&
|
|
164
|
+
return ts.sys.fileExists(artifact) && TYPESCRIPT_FILE.test(artifact) ? artifact : undefined;
|
|
160
165
|
}
|
|
161
166
|
|
|
162
167
|
/** Top-level ambient type declarations of a script (non-module) file — a `lib.*.d.ts`'s globals; namespaces descended for nested types. */
|
|
@@ -186,30 +191,34 @@ function globalTypeSymbols(checker: ts.TypeChecker, sourceFile: ts.SourceFile):
|
|
|
186
191
|
}
|
|
187
192
|
|
|
188
193
|
/**
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
* else a top-level `index.d.ts` (then `index.ts`).
|
|
194
|
+
* A package directory's declaration entry, found by resolving the package's own name from inside
|
|
195
|
+
* it so `types`, `exports` conditions and `typesVersions` all apply; else the declared `types`
|
|
196
|
+
* file; else a top-level `index.d.ts` (then `index.ts`). Reaching none of them means the package
|
|
197
|
+
* ships no types, which leaves the caller to fall back to its DefinitelyTyped package.
|
|
192
198
|
*/
|
|
193
|
-
function resolvePackageEntry(dir: string): string | undefined {
|
|
194
|
-
const
|
|
195
|
-
if (
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
:
|
|
202
|
-
if (
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
199
|
+
function resolvePackageEntry(dir: string, options: ts.CompilerOptions, host: ts.ModuleResolutionHost): string | undefined {
|
|
200
|
+
const manifest = packageManifest(dir);
|
|
201
|
+
if (typeof manifest?.name === "string") {
|
|
202
|
+
const conditions = options.customConditions ?? [];
|
|
203
|
+
// A package's declarations count under whichever condition carries them, since no
|
|
204
|
+
// consumer's import mode is choosing between `import` and `require` here.
|
|
205
|
+
for (const attempt of [conditions, [...conditions, "require"]]) {
|
|
206
|
+
const resolved = ts.resolveModuleName(manifest.name, path.join(dir, "__entry__.ts"),
|
|
207
|
+
{...options, customConditions: attempt}, host).resolvedModule?.resolvedFileName;
|
|
208
|
+
if (resolved && TYPESCRIPT_FILE.test(resolved) && containedIn(dir, resolved)) {
|
|
209
|
+
return resolved;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
// An `exports` map without a `types` condition takes resolution to the runtime entry and stops
|
|
214
|
+
// it there, while `types` still names the declarations.
|
|
215
|
+
const declared = manifest?.types ?? manifest?.typings;
|
|
216
|
+
if (typeof declared === "string") {
|
|
217
|
+
const resolved = path.resolve(dir, declared);
|
|
218
|
+
for (const candidate of [resolved, resolved + ".d.ts"]) {
|
|
219
|
+
if (ts.sys.fileExists(candidate)) {
|
|
220
|
+
return candidate;
|
|
210
221
|
}
|
|
211
|
-
} catch {
|
|
212
|
-
// Malformed package.json; fall through to conventional entry points.
|
|
213
222
|
}
|
|
214
223
|
}
|
|
215
224
|
for (const candidate of ["index.d.ts", "index.ts", "index.tsx"]) {
|
|
@@ -221,49 +230,26 @@ function resolvePackageEntry(dir: string): string | undefined {
|
|
|
221
230
|
return undefined;
|
|
222
231
|
}
|
|
223
232
|
|
|
224
|
-
/** The declaration file for the package's `.` subpath from its `exports` map, if any. */
|
|
225
|
-
function exportsTypesEntry(exports: unknown): string | undefined {
|
|
226
|
-
if (typeof exports === "string") {
|
|
227
|
-
return typesFromCondition(exports);
|
|
228
|
-
}
|
|
229
|
-
if (!exports || typeof exports !== "object") {
|
|
230
|
-
return undefined;
|
|
231
|
-
}
|
|
232
|
-
const map = exports as Record<string, unknown>;
|
|
233
|
-
// `exports["."]`, or the whole object when it is condition-only sugar (no subpath keys).
|
|
234
|
-
const dot = "." in map
|
|
235
|
-
? map["."]
|
|
236
|
-
: (Object.keys(map).some(k => k.startsWith(".")) ? undefined : map);
|
|
237
|
-
return dot === undefined ? undefined : typesFromCondition(dot);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
233
|
/**
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
*
|
|
234
|
+
* Whether `file` belongs to the package installed at `dir`. Resolution by name walks up the tree,
|
|
235
|
+
* so a same-named package elsewhere can answer — which an npm alias (`"a": "npm:b@1"`) installs by
|
|
236
|
+
* construction.
|
|
244
237
|
*/
|
|
245
|
-
function
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
238
|
+
function containedIn(dir: string, file: string): boolean {
|
|
239
|
+
return path.resolve(file).startsWith(path.resolve(dir) + path.sep);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function packageManifest(dir: string): {name?: unknown, types?: unknown, typings?: unknown} | undefined {
|
|
243
|
+
const packageJson = path.join(dir, "package.json");
|
|
244
|
+
if (!ts.sys.fileExists(packageJson)) {
|
|
250
245
|
return undefined;
|
|
251
246
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
if (nestedTypes) {
|
|
258
|
-
return nestedTypes;
|
|
259
|
-
}
|
|
260
|
-
for (const cond of ["import", "require", "default"]) {
|
|
261
|
-
const nested = typesFromCondition(o[cond]);
|
|
262
|
-
if (nested) {
|
|
263
|
-
return nested;
|
|
264
|
-
}
|
|
247
|
+
try {
|
|
248
|
+
return JSON.parse(ts.sys.readFile(packageJson) || "{}");
|
|
249
|
+
} catch {
|
|
250
|
+
// Malformed package.json; fall through to conventional entry points.
|
|
251
|
+
return undefined;
|
|
265
252
|
}
|
|
266
|
-
return undefined;
|
|
267
253
|
}
|
|
268
254
|
|
|
269
255
|
/**
|
|
@@ -394,6 +394,7 @@ const excludedCodes = new Set([
|
|
|
394
394
|
1183, // An implementation cannot be declared in ambient contexts.
|
|
395
395
|
1203, // Export assignment cannot be used when targeting ECMAScript modules. Consider using 'export default' or another module format instead.
|
|
396
396
|
1207, // Decorators cannot be applied to multiple get/set accessors of the same name.
|
|
397
|
+
1212, // Identifier expected. '{0}' is a reserved word in strict mode. The node is still parsed as an identifier.
|
|
397
398
|
1215, // Invalid use of '{0}'. Modules are automatically in strict mode.
|
|
398
399
|
1238, // Unable to resolve signature of class decorator when called as an expression.
|
|
399
400
|
1239, // Unable to resolve signature of parameter decorator when called as an expression.
|
|
@@ -422,6 +423,7 @@ const excludedCodes = new Set([
|
|
|
422
423
|
1375, // 'await' expressions are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module.
|
|
423
424
|
1378, // Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher.
|
|
424
425
|
1432, // Top-level 'for await' loops are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher.
|
|
426
|
+
1540, // A 'namespace' declaration should not be declared using the 'module' keyword. The `module` spelling yields a ModuleDeclaration.
|
|
425
427
|
]);
|
|
426
428
|
|
|
427
429
|
// Errors to exclude only for JavaScript files (.js, .jsx, .mjs, .cjs)
|
package/src/javascript/parser.ts
CHANGED
|
@@ -54,6 +54,12 @@ import SpreadAttribute = JSX.SpreadAttribute;
|
|
|
54
54
|
export interface JavaScriptParserOptions extends ParserOptions {
|
|
55
55
|
styles?: NamedStyles[],
|
|
56
56
|
sourceFileCache?: Map<string, ts.SourceFile>,
|
|
57
|
+
/**
|
|
58
|
+
* Type packages to load whose declarations nothing imports. Unset leaves TypeScript's default,
|
|
59
|
+
* which reads `@types/*` and nothing else; a package declaring its modules ambiently needs
|
|
60
|
+
* naming here for those declarations to be in scope.
|
|
61
|
+
*/
|
|
62
|
+
types?: string[],
|
|
57
63
|
}
|
|
58
64
|
|
|
59
65
|
function getScriptKindFromFileName(fileName: string): ts.ScriptKind {
|
|
@@ -86,13 +92,20 @@ export class JavaScriptParser extends Parser {
|
|
|
86
92
|
relativeTo,
|
|
87
93
|
styles,
|
|
88
94
|
sourceFileCache,
|
|
95
|
+
types,
|
|
89
96
|
}: JavaScriptParserOptions = {},
|
|
90
97
|
) {
|
|
91
98
|
super({ctx, relativeTo});
|
|
92
99
|
this.compilerOptions = {
|
|
93
100
|
target: ts.ScriptTarget.Latest,
|
|
94
|
-
|
|
95
|
-
|
|
101
|
+
// Bundler matches `exports` conditions leniently, so packages that publish types only under
|
|
102
|
+
// an `import` condition resolve; it pairs with `preserve`, which `commonjs` cannot (TS5095).
|
|
103
|
+
// A `node16` module kind makes TS1479 reachable, and that error costs the whole LST.
|
|
104
|
+
module: ts.ModuleKind.Preserve,
|
|
105
|
+
moduleResolution: ts.ModuleResolutionKind.Bundler,
|
|
106
|
+
// Bundler's own condition set omits `node`, which takes the browser branch of packages
|
|
107
|
+
// that publish one, typing them against an API surface the source does not use.
|
|
108
|
+
customConditions: ["node"],
|
|
96
109
|
noEmit: true,
|
|
97
110
|
allowJs: true,
|
|
98
111
|
checkJs: true,
|
|
@@ -102,6 +115,12 @@ export class JavaScriptParser extends Parser {
|
|
|
102
115
|
emitDecoratorMetadata: true,
|
|
103
116
|
forceConsistentCasingInFileNames: false,
|
|
104
117
|
jsx: ts.JsxEmit.Preserve,
|
|
118
|
+
// Strictness is a property of the parsed project rather than of the compiler we pin: under
|
|
119
|
+
// `strictNullChecks` every nullable type carries an extra `null` union constituent.
|
|
120
|
+
strict: false,
|
|
121
|
+
// `types` defaults to `[]`, which attributes ambient `@types/*` packages only when named;
|
|
122
|
+
// `*` enumerates everything under `node_modules/@types`.
|
|
123
|
+
types: types ?? ["*"],
|
|
105
124
|
baseUrl: relativeTo || process.cwd()
|
|
106
125
|
};
|
|
107
126
|
this.styles = styles;
|
|
@@ -326,7 +345,8 @@ export class JavaScriptParser extends Parser {
|
|
|
326
345
|
return resolvedModules;
|
|
327
346
|
};
|
|
328
347
|
|
|
329
|
-
//
|
|
348
|
+
// TypeScript carries the previous program's bound files forward when the root paths match,
|
|
349
|
+
// so a parser held across parses of one path costs a fraction of a freshly built one.
|
|
330
350
|
const program = ts.createProgram([...inputFiles.keys()], this.compilerOptions, host, this.oldProgram);
|
|
331
351
|
|
|
332
352
|
// Update the oldProgram reference
|