@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.
Files changed (91) hide show
  1. package/dist/baseline.d.ts +39 -0
  2. package/dist/baseline.d.ts.map +1 -0
  3. package/dist/baseline.js +104 -0
  4. package/dist/baseline.js.map +1 -0
  5. package/dist/boundaries.d.ts +63 -0
  6. package/dist/boundaries.d.ts.map +1 -0
  7. package/dist/boundaries.js +436 -0
  8. package/dist/boundaries.js.map +1 -0
  9. package/dist/check.d.ts +73 -0
  10. package/dist/check.d.ts.map +1 -0
  11. package/dist/check.js +130 -0
  12. package/dist/check.js.map +1 -0
  13. package/dist/claims.d.ts +24 -0
  14. package/dist/claims.d.ts.map +1 -0
  15. package/dist/claims.js +201 -0
  16. package/dist/claims.js.map +1 -0
  17. package/dist/config.d.ts +53 -0
  18. package/dist/config.d.ts.map +1 -0
  19. package/dist/config.js +159 -0
  20. package/dist/config.js.map +1 -0
  21. package/dist/dependencies.d.ts +30 -0
  22. package/dist/dependencies.d.ts.map +1 -0
  23. package/dist/dependencies.js +179 -0
  24. package/dist/dependencies.js.map +1 -0
  25. package/dist/exceptions.d.ts +43 -0
  26. package/dist/exceptions.d.ts.map +1 -0
  27. package/dist/exceptions.js +233 -0
  28. package/dist/exceptions.js.map +1 -0
  29. package/dist/extract.d.ts +24 -0
  30. package/dist/extract.d.ts.map +1 -0
  31. package/dist/extract.js +316 -0
  32. package/dist/extract.js.map +1 -0
  33. package/dist/finding.d.ts +39 -0
  34. package/dist/finding.d.ts.map +1 -0
  35. package/dist/finding.js +29 -0
  36. package/dist/finding.js.map +1 -0
  37. package/dist/imports.d.ts +30 -0
  38. package/dist/imports.d.ts.map +1 -0
  39. package/dist/imports.js +48 -0
  40. package/dist/imports.js.map +1 -0
  41. package/dist/index.d.ts +23 -0
  42. package/dist/index.d.ts.map +1 -0
  43. package/dist/index.js +22 -0
  44. package/dist/index.js.map +1 -0
  45. package/dist/layers.d.ts +38 -0
  46. package/dist/layers.d.ts.map +1 -0
  47. package/dist/layers.js +41 -0
  48. package/dist/layers.js.map +1 -0
  49. package/dist/ownership.d.ts +25 -0
  50. package/dist/ownership.d.ts.map +1 -0
  51. package/dist/ownership.js +97 -0
  52. package/dist/ownership.js.map +1 -0
  53. package/dist/paths.d.ts +18 -0
  54. package/dist/paths.d.ts.map +1 -0
  55. package/dist/paths.js +54 -0
  56. package/dist/paths.js.map +1 -0
  57. package/dist/patterns.d.ts +25 -0
  58. package/dist/patterns.d.ts.map +1 -0
  59. package/dist/patterns.js +101 -0
  60. package/dist/patterns.js.map +1 -0
  61. package/dist/regions.d.ts +85 -0
  62. package/dist/regions.d.ts.map +1 -0
  63. package/dist/regions.js +144 -0
  64. package/dist/regions.js.map +1 -0
  65. package/dist/resolve.d.ts +53 -0
  66. package/dist/resolve.d.ts.map +1 -0
  67. package/dist/resolve.js +268 -0
  68. package/dist/resolve.js.map +1 -0
  69. package/dist/tsconfig.d.ts +42 -0
  70. package/dist/tsconfig.d.ts.map +1 -0
  71. package/dist/tsconfig.js +186 -0
  72. package/dist/tsconfig.js.map +1 -0
  73. package/package.json +36 -0
  74. package/src/baseline.ts +126 -0
  75. package/src/boundaries.ts +499 -0
  76. package/src/check.ts +197 -0
  77. package/src/claims.ts +229 -0
  78. package/src/config.ts +212 -0
  79. package/src/dependencies.ts +211 -0
  80. package/src/exceptions.ts +269 -0
  81. package/src/extract.ts +344 -0
  82. package/src/finding.ts +64 -0
  83. package/src/imports.ts +77 -0
  84. package/src/index.ts +58 -0
  85. package/src/layers.ts +67 -0
  86. package/src/ownership.ts +135 -0
  87. package/src/paths.ts +53 -0
  88. package/src/patterns.ts +95 -0
  89. package/src/regions.ts +243 -0
  90. package/src/resolve.ts +283 -0
  91. package/src/tsconfig.ts +198 -0
@@ -0,0 +1,233 @@
1
+ /**
2
+ * Exception records (VSA §9). A record names one rule and the exact paths or
3
+ * edges it tolerates, with rationale, accountable owner, approver, creation
4
+ * and expiry dates and a remediation issue. Records live one per file in
5
+ * `architecture/exceptions/*.yaml` (profile §1), or are handed in.
6
+ *
7
+ * A diagnostic a current record covers is kept, never hidden: it becomes a
8
+ * warning whose message says which exception covers it and until when, so a
9
+ * report built on it reads "with exceptions" rather than as a pass (Core
10
+ * §11). An expired record is itself an error, VSA013, and what it covered
11
+ * stays an error. A record that is malformed is VSA013 and covers nothing; a
12
+ * current record that covers nothing is a VSA013 warning, so retired
13
+ * violations retire their exceptions too.
14
+ */
15
+ import { ID_PATTERN, parseYamlDetailed } from "@intentset/core";
16
+ import { finding } from "./finding.js";
17
+ import { compareStrings, matchPattern, validatePattern } from "./patterns.js";
18
+ export const EXCEPTIONS_PATTERNS = ["architecture/exceptions/*.yaml", "architecture/exceptions/*.yml"];
19
+ const TEXT_FIELDS = ["id", "rule", "rationale", "owner", "approver", "created", "expires", "remediation"];
20
+ const KNOWN_FIELDS = [...TEXT_FIELDS, "paths", "edges"];
21
+ const DATE = /^(\d{4})-(\d{2})-(\d{2})$/;
22
+ const CODE = /^[A-Z]+[0-9]{3}$/;
23
+ function isDate(text) {
24
+ const match = DATE.exec(text);
25
+ if (match === null)
26
+ return false;
27
+ const date = new Date(Date.UTC(Number(match[1]), Number(match[2]) - 1, Number(match[3])));
28
+ return date.toISOString().slice(0, 10) === text;
29
+ }
30
+ /** Validate one record. Returns the record, or the problems that keep it from covering anything. */
31
+ export function readExceptionRecord(value, source, lines = new Map()) {
32
+ const findings = [];
33
+ const fail = (field, message) => {
34
+ const line = field === undefined ? undefined : lines.get(field);
35
+ findings.push(finding({
36
+ code: "VSA013",
37
+ artifact: null,
38
+ path: source,
39
+ ...(line !== undefined ? { location: { line } } : {}),
40
+ ...(field !== undefined ? { field } : {}),
41
+ message,
42
+ remediation: "An exception records id, rule, paths or edges, rationale, owner, approver, created, expires and remediation (VSA §9).",
43
+ }));
44
+ };
45
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
46
+ fail(undefined, "The exception record is not a mapping.");
47
+ return { record: null, findings };
48
+ }
49
+ const map = value;
50
+ for (const key of Object.keys(map).sort(compareStrings)) {
51
+ if (!KNOWN_FIELDS.includes(key))
52
+ fail(`/${key}`, `The exception record has the unknown key \`${key}\`.`);
53
+ }
54
+ for (const key of TEXT_FIELDS) {
55
+ if (typeof map[key] !== "string" || map[key].trim() === "") {
56
+ fail(`/${key}`, `The exception record has no \`${key}\`.`);
57
+ }
58
+ }
59
+ const text = (key) => (typeof map[key] === "string" ? map[key] : "");
60
+ if (text("id") !== "" && !ID_PATTERN.test(text("id")))
61
+ fail("/id", `The exception id ${text("id")} does not match the ID pattern.`);
62
+ if (text("rule") !== "" && !CODE.test(text("rule")))
63
+ fail("/rule", `The exception rule ${text("rule")} is not a diagnostic code.`);
64
+ for (const key of ["created", "expires"]) {
65
+ if (text(key) !== "" && !isDate(text(key)))
66
+ fail(`/${key}`, `The exception's ${key} date ${text(key)} is not a quoted YYYY-MM-DD date.`);
67
+ }
68
+ if (isDate(text("created")) && isDate(text("expires")) && text("expires") < text("created")) {
69
+ fail("/expires", `The exception expires on ${text("expires")}, before it was created on ${text("created")}.`);
70
+ }
71
+ const paths = [];
72
+ if (map.paths !== undefined && map.paths !== null) {
73
+ if (!Array.isArray(map.paths))
74
+ fail("/paths", "The exception's paths is not a list.");
75
+ else
76
+ map.paths.forEach((item, i) => {
77
+ const why = typeof item === "string" ? validatePattern(item) : "is not a string";
78
+ if (why !== null)
79
+ fail(`/paths/${i}`, `Exception path ${i} ${why}.`);
80
+ else
81
+ paths.push(item);
82
+ });
83
+ }
84
+ const edges = [];
85
+ if (map.edges !== undefined && map.edges !== null) {
86
+ if (!Array.isArray(map.edges))
87
+ fail("/edges", "The exception's edges is not a list.");
88
+ else
89
+ map.edges.forEach((item, i) => {
90
+ const edge = item;
91
+ if (typeof edge !== "object" || edge === null || typeof edge.from !== "string" || typeof edge.to !== "string") {
92
+ fail(`/edges/${i}`, `Exception edge ${i} is not a mapping with from and to.`);
93
+ }
94
+ else
95
+ edges.push({ from: edge.from, to: edge.to });
96
+ });
97
+ }
98
+ if (paths.length === 0 && edges.length === 0) {
99
+ fail("/paths", "The exception names no exact paths or edges, and an exception is never a blanket waiver.");
100
+ }
101
+ if (findings.length > 0)
102
+ return { record: null, findings };
103
+ return {
104
+ record: {
105
+ id: text("id"),
106
+ rule: text("rule"),
107
+ paths,
108
+ edges,
109
+ rationale: text("rationale"),
110
+ owner: text("owner"),
111
+ approver: text("approver"),
112
+ created: text("created"),
113
+ expires: text("expires"),
114
+ remediation: text("remediation"),
115
+ source,
116
+ },
117
+ findings,
118
+ };
119
+ }
120
+ /** Every exception file in the tree, read with core's strict YAML reader. */
121
+ export function readExceptions(files) {
122
+ const records = [];
123
+ const findings = [];
124
+ for (const path of [...files.keys()].sort(compareStrings)) {
125
+ if (!EXCEPTIONS_PATTERNS.some((pattern) => matchPattern(pattern, path)))
126
+ continue;
127
+ const parsed = parseYamlDetailed(files.get(path));
128
+ if (parsed.error !== null) {
129
+ findings.push(finding({
130
+ code: "VSA013",
131
+ artifact: null,
132
+ path,
133
+ location: { line: parsed.error.line },
134
+ message: `The exception file does not parse: ${parsed.error.message}`,
135
+ remediation: "Write the exception as one block mapping (VSA §9).",
136
+ }));
137
+ continue;
138
+ }
139
+ const read = readExceptionRecord(parsed.value, path, parsed.lines);
140
+ findings.push(...read.findings);
141
+ if (read.record !== null)
142
+ records.push(read.record);
143
+ }
144
+ return { records, findings };
145
+ }
146
+ /** Does the record name this finding's rule and one of its exact paths or edges? */
147
+ export function covers(record, target) {
148
+ if (record.rule !== target.diagnostic.code)
149
+ return false;
150
+ if (record.paths.some((pattern) => target.paths.some((path) => matchPattern(pattern, path))))
151
+ return true;
152
+ return record.edges.some((edge) => target.edges.some((other) => other.from === edge.from && other.to === edge.to));
153
+ }
154
+ /** Put a note in parentheses before a message's final period. */
155
+ export function annotate(message, note) {
156
+ return message.endsWith(".") ? `${message.slice(0, -1)} (${note}).` : `${message} (${note})`;
157
+ }
158
+ /**
159
+ * Apply exceptions on a given date (YYYY-MM-DD). Returns the findings with
160
+ * covered ones rewritten, the VSA013 findings about the records themselves,
161
+ * and how many diagnostics a current exception covers.
162
+ */
163
+ export function applyExceptions(findings, records, today) {
164
+ const recordFindings = [];
165
+ const seen = new Map();
166
+ const usable = [];
167
+ for (const record of [...records].sort((a, b) => compareStrings(a.id, b.id) || compareStrings(a.source ?? "", b.source ?? ""))) {
168
+ const earlier = seen.get(record.id);
169
+ if (earlier !== undefined) {
170
+ recordFindings.push(finding({
171
+ code: "VSA013",
172
+ artifact: null,
173
+ path: record.source,
174
+ field: "/id",
175
+ message: `Exception ${record.id} is recorded twice, here and in ${earlier.source ?? "the records handed in"}.`,
176
+ remediation: "Keep one record per exception ID; IDs are never reused (VSA §9).",
177
+ }));
178
+ continue;
179
+ }
180
+ seen.set(record.id, record);
181
+ usable.push(record);
182
+ }
183
+ let excepted = 0;
184
+ const used = new Set();
185
+ const out = findings.map((item) => {
186
+ const record = usable.find((candidate) => covers(candidate, item));
187
+ if (record === undefined)
188
+ return item;
189
+ used.add(record.id);
190
+ if (record.expires < today) {
191
+ return {
192
+ ...item,
193
+ diagnostic: {
194
+ ...item.diagnostic,
195
+ message: annotate(item.diagnostic.message, `exception ${record.id} expired ${record.expires}`),
196
+ },
197
+ };
198
+ }
199
+ excepted++;
200
+ return {
201
+ ...item,
202
+ diagnostic: {
203
+ ...item.diagnostic,
204
+ severity: "warning",
205
+ message: annotate(item.diagnostic.message, `excepted by ${record.id} until ${record.expires}`),
206
+ },
207
+ };
208
+ });
209
+ for (const record of usable) {
210
+ if (record.expires < today) {
211
+ recordFindings.push(finding({
212
+ code: "VSA013",
213
+ artifact: null,
214
+ path: record.source,
215
+ field: "/expires",
216
+ message: `Exception ${record.id} for ${record.rule} expired on ${record.expires}, so what it covered is an error again.`,
217
+ remediation: `Fix the violation tracked by ${record.remediation}, or have ${record.approver} renew the exception with a new expiry (VSA §9).`,
218
+ }));
219
+ }
220
+ else if (!used.has(record.id)) {
221
+ recordFindings.push(finding({
222
+ code: "VSA013",
223
+ severity: "warning",
224
+ artifact: null,
225
+ path: record.source,
226
+ message: `Exception ${record.id} for ${record.rule} covers no current diagnostic.`,
227
+ remediation: "Remove the record; the violation it tolerated is gone (VSA §9).",
228
+ }));
229
+ }
230
+ }
231
+ return { findings: out, excepted, recordFindings };
232
+ }
233
+ //# sourceMappingURL=exceptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exceptions.js","sourceRoot":"","sources":["../src/exceptions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ export interface RawImport {
2
+ specifier: string;
3
+ /** 1-based line of the specifier. */
4
+ line: number;
5
+ /** `import type`, `export type`, every named specifier marked `type`, or `typeof import("x")`. */
6
+ typeOnly: boolean;
7
+ /** `import("x")` or `require("x")`. */
8
+ dynamic: boolean;
9
+ /** `export ... from "x"`. */
10
+ reexport: boolean;
11
+ /** `export * from "x"` or `export * as ns from "x"`. */
12
+ wildcard: boolean;
13
+ }
14
+ export interface ExtractProblem {
15
+ line: number;
16
+ message: string;
17
+ }
18
+ export interface Extraction {
19
+ imports: RawImport[];
20
+ problems: ExtractProblem[];
21
+ }
22
+ /** Extract every module reference from one file. */
23
+ export declare function extractImports(path: string, text: string): Extraction;
24
+ //# sourceMappingURL=extract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../src/extract.ts"],"names":[],"mappings":"AA2BA,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,kGAAkG;IAClG,QAAQ,EAAE,OAAO,CAAC;IAClB,uCAAuC;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,6BAA6B;IAC7B,QAAQ,EAAE,OAAO,CAAC;IAClB,wDAAwD;IACxD,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,QAAQ,EAAE,cAAc,EAAE,CAAC;CAC5B;AAyID,oDAAoD;AACpD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,CA4JrE"}
@@ -0,0 +1,316 @@
1
+ /**
2
+ * Every module reference in one TypeScript or JavaScript file (profile TS004:
3
+ * type-only imports, dynamic imports and re-exports all count).
4
+ *
5
+ * TypeScript 7 ships its parser inside the native compiler and exposes no
6
+ * in-process `createSourceFile`; what it does ship in JavaScript is the
7
+ * scanner. So this module tokenizes with TypeScript's own scanner, which is
8
+ * what gets strings, comments, template literals and regular expressions
9
+ * right, and recognizes the handful of declaration shapes that carry a module
10
+ * specifier over the token stream:
11
+ *
12
+ * import d, { a, type B } from "x" import type { A } from "x"
13
+ * import "x" import X = require("x")
14
+ * export { a } from "x" export type { A } from "x"
15
+ * export * from "x" export * as ns from "x"
16
+ * import("x") require("x")
17
+ *
18
+ * The scanner leaves two decisions to its parser: whether `/` starts a
19
+ * regular expression, and whether `}` resumes a template literal. Both are
20
+ * made here from the preceding token and a stack of template brace depths.
21
+ * Anything this module cannot read is returned as a problem, never dropped:
22
+ * a dynamic import with a computed specifier, or a token the scanner could
23
+ * not terminate (invariant 6).
24
+ */
25
+ import { LanguageVariant, SyntaxKind } from "typescript/unstable/ast";
26
+ import { computeLineStarts, createScanner, tokenIsIdentifierOrKeyword } from "typescript/unstable/ast/scanner";
27
+ /** Keywords after which `/` begins a regular expression rather than a division. */
28
+ const REGEX_AFTER_WORD = new Set([
29
+ "return",
30
+ "typeof",
31
+ "case",
32
+ "in",
33
+ "of",
34
+ "delete",
35
+ "void",
36
+ "throw",
37
+ "new",
38
+ "else",
39
+ "do",
40
+ "instanceof",
41
+ "yield",
42
+ "await",
43
+ ]);
44
+ const VALUE_ENDING = new Set([
45
+ SyntaxKind.NumericLiteral,
46
+ SyntaxKind.BigIntLiteral,
47
+ SyntaxKind.StringLiteral,
48
+ SyntaxKind.RegularExpressionLiteral,
49
+ SyntaxKind.NoSubstitutionTemplateLiteral,
50
+ SyntaxKind.TemplateTail,
51
+ SyntaxKind.CloseParenToken,
52
+ SyntaxKind.CloseBracketToken,
53
+ SyntaxKind.CloseBraceToken,
54
+ SyntaxKind.PlusPlusToken,
55
+ SyntaxKind.MinusMinusToken,
56
+ ]);
57
+ function regexAllowed(previous) {
58
+ if (previous === undefined)
59
+ return true;
60
+ if (VALUE_ENDING.has(previous.kind))
61
+ return false;
62
+ if (tokenIsIdentifierOrKeyword(previous.kind))
63
+ return REGEX_AFTER_WORD.has(previous.text);
64
+ return true;
65
+ }
66
+ function isJsx(path) {
67
+ return path.endsWith(".tsx") || path.endsWith(".jsx");
68
+ }
69
+ function tokenize(path, text) {
70
+ const jsx = isJsx(path);
71
+ const scanner = createScanner(true, jsx ? LanguageVariant.JSX : LanguageVariant.Standard, text);
72
+ const starts = computeLineStarts(text);
73
+ const lineOf = (position) => {
74
+ let low = 0;
75
+ let high = starts.length - 1;
76
+ while (low < high) {
77
+ const mid = (low + high + 1) >> 1;
78
+ if (starts[mid] <= position)
79
+ low = mid;
80
+ else
81
+ high = mid - 1;
82
+ }
83
+ return low + 1;
84
+ };
85
+ const tokens = [];
86
+ const problems = [];
87
+ /** Open brace depth inside each `${` of an unfinished template literal. */
88
+ const templates = [];
89
+ let previous;
90
+ let lastEnd = -1;
91
+ for (;;) {
92
+ let kind = scanner.scan();
93
+ if (kind === SyntaxKind.EndOfFile)
94
+ break;
95
+ // TypeScript 7's scanner can return a token without advancing: JSX text
96
+ // such as `#{n}` scans as an empty private identifier at the `#`, forever.
97
+ // A token that ends where the last one did makes no progress, so step over
98
+ // one character. In JSX that costs nothing, since no import is written in
99
+ // JSX text; anywhere else it is reported, because something was skipped.
100
+ if (scanner.getTokenEnd() <= lastEnd) {
101
+ if (!jsx) {
102
+ problems.push({
103
+ line: lineOf(lastEnd),
104
+ message: "the scanner could not advance here, so one character was skipped",
105
+ });
106
+ }
107
+ lastEnd++;
108
+ scanner.resetTokenState(lastEnd);
109
+ continue;
110
+ }
111
+ lastEnd = scanner.getTokenEnd();
112
+ if ((kind === SyntaxKind.SlashToken || kind === SyntaxKind.SlashEqualsToken) && regexAllowed(previous)) {
113
+ kind = scanner.reScanSlashToken();
114
+ }
115
+ else if (kind === SyntaxKind.OpenBraceToken && templates.length > 0) {
116
+ templates[templates.length - 1]++;
117
+ }
118
+ else if (kind === SyntaxKind.CloseBraceToken && templates.length > 0) {
119
+ if (templates[templates.length - 1] === 0) {
120
+ kind = scanner.reScanTemplateToken(false);
121
+ if (kind === SyntaxKind.TemplateTail)
122
+ templates.pop();
123
+ }
124
+ else
125
+ templates[templates.length - 1]--;
126
+ }
127
+ if (kind === SyntaxKind.TemplateHead)
128
+ templates.push(0);
129
+ const line = lineOf(scanner.getTokenStart());
130
+ if (scanner.isUnterminated()) {
131
+ // In JSX, text such as `Don't` scans as a string that runs to the end of its line and no further;
132
+ // it costs at most that line, and no import is written inside JSX text.
133
+ if (!(jsx && kind === SyntaxKind.StringLiteral)) {
134
+ problems.push({ line, message: `the scanner could not terminate a ${describe(kind)} that starts here` });
135
+ }
136
+ }
137
+ const token = { kind, text: scanner.getTokenText(), value: scanner.getTokenValue(), line };
138
+ tokens.push(token);
139
+ previous = token;
140
+ }
141
+ if (templates.length > 0) {
142
+ problems.push({ line: previous?.line ?? 1, message: "a template literal is still open at the end of the file" });
143
+ }
144
+ return { tokens, problems };
145
+ }
146
+ function describe(kind) {
147
+ switch (kind) {
148
+ case SyntaxKind.StringLiteral:
149
+ return "string literal";
150
+ case SyntaxKind.RegularExpressionLiteral:
151
+ return "regular expression";
152
+ case SyntaxKind.NoSubstitutionTemplateLiteral:
153
+ case SyntaxKind.TemplateHead:
154
+ case SyntaxKind.TemplateMiddle:
155
+ case SyntaxKind.TemplateTail:
156
+ return "template literal";
157
+ default:
158
+ return "token";
159
+ }
160
+ }
161
+ /** Extract every module reference from one file. */
162
+ export function extractImports(path, text) {
163
+ const { tokens, problems } = tokenize(path, text);
164
+ const imports = [];
165
+ const consumed = new Set();
166
+ const word = (i, text) => {
167
+ const token = tokens[i];
168
+ return token !== undefined && tokenIsIdentifierOrKeyword(token.kind) && (text === undefined || token.text === text);
169
+ };
170
+ const is = (i, kind) => tokens[i]?.kind === kind;
171
+ const isString = (i) => is(i, SyntaxKind.StringLiteral);
172
+ const isLiteral = (i) => isString(i) || is(i, SyntaxKind.NoSubstitutionTemplateLiteral);
173
+ const afterDot = (i) => is(i - 1, SyntaxKind.DotToken) || is(i - 1, SyntaxKind.QuestionDotToken);
174
+ const add = (i, fields) => {
175
+ imports.push({ specifier: tokens[i].value, line: tokens[i].line, ...fields });
176
+ };
177
+ /** Index of the token closing the bracket opened at i, or tokens.length. */
178
+ const closing = (i, open, close) => {
179
+ let depth = 0;
180
+ for (let k = i; k < tokens.length; k++) {
181
+ if (tokens[k].kind === open)
182
+ depth++;
183
+ else if (tokens[k].kind === close && --depth === 0)
184
+ return k;
185
+ }
186
+ return tokens.length;
187
+ };
188
+ /** Named elements between braces: true when every one is written `type X`. */
189
+ const allTyped = (open, close) => {
190
+ let count = 0;
191
+ let typed = 0;
192
+ let start = true;
193
+ for (let k = open + 1; k < close; k++) {
194
+ if (is(k, SyntaxKind.CommaToken)) {
195
+ start = true;
196
+ continue;
197
+ }
198
+ if (start) {
199
+ count++;
200
+ if (word(k, "type") && word(k + 1) && !word(k + 1, "as"))
201
+ typed++;
202
+ start = false;
203
+ }
204
+ }
205
+ return count > 0 && typed === count;
206
+ };
207
+ /** A call such as `import(x)` or `require(x)` that is really a method declaration `import(x) { ... }`. */
208
+ const isMethod = (open) => is(closing(open, SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken) + 1, SyntaxKind.OpenBraceToken);
209
+ for (let i = 0; i < tokens.length; i++) {
210
+ if (consumed.has(i) || afterDot(i))
211
+ continue;
212
+ if (word(i, "import") && tokens[i].kind === SyntaxKind.ImportKeyword) {
213
+ if (is(i + 1, SyntaxKind.OpenParenToken)) {
214
+ if (isLiteral(i + 2) && (is(i + 3, SyntaxKind.CloseParenToken) || is(i + 3, SyntaxKind.CommaToken))) {
215
+ add(i + 2, { typeOnly: word(i - 1, "typeof"), dynamic: true, reexport: false, wildcard: false });
216
+ }
217
+ else if (!is(i + 2, SyntaxKind.CloseParenToken) && !isMethod(i + 1)) {
218
+ problems.push({
219
+ line: tokens[i].line,
220
+ message: "a dynamic import has a computed specifier, so its target cannot be known",
221
+ });
222
+ }
223
+ continue;
224
+ }
225
+ if (is(i + 1, SyntaxKind.DotToken) ||
226
+ is(i + 1, SyntaxKind.ColonToken) ||
227
+ is(i + 1, SyntaxKind.CommaToken) ||
228
+ is(i + 1, SyntaxKind.CloseBraceToken) ||
229
+ is(i + 1, SyntaxKind.CloseParenToken)) {
230
+ continue;
231
+ }
232
+ let j = i + 1;
233
+ let typeOnly = false;
234
+ if (word(j, "type") &&
235
+ !is(j + 1, SyntaxKind.CommaToken) &&
236
+ !is(j + 1, SyntaxKind.EqualsToken) &&
237
+ !(word(j + 1, "from") && isString(j + 2))) {
238
+ typeOnly = true;
239
+ j++;
240
+ }
241
+ if (isString(j)) {
242
+ add(j, { typeOnly, dynamic: false, reexport: false, wildcard: false });
243
+ continue;
244
+ }
245
+ if (word(j) && is(j + 1, SyntaxKind.EqualsToken)) {
246
+ if (word(j + 2, "require") && is(j + 3, SyntaxKind.OpenParenToken) && isString(j + 4)) {
247
+ add(j + 4, { typeOnly, dynamic: false, reexport: false, wildcard: false });
248
+ consumed.add(j + 2);
249
+ }
250
+ continue;
251
+ }
252
+ // Default, namespace and named bindings, then `from "x"`.
253
+ let hasPlainBinding = false;
254
+ let typedNamed = false;
255
+ for (let k = j; k < tokens.length && k < j + 4096; k++) {
256
+ if (is(k, SyntaxKind.OpenBraceToken)) {
257
+ const close = closing(k, SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken);
258
+ typedNamed = allTyped(k, close);
259
+ k = close;
260
+ continue;
261
+ }
262
+ if (word(k, "from") && isString(k + 1)) {
263
+ const typed = typeOnly || (typedNamed && !hasPlainBinding);
264
+ add(k + 1, { typeOnly: typed, dynamic: false, reexport: false, wildcard: false });
265
+ i = k + 1;
266
+ break;
267
+ }
268
+ if (is(k, SyntaxKind.SemicolonToken) || word(k, "import") || word(k, "export"))
269
+ break;
270
+ if (is(k, SyntaxKind.AsteriskToken) || (word(k) && !word(k, "as") && !is(k - 1, SyntaxKind.AsKeyword))) {
271
+ hasPlainBinding = true;
272
+ }
273
+ }
274
+ continue;
275
+ }
276
+ if (word(i, "export") && tokens[i].kind === SyntaxKind.ExportKeyword) {
277
+ let j = i + 1;
278
+ let typeOnly = false;
279
+ if (word(j, "type") && (is(j + 1, SyntaxKind.OpenBraceToken) || is(j + 1, SyntaxKind.AsteriskToken))) {
280
+ typeOnly = true;
281
+ j++;
282
+ }
283
+ if (is(j, SyntaxKind.AsteriskToken)) {
284
+ let k = j + 1;
285
+ if (word(k, "as"))
286
+ k += 2;
287
+ if (word(k, "from") && isString(k + 1)) {
288
+ add(k + 1, { typeOnly, dynamic: false, reexport: true, wildcard: true });
289
+ i = k + 1;
290
+ }
291
+ continue;
292
+ }
293
+ if (is(j, SyntaxKind.OpenBraceToken)) {
294
+ const close = closing(j, SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken);
295
+ if (word(close + 1, "from") && isString(close + 2)) {
296
+ add(close + 2, { typeOnly: typeOnly || allTyped(j, close), dynamic: false, reexport: true, wildcard: false });
297
+ i = close + 2;
298
+ }
299
+ }
300
+ continue;
301
+ }
302
+ if (word(i, "require") && is(i + 1, SyntaxKind.OpenParenToken) && !word(i - 1, "function")) {
303
+ if (isLiteral(i + 2) && is(i + 3, SyntaxKind.CloseParenToken)) {
304
+ add(i + 2, { typeOnly: false, dynamic: true, reexport: false, wildcard: false });
305
+ }
306
+ else if (!is(i + 2, SyntaxKind.CloseParenToken) && !isMethod(i + 1)) {
307
+ problems.push({
308
+ line: tokens[i].line,
309
+ message: "a require call has a computed specifier, so its target cannot be known",
310
+ });
311
+ }
312
+ }
313
+ }
314
+ return { imports, problems };
315
+ }
316
+ //# sourceMappingURL=extract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract.js","sourceRoot":"","sources":["../src/extract.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * A diagnostic plus what it is about. Exceptions (VSA §9) match on exact
3
+ * paths and edges, which a message cannot be trusted to carry, so every
4
+ * check reports a Finding: the diagnostic in core's shape (ADR 0004 key
5
+ * order, origin "architecture") and the subject an exception can name.
6
+ */
7
+ import type { Diagnostic, Location, Severity } from "@intentset/core";
8
+ export interface SubjectEdge {
9
+ /** A file path or a slice ID. */
10
+ from: string;
11
+ /** A file path, a slice ID, or a package specifier. */
12
+ to: string;
13
+ }
14
+ export interface Finding {
15
+ diagnostic: Diagnostic;
16
+ /** Every path the finding concerns; the diagnostic's own path is always included. */
17
+ paths: string[];
18
+ /** File-level and slice-level edges the finding concerns. */
19
+ edges: SubjectEdge[];
20
+ }
21
+ export interface FindingFields {
22
+ code: string;
23
+ severity?: Severity;
24
+ artifact: string | null;
25
+ path: string | null;
26
+ location?: Location;
27
+ field?: string;
28
+ message: string;
29
+ remediation: string;
30
+ paths?: string[];
31
+ edges?: SubjectEdge[];
32
+ }
33
+ /** One diagnostic, members in contract order, optional members present only when known. */
34
+ export declare function finding(fields: FindingFields): Finding;
35
+ /** "1 file" / "3 files". */
36
+ export declare function plural(count: number, noun: string, many?: string): string;
37
+ /** At most `limit` items joined with commas, then "and N more". */
38
+ export declare function listSome(items: readonly string[], limit?: number): string;
39
+ //# sourceMappingURL=finding.d.ts.map