@cplieger/deadset-ts 8.0.0-dev.1 → 8.0.0-dev.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/bin/mapper-connection.js +2 -1
- package/dist/bin/node-host.js +24 -5
- package/dist/src/analysis.js +181 -341
- package/dist/src/augmentations.js +106 -13
- package/dist/src/automatic-types.js +10 -29
- package/dist/src/build-scripts.js +425 -0
- package/dist/src/component-layer.js +4 -2
- package/dist/src/components.js +2 -3
- package/dist/src/config.js +6 -82
- package/dist/src/configuration-files.js +28 -176
- package/dist/src/configured-declarations.js +15 -20
- package/dist/src/conformance-record.js +1 -1
- package/dist/src/consumers.js +3 -30
- package/dist/src/contextual-uses.js +56 -9
- package/dist/src/contract/config.generated.js +558 -0
- package/dist/src/contract/contract.generated.js +1244 -0
- package/dist/src/contract/report.generated.js +862 -0
- package/dist/src/convention-rows.js +73 -3
- package/dist/src/conventions.js +36 -66
- package/dist/src/dependencies.js +103 -40
- package/dist/src/edges.js +38 -122
- package/dist/src/element-access.js +4 -6
- package/dist/src/entry-point-gaps.js +2 -8
- package/dist/src/entry-points.js +11 -27
- package/dist/src/enum-group.js +3 -10
- package/dist/src/erased-stores.js +4 -6
- package/dist/src/exempt-classes.js +1 -63
- package/dist/src/exempt.js +21 -40
- package/dist/src/failure.js +36 -0
- package/dist/src/file-facts.js +2 -25
- package/dist/src/findings/completion.js +139 -72
- package/dist/src/findings/dependencies-and-module-machinery.js +4 -5
- package/dist/src/findings/emitters.js +5 -5
- package/dist/src/findings/interfaces.js +4 -5
- package/dist/src/findings/intra-function.js +13 -10
- package/dist/src/findings/non-code-artifacts.js +7 -8
- package/dist/src/findings/reads-and-writes.js +16 -13
- package/dist/src/findings/self-check.js +10 -12
- package/dist/src/findings/unused-declarations.js +41 -32
- package/dist/src/findings/visibility-narrowing.js +19 -16
- package/dist/src/findings-pass.js +8 -15
- package/dist/src/framework-lifecycle.js +7 -7
- package/dist/src/fs/document.js +52 -0
- package/dist/src/fs/manifest.js +72 -0
- package/dist/src/fs/tree.js +88 -0
- package/dist/src/generated-file.js +7 -4
- package/dist/src/git-ignore.js +39 -26
- package/dist/src/graph.js +5 -3
- package/dist/src/html-entries.js +6 -33
- package/dist/src/in-operands.js +2 -1
- package/dist/src/index.js +1 -1
- package/dist/src/injection-container.js +1 -1
- package/dist/src/intra-function-parts.js +63 -43
- package/dist/src/inventory.js +2 -21
- package/dist/src/javascript-file.js +33 -0
- package/dist/src/json-document.js +198 -67
- package/dist/src/keyof-comparisons.js +4 -6
- package/dist/src/kinds.js +3 -366
- package/dist/src/load/classify.js +270 -0
- package/dist/src/load/diagnostics.js +80 -0
- package/dist/src/load/discover.js +277 -0
- package/dist/src/{emit-map.js → load/emit-map.js} +1 -1
- package/dist/src/load/expected-module.js +136 -0
- package/dist/src/load/load.js +27 -0
- package/dist/src/load/module-lookup.js +37 -0
- package/dist/src/load/plan.js +313 -0
- package/dist/src/load/specifiers.js +115 -0
- package/dist/src/load/synthesize.js +140 -0
- package/dist/src/load/test-globals.js +207 -0
- package/dist/src/load/test-joins.js +82 -0
- package/dist/src/{workspace-manifests.js → load/workspace-manifests.js} +4 -4
- package/dist/src/{workspace-programs.js → load/workspace-programs.js} +89 -66
- package/dist/src/{workspace-resolution.js → load/workspace-resolution.js} +23 -65
- package/dist/src/{workspace-run.js → load/workspace-run.js} +7 -7
- package/dist/src/{workspace.js → load/workspace.js} +62 -124
- package/dist/src/manifest.js +49 -54
- package/dist/src/matrix.js +76 -4
- package/dist/src/mdx-entries.js +3 -26
- package/dist/src/outside-tests.js +1 -1
- package/dist/src/partial.js +2 -1
- package/dist/src/paths.js +26 -15
- package/dist/src/position.js +2 -1
- package/dist/src/print.js +11 -79
- package/dist/src/product.js +13 -0
- package/dist/src/query.js +1 -0
- package/dist/src/ref.js +1 -0
- package/dist/src/references.js +48 -30
- package/dist/src/report-schema.js +51 -0
- package/dist/src/report.js +57 -41
- package/dist/src/reporters/annotations.js +15 -8
- package/dist/src/reporters/sarif.js +16 -10
- package/dist/src/reporters/template.js +4 -19
- package/dist/src/resolve.js +245 -729
- package/dist/src/roots.js +273 -87
- package/dist/src/run.js +66 -77
- package/dist/src/schema.js +320 -343
- package/dist/src/scope.js +38 -115
- package/dist/src/serialization-contract.js +595 -21
- package/dist/src/session.js +34 -29
- package/dist/src/source-files.js +1 -1
- package/dist/src/suppress-file.js +25 -28
- package/dist/src/suppress-inline.js +3 -2
- package/dist/src/suppress.js +33 -51
- package/dist/src/sweep.js +7 -9
- package/dist/src/symbol-keys.js +3 -5
- package/dist/src/template-field.js +9 -19
- package/dist/src/test-support.js +8 -11
- package/dist/src/text/compare.js +26 -0
- package/dist/src/text/glob.js +194 -0
- package/dist/src/text/named-files.js +54 -0
- package/dist/src/text/shell.js +159 -0
- package/dist/src/text/yaml.js +393 -0
- package/dist/src/type-errors.js +11 -232
- package/dist/src/unseen-loads.js +100 -0
- package/dist/src/unwrap.js +23 -0
- package/dist/src/usage.js +10 -0
- package/dist/src/verbs/analyze.js +166 -126
- package/dist/src/verbs/describe.js +9 -16
- package/dist/src/verbs/explain.js +10 -7
- package/dist/src/verbs/print-config.js +2 -1
- package/dist/src/verbs/print-projects.js +6 -4
- package/dist/src/verbs/print-retained.js +4 -2
- package/dist/src/verbs/print-roots.js +4 -2
- package/dist/src/verbs/verb.js +1 -5
- package/dist/src/verbs/version.js +14 -3
- package/dist/src/workflow-steps.js +62 -64
- package/jsr.json +1 -1
- package/package.json +4 -3
- package/src/analysis.ts +245 -502
- package/src/augmentations.ts +135 -17
- package/src/automatic-types.ts +11 -29
- package/src/build-scripts.ts +543 -0
- package/src/component-layer.ts +4 -2
- package/src/components.ts +2 -4
- package/src/config.ts +31 -302
- package/src/configuration-files.ts +34 -179
- package/src/configured-declarations.ts +18 -23
- package/src/conformance-record.ts +1 -1
- package/src/consumers.ts +6 -57
- package/src/contextual-uses.ts +64 -12
- package/src/contract/config.generated.ts +818 -0
- package/src/contract/contract.generated.ts +1308 -0
- package/src/contract/report.generated.ts +1237 -0
- package/src/convention-rows.ts +85 -3
- package/src/conventions.ts +46 -84
- package/src/dependencies.ts +118 -46
- package/src/edges.ts +41 -140
- package/src/element-access.ts +4 -7
- package/src/entry-point-gaps.ts +3 -9
- package/src/entry-points.ts +12 -38
- package/src/enum-group.ts +2 -11
- package/src/erased-stores.ts +3 -7
- package/src/exempt-classes.ts +1 -75
- package/src/exempt.ts +36 -50
- package/src/failure.ts +63 -0
- package/src/file-facts.ts +9 -24
- package/src/finding.ts +14 -9
- package/src/findings/boundary.ts +2 -0
- package/src/findings/completion.ts +181 -84
- package/src/findings/dependencies-and-module-machinery.ts +4 -7
- package/src/findings/emitter.ts +8 -9
- package/src/findings/emitters.ts +7 -7
- package/src/findings/interfaces.ts +4 -6
- package/src/findings/intra-function.ts +13 -11
- package/src/findings/non-code-artifacts.ts +9 -11
- package/src/findings/reads-and-writes.ts +20 -16
- package/src/findings/self-check.ts +11 -17
- package/src/findings/unused-declarations.ts +45 -32
- package/src/findings/visibility-narrowing.ts +20 -17
- package/src/findings-pass.ts +10 -19
- package/src/framework-lifecycle.ts +7 -7
- package/src/fs/document.ts +70 -0
- package/src/fs/manifest.ts +92 -0
- package/src/fs/tree.ts +110 -0
- package/src/generated-file.ts +7 -4
- package/src/git-ignore.ts +50 -26
- package/src/graph.ts +5 -3
- package/src/host.ts +12 -5
- package/src/html-entries.ts +6 -33
- package/src/in-operands.ts +2 -1
- package/src/index.ts +1 -1
- package/src/injection-container.ts +1 -1
- package/src/intra-function-parts.ts +73 -44
- package/src/inventory.ts +2 -20
- package/src/javascript-file.ts +37 -0
- package/src/json-document.ts +241 -76
- package/src/keyof-comparisons.ts +3 -7
- package/src/kinds.ts +5 -413
- package/src/load/classify.ts +397 -0
- package/src/load/diagnostics.ts +144 -0
- package/src/load/discover.ts +455 -0
- package/src/{emit-map.ts → load/emit-map.ts} +1 -1
- package/src/load/expected-module.ts +188 -0
- package/src/load/load.ts +73 -0
- package/src/load/module-lookup.ts +50 -0
- package/src/load/plan.ts +504 -0
- package/src/load/specifiers.ts +168 -0
- package/src/load/synthesize.ts +211 -0
- package/src/load/test-globals.ts +251 -0
- package/src/load/test-joins.ts +98 -0
- package/src/{workspace-manifests.ts → load/workspace-manifests.ts} +5 -5
- package/src/{workspace-programs.ts → load/workspace-programs.ts} +128 -85
- package/src/{workspace-resolution.ts → load/workspace-resolution.ts} +33 -76
- package/src/{workspace-run.ts → load/workspace-run.ts} +18 -16
- package/src/{workspace.ts → load/workspace.ts} +90 -134
- package/src/manifest.ts +81 -75
- package/src/matrix.ts +122 -4
- package/src/mdx-entries.ts +3 -26
- package/src/outside-tests.ts +1 -1
- package/src/partial.ts +3 -2
- package/src/paths.ts +27 -15
- package/src/position.ts +2 -1
- package/src/print.ts +12 -92
- package/src/product.ts +18 -0
- package/src/query.ts +11 -0
- package/src/ref.ts +1 -0
- package/src/references.ts +52 -31
- package/src/report-schema.ts +68 -0
- package/src/report.ts +101 -224
- package/src/reporters/annotations.ts +22 -11
- package/src/reporters/json.ts +1 -1
- package/src/reporters/reporter.ts +2 -4
- package/src/reporters/reporters.ts +1 -1
- package/src/reporters/sarif.ts +29 -16
- package/src/reporters/template.ts +4 -20
- package/src/reporters/text.ts +3 -3
- package/src/resolve.ts +283 -1114
- package/src/roots.ts +339 -104
- package/src/run.ts +75 -91
- package/src/schema.ts +391 -388
- package/src/scope.ts +46 -138
- package/src/serialization-contract.ts +763 -22
- package/src/session.ts +70 -54
- package/src/source-files.ts +1 -1
- package/src/suppress-file.ts +24 -33
- package/src/suppress-inline.ts +2 -2
- package/src/suppress.ts +43 -58
- package/src/sweep.ts +23 -9
- package/src/symbol-keys.ts +2 -5
- package/src/template-field.ts +15 -25
- package/src/test-support.ts +17 -13
- package/src/text/compare.ts +27 -0
- package/src/text/glob.ts +210 -0
- package/src/text/named-files.inputs.json +1522 -0
- package/src/text/named-files.ts +68 -0
- package/src/text/shell.ts +161 -0
- package/src/text/yaml.ts +423 -0
- package/src/type-errors.ts +18 -288
- package/src/unseen-loads.ts +134 -0
- package/src/unwrap.ts +34 -0
- package/src/usage.ts +10 -0
- package/src/verbs/analyze.ts +224 -162
- package/src/verbs/describe.ts +14 -15
- package/src/verbs/explain.ts +10 -11
- package/src/verbs/print-config.ts +2 -1
- package/src/verbs/print-projects.ts +6 -4
- package/src/verbs/print-retained.ts +4 -2
- package/src/verbs/print-roots.ts +4 -2
- package/src/verbs/verb.ts +2 -8
- package/src/verbs/version.ts +15 -3
- package/src/workflow-steps.ts +74 -64
- package/dist/src/base-url.js +0 -18
- package/dist/src/discover.js +0 -468
- package/dist/src/glob.js +0 -65
- package/dist/src/pnpm-workspace.js +0 -120
- package/dist/src/setup-failure.js +0 -23
- package/dist/src/test-joins.js +0 -101
- package/dist/src/version.js +0 -7
- package/src/base-url.ts +0 -24
- package/src/discover.ts +0 -653
- package/src/glob.ts +0 -67
- package/src/pnpm-workspace.ts +0 -135
- package/src/setup-failure.ts +0 -39
- package/src/test-joins.ts +0 -120
- package/src/version.ts +0 -7
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The test files a derived matrix holds although no configuration's file list names them.
|
|
3
|
+
* The test runner compiles such a file with the options of the nearest compiler
|
|
4
|
+
* configuration at or above it, so the file joins that configuration's program as a file
|
|
5
|
+
* its list names, unless a `package.json` below that configuration's directory makes the
|
|
6
|
+
* file another package's, which its own test runner compiles.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { sourcePaths } from "../file-facts.ts";
|
|
10
|
+
import type { Host } from "../host.ts";
|
|
11
|
+
import { ancestors, dirnamePath, joinPath } from "../paths.ts";
|
|
12
|
+
import { bytewise } from "../text/compare.ts";
|
|
13
|
+
import { holdsManifest } from "../fs/manifest.ts";
|
|
14
|
+
import type { Configuration } from "./discover.ts";
|
|
15
|
+
import type { ProgramPlan } from "./plan.ts";
|
|
16
|
+
|
|
17
|
+
const PREFERRED = "/tsconfig.json";
|
|
18
|
+
|
|
19
|
+
/** The configurations of one directory in the order a file joins them: `tsconfig.json` first. */
|
|
20
|
+
function byPreference(a: string, b: string): number {
|
|
21
|
+
const first = a.endsWith(PREFERRED) ? 0 : 1;
|
|
22
|
+
const second = b.endsWith(PREFERRED) ? 0 : 1;
|
|
23
|
+
return first - second || bytewise(a, b);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Per configuration of `configurations`, the absolute paths of the test files that join it:
|
|
28
|
+
* each file below `root` a pattern of `patterns` names, that no configuration's file list
|
|
29
|
+
* holds, joins the configuration nearest at or above its directory when no `package.json`
|
|
30
|
+
* sits between them.
|
|
31
|
+
*/
|
|
32
|
+
export function joinedTestFiles(
|
|
33
|
+
host: Host,
|
|
34
|
+
root: string,
|
|
35
|
+
configurations: readonly Configuration[],
|
|
36
|
+
patterns: readonly RegExp[],
|
|
37
|
+
): ReadonlyMap<string, readonly string[]> {
|
|
38
|
+
const listed = new Set<string>();
|
|
39
|
+
const byDir = new Map<string, string[]>();
|
|
40
|
+
for (const { configFile, parsed } of configurations) {
|
|
41
|
+
parsed.fileNames.forEach((name) => listed.add(name));
|
|
42
|
+
const dir = dirnamePath(configFile);
|
|
43
|
+
byDir.set(dir, [...(byDir.get(dir) ?? []), configFile].sort(byPreference));
|
|
44
|
+
}
|
|
45
|
+
const joins = new Map<string, string[]>();
|
|
46
|
+
for (const path of sourcePaths(host, root)) {
|
|
47
|
+
const file = joinPath(root, path);
|
|
48
|
+
if (listed.has(file) || !patterns.some((pattern) => pattern.test(path))) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
for (const dir of ancestors(dirnamePath(file), root)) {
|
|
52
|
+
const [nearest] = byDir.get(dir) ?? [];
|
|
53
|
+
if (nearest !== undefined) {
|
|
54
|
+
joins.set(nearest, [...(joins.get(nearest) ?? []), file]);
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
if (holdsManifest(host, dir)) {
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return joins;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* The plans with each joined test file added to the configuration it joins: to a described
|
|
67
|
+
* program's root files, or to the file list of a configuration only the snapshot holds, which
|
|
68
|
+
* lists every file the configuration lists and the joined ones.
|
|
69
|
+
*/
|
|
70
|
+
export function joinedTests(
|
|
71
|
+
plans: readonly ProgramPlan[],
|
|
72
|
+
joins: ReadonlyMap<string, readonly string[]>,
|
|
73
|
+
): readonly ProgramPlan[] {
|
|
74
|
+
return plans.map((plan): ProgramPlan => {
|
|
75
|
+
const files = joins.get(plan.configFile);
|
|
76
|
+
const { build } = plan;
|
|
77
|
+
if (files === undefined) {
|
|
78
|
+
return plan;
|
|
79
|
+
}
|
|
80
|
+
if (build.kind === "program") {
|
|
81
|
+
return {
|
|
82
|
+
...plan,
|
|
83
|
+
build: {
|
|
84
|
+
kind: "program",
|
|
85
|
+
params: { ...build.params, rootFiles: [...(build.params.rootFiles ?? []), ...files] },
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
const written = build.kind === "configuration" ? build.value : { extends: plan.configFile };
|
|
90
|
+
return {
|
|
91
|
+
...plan,
|
|
92
|
+
build: {
|
|
93
|
+
kind: "configuration",
|
|
94
|
+
value: { ...written, files: [...plan.parsed.fileNames, ...files], include: [] },
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
});
|
|
98
|
+
}
|
|
@@ -7,11 +7,12 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { emittedFrom } from "./emit-map.ts";
|
|
10
|
-
import type { Host } from "
|
|
11
|
-
import { readManifest, type Manifest, type ManifestEntry } from "
|
|
12
|
-
import { joinPath, relativePath } from "
|
|
10
|
+
import type { Host } from "../host.ts";
|
|
11
|
+
import { readManifest, type Manifest, type ManifestEntry } from "../manifest.ts";
|
|
12
|
+
import { joinPath, relativePath } from "../paths.ts";
|
|
13
13
|
import type { WorkspaceMember } from "./workspace.ts";
|
|
14
14
|
import type { WorkspaceResolver } from "./workspace-resolution.ts";
|
|
15
|
+
import { MANIFEST } from "../fs/manifest.ts";
|
|
15
16
|
|
|
16
17
|
/** The one character a subpath pattern of a manifest's `exports` holds. */
|
|
17
18
|
const SUBPATH_WILDCARD = "*";
|
|
@@ -84,8 +85,7 @@ export function memberEntries(
|
|
|
84
85
|
}
|
|
85
86
|
const manifest = readManifest(host, member.dir);
|
|
86
87
|
const where =
|
|
87
|
-
relativePath(targetRoot, joinPath(member.dir,
|
|
88
|
-
joinPath(member.dir, "package.json");
|
|
88
|
+
relativePath(targetRoot, joinPath(member.dir, MANIFEST)) ?? joinPath(member.dir, MANIFEST);
|
|
89
89
|
const kept = manifest.entries.flatMap((entry): ManifestEntry[] => {
|
|
90
90
|
const exported = entry.member.startsWith("exports");
|
|
91
91
|
if (member.private && exported) {
|
|
@@ -16,11 +16,16 @@ import type {
|
|
|
16
16
|
} from "@typescript/native/sync";
|
|
17
17
|
import { isStringLiteralLikeNode } from "@typescript/native/ast";
|
|
18
18
|
import type { StringLiteralLikeNode } from "@typescript/native/ast";
|
|
19
|
-
import {
|
|
20
|
-
import
|
|
21
|
-
import {
|
|
22
|
-
import
|
|
19
|
+
import type { Host } from "../host.ts";
|
|
20
|
+
import { JAVASCRIPT_FILE } from "../javascript-file.ts";
|
|
21
|
+
import { isRecord } from "../json-document.ts";
|
|
22
|
+
import { dirnamePath, resolvePath } from "../paths.ts";
|
|
23
|
+
import { batched, type Engine, type ProgramBuild } from "../session.ts";
|
|
23
24
|
import type { WorkspaceResolver } from "./workspace-resolution.ts";
|
|
25
|
+
import { bytewise } from "../text/compare.ts";
|
|
26
|
+
import { PRODUCT } from "../product.ts";
|
|
27
|
+
import type { Parsed } from "./discover.ts";
|
|
28
|
+
import type { Build, CompilerOptions } from "./plan.ts";
|
|
24
29
|
|
|
25
30
|
/** One member import no member source answers for. */
|
|
26
31
|
interface UnresolvedImport {
|
|
@@ -43,32 +48,35 @@ export interface MemberReading {
|
|
|
43
48
|
readonly componentsUnread: string | undefined;
|
|
44
49
|
}
|
|
45
50
|
|
|
46
|
-
/**
|
|
47
|
-
|
|
48
|
-
| { readonly kind: "program"; readonly params: CreateSnapshotProgramParams }
|
|
49
|
-
/** A configuration only the snapshot holds, at a path no file has. */
|
|
50
|
-
| { readonly kind: "configuration"; readonly file: string; readonly text: string };
|
|
51
|
+
/** One configuration as a written configuration or a described program. */
|
|
52
|
+
type Written = Exclude<Build, { readonly kind: "project" }>;
|
|
51
53
|
|
|
52
54
|
/** The programs one run builds instead of opening projects, with what reading them did. */
|
|
53
55
|
interface WorkspacePrograms {
|
|
54
56
|
/** Per configuration that imports a member, how the snapshot reads it. */
|
|
55
|
-
readonly programs: ReadonlyMap<string,
|
|
57
|
+
readonly programs: ReadonlyMap<string, Written>;
|
|
56
58
|
readonly readings: readonly MemberReading[];
|
|
57
59
|
}
|
|
58
60
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
/** One configuration the rounds read: its parse and the options the plan builds it with. */
|
|
62
|
+
export interface PlannedConfiguration {
|
|
63
|
+
readonly configFile: string;
|
|
64
|
+
readonly parsed: Parsed;
|
|
65
|
+
readonly options: CompilerOptions;
|
|
66
|
+
/** The configuration of a program the run forms, which only the snapshot holds, at `configFile`. */
|
|
67
|
+
readonly written?: Readonly<Record<string, unknown>> | undefined;
|
|
68
|
+
}
|
|
63
69
|
|
|
64
70
|
/**
|
|
65
|
-
* The options a configuration's program is built with:
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* the compiler refuses under such a layout.
|
|
71
|
+
* The options a configuration's program is built with: the plan's, less the ones that lay
|
|
72
|
+
* out an emitted program's inputs and outputs. The analysis emits nothing, and a member's
|
|
73
|
+
* source is outside the importer's root directory by construction, which the compiler
|
|
74
|
+
* refuses under such a layout.
|
|
70
75
|
*/
|
|
71
|
-
function analysisOptions(
|
|
76
|
+
function analysisOptions(
|
|
77
|
+
options: CompilerOptions,
|
|
78
|
+
readsJavaScript: boolean,
|
|
79
|
+
): CreateSnapshotProgramParams["compilerOptions"] {
|
|
72
80
|
const {
|
|
73
81
|
composite,
|
|
74
82
|
rootDir: _rootDir,
|
|
@@ -76,10 +84,24 @@ function analysisOptions(parsed: Parsed): CreateSnapshotProgramParams["compilerO
|
|
|
76
84
|
declarationDir: _declarationDir,
|
|
77
85
|
tsBuildInfoFile: _tsBuildInfoFile,
|
|
78
86
|
...kept
|
|
79
|
-
} =
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
87
|
+
} = options;
|
|
88
|
+
const read = readsJavaScript ? { ...kept, allowJs: true } : kept;
|
|
89
|
+
return composite === true ? { ...read, declaration: true } : read;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Whether one reading answers a member import with a JavaScript file, which its program reads
|
|
94
|
+
* as source only where it allows JavaScript, a program formed for a JavaScript member being the
|
|
95
|
+
* member's source.
|
|
96
|
+
*/
|
|
97
|
+
function readsJavaScript(reading: Reading): boolean {
|
|
98
|
+
return (
|
|
99
|
+
reading.options.allowJs !== true &&
|
|
100
|
+
reading.entries.some((entry) => {
|
|
101
|
+
const file = entry.result.resolvedFileName;
|
|
102
|
+
return typeof file === "string" && JAVASCRIPT_FILE.test(file);
|
|
103
|
+
})
|
|
104
|
+
);
|
|
83
105
|
}
|
|
84
106
|
|
|
85
107
|
/** The conditions an `exports` lookup under one configuration and one resolution mode reads. */
|
|
@@ -101,9 +123,7 @@ function resolutionMode(kind: ModuleKind): ResolutionMode | undefined {
|
|
|
101
123
|
}
|
|
102
124
|
|
|
103
125
|
/** One configuration's state across the rounds. */
|
|
104
|
-
interface Reading {
|
|
105
|
-
readonly configFile: string;
|
|
106
|
-
readonly parsed: Parsed;
|
|
126
|
+
interface Reading extends PlannedConfiguration {
|
|
107
127
|
readonly entries: ModuleResolutionEntry[];
|
|
108
128
|
readonly seen: Set<string>;
|
|
109
129
|
/** Per member specifier, every file an import of it is read as. */
|
|
@@ -125,38 +145,60 @@ function unstatable(reading: Reading): string | undefined {
|
|
|
125
145
|
return undefined;
|
|
126
146
|
}
|
|
127
147
|
|
|
128
|
-
/** The path beside `configFile` its written configuration takes, which no file has. */
|
|
129
|
-
export function writtenPath(
|
|
148
|
+
/** The path beside `configFile` its written configuration takes, which no file and none of `taken` has. */
|
|
149
|
+
export function writtenPath(
|
|
150
|
+
host: Host,
|
|
151
|
+
configFile: string,
|
|
152
|
+
taken: ReadonlySet<string> = new Set(),
|
|
153
|
+
): string {
|
|
130
154
|
const stem = configFile.replace(/\.json$/u, "");
|
|
131
155
|
for (let counter = 0; ; counter += 1) {
|
|
132
|
-
const path = `${stem}
|
|
133
|
-
if (host.kindOf(path) === "absent") {
|
|
156
|
+
const path = `${stem}.${PRODUCT}${counter === 0 ? "" : `-${String(counter)}`}.json`;
|
|
157
|
+
if (host.kindOf(path) === "absent" && !taken.has(path)) {
|
|
134
158
|
return path;
|
|
135
159
|
}
|
|
136
160
|
}
|
|
137
161
|
}
|
|
138
162
|
|
|
139
163
|
/**
|
|
140
|
-
* The
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
|
|
144
|
-
|
|
164
|
+
* The path the snapshot holds one configuration's written form at: a formed configuration's
|
|
165
|
+
* own path, else a free one beside it that no configuration of `formed` holds, because a formed
|
|
166
|
+
* program in a directory with a `jsconfig.json` takes the name that file's written form would.
|
|
167
|
+
*/
|
|
168
|
+
export function writtenFileOf(
|
|
169
|
+
host: Host,
|
|
170
|
+
configuration: Pick<PlannedConfiguration, "configFile" | "written">,
|
|
171
|
+
formed: ReadonlySet<string>,
|
|
172
|
+
): string {
|
|
173
|
+
return configuration.written === undefined
|
|
174
|
+
? writtenPath(host, configuration.configFile, formed)
|
|
175
|
+
: configuration.configFile;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* The configuration that reads as one configuration's program: it extends it, lays out no output
|
|
180
|
+
* ({@link analysisOptions}), maps each answered specifier to its file and keeps its references.
|
|
181
|
+
* Where the file list moves, the default `exclude` the dropped output directories are named in is
|
|
182
|
+
* restated, and one that {@link readsJavaScript} lists its files outright, as `allowJs` widens its
|
|
183
|
+
* `include` to JavaScript; a list that still differs, or answers `paths` cannot state, are a
|
|
184
|
+
* reason. A formed configuration, which no file holds to extend, is its own value with `paths`.
|
|
145
185
|
*/
|
|
146
186
|
function configurationOf(
|
|
147
187
|
engine: Engine,
|
|
148
188
|
host: Host,
|
|
149
189
|
reading: Reading,
|
|
150
|
-
|
|
190
|
+
formed: ReadonlySet<string>,
|
|
191
|
+
): Written | { readonly kind: "unread"; readonly reason: string } {
|
|
151
192
|
const reason = unstatable(reading);
|
|
152
193
|
if (reason !== undefined) {
|
|
153
194
|
return { kind: "unread", reason };
|
|
154
195
|
}
|
|
155
|
-
const { options
|
|
196
|
+
const { options } = reading;
|
|
197
|
+
const references = reading.parsed.projectReferences ?? [];
|
|
156
198
|
const raw: unknown = (options as Record<string, unknown>)["pathsBasePath"];
|
|
157
199
|
const base = typeof raw === "string" ? raw : dirnamePath(reading.configFile);
|
|
158
200
|
const paths: Record<string, string[]> = {};
|
|
159
|
-
for (const [key, targets] of Object.entries(
|
|
201
|
+
for (const [key, targets] of Object.entries(options.paths ?? {})) {
|
|
160
202
|
paths[key] = targets.map((target) => resolvePath(base, target));
|
|
161
203
|
}
|
|
162
204
|
for (const entry of reading.entries) {
|
|
@@ -165,6 +207,17 @@ function configurationOf(
|
|
|
165
207
|
paths[entry.moduleName] = [file];
|
|
166
208
|
}
|
|
167
209
|
}
|
|
210
|
+
if (reading.written !== undefined) {
|
|
211
|
+
const held = reading.written["compilerOptions"];
|
|
212
|
+
return {
|
|
213
|
+
kind: "configuration",
|
|
214
|
+
value: {
|
|
215
|
+
...reading.written,
|
|
216
|
+
compilerOptions: { ...(isRecord(held) ? held : {}), paths },
|
|
217
|
+
},
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
const javascript = readsJavaScript(reading);
|
|
168
221
|
const json = (exclude: readonly string[] | undefined): Record<string, unknown> => ({
|
|
169
222
|
extends: reading.configFile,
|
|
170
223
|
compilerOptions: {
|
|
@@ -173,18 +226,20 @@ function configurationOf(
|
|
|
173
226
|
declarationDir: null,
|
|
174
227
|
tsBuildInfoFile: null,
|
|
175
228
|
...(options.composite === true ? { composite: false, declaration: true } : {}),
|
|
229
|
+
...(javascript ? { allowJs: true } : {}),
|
|
176
230
|
paths,
|
|
177
231
|
},
|
|
178
232
|
...(references.length > 0
|
|
179
233
|
? { references: references.map((reference) => ({ path: reference.path })) }
|
|
180
234
|
: {}),
|
|
235
|
+
...(javascript ? { files: [...reading.parsed.fileNames], include: [] } : {}),
|
|
181
236
|
...(exclude === undefined ? {} : { exclude }),
|
|
182
237
|
});
|
|
183
|
-
const file =
|
|
184
|
-
const expected = [...reading.parsed.fileNames].sort().join("\u0000");
|
|
238
|
+
const file = writtenFileOf(host, reading, formed);
|
|
239
|
+
const expected = [...reading.parsed.fileNames].sort(bytewise).join("\u0000");
|
|
185
240
|
const listed = (value: Record<string, unknown>): string | undefined => {
|
|
186
241
|
try {
|
|
187
|
-
return [...engine.parseConfigJson(value, file).fileNames].sort().join("\u0000");
|
|
242
|
+
return [...engine.parseConfigJson(value, file).fileNames].sort(bytewise).join("\u0000");
|
|
188
243
|
} catch {
|
|
189
244
|
return undefined;
|
|
190
245
|
}
|
|
@@ -202,7 +257,7 @@ function configurationOf(
|
|
|
202
257
|
};
|
|
203
258
|
}
|
|
204
259
|
}
|
|
205
|
-
return { kind: "configuration",
|
|
260
|
+
return { kind: "configuration", value };
|
|
206
261
|
}
|
|
207
262
|
|
|
208
263
|
/** The program one configuration is built as, under the answers it holds so far. */
|
|
@@ -210,7 +265,7 @@ function programOf(
|
|
|
210
265
|
engine: Engine,
|
|
211
266
|
reading: Reading,
|
|
212
267
|
): { readonly params: CreateSnapshotProgramParams; readonly resolver: ModuleResolver } {
|
|
213
|
-
const compilerOptions = analysisOptions(reading.
|
|
268
|
+
const compilerOptions = analysisOptions(reading.options, readsJavaScript(reading));
|
|
214
269
|
const references = reading.parsed.projectReferences ?? [];
|
|
215
270
|
const resolver = engine.createModuleResolver(compilerOptions, reading.entries);
|
|
216
271
|
return {
|
|
@@ -227,23 +282,6 @@ function programOf(
|
|
|
227
282
|
};
|
|
228
283
|
}
|
|
229
284
|
|
|
230
|
-
function chunks<T>(items: readonly T[]): readonly (readonly T[])[] {
|
|
231
|
-
const found: T[][] = [];
|
|
232
|
-
for (let at = 0; at < items.length; at += BATCH) {
|
|
233
|
-
found.push(items.slice(at, at + BATCH));
|
|
234
|
-
}
|
|
235
|
-
return found;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
/** Asks one question of every item, in round trips of at most {@link BATCH}. */
|
|
239
|
-
function batched<T, A>(
|
|
240
|
-
engine: Engine,
|
|
241
|
-
items: readonly T[],
|
|
242
|
-
question: (item: T) => Parameters<Engine["batch"]>[0][number],
|
|
243
|
-
): A[] {
|
|
244
|
-
return chunks(items).flatMap((run) => engine.batch(run.map(question)) as A[]);
|
|
245
|
-
}
|
|
246
|
-
|
|
247
285
|
/** One round over one program: answers the member imports no earlier round asked about. */
|
|
248
286
|
function scan(
|
|
249
287
|
engine: Engine,
|
|
@@ -336,6 +374,18 @@ type Built =
|
|
|
336
374
|
}
|
|
337
375
|
| { readonly kind: "configuration"; readonly file: string; readonly text: string };
|
|
338
376
|
|
|
377
|
+
function configurationText(value: Readonly<Record<string, unknown>>): string {
|
|
378
|
+
return `${JSON.stringify(value, null, 2)}\n`;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/** One configuration value as the snapshot holds it, at `file`, which no file on disk holds. */
|
|
382
|
+
export function writtenConfiguration(
|
|
383
|
+
file: string,
|
|
384
|
+
value: Readonly<Record<string, unknown>>,
|
|
385
|
+
): Extract<ProgramBuild, { readonly kind: "configuration" }> {
|
|
386
|
+
return { kind: "configuration", file, text: configurationText(value) };
|
|
387
|
+
}
|
|
388
|
+
|
|
339
389
|
/**
|
|
340
390
|
* Answers the member imports of every reading `build` describes, round by round, all
|
|
341
391
|
* the readings still adding answers built in one snapshot per round. A reading `build`
|
|
@@ -391,45 +441,38 @@ function readRounds(
|
|
|
391
441
|
export function workspacePrograms(
|
|
392
442
|
engine: Engine,
|
|
393
443
|
host: Host,
|
|
394
|
-
|
|
444
|
+
configurations: readonly PlannedConfiguration[],
|
|
395
445
|
resolver: WorkspaceResolver,
|
|
396
446
|
): WorkspacePrograms {
|
|
397
|
-
const readings: Reading[] =
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
configFile,
|
|
408
|
-
parsed,
|
|
409
|
-
entries: [],
|
|
410
|
-
seen: new Set<string>(),
|
|
411
|
-
bound: new Map<string, Set<string>>(),
|
|
412
|
-
unresolved: [],
|
|
413
|
-
},
|
|
414
|
-
];
|
|
415
|
-
});
|
|
447
|
+
const readings: Reading[] = configurations.map((configuration) => ({
|
|
448
|
+
...configuration,
|
|
449
|
+
entries: [],
|
|
450
|
+
seen: new Set<string>(),
|
|
451
|
+
bound: new Map<string, Set<string>>(),
|
|
452
|
+
unresolved: [],
|
|
453
|
+
}));
|
|
454
|
+
const formed = new Set(
|
|
455
|
+
configurations.filter((one) => one.written !== undefined).map((one) => one.configFile),
|
|
456
|
+
);
|
|
416
457
|
readRounds(engine, readings, resolver, (reading) => ({
|
|
417
458
|
kind: "program",
|
|
418
459
|
...programOf(engine, reading),
|
|
419
460
|
}));
|
|
420
461
|
if (engine.readsComponents) {
|
|
421
462
|
readRounds(engine, readings, resolver, (reading) => {
|
|
422
|
-
const one = configurationOf(engine, host, reading);
|
|
423
|
-
return one.kind === "configuration"
|
|
463
|
+
const one = configurationOf(engine, host, reading, formed);
|
|
464
|
+
return one.kind === "configuration"
|
|
465
|
+
? writtenConfiguration(writtenFileOf(host, reading, formed), one.value)
|
|
466
|
+
: undefined;
|
|
424
467
|
});
|
|
425
468
|
}
|
|
426
|
-
const programs = new Map<string,
|
|
469
|
+
const programs = new Map<string, Written>();
|
|
427
470
|
const unread = new Map<string, string>();
|
|
428
471
|
for (const reading of readings) {
|
|
429
472
|
if (reading.entries.length === 0) {
|
|
430
473
|
continue;
|
|
431
474
|
}
|
|
432
|
-
const one = engine.readsComponents ? configurationOf(engine, host, reading) : undefined;
|
|
475
|
+
const one = engine.readsComponents ? configurationOf(engine, host, reading, formed) : undefined;
|
|
433
476
|
if (one !== undefined && one.kind !== "unread") {
|
|
434
477
|
programs.set(reading.configFile, one);
|
|
435
478
|
continue;
|
|
@@ -7,11 +7,20 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { emittedFrom } from "./emit-map.ts";
|
|
10
|
-
import {
|
|
11
|
-
import
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
10
|
+
import { packageOfSpecifier } from "../dependencies.ts";
|
|
11
|
+
import { gitIgnored } from "../git-ignore.ts";
|
|
12
|
+
import type { Host } from "../host.ts";
|
|
13
|
+
import { ancestors, dirnamePath, joinPath, relativePath, resolvePath } from "../paths.ts";
|
|
14
|
+
import { satisfies } from "../version-range.ts";
|
|
14
15
|
import type { Workspace, WorkspaceMember } from "./workspace.ts";
|
|
16
|
+
import { isRecord } from "../json-document.ts";
|
|
17
|
+
import { MANIFEST } from "../fs/manifest.ts";
|
|
18
|
+
import {
|
|
19
|
+
dependencySpecifiers,
|
|
20
|
+
installedPackage,
|
|
21
|
+
manifestsAbove,
|
|
22
|
+
type ManifestAt,
|
|
23
|
+
} from "./module-lookup.ts";
|
|
15
24
|
|
|
16
25
|
/** What the compiler's own resolution answered for one import. */
|
|
17
26
|
export interface DefaultResolution {
|
|
@@ -36,39 +45,9 @@ export type MemberResolution =
|
|
|
36
45
|
/** The manifest members that name an entry point for the subpath `.` without `exports`. */
|
|
37
46
|
const LEGACY_MEMBERS = ["types", "typings", "module", "main"] as const;
|
|
38
47
|
|
|
39
|
-
/** The dependency members a manifest declares other packages under. */
|
|
40
|
-
const DEPENDENCY_MEMBERS = [
|
|
41
|
-
"dependencies",
|
|
42
|
-
"devDependencies",
|
|
43
|
-
"peerDependencies",
|
|
44
|
-
"optionalDependencies",
|
|
45
|
-
] as const;
|
|
46
|
-
|
|
47
48
|
const SOURCE = /(?<!\.d)\.(?:[mc]?ts|tsx)$/u;
|
|
48
49
|
const OUTPUT = /(?:\.d\.[mc]?ts|\.[mc]?js|\.jsx)$/u;
|
|
49
50
|
|
|
50
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
51
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/** The package name a bare specifier names, or `undefined` for any other specifier. */
|
|
55
|
-
export function packageNameOf(specifier: string): string | undefined {
|
|
56
|
-
if (
|
|
57
|
-
specifier === "" ||
|
|
58
|
-
specifier.startsWith(".") ||
|
|
59
|
-
specifier.startsWith("#") ||
|
|
60
|
-
isAbsolutePath(specifier) ||
|
|
61
|
-
specifier.includes(":")
|
|
62
|
-
) {
|
|
63
|
-
return undefined;
|
|
64
|
-
}
|
|
65
|
-
const [first, second] = specifier.split("/");
|
|
66
|
-
if (specifier.startsWith("@")) {
|
|
67
|
-
return second === undefined || second === "" ? undefined : `${first ?? ""}/${second}`;
|
|
68
|
-
}
|
|
69
|
-
return first;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
51
|
function inside(dir: string, path: string): boolean {
|
|
73
52
|
return relativePath(dir, path) !== undefined;
|
|
74
53
|
}
|
|
@@ -210,52 +189,32 @@ type Linked =
|
|
|
210
189
|
/** The member imports of one workspace, read from the members' sources. */
|
|
211
190
|
export function workspaceResolver(host: Host, workspace: Workspace): WorkspaceResolver {
|
|
212
191
|
const links = new Map<string, string | undefined>();
|
|
213
|
-
/** The directory `
|
|
192
|
+
/** The directory the package `name` installed for one directory is, links followed. */
|
|
214
193
|
const linkedFrom = (name: string, dir: string): string | undefined => {
|
|
215
194
|
const key = `${name}\u0000${dir}`;
|
|
216
|
-
if (links.has(key)) {
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
const candidate = joinPath(dir, "node_modules", name);
|
|
220
|
-
let found: string | undefined;
|
|
221
|
-
if (host.kindOf(candidate) === "absent") {
|
|
222
|
-
const up = dirnamePath(dir);
|
|
223
|
-
found = up === dir ? undefined : linkedFrom(name, up);
|
|
224
|
-
} else {
|
|
195
|
+
if (!links.has(key)) {
|
|
196
|
+
const installed = installedPackage(host, dir, name);
|
|
197
|
+
let found: string | undefined;
|
|
225
198
|
try {
|
|
226
|
-
found = host.realPath(
|
|
199
|
+
found = installed === undefined ? undefined : host.realPath(installed);
|
|
227
200
|
} catch {
|
|
228
201
|
found = undefined;
|
|
229
202
|
}
|
|
203
|
+
links.set(key, found);
|
|
230
204
|
}
|
|
231
|
-
links.
|
|
232
|
-
return found;
|
|
205
|
+
return links.get(key);
|
|
233
206
|
};
|
|
234
207
|
|
|
235
208
|
const root = workspace.members[0]?.dir;
|
|
236
209
|
const ignored = root === undefined ? () => false : gitIgnored(host, root);
|
|
237
|
-
const manifests = new Map<
|
|
238
|
-
string,
|
|
239
|
-
{ dir: string; manifest: Record<string, unknown> } | undefined
|
|
240
|
-
>();
|
|
210
|
+
const manifests = new Map<string, ManifestAt | undefined>();
|
|
241
211
|
/** The nearest manifest at or above one directory, up to the workspace's root. */
|
|
242
|
-
const nearestManifest = (
|
|
243
|
-
dir
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
return manifests.get(dir);
|
|
212
|
+
const nearestManifest = (dir: string): ManifestAt | undefined => {
|
|
213
|
+
if (!manifests.has(dir)) {
|
|
214
|
+
const [nearest] = manifestsAbove(host, dir, root ?? dir);
|
|
215
|
+
manifests.set(dir, nearest);
|
|
247
216
|
}
|
|
248
|
-
|
|
249
|
-
try {
|
|
250
|
-
const value: unknown = JSON.parse(host.readFile(joinPath(dir, "package.json")));
|
|
251
|
-
found = isRecord(value) ? { dir, manifest: value } : undefined;
|
|
252
|
-
} catch {
|
|
253
|
-
const up = dirnamePath(dir);
|
|
254
|
-
found =
|
|
255
|
-
up === dir || root === undefined || !inside(root, up) ? undefined : nearestManifest(up);
|
|
256
|
-
}
|
|
257
|
-
manifests.set(dir, found);
|
|
258
|
-
return found;
|
|
217
|
+
return manifests.get(dir);
|
|
259
218
|
};
|
|
260
219
|
|
|
261
220
|
const linkOf = (candidates: readonly WorkspaceMember[], fromDir: string): Linked => {
|
|
@@ -265,18 +224,16 @@ export function workspaceResolver(host: Host, workspace: Workspace): WorkspaceRe
|
|
|
265
224
|
const member = candidates.find((one) => one.dir === linked);
|
|
266
225
|
return member === undefined ? { kind: "none" } : { kind: "member", member };
|
|
267
226
|
}
|
|
268
|
-
const scope = workspace.memberOf(joinPath(fromDir,
|
|
227
|
+
const scope = workspace.memberOf(joinPath(fromDir, MANIFEST));
|
|
269
228
|
if (scope?.name === name) {
|
|
270
229
|
return { kind: "member", member: scope };
|
|
271
230
|
}
|
|
272
231
|
// A package below the root that no workspace lists depends on a member as a member does.
|
|
273
232
|
const owner = scope ?? nearestManifest(fromDir);
|
|
274
233
|
const manifest = owner?.manifest;
|
|
275
|
-
const declared =
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
return typeof specifier === "string" ? [specifier] : [];
|
|
279
|
-
});
|
|
234
|
+
const declared = (manifest === undefined ? [] : dependencySpecifiers(manifest, name)).filter(
|
|
235
|
+
(specifier) => typeof specifier === "string",
|
|
236
|
+
);
|
|
280
237
|
const matched = candidates.filter((member) =>
|
|
281
238
|
declared.some((specifier) => dependsOn(specifier, member, owner?.dir ?? fromDir)),
|
|
282
239
|
);
|
|
@@ -300,7 +257,7 @@ export function workspaceResolver(host: Host, workspace: Workspace): WorkspaceRe
|
|
|
300
257
|
* directory however its configuration writes it.
|
|
301
258
|
*/
|
|
302
259
|
const mirrored = (member: WorkspaceMember, path: string): string | undefined => {
|
|
303
|
-
for (
|
|
260
|
+
for (const dir of ancestors(dirnamePath(path), member.dir).filter((at) => at !== member.dir)) {
|
|
304
261
|
const found = emittedFrom(path, { outDir: dir, sourceDirs: [member.dir] }).find(
|
|
305
262
|
(candidate) =>
|
|
306
263
|
SOURCE.test(candidate) && !ignored(candidate) && host.kindOf(candidate) === "file",
|
|
@@ -379,11 +336,11 @@ export function workspaceResolver(host: Host, workspace: Workspace): WorkspaceRe
|
|
|
379
336
|
workspace,
|
|
380
337
|
sourceOf,
|
|
381
338
|
names: (specifier) => {
|
|
382
|
-
const name =
|
|
339
|
+
const name = packageOfSpecifier(specifier);
|
|
383
340
|
return name !== undefined && workspace.named.has(name);
|
|
384
341
|
},
|
|
385
342
|
resolve(specifier, fromDir, conditions, answered) {
|
|
386
|
-
const name =
|
|
343
|
+
const name = packageOfSpecifier(specifier);
|
|
387
344
|
const candidates = name === undefined ? undefined : workspace.named.get(name);
|
|
388
345
|
if (name === undefined || candidates === undefined) {
|
|
389
346
|
return { kind: "default" };
|