@descent-vtt/spec-guard 0.5.1 → 0.7.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/CHANGELOG.md +444 -283
- package/README.md +1094 -868
- package/dist/cli.d.ts +18 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +136 -7
- package/dist/cli.js.map +1 -1
- package/dist/glob.d.ts +17 -2
- package/dist/glob.d.ts.map +1 -1
- package/dist/glob.js +25 -9
- package/dist/glob.js.map +1 -1
- package/dist/graph.d.ts +124 -0
- package/dist/graph.d.ts.map +1 -0
- package/dist/graph.js +241 -0
- package/dist/graph.js.map +1 -0
- package/dist/index.d.ts +19 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -3
- package/dist/index.js.map +1 -1
- package/dist/layers.d.ts +72 -0
- package/dist/layers.d.ts.map +1 -0
- package/dist/layers.js +102 -0
- package/dist/layers.js.map +1 -0
- package/dist/mcp.d.ts +117 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +544 -0
- package/dist/mcp.js.map +1 -0
- package/dist/parser.d.ts +50 -1
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +232 -16
- package/dist/parser.js.map +1 -1
- package/dist/query.d.ts +108 -0
- package/dist/query.d.ts.map +1 -0
- package/dist/query.js +206 -0
- package/dist/query.js.map +1 -0
- package/dist/reporter.d.ts.map +1 -1
- package/dist/reporter.js +62 -5
- package/dist/reporter.js.map +1 -1
- package/dist/rules.d.ts +108 -0
- package/dist/rules.d.ts.map +1 -0
- package/dist/rules.js +153 -0
- package/dist/rules.js.map +1 -0
- package/dist/runner.d.ts +24 -0
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +335 -117
- package/dist/runner.js.map +1 -1
- package/dist/specs.d.ts +44 -0
- package/dist/specs.d.ts.map +1 -0
- package/dist/specs.js +62 -0
- package/dist/specs.js.map +1 -0
- package/dist/types.d.ts +60 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +73 -73
package/dist/graph.d.ts
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The import graph behind `@assert-import-cycle`.
|
|
3
|
+
*
|
|
4
|
+
* Pure: no filesystem, no reading. The runner walks and tokenizes; everything
|
|
5
|
+
* here is a function of the references it was handed and the list of files the
|
|
6
|
+
* walk produced. That is the one thing ADR-0011 changed about resolution. A
|
|
7
|
+
* specifier is still turned into a path by arithmetic alone, as ADR-0005
|
|
8
|
+
* requires - but the path may now be compared with a set the run already holds,
|
|
9
|
+
* and that membership test is what gives a reference a file to point at.
|
|
10
|
+
*
|
|
11
|
+
* Layering lives elsewhere, in `layers.ts`, and on purpose. A layering rule
|
|
12
|
+
* matches names and never needs to know which file a reference is; a cycle
|
|
13
|
+
* cannot be seen without knowing exactly that. The two rest on different
|
|
14
|
+
* foundations, and keeping them in different modules keeps either from
|
|
15
|
+
* borrowing the other's.
|
|
16
|
+
*/
|
|
17
|
+
import { type ModuleReference } from './imports.js';
|
|
18
|
+
/**
|
|
19
|
+
* Every file a relative specifier might mean, most likely first.
|
|
20
|
+
*
|
|
21
|
+
* The whole resolver, and deliberately short enough to read in one go: the
|
|
22
|
+
* TypeScript source of an emitted extension, the path as written, the path
|
|
23
|
+
* with an extension, the directory's index. No `tsconfig` paths, no `exports`
|
|
24
|
+
* maps, no guessing at a build - ADR-0011 has the table and the reasons.
|
|
25
|
+
*/
|
|
26
|
+
export declare function candidates(resolved: string): string[];
|
|
27
|
+
/**
|
|
28
|
+
* Where a reference leads, as far as the graph is concerned.
|
|
29
|
+
*
|
|
30
|
+
* `edge` has a file. The other four do not, and they are distinguished because
|
|
31
|
+
* only one of them is a hole in the answer: `outside`, `not-code` and
|
|
32
|
+
* `external` are references the graph was never meant to follow, while
|
|
33
|
+
* `unresolved` is one it should have followed and could not.
|
|
34
|
+
*/
|
|
35
|
+
export type Resolution = {
|
|
36
|
+
kind: 'edge';
|
|
37
|
+
file: string;
|
|
38
|
+
} | {
|
|
39
|
+
kind: 'outside';
|
|
40
|
+
} | {
|
|
41
|
+
kind: 'not-code';
|
|
42
|
+
} | {
|
|
43
|
+
kind: 'external';
|
|
44
|
+
} | {
|
|
45
|
+
kind: 'unresolved';
|
|
46
|
+
};
|
|
47
|
+
export interface GraphScope {
|
|
48
|
+
/** The graph's nodes: JS and TS files in scope, root-relative, POSIX. */
|
|
49
|
+
nodes: ReadonlySet<string>;
|
|
50
|
+
/** Every file the walk produced, whatever its language. */
|
|
51
|
+
walked: ReadonlySet<string>;
|
|
52
|
+
/** Whether a root-relative path lies under one of the assertion's targets. */
|
|
53
|
+
covers: (relativePath: string) => boolean;
|
|
54
|
+
/** Whether a root-relative path is left out by the assertion's `exclude`. */
|
|
55
|
+
excluded: (relativePath: string) => boolean;
|
|
56
|
+
}
|
|
57
|
+
/** Resolves one specifier written in `importingFile` against the graph's scope. */
|
|
58
|
+
export declare function resolveReference(specifier: string, importingFile: string, scope: GraphScope): Resolution;
|
|
59
|
+
/** Whether a path is a file the graph can hold. */
|
|
60
|
+
export declare function isGraphFile(relativePath: string): boolean;
|
|
61
|
+
export interface GraphInput {
|
|
62
|
+
/** Root-relative path of the importing file. */
|
|
63
|
+
file: string;
|
|
64
|
+
references: readonly ModuleReference[];
|
|
65
|
+
}
|
|
66
|
+
export interface Unresolved {
|
|
67
|
+
file: string;
|
|
68
|
+
reference: ModuleReference;
|
|
69
|
+
}
|
|
70
|
+
export interface ImportGraph {
|
|
71
|
+
/** Every node, in path order. */
|
|
72
|
+
nodes: string[];
|
|
73
|
+
/** Out-edges of each node that has any, in path order, without duplicates. */
|
|
74
|
+
successors: Map<string, string[]>;
|
|
75
|
+
/** The first reference, in source order, that produced each edge. */
|
|
76
|
+
via: Map<string, ModuleReference>;
|
|
77
|
+
/** References that should have produced an edge and did not. */
|
|
78
|
+
unresolved: Unresolved[];
|
|
79
|
+
}
|
|
80
|
+
/** The key `via` stores an edge under. */
|
|
81
|
+
export declare function edgeKey(from: string, to: string): string;
|
|
82
|
+
/**
|
|
83
|
+
* Builds the graph from each file's references.
|
|
84
|
+
*
|
|
85
|
+
* Type-only references are left out when `includeTypes` is false, which is the
|
|
86
|
+
* difference between the coupling question and the runtime one - erased imports
|
|
87
|
+
* create no load-order cycle.
|
|
88
|
+
*/
|
|
89
|
+
export declare function buildGraph(inputs: readonly GraphInput[], scope: GraphScope, includeTypes: boolean): ImportGraph;
|
|
90
|
+
/**
|
|
91
|
+
* Tarjan's strongly connected components, iteratively.
|
|
92
|
+
*
|
|
93
|
+
* The recursive form is the textbook one and recurses once per node on a
|
|
94
|
+
* dependency chain, so a long enough chain - a generated barrel file will make
|
|
95
|
+
* one - overflows the stack. Here the call stack is an explicit array of frames,
|
|
96
|
+
* each remembering how far through its out-edges it had got.
|
|
97
|
+
*
|
|
98
|
+
* Every component is returned, including the single nodes that are not in any
|
|
99
|
+
* cycle; `cyclicComponents` is the filter.
|
|
100
|
+
*/
|
|
101
|
+
export declare function stronglyConnected(nodes: readonly string[], successors: ReadonlyMap<string, readonly string[]>): string[][];
|
|
102
|
+
/**
|
|
103
|
+
* The components that contain a cycle, each in path order, ordered by first
|
|
104
|
+
* member.
|
|
105
|
+
*
|
|
106
|
+
* A component of one node is a cycle only if that node imports itself. The
|
|
107
|
+
* ordering is for the report: the same tree yields the same list, whichever
|
|
108
|
+
* order the walk or the tokenizer happened to finish in.
|
|
109
|
+
*/
|
|
110
|
+
export declare function cyclicComponents(graph: Pick<ImportGraph, 'nodes' | 'successors'>): string[][];
|
|
111
|
+
/**
|
|
112
|
+
* One concrete cycle through a component: the shortest through its first file.
|
|
113
|
+
*
|
|
114
|
+
* A component is a set, and nobody fixes a set. What someone changes is an
|
|
115
|
+
* import, so the report has to name the imports that close a loop. Breadth-first
|
|
116
|
+
* from the first file, confined to the component - a node outside it cannot lead
|
|
117
|
+
* back, so searching there costs time and cannot change the answer - and the
|
|
118
|
+
* first node reached that imports the start closes the shortest loop.
|
|
119
|
+
*
|
|
120
|
+
* Returned with the start at both ends: `[a, b, a]`, or `[a, a]` for a file that
|
|
121
|
+
* imports itself.
|
|
122
|
+
*/
|
|
123
|
+
export declare function witness(component: readonly string[], successors: ReadonlyMap<string, readonly string[]>): string[];
|
|
124
|
+
//# sourceMappingURL=graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,EAAiB,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAenE;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CASrD;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,CAAC;AAE3B,MAAM,WAAW,UAAU;IACzB,yEAAyE;IACzE,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3B,2DAA2D;IAC3D,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC5B,8EAA8E;IAC9E,MAAM,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC;IAC1C,6EAA6E;IAC7E,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC;CAC7C;AAmBD,mFAAmF;AACnF,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,UAAU,CAoBxG;AAED,mDAAmD;AACnD,wBAAgB,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAEzD;AAID,MAAM,WAAW,UAAU;IACzB,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,SAAS,eAAe,EAAE,CAAC;CACxC;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,eAAe,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,iCAAiC;IACjC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,8EAA8E;IAC9E,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAClC,qEAAqE;IACrE,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAClC,gEAAgE;IAChE,UAAU,EAAE,UAAU,EAAE,CAAC;CAC1B;AAED,0CAA0C;AAC1C,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,OAAO,GAAG,WAAW,CAsB/G;AAID;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,EAAE,CAiD1H;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,YAAY,CAAC,GAAG,MAAM,EAAE,EAAE,CAU7F;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,OAAO,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,EAAE,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,CAyBlH"}
|
package/dist/graph.js
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The import graph behind `@assert-import-cycle`.
|
|
3
|
+
*
|
|
4
|
+
* Pure: no filesystem, no reading. The runner walks and tokenizes; everything
|
|
5
|
+
* here is a function of the references it was handed and the list of files the
|
|
6
|
+
* walk produced. That is the one thing ADR-0011 changed about resolution. A
|
|
7
|
+
* specifier is still turned into a path by arithmetic alone, as ADR-0005
|
|
8
|
+
* requires - but the path may now be compared with a set the run already holds,
|
|
9
|
+
* and that membership test is what gives a reference a file to point at.
|
|
10
|
+
*
|
|
11
|
+
* Layering lives elsewhere, in `layers.ts`, and on purpose. A layering rule
|
|
12
|
+
* matches names and never needs to know which file a reference is; a cycle
|
|
13
|
+
* cannot be seen without knowing exactly that. The two rest on different
|
|
14
|
+
* foundations, and keeping them in different modules keeps either from
|
|
15
|
+
* borrowing the other's.
|
|
16
|
+
*/
|
|
17
|
+
import path from 'node:path';
|
|
18
|
+
import { comparePaths } from './engine.js';
|
|
19
|
+
import { JS_EXTENSIONS } from './imports.js';
|
|
20
|
+
/* --------------------------------------------------------------- resolution */
|
|
21
|
+
/** What an emitted extension was compiled from, in the order TypeScript tries. */
|
|
22
|
+
const SOURCE_EXTENSIONS = {
|
|
23
|
+
'.js': ['.ts', '.tsx'],
|
|
24
|
+
'.jsx': ['.tsx'],
|
|
25
|
+
'.mjs': ['.mts'],
|
|
26
|
+
'.cjs': ['.cts'],
|
|
27
|
+
};
|
|
28
|
+
/** Appended to an extensionless path, and to `/index`, in TypeScript's order. */
|
|
29
|
+
const APPENDED_EXTENSIONS = ['.ts', '.tsx', '.d.ts', '.js', '.jsx', '.mjs', '.cjs', '.mts', '.cts'];
|
|
30
|
+
/**
|
|
31
|
+
* Every file a relative specifier might mean, most likely first.
|
|
32
|
+
*
|
|
33
|
+
* The whole resolver, and deliberately short enough to read in one go: the
|
|
34
|
+
* TypeScript source of an emitted extension, the path as written, the path
|
|
35
|
+
* with an extension, the directory's index. No `tsconfig` paths, no `exports`
|
|
36
|
+
* maps, no guessing at a build - ADR-0011 has the table and the reasons.
|
|
37
|
+
*/
|
|
38
|
+
export function candidates(resolved) {
|
|
39
|
+
const extension = path.posix.extname(resolved);
|
|
40
|
+
const stem = resolved.slice(0, resolved.length - extension.length);
|
|
41
|
+
return [
|
|
42
|
+
...(SOURCE_EXTENSIONS[extension] ?? []).map((source) => `${stem}${source}`),
|
|
43
|
+
resolved,
|
|
44
|
+
...APPENDED_EXTENSIONS.map((appended) => `${resolved}${appended}`),
|
|
45
|
+
...APPENDED_EXTENSIONS.map((appended) => `${resolved}/index${appended}`),
|
|
46
|
+
];
|
|
47
|
+
}
|
|
48
|
+
function isRelative(specifier) {
|
|
49
|
+
return specifier === '.' || specifier === '..' || specifier.startsWith('./') || specifier.startsWith('../');
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* A non-relative specifier that no package could be named.
|
|
53
|
+
*
|
|
54
|
+
* `#` is Node's prefix for imports private to the importing package, and `@/`,
|
|
55
|
+
* `~/` and a leading `/` are not valid package names. Something written that way
|
|
56
|
+
* has to be an alias for code inside the project, so an edge that cannot be
|
|
57
|
+
* followed is missing rather than absent. This is the only inference in the
|
|
58
|
+
* resolver, and it is made from npm's naming rules, not from anyone's config.
|
|
59
|
+
*/
|
|
60
|
+
function cannotBePackage(specifier) {
|
|
61
|
+
return /^(?:#|@\/|~\/|\/)/.test(specifier);
|
|
62
|
+
}
|
|
63
|
+
/** Resolves one specifier written in `importingFile` against the graph's scope. */
|
|
64
|
+
export function resolveReference(specifier, importingFile, scope) {
|
|
65
|
+
if (!isRelative(specifier)) {
|
|
66
|
+
return cannotBePackage(specifier) ? { kind: 'unresolved' } : { kind: 'external' };
|
|
67
|
+
}
|
|
68
|
+
const resolved = path.posix.join(path.posix.dirname(importingFile), specifier).replace(/\/$/, '');
|
|
69
|
+
const names = candidates(resolved);
|
|
70
|
+
const file = names.find((candidate) => scope.nodes.has(candidate));
|
|
71
|
+
if (file !== undefined)
|
|
72
|
+
return { kind: 'edge', file };
|
|
73
|
+
// Every name for `exclude`, not only the path as written: `exclude="src/b.ts"`
|
|
74
|
+
// names the file and `./b.js` is what imports it, and tested against the
|
|
75
|
+
// specifier alone an excluded file looked like a broken import and failed
|
|
76
|
+
// --strict. Targets need no such care - a candidate only ever appends to the
|
|
77
|
+
// path, so it is under a target exactly when the path is.
|
|
78
|
+
if (!scope.covers(resolved) || names.some(scope.excluded))
|
|
79
|
+
return { kind: 'outside' };
|
|
80
|
+
// Membership, not an extension list. `./styles.css` that exists is not code;
|
|
81
|
+
// `./widget.service` that does not exist is a broken import, whatever its
|
|
82
|
+
// suffix happens to look like.
|
|
83
|
+
if (scope.walked.has(resolved))
|
|
84
|
+
return { kind: 'not-code' };
|
|
85
|
+
return { kind: 'unresolved' };
|
|
86
|
+
}
|
|
87
|
+
/** Whether a path is a file the graph can hold. */
|
|
88
|
+
export function isGraphFile(relativePath) {
|
|
89
|
+
return JS_EXTENSIONS.has(path.posix.extname(relativePath));
|
|
90
|
+
}
|
|
91
|
+
/** The key `via` stores an edge under. */
|
|
92
|
+
export function edgeKey(from, to) {
|
|
93
|
+
return `${from}\n${to}`;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Builds the graph from each file's references.
|
|
97
|
+
*
|
|
98
|
+
* Type-only references are left out when `includeTypes` is false, which is the
|
|
99
|
+
* difference between the coupling question and the runtime one - erased imports
|
|
100
|
+
* create no load-order cycle.
|
|
101
|
+
*/
|
|
102
|
+
export function buildGraph(inputs, scope, includeTypes) {
|
|
103
|
+
const targets = new Map();
|
|
104
|
+
const via = new Map();
|
|
105
|
+
const unresolved = [];
|
|
106
|
+
for (const { file, references } of inputs) {
|
|
107
|
+
for (const reference of references) {
|
|
108
|
+
if (reference.typeOnly && !includeTypes)
|
|
109
|
+
continue;
|
|
110
|
+
const resolution = resolveReference(reference.specifier, file, scope);
|
|
111
|
+
if (resolution.kind === 'unresolved')
|
|
112
|
+
unresolved.push({ file, reference });
|
|
113
|
+
if (resolution.kind !== 'edge')
|
|
114
|
+
continue;
|
|
115
|
+
const out = targets.get(file) ?? new Set();
|
|
116
|
+
targets.set(file, out);
|
|
117
|
+
out.add(resolution.file);
|
|
118
|
+
const key = edgeKey(file, resolution.file);
|
|
119
|
+
if (!via.has(key))
|
|
120
|
+
via.set(key, reference);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const successors = new Map([...targets].map(([file, out]) => [file, [...out].sort(comparePaths)]));
|
|
124
|
+
return { nodes: [...scope.nodes].sort(comparePaths), successors, via, unresolved };
|
|
125
|
+
}
|
|
126
|
+
/* ------------------------------------------------------------------- cycles */
|
|
127
|
+
/**
|
|
128
|
+
* Tarjan's strongly connected components, iteratively.
|
|
129
|
+
*
|
|
130
|
+
* The recursive form is the textbook one and recurses once per node on a
|
|
131
|
+
* dependency chain, so a long enough chain - a generated barrel file will make
|
|
132
|
+
* one - overflows the stack. Here the call stack is an explicit array of frames,
|
|
133
|
+
* each remembering how far through its out-edges it had got.
|
|
134
|
+
*
|
|
135
|
+
* Every component is returned, including the single nodes that are not in any
|
|
136
|
+
* cycle; `cyclicComponents` is the filter.
|
|
137
|
+
*/
|
|
138
|
+
export function stronglyConnected(nodes, successors) {
|
|
139
|
+
const index = new Map();
|
|
140
|
+
const low = new Map();
|
|
141
|
+
const stack = [];
|
|
142
|
+
const onStack = new Set();
|
|
143
|
+
const components = [];
|
|
144
|
+
const visit = (node) => {
|
|
145
|
+
const order = index.size;
|
|
146
|
+
index.set(node, order);
|
|
147
|
+
low.set(node, order);
|
|
148
|
+
stack.push(node);
|
|
149
|
+
onStack.add(node);
|
|
150
|
+
return { node, next: 0 };
|
|
151
|
+
};
|
|
152
|
+
for (const start of nodes) {
|
|
153
|
+
if (index.has(start))
|
|
154
|
+
continue;
|
|
155
|
+
const frames = [visit(start)];
|
|
156
|
+
while (frames.length > 0) {
|
|
157
|
+
const frame = frames[frames.length - 1];
|
|
158
|
+
const out = successors.get(frame.node) ?? [];
|
|
159
|
+
if (frame.next < out.length) {
|
|
160
|
+
const next = out[frame.next++];
|
|
161
|
+
if (!index.has(next))
|
|
162
|
+
frames.push(visit(next));
|
|
163
|
+
else if (onStack.has(next))
|
|
164
|
+
low.set(frame.node, Math.min(low.get(frame.node), index.get(next)));
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
frames.pop();
|
|
168
|
+
const parent = frames[frames.length - 1];
|
|
169
|
+
if (parent)
|
|
170
|
+
low.set(parent.node, Math.min(low.get(parent.node), low.get(frame.node)));
|
|
171
|
+
if (low.get(frame.node) === index.get(frame.node)) {
|
|
172
|
+
const component = [];
|
|
173
|
+
let member;
|
|
174
|
+
do {
|
|
175
|
+
member = stack.pop();
|
|
176
|
+
onStack.delete(member);
|
|
177
|
+
component.push(member);
|
|
178
|
+
} while (member !== frame.node);
|
|
179
|
+
components.push(component);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return components;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* The components that contain a cycle, each in path order, ordered by first
|
|
187
|
+
* member.
|
|
188
|
+
*
|
|
189
|
+
* A component of one node is a cycle only if that node imports itself. The
|
|
190
|
+
* ordering is for the report: the same tree yields the same list, whichever
|
|
191
|
+
* order the walk or the tokenizer happened to finish in.
|
|
192
|
+
*/
|
|
193
|
+
export function cyclicComponents(graph) {
|
|
194
|
+
return stronglyConnected(graph.nodes, graph.successors)
|
|
195
|
+
.filter((component) => {
|
|
196
|
+
const first = component[0];
|
|
197
|
+
// A file with no imports is not in the map at all; `?.` says so rather
|
|
198
|
+
// than inventing an empty list for it to be absent from.
|
|
199
|
+
return component.length > 1 || graph.successors.get(first)?.includes(first) === true;
|
|
200
|
+
})
|
|
201
|
+
.map((component) => component.sort(comparePaths))
|
|
202
|
+
.sort((a, b) => comparePaths(a[0], b[0]));
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* One concrete cycle through a component: the shortest through its first file.
|
|
206
|
+
*
|
|
207
|
+
* A component is a set, and nobody fixes a set. What someone changes is an
|
|
208
|
+
* import, so the report has to name the imports that close a loop. Breadth-first
|
|
209
|
+
* from the first file, confined to the component - a node outside it cannot lead
|
|
210
|
+
* back, so searching there costs time and cannot change the answer - and the
|
|
211
|
+
* first node reached that imports the start closes the shortest loop.
|
|
212
|
+
*
|
|
213
|
+
* Returned with the start at both ends: `[a, b, a]`, or `[a, a]` for a file that
|
|
214
|
+
* imports itself.
|
|
215
|
+
*/
|
|
216
|
+
export function witness(component, successors) {
|
|
217
|
+
const start = component[0];
|
|
218
|
+
const members = new Set(component);
|
|
219
|
+
const previous = new Map();
|
|
220
|
+
const queue = [start];
|
|
221
|
+
// No `?? []` on these lookups. Every file in a cyclic component imports at
|
|
222
|
+
// least one other file in it - that is what being in one means - so the
|
|
223
|
+
// fallback could never be taken, and a branch nothing can reach reads exactly
|
|
224
|
+
// like one that something can.
|
|
225
|
+
const out = (node) => successors.get(node);
|
|
226
|
+
for (let at = 0; at < queue.length; at++) {
|
|
227
|
+
const node = queue[at];
|
|
228
|
+
for (const next of out(node)) {
|
|
229
|
+
if (!members.has(next) || previous.has(next))
|
|
230
|
+
continue;
|
|
231
|
+
previous.set(next, node);
|
|
232
|
+
queue.push(next);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
const last = queue.find((node) => out(node).includes(start));
|
|
236
|
+
const loop = [start];
|
|
237
|
+
for (let node = last; node !== start; node = previous.get(node))
|
|
238
|
+
loop.splice(1, 0, node);
|
|
239
|
+
return [...loop, start];
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -12,23 +12,35 @@
|
|
|
12
12
|
* ```
|
|
13
13
|
*/
|
|
14
14
|
export { main, parseArgs, version, HELP, UsageError, EXIT_OK, EXIT_FAILED, EXIT_ERROR } from './cli.js';
|
|
15
|
-
export type { CliIO, CliOptions, OutputFormat } from './cli.js';
|
|
15
|
+
export type { CliIO, CliOptions, Command, OutputFormat } from './cli.js';
|
|
16
16
|
export { buildJsRegExp, buildRipgrepArgs, createCachedEngine, enumerateCandidates, escapeRegExp, ANY_FILE_PROBE, findRipgrep, parseRipgrepErrors, isMissingBinary, javascriptEngine, resetRipgrepProbe, resolveEngine, runSearches, scanContent, sortLocations, MAX_FILE_SIZE, SMALL_TREE_BUDGET, } from './engine.js';
|
|
17
17
|
export type { BatchEngine, CachedEngine, Engine, EnginePreference, Enumeration, EnumerationBudget, SearchRequest, } from './engine.js';
|
|
18
|
-
export { compareDirents, createExcludeMatcher, createGlobMatcher, defaultDirectoryReader, expandSpecPatterns, globBase, globToRegExp, isGlob, toPosix, walkFiles, } from './glob.js';
|
|
19
|
-
export type { DirectoryReader, WalkedFile, WalkOptions } from './glob.js';
|
|
18
|
+
export { compareDirents, createExcludeMatcher, createGlobMatcher, defaultDirectoryReader, expandSpecPatterns, globBase, globToRegExp, isGlob, toPosix, walkFiles, walkPaths, } from './glob.js';
|
|
19
|
+
export type { DirectoryReader, WalkedFile, WalkedPath, WalkOptions } from './glob.js';
|
|
20
20
|
export { createScope, isBinary, mergeLedgers, tallyLedger, LedgerBuilder, DEFAULT_SCOPE, DEFAULT_SKIPPED_DIRECTORIES, MAX_LEDGER_ENTRIES, SCAN_EVERYTHING, UNCERTAIN_REASONS, } from './scope.js';
|
|
21
21
|
export type { ScopeLedger, ScopePolicy, SkippedPath, SkipReason } from './scope.js';
|
|
22
22
|
export { analyzeJavaScript, analyzeSource, createImportIndex, extractReferences, resolveModule, resolveSpecifier, tokenize, ANALYSABLE_EXTENSIONS, JS_EXTENSIONS, } from './imports.js';
|
|
23
23
|
export type { AnalysisNote, FileImports, ImportIndex, ModuleReference, NoteKind, ReferenceKind } from './imports.js';
|
|
24
24
|
export { analyzePolyglot, expandUsePath, languageFor, literalValue, logicalLines, matchingClose, normalizeModule, Reader, MAX_EXPANSION, POLYGLOT_EXTENSIONS, } from './polyglot.js';
|
|
25
25
|
export type { ModuleLanguage } from './polyglot.js';
|
|
26
|
+
export { buildGraph, candidates, cyclicComponents, edgeKey, isGraphFile, resolveReference, stronglyConnected, witness, } from './graph.js';
|
|
27
|
+
export type { GraphInput, GraphScope, ImportGraph, Resolution, Unresolved } from './graph.js';
|
|
28
|
+
export { checkLayers, layerMatcher } from './layers.js';
|
|
29
|
+
export type { LayerInput, LayerReport, LayerViolation } from './layers.js';
|
|
26
30
|
export { lineStarts, locate, maskRanges } from './text.js';
|
|
27
|
-
export { maskCode, parseAttributes, parseDirectives } from './parser.js';
|
|
28
|
-
export type { ParseContext } from './parser.js';
|
|
29
|
-
export {
|
|
31
|
+
export { maskCode, parseAttributes, parseDirectives, parseDocument, parseStatus, parseTitle, INACTIVE_STATUSES } from './parser.js';
|
|
32
|
+
export type { ParseContext, ParsedDocument } from './parser.js';
|
|
33
|
+
export { readSpecs, specPath } from './specs.js';
|
|
34
|
+
export type { SpecDocument, SpecSet } from './specs.js';
|
|
35
|
+
export { governs, layerPosition, viewRule, within } from './rules.js';
|
|
36
|
+
export type { DocumentView, LayerPosition, PathShape, QueryPath, RuleView } from './rules.js';
|
|
37
|
+
export { answerQuery, formatQuery, formatQueryJson, inQueriedPaths, loadRuleSet, queryRules, resolveQueryPath, viewDocument, QueryPathError, } from './query.js';
|
|
38
|
+
export type { PathRules, QueryOptions, QueryReport, RuleSet, RuleSetOptions } from './query.js';
|
|
39
|
+
export { classifyRequest, createMcpHandler, documentPath, documentUri, envelopeIssue, negotiateLegacyVersion, serveStdio, LEGACY_PROTOCOL_VERSIONS, MODERN_PROTOCOL_VERSIONS, RESOURCE_TEMPLATES, TOOLS, } from './mcp.js';
|
|
40
|
+
export type { Era, McpServerOptions, OutgoingMessage } from './mcp.js';
|
|
41
|
+
export { applyBaseline, createScopeProbe, executeAssertion, resolveDirective, runSpecGuard, specExclusions, DEFAULT_CONCURRENCY, DEFAULT_MAX_SNIPPETS, } from './runner.js';
|
|
30
42
|
export type { ResolveContext, RunOptions, RunResult } from './runner.js';
|
|
31
43
|
export { createPainter, formatBaselines, formatJson, formatReport, formatSarif, shouldUseAscii, shouldUseColor } from './reporter.js';
|
|
32
44
|
export type { ReporterOptions } from './reporter.js';
|
|
33
|
-
export type { Assertion, AssertionResult, BaselineEntry, Bounds, Directive, DirectiveError, DirectiveKind, EngineName, ImportQuery, MatchLocation, ParseResult, RatchetMode, RunReport, RunSummary, SearchOptions, SearchResult, SourceLocation, StaleBaselineEntry, } from './types.js';
|
|
45
|
+
export type { Assertion, AssertionResult, BaselineEntry, Bounds, Directive, DirectiveError, DirectiveKind, EngineName, ImportQuery, InactiveSpec, MatchLocation, ParseResult, RatchetMode, RunReport, RunSummary, SearchOptions, SearchResult, SourceLocation, SpecStatus, StaleBaselineEntry, } from './types.js';
|
|
34
46
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACxG,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -13,12 +13,18 @@
|
|
|
13
13
|
*/
|
|
14
14
|
export { main, parseArgs, version, HELP, UsageError, EXIT_OK, EXIT_FAILED, EXIT_ERROR } from './cli.js';
|
|
15
15
|
export { buildJsRegExp, buildRipgrepArgs, createCachedEngine, enumerateCandidates, escapeRegExp, ANY_FILE_PROBE, findRipgrep, parseRipgrepErrors, isMissingBinary, javascriptEngine, resetRipgrepProbe, resolveEngine, runSearches, scanContent, sortLocations, MAX_FILE_SIZE, SMALL_TREE_BUDGET, } from './engine.js';
|
|
16
|
-
export { compareDirents, createExcludeMatcher, createGlobMatcher, defaultDirectoryReader, expandSpecPatterns, globBase, globToRegExp, isGlob, toPosix, walkFiles, } from './glob.js';
|
|
16
|
+
export { compareDirents, createExcludeMatcher, createGlobMatcher, defaultDirectoryReader, expandSpecPatterns, globBase, globToRegExp, isGlob, toPosix, walkFiles, walkPaths, } from './glob.js';
|
|
17
17
|
export { createScope, isBinary, mergeLedgers, tallyLedger, LedgerBuilder, DEFAULT_SCOPE, DEFAULT_SKIPPED_DIRECTORIES, MAX_LEDGER_ENTRIES, SCAN_EVERYTHING, UNCERTAIN_REASONS, } from './scope.js';
|
|
18
18
|
export { analyzeJavaScript, analyzeSource, createImportIndex, extractReferences, resolveModule, resolveSpecifier, tokenize, ANALYSABLE_EXTENSIONS, JS_EXTENSIONS, } from './imports.js';
|
|
19
19
|
export { analyzePolyglot, expandUsePath, languageFor, literalValue, logicalLines, matchingClose, normalizeModule, Reader, MAX_EXPANSION, POLYGLOT_EXTENSIONS, } from './polyglot.js';
|
|
20
|
+
export { buildGraph, candidates, cyclicComponents, edgeKey, isGraphFile, resolveReference, stronglyConnected, witness, } from './graph.js';
|
|
21
|
+
export { checkLayers, layerMatcher } from './layers.js';
|
|
20
22
|
export { lineStarts, locate, maskRanges } from './text.js';
|
|
21
|
-
export { maskCode, parseAttributes, parseDirectives } from './parser.js';
|
|
22
|
-
export {
|
|
23
|
+
export { maskCode, parseAttributes, parseDirectives, parseDocument, parseStatus, parseTitle, INACTIVE_STATUSES } from './parser.js';
|
|
24
|
+
export { readSpecs, specPath } from './specs.js';
|
|
25
|
+
export { governs, layerPosition, viewRule, within } from './rules.js';
|
|
26
|
+
export { answerQuery, formatQuery, formatQueryJson, inQueriedPaths, loadRuleSet, queryRules, resolveQueryPath, viewDocument, QueryPathError, } from './query.js';
|
|
27
|
+
export { classifyRequest, createMcpHandler, documentPath, documentUri, envelopeIssue, negotiateLegacyVersion, serveStdio, LEGACY_PROTOCOL_VERSIONS, MODERN_PROTOCOL_VERSIONS, RESOURCE_TEMPLATES, TOOLS, } from './mcp.js';
|
|
28
|
+
export { applyBaseline, createScopeProbe, executeAssertion, resolveDirective, runSpecGuard, specExclusions, DEFAULT_CONCURRENCY, DEFAULT_MAX_SNIPPETS, } from './runner.js';
|
|
23
29
|
export { createPainter, formatBaselines, formatJson, formatReport, formatSarif, shouldUseAscii, shouldUseColor } from './reporter.js';
|
|
24
30
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAGxG,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,EACZ,cAAc,EACd,WAAW,EACX,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,WAAW,EACX,aAAa,EACb,aAAa,EACb,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAWrB,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,EAClB,QAAQ,EACR,YAAY,EACZ,MAAM,EACN,OAAO,EACP,SAAS,GACV,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,aAAa,EACb,aAAa,EACb,2BAA2B,EAC3B,kBAAkB,EAClB,eAAe,EACf,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,QAAQ,EACR,qBAAqB,EACrB,aAAa,GACd,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,eAAe,EACf,aAAa,EACb,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,eAAe,EACf,MAAM,EACN,aAAa,EACb,mBAAmB,GACpB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE3D,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAGxG,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,EACZ,cAAc,EACd,WAAW,EACX,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,WAAW,EACX,aAAa,EACb,aAAa,EACb,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAWrB,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,EAClB,QAAQ,EACR,YAAY,EACZ,MAAM,EACN,OAAO,EACP,SAAS,EACT,SAAS,GACV,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,aAAa,EACb,aAAa,EACb,2BAA2B,EAC3B,kBAAkB,EAClB,eAAe,EACf,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,QAAQ,EACR,qBAAqB,EACrB,aAAa,GACd,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,eAAe,EACf,aAAa,EACb,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,eAAe,EACf,MAAM,EACN,aAAa,EACb,mBAAmB,GACpB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,OAAO,EACP,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,OAAO,GACR,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGxD,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE3D,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,eAAe,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGpI,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGjD,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAGtE,OAAO,EACL,WAAW,EACX,WAAW,EACX,eAAe,EACf,cAAc,EACd,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,cAAc,GACf,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,aAAa,EACb,sBAAsB,EACtB,UAAU,EACV,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,KAAK,GACN,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/layers.d.ts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The layering rule behind `@assert-layers`.
|
|
3
|
+
*
|
|
4
|
+
* Pure, and built on almost nothing new. A layer is a pattern in the language
|
|
5
|
+
* `module=` and `exclude` already speak; a file belongs to a layer when its path
|
|
6
|
+
* matches, and a reference points into one when any name it can denote does -
|
|
7
|
+
* see `referenceForms`. That is why layering needs no resolver and works in
|
|
8
|
+
* every language spec-guard reads: it never asks which file a reference *is*,
|
|
9
|
+
* only which areas it could be about.
|
|
10
|
+
*
|
|
11
|
+
* Cycles are the opposite case, and live in `graph.ts` - see ADR-0011.
|
|
12
|
+
*/
|
|
13
|
+
import { type ModuleReference } from './imports.js';
|
|
14
|
+
/**
|
|
15
|
+
* Every name a reference can be matched under.
|
|
16
|
+
*
|
|
17
|
+
* The specifier as written and the module it resolves to, as `module=` tries -
|
|
18
|
+
* and, for the two languages whose modules are files, the files that module can
|
|
19
|
+
* denote. Without the last, a layer that names a file could never be reached:
|
|
20
|
+
* `src/runner.ts` is where the file is, `./runner.js` is what imports it, and
|
|
21
|
+
* the first rule this project wrote with file-sized layers passed while its
|
|
22
|
+
* order was reversed, because no reference matched any layer at all.
|
|
23
|
+
*
|
|
24
|
+
* Names only. Nothing here asks whether a candidate exists, which is why a layer
|
|
25
|
+
* outside the assertion's target still works: `../infrastructure/db.js` reaches
|
|
26
|
+
* `src/infrastructure/db.ts` whether or not the walk ever went there.
|
|
27
|
+
*/
|
|
28
|
+
export declare function referenceForms(specifier: string, importingFile: string): string[];
|
|
29
|
+
export interface LayerInput {
|
|
30
|
+
/** Root-relative path of the importing file. */
|
|
31
|
+
file: string;
|
|
32
|
+
references: readonly ModuleReference[];
|
|
33
|
+
}
|
|
34
|
+
export interface LayerViolation {
|
|
35
|
+
file: string;
|
|
36
|
+
/** The layer the file belongs to, as an index into the order. */
|
|
37
|
+
from: number;
|
|
38
|
+
/** The latest layer its reference reaches, also an index. */
|
|
39
|
+
to: number;
|
|
40
|
+
/** The first reference, in source order, that reaches a later layer. */
|
|
41
|
+
reference: ModuleReference;
|
|
42
|
+
}
|
|
43
|
+
export interface LayerReport {
|
|
44
|
+
/** Files in scope matched by each layer, by index. */
|
|
45
|
+
members: number[];
|
|
46
|
+
/** Files in scope that no layer matches, and which are therefore unconstrained. */
|
|
47
|
+
unassigned: string[];
|
|
48
|
+
/** Files matched by more than one layer, with every layer that matched. */
|
|
49
|
+
ambiguous: Array<{
|
|
50
|
+
file: string;
|
|
51
|
+
layers: number[];
|
|
52
|
+
}>;
|
|
53
|
+
/** At most one per file. */
|
|
54
|
+
violations: LayerViolation[];
|
|
55
|
+
}
|
|
56
|
+
/** A function from a path to the indices of every layer that matches it. */
|
|
57
|
+
export declare function layerMatcher(order: readonly string[]): (relativePath: string) => number[];
|
|
58
|
+
/**
|
|
59
|
+
* Checks each file's references against the order.
|
|
60
|
+
*
|
|
61
|
+
* A file may import from its own layer and from layers listed before it. The
|
|
62
|
+
* unit of violation is the file, as it is for every import assertion: one
|
|
63
|
+
* import statement split into two is not twice the problem.
|
|
64
|
+
*
|
|
65
|
+
* A file two layers claim is not checked for violations - which layer's rule
|
|
66
|
+
* applies is exactly the thing that is unknown - and is reported instead. So is
|
|
67
|
+
* every file no layer claims, because a shared utility and a directory someone
|
|
68
|
+
* forgot to assign look identical from here and only the author can say which a
|
|
69
|
+
* count describes.
|
|
70
|
+
*/
|
|
71
|
+
export declare function checkLayers(inputs: readonly LayerInput[], order: readonly string[], includeTypes: boolean): LayerReport;
|
|
72
|
+
//# sourceMappingURL=layers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layers.d.ts","sourceRoot":"","sources":["../src/layers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,EAAiB,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAGnE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,EAAE,CAKjF;AAED,MAAM,WAAW,UAAU;IACzB,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,SAAS,eAAe,EAAE,CAAC;CACxC;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,EAAE,EAAE,MAAM,CAAC;IACX,wEAAwE;IACxE,SAAS,EAAE,eAAe,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,sDAAsD;IACtD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,mFAAmF;IACnF,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,2EAA2E;IAC3E,SAAS,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACrD,4BAA4B;IAC5B,UAAU,EAAE,cAAc,EAAE,CAAC;CAC9B;AAED,4EAA4E;AAC5E,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,CAAC,YAAY,EAAE,MAAM,KAAK,MAAM,EAAE,CAIzF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,YAAY,EAAE,OAAO,GAAG,WAAW,CA6CvH"}
|