@intentset/architecture 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/baseline.d.ts +39 -0
- package/dist/baseline.d.ts.map +1 -0
- package/dist/baseline.js +104 -0
- package/dist/baseline.js.map +1 -0
- package/dist/boundaries.d.ts +63 -0
- package/dist/boundaries.d.ts.map +1 -0
- package/dist/boundaries.js +436 -0
- package/dist/boundaries.js.map +1 -0
- package/dist/check.d.ts +73 -0
- package/dist/check.d.ts.map +1 -0
- package/dist/check.js +130 -0
- package/dist/check.js.map +1 -0
- package/dist/claims.d.ts +24 -0
- package/dist/claims.d.ts.map +1 -0
- package/dist/claims.js +201 -0
- package/dist/claims.js.map +1 -0
- package/dist/config.d.ts +53 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +159 -0
- package/dist/config.js.map +1 -0
- package/dist/dependencies.d.ts +30 -0
- package/dist/dependencies.d.ts.map +1 -0
- package/dist/dependencies.js +179 -0
- package/dist/dependencies.js.map +1 -0
- package/dist/exceptions.d.ts +43 -0
- package/dist/exceptions.d.ts.map +1 -0
- package/dist/exceptions.js +233 -0
- package/dist/exceptions.js.map +1 -0
- package/dist/extract.d.ts +24 -0
- package/dist/extract.d.ts.map +1 -0
- package/dist/extract.js +316 -0
- package/dist/extract.js.map +1 -0
- package/dist/finding.d.ts +39 -0
- package/dist/finding.d.ts.map +1 -0
- package/dist/finding.js +29 -0
- package/dist/finding.js.map +1 -0
- package/dist/imports.d.ts +30 -0
- package/dist/imports.d.ts.map +1 -0
- package/dist/imports.js +48 -0
- package/dist/imports.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/layers.d.ts +38 -0
- package/dist/layers.d.ts.map +1 -0
- package/dist/layers.js +41 -0
- package/dist/layers.js.map +1 -0
- package/dist/ownership.d.ts +25 -0
- package/dist/ownership.d.ts.map +1 -0
- package/dist/ownership.js +97 -0
- package/dist/ownership.js.map +1 -0
- package/dist/paths.d.ts +18 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +54 -0
- package/dist/paths.js.map +1 -0
- package/dist/patterns.d.ts +25 -0
- package/dist/patterns.d.ts.map +1 -0
- package/dist/patterns.js +101 -0
- package/dist/patterns.js.map +1 -0
- package/dist/regions.d.ts +85 -0
- package/dist/regions.d.ts.map +1 -0
- package/dist/regions.js +144 -0
- package/dist/regions.js.map +1 -0
- package/dist/resolve.d.ts +53 -0
- package/dist/resolve.d.ts.map +1 -0
- package/dist/resolve.js +268 -0
- package/dist/resolve.js.map +1 -0
- package/dist/tsconfig.d.ts +42 -0
- package/dist/tsconfig.d.ts.map +1 -0
- package/dist/tsconfig.js +186 -0
- package/dist/tsconfig.js.map +1 -0
- package/package.json +36 -0
- package/src/baseline.ts +126 -0
- package/src/boundaries.ts +499 -0
- package/src/check.ts +197 -0
- package/src/claims.ts +229 -0
- package/src/config.ts +212 -0
- package/src/dependencies.ts +211 -0
- package/src/exceptions.ts +269 -0
- package/src/extract.ts +344 -0
- package/src/finding.ts +64 -0
- package/src/imports.ts +77 -0
- package/src/index.ts +58 -0
- package/src/layers.ts +67 -0
- package/src/ownership.ts +135 -0
- package/src/paths.ts +53 -0
- package/src/patterns.ts +95 -0
- package/src/regions.ts +243 -0
- package/src/resolve.ts +283 -0
- package/src/tsconfig.ts +198 -0
package/dist/patterns.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VSA §3 path patterns: repository-relative POSIX paths made of literal
|
|
3
|
+
* segments, `*` within one segment, and `**` across zero or more segments.
|
|
4
|
+
* Nothing else is special: `?`, `[` and `]` are literal characters, because
|
|
5
|
+
* real trees have directories named `[id]`. A `*` never matches `/`, so the
|
|
6
|
+
* only way to write a star that spans segments is `**` mixed with other
|
|
7
|
+
* characters, which validatePattern rejects.
|
|
8
|
+
*/
|
|
9
|
+
/** Why a pattern is not a v0.1 pattern, or null when it is one. */
|
|
10
|
+
export function validatePattern(pattern) {
|
|
11
|
+
if (pattern === "")
|
|
12
|
+
return "is empty";
|
|
13
|
+
if (pattern.startsWith("/"))
|
|
14
|
+
return "is absolute";
|
|
15
|
+
if (pattern.includes("\\"))
|
|
16
|
+
return "uses a backslash; patterns are POSIX paths";
|
|
17
|
+
if (/[{}]/.test(pattern))
|
|
18
|
+
return "uses brace expansion";
|
|
19
|
+
if (pattern.includes("!"))
|
|
20
|
+
return "uses negation";
|
|
21
|
+
const segments = pattern.split("/");
|
|
22
|
+
if (segments.includes(".."))
|
|
23
|
+
return "contains `..`";
|
|
24
|
+
if (segments.includes("."))
|
|
25
|
+
return "contains a `.` segment";
|
|
26
|
+
if (segments.includes(""))
|
|
27
|
+
return "has an empty segment";
|
|
28
|
+
for (const segment of segments) {
|
|
29
|
+
if (segment.includes("**") && segment !== "**")
|
|
30
|
+
return `puts \`**\` inside the segment \`${segment}\`; \`**\` stands alone`;
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
const compiled = new Map();
|
|
35
|
+
function compile(pattern) {
|
|
36
|
+
let segments = compiled.get(pattern);
|
|
37
|
+
if (segments !== undefined)
|
|
38
|
+
return segments;
|
|
39
|
+
segments = pattern.split("/").map((text) => {
|
|
40
|
+
if (text === "**")
|
|
41
|
+
return { kind: "globstar" };
|
|
42
|
+
if (!text.includes("*"))
|
|
43
|
+
return { kind: "literal", text };
|
|
44
|
+
const source = text
|
|
45
|
+
.split("*")
|
|
46
|
+
.map((part) => part.replace(/[.+?^${}()|[\]\\]/g, "\\$&"))
|
|
47
|
+
.join("[^/]*");
|
|
48
|
+
return { kind: "glob", regex: new RegExp(`^${source}$`) };
|
|
49
|
+
});
|
|
50
|
+
compiled.set(pattern, segments);
|
|
51
|
+
return segments;
|
|
52
|
+
}
|
|
53
|
+
/** Does a repository-relative path match a VSA §3 pattern? Invalid patterns match nothing. */
|
|
54
|
+
export function matchPattern(pattern, path) {
|
|
55
|
+
if (validatePattern(pattern) !== null)
|
|
56
|
+
return false;
|
|
57
|
+
const want = compile(pattern);
|
|
58
|
+
const have = path.split("/");
|
|
59
|
+
const memo = new Map();
|
|
60
|
+
const step = (p, s) => {
|
|
61
|
+
const key = p * (have.length + 1) + s;
|
|
62
|
+
const known = memo.get(key);
|
|
63
|
+
if (known !== undefined)
|
|
64
|
+
return known;
|
|
65
|
+
let result;
|
|
66
|
+
if (p === want.length)
|
|
67
|
+
result = s === have.length;
|
|
68
|
+
else {
|
|
69
|
+
const segment = want[p];
|
|
70
|
+
if (segment.kind === "globstar")
|
|
71
|
+
result = step(p + 1, s) || (s < have.length && step(p, s + 1));
|
|
72
|
+
else if (s === have.length)
|
|
73
|
+
result = false;
|
|
74
|
+
else if (segment.kind === "literal")
|
|
75
|
+
result = segment.text === have[s] && step(p + 1, s + 1);
|
|
76
|
+
else
|
|
77
|
+
result = segment.regex.test(have[s]) && step(p + 1, s + 1);
|
|
78
|
+
}
|
|
79
|
+
memo.set(key, result);
|
|
80
|
+
return result;
|
|
81
|
+
};
|
|
82
|
+
return step(0, 0);
|
|
83
|
+
}
|
|
84
|
+
/** True when any of the patterns matches the path. */
|
|
85
|
+
export function matchAny(patterns, path) {
|
|
86
|
+
return patterns.some((pattern) => matchPattern(pattern, path));
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Resolve each claim against the repository's files: for claim i, the sorted
|
|
90
|
+
* files it matches, minus those any ignore pattern matches (VSA §3: source
|
|
91
|
+
* enumeration uses a versioned ignore list). An invalid pattern resolves to
|
|
92
|
+
* nothing; the caller reports it.
|
|
93
|
+
*/
|
|
94
|
+
export function expandClaims(claims, files, ignore) {
|
|
95
|
+
const candidates = [...files].filter((file) => !matchAny(ignore, file)).sort(compareStrings);
|
|
96
|
+
return claims.map((claim) => candidates.filter((file) => matchPattern(claim.path, file)));
|
|
97
|
+
}
|
|
98
|
+
export function compareStrings(a, b) {
|
|
99
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=patterns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patterns.js","sourceRoot":"","sources":["../src/patterns.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Who owns each file (VSA §1, §3, §5). Every file the checker sees falls in
|
|
3
|
+
* exactly one region, decided in this order:
|
|
4
|
+
*
|
|
5
|
+
* slice:<ID> claimed by a slice (any claim kind; overlaps are VSA009)
|
|
6
|
+
* composition config.composition, e.g. src/app/**
|
|
7
|
+
* shared config.shared, e.g. src/shared/**
|
|
8
|
+
* infrastructure config.infrastructure, e.g. src/infrastructure/**
|
|
9
|
+
* resource:<ID> under a backend root and matched by a registry resource path
|
|
10
|
+
* backend under a backend root and owned by nothing (AMP004)
|
|
11
|
+
* unowned a code file under a source root owned by nothing (VSA009)
|
|
12
|
+
* external everything else: root configuration, scripts, documents
|
|
13
|
+
*
|
|
14
|
+
* Test files are kept apart (profile §3): they belong to the slice whose
|
|
15
|
+
* claim patterns match them, and only the foreign-internals rules apply.
|
|
16
|
+
*/
|
|
17
|
+
import type { Artifact, Graph, Registries, Resource, SliceMeta } from "@intentset/core";
|
|
18
|
+
import type { ArchitectureConfig } from "./config.ts";
|
|
19
|
+
export type RegionKind = "slice" | "composition" | "shared" | "infrastructure" | "resource" | "backend" | "unowned" | "external";
|
|
20
|
+
export interface Region {
|
|
21
|
+
kind: RegionKind;
|
|
22
|
+
/** Slice ID for "slice", resource ID for "resource". */
|
|
23
|
+
owner?: string;
|
|
24
|
+
}
|
|
25
|
+
export declare function regionLabel(region: Region): string;
|
|
26
|
+
export interface SliceInfo {
|
|
27
|
+
id: string;
|
|
28
|
+
/** The slice.md path. */
|
|
29
|
+
path: string;
|
|
30
|
+
artifact: Artifact;
|
|
31
|
+
meta: SliceMeta;
|
|
32
|
+
/**
|
|
33
|
+
* Directories of the entrypoints, sorted: where the profile's ui/, client/ and domain/ folders live, one root per
|
|
34
|
+
* package the slice spans. A file belongs to the deepest root above it (`rootOf`).
|
|
35
|
+
*/
|
|
36
|
+
roots: string[];
|
|
37
|
+
dependsOn: string[];
|
|
38
|
+
exposes: string[];
|
|
39
|
+
consumes: string[];
|
|
40
|
+
/** Files per claim, in claim order; empty for an invalid pattern. */
|
|
41
|
+
claimFiles: string[][];
|
|
42
|
+
/** Claim indexes whose pattern is invalid. */
|
|
43
|
+
invalidClaims: number[];
|
|
44
|
+
}
|
|
45
|
+
export interface ResourceInfo {
|
|
46
|
+
resource: Resource;
|
|
47
|
+
index: number;
|
|
48
|
+
files: string[];
|
|
49
|
+
}
|
|
50
|
+
export interface Model {
|
|
51
|
+
config: ArchitectureConfig;
|
|
52
|
+
/** Every file not ignored, by path. */
|
|
53
|
+
files: ReadonlyMap<string, string>;
|
|
54
|
+
/** Files not ignored and not tests, sorted. */
|
|
55
|
+
production: string[];
|
|
56
|
+
/** Test files not ignored, sorted. */
|
|
57
|
+
tests: string[];
|
|
58
|
+
slices: SliceInfo[];
|
|
59
|
+
sliceById: Map<string, SliceInfo>;
|
|
60
|
+
/** Production file -> the slices (and claim index) that claim it, sorted by slice ID. */
|
|
61
|
+
claimOwners: Map<string, {
|
|
62
|
+
slice: string;
|
|
63
|
+
claim: number;
|
|
64
|
+
}[]>;
|
|
65
|
+
resources: ResourceInfo[];
|
|
66
|
+
regionOf(path: string): Region;
|
|
67
|
+
/** The slice a test file belongs to, by claim pattern, or null. */
|
|
68
|
+
testOwner(path: string): string | null;
|
|
69
|
+
/**
|
|
70
|
+
* A file's package (VSA §3): the nearest ancestor directory holding a package.json in the tree, or the
|
|
71
|
+
* repository root, "", when there is none.
|
|
72
|
+
*/
|
|
73
|
+
packageOf(path: string): string;
|
|
74
|
+
inScope(path: string): boolean;
|
|
75
|
+
isTest(path: string): boolean;
|
|
76
|
+
underBackend(path: string): boolean;
|
|
77
|
+
}
|
|
78
|
+
/** Slices that own files: every slice artifact with slice metadata that is not retired. */
|
|
79
|
+
export declare function activeSlices(graph: Graph): Artifact[];
|
|
80
|
+
export declare function buildModel(graph: Graph, registries: Registries, tree: ReadonlyMap<string, string>, config: ArchitectureConfig): Model;
|
|
81
|
+
/** The deepest of the slice's entrypoint directories above a file, or null when it lies under none (a backend claim, say). */
|
|
82
|
+
export declare function rootOf(slice: SliceInfo, path: string): string | null;
|
|
83
|
+
/** "the repository root" or "the package at apps/web", for messages. */
|
|
84
|
+
export declare function describePackage(directory: string): string;
|
|
85
|
+
//# sourceMappingURL=regions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"regions.d.ts","sourceRoot":"","sources":["../src/regions.ts"],"names":[],"mappings":"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"}
|
package/dist/regions.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { ancestors, dirname, isCode, within } from "./paths.js";
|
|
2
|
+
import { compareStrings, expandClaims, matchAny, matchPattern, validatePattern } from "./patterns.js";
|
|
3
|
+
export function regionLabel(region) {
|
|
4
|
+
return region.owner === undefined ? region.kind : `${region.kind}:${region.owner}`;
|
|
5
|
+
}
|
|
6
|
+
/** Slices that own files: every slice artifact with slice metadata that is not retired. */
|
|
7
|
+
export function activeSlices(graph) {
|
|
8
|
+
return [...graph.artifacts.values()]
|
|
9
|
+
.filter((artifact) => artifact.meta.type === "slice" && artifact.meta.slice !== undefined && artifact.meta.status !== "retired")
|
|
10
|
+
.sort((a, b) => compareStrings(a.meta.id, b.meta.id));
|
|
11
|
+
}
|
|
12
|
+
export function buildModel(graph, registries, tree, config) {
|
|
13
|
+
const files = new Map();
|
|
14
|
+
for (const path of [...tree.keys()].sort(compareStrings)) {
|
|
15
|
+
if (!matchAny(config.ignore, path))
|
|
16
|
+
files.set(path, tree.get(path));
|
|
17
|
+
}
|
|
18
|
+
const isTest = (path) => matchAny(config.tests, path);
|
|
19
|
+
const production = [...files.keys()].filter((path) => !isTest(path));
|
|
20
|
+
const tests = [...files.keys()].filter(isTest);
|
|
21
|
+
const slices = activeSlices(graph).map((artifact) => {
|
|
22
|
+
const meta = artifact.meta.slice;
|
|
23
|
+
const invalidClaims = [];
|
|
24
|
+
meta.claims.forEach((claim, i) => {
|
|
25
|
+
if (validatePattern(claim.path) !== null)
|
|
26
|
+
invalidClaims.push(i);
|
|
27
|
+
});
|
|
28
|
+
// A verification claim names tests, so it resolves against them as well;
|
|
29
|
+
// every other kind resolves against production files only, so a source
|
|
30
|
+
// claim over a directory does not sweep in the tests that sit beside it.
|
|
31
|
+
const withTests = [...production, ...tests].sort(compareStrings);
|
|
32
|
+
const claimFiles = meta.claims.map((claim, i) => invalidClaims.includes(i)
|
|
33
|
+
? []
|
|
34
|
+
: (expandClaims([claim], claim.kind === "verification" ? withTests : production, [])[0] ?? []));
|
|
35
|
+
return {
|
|
36
|
+
id: artifact.meta.id,
|
|
37
|
+
path: artifact.path,
|
|
38
|
+
artifact,
|
|
39
|
+
meta,
|
|
40
|
+
roots: [...new Set(meta.entrypoints.map(dirname))].sort(compareStrings),
|
|
41
|
+
dependsOn: [...(artifact.meta.links.dependsOn ?? [])].sort(compareStrings),
|
|
42
|
+
exposes: [...(artifact.meta.links.exposes ?? [])].sort(compareStrings),
|
|
43
|
+
consumes: [...(artifact.meta.links.consumes ?? [])].sort(compareStrings),
|
|
44
|
+
claimFiles,
|
|
45
|
+
invalidClaims,
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
const sliceById = new Map(slices.map((slice) => [slice.id, slice]));
|
|
49
|
+
const claimOwners = new Map();
|
|
50
|
+
for (const slice of slices) {
|
|
51
|
+
slice.claimFiles.forEach((list, claim) => {
|
|
52
|
+
for (const file of list) {
|
|
53
|
+
const owners = claimOwners.get(file) ?? [];
|
|
54
|
+
owners.push({ slice: slice.id, claim });
|
|
55
|
+
claimOwners.set(file, owners);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
// A file two slices claim is VSA009 either way; for its region, the slice whose directory holds it is the
|
|
60
|
+
// likelier owner, so an overlap reports once rather than turning every import of the file into a boundary error.
|
|
61
|
+
const home = (file, id) => rootOf(sliceById.get(id), file)?.length ?? -1;
|
|
62
|
+
for (const [file, owners] of claimOwners) {
|
|
63
|
+
owners.sort((a, b) => home(file, b.slice) - home(file, a.slice) || compareStrings(a.slice, b.slice) || a.claim - b.claim);
|
|
64
|
+
}
|
|
65
|
+
const resources = registries.resources.map((resource, index) => ({
|
|
66
|
+
resource,
|
|
67
|
+
index,
|
|
68
|
+
files: validatePattern(resource.path) === null ? production.filter((file) => matchPattern(resource.path, file)) : [],
|
|
69
|
+
}));
|
|
70
|
+
const underBackend = (path) => matchAny(config.backendRoots, path);
|
|
71
|
+
const regions = new Map();
|
|
72
|
+
const regionOf = (path) => {
|
|
73
|
+
const cached = regions.get(path);
|
|
74
|
+
if (cached !== undefined)
|
|
75
|
+
return cached;
|
|
76
|
+
let region;
|
|
77
|
+
const owners = claimOwners.get(path);
|
|
78
|
+
if (owners !== undefined && owners.length > 0)
|
|
79
|
+
region = { kind: "slice", owner: owners[0].slice };
|
|
80
|
+
else if (matchAny(config.composition, path))
|
|
81
|
+
region = { kind: "composition" };
|
|
82
|
+
else if (matchAny(config.shared, path))
|
|
83
|
+
region = { kind: "shared" };
|
|
84
|
+
else if (matchAny(config.infrastructure, path))
|
|
85
|
+
region = { kind: "infrastructure" };
|
|
86
|
+
else if (underBackend(path)) {
|
|
87
|
+
const resource = resources.find((info) => info.files.includes(path));
|
|
88
|
+
region = resource !== undefined ? { kind: "resource", owner: resource.resource.id } : { kind: "backend" };
|
|
89
|
+
}
|
|
90
|
+
else if (isCode(path) && matchAny(config.sourceRoots, path))
|
|
91
|
+
region = { kind: "unowned" };
|
|
92
|
+
else
|
|
93
|
+
region = { kind: "external" };
|
|
94
|
+
regions.set(path, region);
|
|
95
|
+
return region;
|
|
96
|
+
};
|
|
97
|
+
const packages = new Map();
|
|
98
|
+
const packageOf = (path) => {
|
|
99
|
+
const directory = dirname(path);
|
|
100
|
+
const cached = packages.get(directory);
|
|
101
|
+
if (cached !== undefined)
|
|
102
|
+
return cached;
|
|
103
|
+
const found = ancestors(directory).find((dir) => files.has(dir === "" ? "package.json" : `${dir}/package.json`)) ?? "";
|
|
104
|
+
packages.set(directory, found);
|
|
105
|
+
return found;
|
|
106
|
+
};
|
|
107
|
+
const testOwner = (path) => {
|
|
108
|
+
for (const slice of slices) {
|
|
109
|
+
if (slice.meta.claims.some((claim, i) => !slice.invalidClaims.includes(i) && matchPattern(claim.path, path)))
|
|
110
|
+
return slice.id;
|
|
111
|
+
}
|
|
112
|
+
return null;
|
|
113
|
+
};
|
|
114
|
+
return {
|
|
115
|
+
config,
|
|
116
|
+
files,
|
|
117
|
+
production,
|
|
118
|
+
tests,
|
|
119
|
+
slices,
|
|
120
|
+
sliceById,
|
|
121
|
+
claimOwners,
|
|
122
|
+
resources,
|
|
123
|
+
regionOf,
|
|
124
|
+
testOwner,
|
|
125
|
+
packageOf,
|
|
126
|
+
inScope: (path) => matchAny(config.scope, path),
|
|
127
|
+
isTest,
|
|
128
|
+
underBackend,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
/** The deepest of the slice's entrypoint directories above a file, or null when it lies under none (a backend claim, say). */
|
|
132
|
+
export function rootOf(slice, path) {
|
|
133
|
+
let found = null;
|
|
134
|
+
for (const root of slice.roots) {
|
|
135
|
+
if (within(root, path) !== null && (found === null || root.length > found.length))
|
|
136
|
+
found = root;
|
|
137
|
+
}
|
|
138
|
+
return found;
|
|
139
|
+
}
|
|
140
|
+
/** "the repository root" or "the package at apps/web", for messages. */
|
|
141
|
+
export function describePackage(directory) {
|
|
142
|
+
return directory === "" ? "the repository root" : `the package at ${directory}`;
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=regions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"regions.js","sourceRoot":"","sources":["../src/regions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module resolution over an in-memory tree (profile TS002, TS004–TS006).
|
|
3
|
+
*
|
|
4
|
+
* A specifier resolves, in order, as: a relative path against the importing
|
|
5
|
+
* file; an alias from the nearest tsconfig's `paths`; a path under its
|
|
6
|
+
* `baseUrl`; a workspace package whose package.json is in the tree; or an
|
|
7
|
+
* external package, which is outside the repository and ignored. A specifier
|
|
8
|
+
* that is none of these is a problem the caller reports, never a silent miss.
|
|
9
|
+
*
|
|
10
|
+
* File probes follow TypeScript: `./x.js` tries `./x.ts` and `./x.tsx` first,
|
|
11
|
+
* then the exact file, then `x` plus each code extension, then `x/index.*`.
|
|
12
|
+
* A workspace package's entry is its `exports` (the configured conditions,
|
|
13
|
+
* then types, import, default), then `types`, then `main`; nothing is
|
|
14
|
+
* guessed, so a package that exports only built output that is not in the
|
|
15
|
+
* tree is a problem until a source condition is configured.
|
|
16
|
+
*/
|
|
17
|
+
import type { ArchitectureConfig } from "./config.ts";
|
|
18
|
+
import { TsConfigs } from "./tsconfig.ts";
|
|
19
|
+
export type Via = "relative" | "alias" | "baseUrl" | "workspace" | "package";
|
|
20
|
+
export interface Resolution {
|
|
21
|
+
/** Repository path of the target, or null for an external package or a problem. */
|
|
22
|
+
to: string | null;
|
|
23
|
+
via: Via;
|
|
24
|
+
/** True when a wildcard opened the path: a `*` alias, an exports pattern, or a package without exports. */
|
|
25
|
+
wildcard: boolean;
|
|
26
|
+
/** Why the specifier could not be resolved; absent when it resolved or is an external package. */
|
|
27
|
+
problem?: string;
|
|
28
|
+
}
|
|
29
|
+
export declare class Resolver {
|
|
30
|
+
readonly tsconfigs: TsConfigs;
|
|
31
|
+
readonly notes: {
|
|
32
|
+
path: string;
|
|
33
|
+
message: string;
|
|
34
|
+
}[];
|
|
35
|
+
private readonly files;
|
|
36
|
+
private readonly conditions;
|
|
37
|
+
private readonly packages;
|
|
38
|
+
constructor(files: ReadonlyMap<string, string>, config: Pick<ArchitectureConfig, "conditions">);
|
|
39
|
+
/** The first existing file a module path names. */
|
|
40
|
+
probe(base: string): string | null;
|
|
41
|
+
resolve(from: string, specifier: string): Resolution;
|
|
42
|
+
private resolveWorkspace;
|
|
43
|
+
private fromExports;
|
|
44
|
+
/** Targets of an exports value in the order tried: configured conditions, then types, import, default. */
|
|
45
|
+
private conditionTargets;
|
|
46
|
+
/**
|
|
47
|
+
* A configured specifier — a tsconfig alias or a workspace package name —
|
|
48
|
+
* that resolves from `from` to `target`, shortest first; null when none
|
|
49
|
+
* does. TS002 asks for this before calling a relative path a bypass.
|
|
50
|
+
*/
|
|
51
|
+
aliasFor(from: string, target: string): string | null;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=resolve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAGtD,OAAO,EAAc,SAAS,EAAE,MAAM,eAAe,CAAC;AAEtD,MAAM,MAAM,GAAG,GAAG,UAAU,GAAG,OAAO,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;AAE7E,MAAM,WAAW,UAAU;IACzB,mFAAmF;IACnF,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,GAAG,EAAE,GAAG,CAAC;IACT,2GAA2G;IAC3G,QAAQ,EAAE,OAAO,CAAC;IAClB,kGAAkG;IAClG,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAoBD,qBAAa,QAAQ;IACnB,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAM;IACzD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA8B;IACpD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAW;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0B;IAEnD,YAAY,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,kBAAkB,EAAE,YAAY,CAAC,EA4B7F;IAED,mDAAmD;IACnD,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAcjC;IAED,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,UAAU,CAkDnD;IAED,OAAO,CAAC,gBAAgB;IA2CxB,OAAO,CAAC,WAAW;IA+BnB,0GAA0G;IAC1G,OAAO,CAAC,gBAAgB;IAUxB;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAkCpD;CACF"}
|