@descent-vtt/spec-guard 0.11.0 → 0.12.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 (157) hide show
  1. package/CHANGELOG.md +354 -3
  2. package/README.md +377 -22
  3. package/dist/cites.d.ts +192 -0
  4. package/dist/cites.d.ts.map +1 -0
  5. package/dist/cites.js +599 -0
  6. package/dist/cites.js.map +1 -0
  7. package/dist/cli.d.ts +14 -6
  8. package/dist/cli.d.ts.map +1 -1
  9. package/dist/cli.js +315 -22
  10. package/dist/cli.js.map +1 -1
  11. package/dist/comments.d.ts +1 -1
  12. package/dist/comments.js +1 -1
  13. package/dist/config.d.ts +3 -0
  14. package/dist/config.d.ts.map +1 -1
  15. package/dist/config.js +46 -5
  16. package/dist/config.js.map +1 -1
  17. package/dist/engine.d.ts.map +1 -1
  18. package/dist/engine.js +38 -14
  19. package/dist/engine.js.map +1 -1
  20. package/dist/glob.d.ts +128 -24
  21. package/dist/glob.d.ts.map +1 -1
  22. package/dist/glob.js +304 -61
  23. package/dist/glob.js.map +1 -1
  24. package/dist/impact.d.ts +179 -0
  25. package/dist/impact.d.ts.map +1 -0
  26. package/dist/impact.js +360 -0
  27. package/dist/impact.js.map +1 -0
  28. package/dist/index.d.ts +13 -5
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +7 -3
  31. package/dist/index.js.map +1 -1
  32. package/dist/mcp.d.ts +16 -75
  33. package/dist/mcp.d.ts.map +1 -1
  34. package/dist/mcp.js +198 -370
  35. package/dist/mcp.js.map +1 -1
  36. package/dist/overlay.d.ts +39 -0
  37. package/dist/overlay.d.ts.map +1 -0
  38. package/dist/overlay.js +133 -0
  39. package/dist/overlay.js.map +1 -0
  40. package/dist/parser.d.ts +41 -24
  41. package/dist/parser.d.ts.map +1 -1
  42. package/dist/parser.js +217 -160
  43. package/dist/parser.js.map +1 -1
  44. package/dist/prove.d.ts +46 -0
  45. package/dist/prove.d.ts.map +1 -0
  46. package/dist/prove.js +549 -0
  47. package/dist/prove.js.map +1 -0
  48. package/dist/query.d.ts +11 -0
  49. package/dist/query.d.ts.map +1 -1
  50. package/dist/query.js +9 -3
  51. package/dist/query.js.map +1 -1
  52. package/dist/reporter.d.ts +139 -1
  53. package/dist/reporter.d.ts.map +1 -1
  54. package/dist/reporter.js +593 -21
  55. package/dist/reporter.js.map +1 -1
  56. package/dist/rules.js +3 -3
  57. package/dist/rules.js.map +1 -1
  58. package/dist/runner.d.ts +24 -1
  59. package/dist/runner.d.ts.map +1 -1
  60. package/dist/runner.js +84 -21
  61. package/dist/runner.js.map +1 -1
  62. package/dist/specs.d.ts +5 -1
  63. package/dist/specs.d.ts.map +1 -1
  64. package/dist/specs.js +5 -1
  65. package/dist/specs.js.map +1 -1
  66. package/dist/structure.d.ts.map +1 -1
  67. package/dist/structure.js +7 -6
  68. package/dist/structure.js.map +1 -1
  69. package/dist/types.d.ts +193 -0
  70. package/dist/types.d.ts.map +1 -1
  71. package/dist/vendor/spec-core/jsonrpc/index.d.ts +3 -0
  72. package/dist/vendor/spec-core/jsonrpc/index.d.ts.map +1 -0
  73. package/dist/vendor/spec-core/jsonrpc/index.js +2 -0
  74. package/dist/vendor/spec-core/jsonrpc/index.js.map +1 -0
  75. package/dist/vendor/spec-core/jsonrpc/mcp.d.ts +158 -0
  76. package/dist/vendor/spec-core/jsonrpc/mcp.d.ts.map +1 -0
  77. package/dist/vendor/spec-core/jsonrpc/mcp.js +353 -0
  78. package/dist/vendor/spec-core/jsonrpc/mcp.js.map +1 -0
  79. package/dist/vendor/spec-core/markdown/frontmatter.d.ts +104 -0
  80. package/dist/vendor/spec-core/markdown/frontmatter.d.ts.map +1 -0
  81. package/dist/vendor/spec-core/markdown/frontmatter.js +459 -0
  82. package/dist/vendor/spec-core/markdown/frontmatter.js.map +1 -0
  83. package/dist/vendor/spec-core/markdown/headings.d.ts +46 -0
  84. package/dist/vendor/spec-core/markdown/headings.d.ts.map +1 -0
  85. package/dist/vendor/spec-core/markdown/headings.js +199 -0
  86. package/dist/vendor/spec-core/markdown/headings.js.map +1 -0
  87. package/dist/vendor/spec-core/markdown/index.d.ts +6 -0
  88. package/dist/vendor/spec-core/markdown/index.d.ts.map +1 -0
  89. package/dist/vendor/spec-core/markdown/index.js +4 -0
  90. package/dist/vendor/spec-core/markdown/index.js.map +1 -0
  91. package/dist/vendor/spec-core/markdown/layout.d.ts +40 -0
  92. package/dist/vendor/spec-core/markdown/layout.d.ts.map +1 -0
  93. package/dist/vendor/spec-core/markdown/layout.js +28 -0
  94. package/dist/vendor/spec-core/markdown/layout.js.map +1 -0
  95. package/dist/vendor/spec-core/markdown/links.d.ts +23 -0
  96. package/dist/vendor/spec-core/markdown/links.d.ts.map +1 -0
  97. package/dist/vendor/spec-core/markdown/links.js +364 -0
  98. package/dist/vendor/spec-core/markdown/links.js.map +1 -0
  99. package/dist/vendor/spec-core/markdown/lists.d.ts +23 -0
  100. package/dist/vendor/spec-core/markdown/lists.d.ts.map +1 -0
  101. package/dist/vendor/spec-core/markdown/lists.js +127 -0
  102. package/dist/vendor/spec-core/markdown/lists.js.map +1 -0
  103. package/dist/vendor/spec-core/markdown/scan.d.ts +37 -0
  104. package/dist/vendor/spec-core/markdown/scan.d.ts.map +1 -0
  105. package/dist/vendor/spec-core/markdown/scan.js +439 -0
  106. package/dist/vendor/spec-core/markdown/scan.js.map +1 -0
  107. package/dist/vendor/spec-core/markdown/syntax.d.ts +76 -0
  108. package/dist/vendor/spec-core/markdown/syntax.d.ts.map +1 -0
  109. package/dist/vendor/spec-core/markdown/syntax.js +181 -0
  110. package/dist/vendor/spec-core/markdown/syntax.js.map +1 -0
  111. package/dist/vendor/spec-core/markdown/tables.d.ts +19 -0
  112. package/dist/vendor/spec-core/markdown/tables.d.ts.map +1 -0
  113. package/dist/vendor/spec-core/markdown/tables.js +86 -0
  114. package/dist/vendor/spec-core/markdown/tables.js.map +1 -0
  115. package/dist/vendor/spec-core/markdown/types.d.ts +288 -0
  116. package/dist/vendor/spec-core/markdown/types.d.ts.map +1 -0
  117. package/dist/vendor/spec-core/markdown/types.js +9 -0
  118. package/dist/vendor/spec-core/markdown/types.js.map +1 -0
  119. package/dist/vendor/spec-core/path/index.d.ts +2 -0
  120. package/dist/vendor/spec-core/path/index.d.ts.map +1 -0
  121. package/dist/vendor/spec-core/path/index.js +2 -0
  122. package/dist/vendor/spec-core/path/index.js.map +1 -0
  123. package/dist/vendor/spec-core/path/posix.d.ts +84 -0
  124. package/dist/vendor/spec-core/path/posix.d.ts.map +1 -0
  125. package/dist/vendor/spec-core/path/posix.js +150 -0
  126. package/dist/vendor/spec-core/path/posix.js.map +1 -0
  127. package/dist/vendor/spec-core/pattern/automaton.d.ts +130 -0
  128. package/dist/vendor/spec-core/pattern/automaton.d.ts.map +1 -0
  129. package/dist/vendor/spec-core/pattern/automaton.js +340 -0
  130. package/dist/vendor/spec-core/pattern/automaton.js.map +1 -0
  131. package/dist/vendor/spec-core/pattern/charset.d.ts +59 -0
  132. package/dist/vendor/spec-core/pattern/charset.d.ts.map +1 -0
  133. package/dist/vendor/spec-core/pattern/charset.js +116 -0
  134. package/dist/vendor/spec-core/pattern/charset.js.map +1 -0
  135. package/dist/vendor/spec-core/pattern/glob.d.ts +122 -0
  136. package/dist/vendor/spec-core/pattern/glob.d.ts.map +1 -0
  137. package/dist/vendor/spec-core/pattern/glob.js +481 -0
  138. package/dist/vendor/spec-core/pattern/glob.js.map +1 -0
  139. package/dist/vendor/spec-core/pattern/index.d.ts +7 -0
  140. package/dist/vendor/spec-core/pattern/index.d.ts.map +1 -0
  141. package/dist/vendor/spec-core/pattern/index.js +4 -0
  142. package/dist/vendor/spec-core/pattern/index.js.map +1 -0
  143. package/dist/vendor/spec-core/pattern/regex.d.ts +68 -0
  144. package/dist/vendor/spec-core/pattern/regex.d.ts.map +1 -0
  145. package/dist/vendor/spec-core/pattern/regex.js +813 -0
  146. package/dist/vendor/spec-core/pattern/regex.js.map +1 -0
  147. package/dist/vendor/spec-core/text/index.d.ts +3 -0
  148. package/dist/vendor/spec-core/text/index.d.ts.map +1 -0
  149. package/dist/vendor/spec-core/text/index.js +2 -0
  150. package/dist/vendor/spec-core/text/index.js.map +1 -0
  151. package/dist/vendor/spec-core/text/lines.d.ts +73 -0
  152. package/dist/vendor/spec-core/text/lines.d.ts.map +1 -0
  153. package/dist/vendor/spec-core/text/lines.js +156 -0
  154. package/dist/vendor/spec-core/text/lines.js.map +1 -0
  155. package/package.json +8 -1
  156. package/src/vendor/spec-core/LICENSE +21 -0
  157. package/src/vendor/spec-core/README.md +8 -0
package/dist/cites.js ADDED
@@ -0,0 +1,599 @@
1
+ /**
2
+ * `spec-guard cites`: the specs a codebase's comments cite, and whether each is
3
+ * still there and still in force. ADR-0017.
4
+ *
5
+ * A comment such as `// ADR-0011: the domain imports no infrastructure` is a
6
+ * claim about the codebase: that a decision exists, and governs this code.
7
+ * When the document is gone, or superseded, the comment sends the next reader
8
+ * to a decision that is not the one in force, and nothing notices - spec-graph
9
+ * reads only Markdown, and a run only the directives. This reads the other
10
+ * side: comment text, as ADR-0006's classifier finds it, for ids a project
11
+ * names.
12
+ *
13
+ * An id is found by a small scanner, never by a regular expression built from
14
+ * the template a project wrote: its literal text, a run of digits, and a word
15
+ * boundary on each side. The digits are a number, so `ADR-7`, `ADR-007` and a
16
+ * file called `0007-x.md` are one document.
17
+ */
18
+ import path from 'node:path';
19
+ import { lexRanges, syntaxFor } from './comments.js';
20
+ import { comparePaths, MAX_CONCURRENT_READS, withinSizeLimit } from './engine.js';
21
+ import { createExcludeMatcher, createPathMatcher, globBase, isGlob, pathPatternError, toPosix, walkPaths } from './glob.js';
22
+ import { nodeIo } from './io.js';
23
+ import { INACTIVE_STATUSES, parseStatus, parseTitle } from './parser.js';
24
+ import { createScope, isBinary } from './scope.js';
25
+ import { readSpecs } from './specs.js';
26
+ import { lineStarts, locate } from './text.js';
27
+ /* ---------------------------------------------------------------- templates */
28
+ /** Where the number goes, in an id template and in a file name. */
29
+ export const NUMBER = '{n}';
30
+ // A letter or digit in any script, or an underscore: what a word boundary
31
+ // separates. Fixed here, and never built from anything a project wrote.
32
+ const WORD = /^[\p{L}\p{N}_]$/u;
33
+ // Both are asked about the character past either end of a text too, which is
34
+ // undefined, and neither takes it for a digit or a letter, so there is no end
35
+ // of the text to test for first: `test` reads it as the word "undefined",
36
+ // which no pattern of one character matches.
37
+ function isDigit(char) {
38
+ // Compared as strings, so undefined is no digit either.
39
+ return char >= '0' && char <= '9';
40
+ }
41
+ function isWord(char) {
42
+ return WORD.test(char);
43
+ }
44
+ /** How many times `{n}` occurs in a template. */
45
+ function numbers(template) {
46
+ return template.split(NUMBER).length - 1;
47
+ }
48
+ /**
49
+ * Why an id template cannot be used, or null.
50
+ *
51
+ * The text around `{n}` is literal, and it has to be there: `{n}` alone would
52
+ * make every number in every comment a citation. It may not be a digit where
53
+ * it meets the number, or the two would run together - `A1{n}` would never
54
+ * know where `A1` ended.
55
+ */
56
+ export function citeIdError(template) {
57
+ const count = numbers(template);
58
+ if (count !== 1) {
59
+ return count === 0
60
+ ? `"${template}" has no ${NUMBER}: an id template says where the number goes, as in ADR-${NUMBER}`
61
+ : `"${template}" has ${NUMBER} more than once, and an id holds one number`;
62
+ }
63
+ const [prefix, suffix] = template.split(NUMBER);
64
+ if (/[{}]/.test(prefix + suffix))
65
+ return `"${template}" holds a brace other than ${NUMBER}, and the rest of an id is literal`;
66
+ if (prefix.trim() === '')
67
+ return `"${template}" has nothing before ${NUMBER}, so every number in every comment would be a citation`;
68
+ if (isDigit(prefix[prefix.length - 1]) || isDigit(suffix[0])) {
69
+ return `"${template}" has a digit beside ${NUMBER}, where it would run into the number`;
70
+ }
71
+ return null;
72
+ }
73
+ /** An id template, read. Only ever given one `citeIdError` accepted. */
74
+ export function parseIdTemplate(template) {
75
+ const [prefix, suffix] = template.split(NUMBER);
76
+ return { prefix, suffix };
77
+ }
78
+ /**
79
+ * Why a files template cannot be used, or null.
80
+ *
81
+ * The number is read from a document's file name, so `{n}` has to be in the
82
+ * last segment, and what comes before it there has to be literal: that is
83
+ * what says where in `0007-ledger.md` or `rfc-12.md` the number starts.
84
+ */
85
+ export function citeFilesError(template) {
86
+ const count = numbers(template);
87
+ if (count !== 1) {
88
+ return count === 0
89
+ ? `"${template}" has no ${NUMBER}: a files template says where the number is, as in docs/adr/${NUMBER}-*.md`
90
+ : `"${template}" has ${NUMBER} more than once, and a file name holds one number`;
91
+ }
92
+ const posix = toPosix(template);
93
+ const name = posix.slice(posix.lastIndexOf('/') + 1);
94
+ if (!name.includes(NUMBER))
95
+ return `"${template}" has ${NUMBER} in a directory, and the number is read from the file name`;
96
+ const [before, after] = name.split(NUMBER);
97
+ if (isGlob(before))
98
+ return `"${template}" has glob syntax before ${NUMBER} in the file name, which has to be literal to say where the number starts`;
99
+ if (isDigit(before[before.length - 1]) || isDigit(after[0])) {
100
+ return `"${template}" has a digit beside ${NUMBER}, where it would run into the number`;
101
+ }
102
+ const error = pathPatternError(numberGlob(posix));
103
+ return error === null ? null : `"${template}": ${error}`;
104
+ }
105
+ /**
106
+ * A template with its number read as `*`.
107
+ *
108
+ * A `*` just after `{n}` is taken in, since digits and then anything is
109
+ * anything: `{n}*.md`, the shape `deriveFamilies` writes, is `*.md`. Replaced
110
+ * alone, it would be `**.md`, which spec-core refuses, as two stars inside a
111
+ * name are read three ways. A second star after it is still refused.
112
+ */
113
+ function numberGlob(posix) {
114
+ return posix.replace(posix.includes(`${NUMBER}*`) ? `${NUMBER}*` : NUMBER, '*');
115
+ }
116
+ /** A files template, read. Only ever given one `citeFilesError` accepted. */
117
+ export function parseFilesTemplate(template) {
118
+ const posix = toPosix(template);
119
+ const name = posix.slice(posix.lastIndexOf('/') + 1);
120
+ const [before, after] = name.split(NUMBER);
121
+ return { glob: numberGlob(posix), before, after };
122
+ }
123
+ /** A number as a comparable key: its digits without leading zeros, and `0` for none. */
124
+ export function numberKey(digits) {
125
+ return digits.replace(/^0+(?=.)/, '');
126
+ }
127
+ /**
128
+ * The number a document's path gives it under a files template - its digits
129
+ * as the file name spells them - or null when the path is not one of the
130
+ * template's documents.
131
+ *
132
+ * The whole path is matched against the glob, and then the file name is read:
133
+ * the literal text before the number, a run of digits as long as it goes, and
134
+ * a rest that the text after the number must match exactly. So `{n}-*.md`
135
+ * reads `0007` from `0007-x.md`, and nothing from `0007x.md` or `x-0007.md`.
136
+ */
137
+ export function documentNumber(template) {
138
+ const { glob, before, after } = parseFilesTemplate(template);
139
+ const matches = createPathMatcher(glob);
140
+ const rest = after === '' ? (text) => text === '' : createPathMatcher(after);
141
+ return (relativePath) => {
142
+ // A name the glob matched starts with the literal before the number.
143
+ if (!matches(relativePath))
144
+ return null;
145
+ const name = relativePath.slice(relativePath.lastIndexOf('/') + 1);
146
+ let end = before.length;
147
+ while (isDigit(name[end]))
148
+ end += 1;
149
+ const digits = name.slice(before.length, end);
150
+ return digits !== '' && rest(name.slice(end)) ? digits : null;
151
+ };
152
+ }
153
+ /**
154
+ * Every id in a text, in order of position; the ids of one template before
155
+ * another's where two begin at one place.
156
+ *
157
+ * For each template: its literal prefix, then a run of digits, then its
158
+ * suffix, with no letter, digit or underscore running into either end - so
159
+ * `XADR-1` and `ADR-12a` are not `ADR-{n}` citations, and `ADR-12.` is. The
160
+ * whole text is read, once per template; which ids lie in a comment is
161
+ * `inComments`'s question.
162
+ */
163
+ export function scanCitations(text, templates) {
164
+ const found = [];
165
+ templates.forEach(({ prefix, suffix }, family) => {
166
+ const needsBoundaryBefore = isWord(prefix[0]);
167
+ for (let at = text.indexOf(prefix); at !== -1; at = text.indexOf(prefix, at + 1)) {
168
+ if (needsBoundaryBefore && isWord(text[at - 1]))
169
+ continue;
170
+ const digitsStart = at + prefix.length;
171
+ let digitsEnd = digitsStart;
172
+ while (isDigit(text[digitsEnd]))
173
+ digitsEnd += 1;
174
+ if (digitsEnd === digitsStart || !text.startsWith(suffix, digitsEnd))
175
+ continue;
176
+ const end = digitsEnd + suffix.length;
177
+ if (isWord(text[end - 1]) && isWord(text[end]))
178
+ continue;
179
+ found.push({ family, start: at, end, number: numberKey(text.slice(digitsStart, digitsEnd)), written: text.slice(at, end) });
180
+ }
181
+ });
182
+ // Stable, so ids at one place keep the order of their templates.
183
+ return found.sort((a, b) => a.start - b.start);
184
+ }
185
+ /** Words whose `'s` is `is` or `us` rather than a possessive: `it's ADR-7` is this project's. */
186
+ const CONTRACTED = new Set(['it', 'that', 'this', 'there', 'here', 'what', 'who', 'where', 'how', 'when', 'why', 'he', 'she', 'let']);
187
+ /** The characters a name before an id is made of: a project's, a package's, a repository's. */
188
+ const NAME = /^[\p{L}\p{N}_\-/'’]$/u;
189
+ /** What comes just before an id that is part of a path, an anchor or a query. */
190
+ const LINKED = new Set(['/', '#', '=', '?']);
191
+ /** Whether an id is written after a `://` with no whitespace between: in a URL, whatever comes just before it. */
192
+ function inUrl(text, start) {
193
+ let begin = start;
194
+ while (begin > 0 && !/\s/.test(text[begin - 1]))
195
+ begin -= 1;
196
+ return text.slice(begin, start).includes('://');
197
+ }
198
+ /**
199
+ * Whether an id is qualified by another owner, and so names that owner's
200
+ * document rather than one of this project's.
201
+ *
202
+ * `spec-core's ADR-0005`, `spec-graph ADR-0017`, `its ADR-0012` and
203
+ * `org/repo ADR-9` each cite a document in another repository, which only has
204
+ * the same number as one here by coincidence: read as this project's, it is a
205
+ * ghost when the number is not used here, and quietly the wrong document when
206
+ * it is. So the word just before an id - past one run of spaces - is read,
207
+ * and the id is another owner's when that word is a possessive (`'s`, `its`,
208
+ * `their`) or a name with a `-` or `/` inside it. `see ADR-7`, `per ADR-7`,
209
+ * `(ADR-7)`, `e.g. ADR-7` and `it's ADR-7` are this project's. What that
210
+ * costs is a hyphenated word used as an ordinary one, `re-read ADR-7`, which
211
+ * is read as a qualifier and not checked: a citation missed, rather than one
212
+ * reported that is not wrong.
213
+ *
214
+ * An id in a link is another owner's too: one just after a `/`, `#`, `=` or
215
+ * `?`, which is a path, an anchor or a query, or in a run of text holding
216
+ * `://`. `https://github.com/org/repo/blob/main/docs/adr/ADR-0042.md` names a
217
+ * document wherever that repository keeps it, and `docs/ADR-0099.html` a page
218
+ * built from one - neither is a document this template finds.
219
+ */
220
+ export function qualified(text, start) {
221
+ if (LINKED.has(text[start - 1]) || inUrl(text, start))
222
+ return true;
223
+ // Neither loop needs to stop at the start of the text: before it is
224
+ // undefined, which is no space and no character of a name.
225
+ let end = start;
226
+ while (text[end - 1] === ' ' || text[end - 1] === '\t')
227
+ end -= 1;
228
+ if (end === start)
229
+ return false;
230
+ let begin = end;
231
+ while (NAME.test(text[begin - 1]))
232
+ begin -= 1;
233
+ const word = text.slice(begin, end);
234
+ if (/^(?:its|their)$/i.test(word))
235
+ return true;
236
+ const possessive = /^(.*\p{L})['’]s$/u.exec(word);
237
+ if (possessive !== null && !CONTRACTED.has(possessive[1].toLowerCase()))
238
+ return true;
239
+ return /\p{L}[-/]\p{L}/u.test(word);
240
+ }
241
+ /**
242
+ * The citations that lie wholly inside a comment. Both lists are in order of
243
+ * position, so one walk through each answers every question: the file is
244
+ * searched once for each template, rather than once per comment - which on a
245
+ * file of many comments and no citations would search to its end each time.
246
+ */
247
+ export function inComments(citations, comments) {
248
+ const kept = [];
249
+ let index = 0;
250
+ for (const citation of citations) {
251
+ while (index < comments.length && comments[index][1] <= citation.start)
252
+ index += 1;
253
+ const comment = comments[index];
254
+ if (comment !== undefined && comment[0] <= citation.start && citation.end <= comment[1])
255
+ kept.push(citation);
256
+ }
257
+ return kept;
258
+ }
259
+ /* ---------------------------------------------------------------- documents */
260
+ /**
261
+ * Words that retire a document for anyone citing it.
262
+ *
263
+ * ADR-0010's closed list, less the two that mean "not yet": a proposal cited
264
+ * from the code that implements it is how a proposal gets built. One list, so
265
+ * a word added to it reaches this too.
266
+ */
267
+ const NOT_YET = new Set(['draft', 'proposed']);
268
+ export function isStale(status) {
269
+ // A document with no status is in no list, so there is nothing to test first.
270
+ return INACTIVE_STATUSES.has(status) && !NOT_YET.has(status);
271
+ }
272
+ /** The id a family writes for a document: `ADR-0007`. */
273
+ function idOf(family, spelled) {
274
+ return `${family.template.prefix}${spelled}${family.template.suffix}`;
275
+ }
276
+ /** Reads files in batches of the engine's read limit, as `readSpecs` does, keeping each failure. */
277
+ async function readAll(io, files) {
278
+ const read = [];
279
+ while (read.length < files.length) {
280
+ const batch = files.slice(read.length, read.length + MAX_CONCURRENT_READS);
281
+ read.push(...(await Promise.all(batch.map((file) => io.readFile(file).catch((error) => error)))));
282
+ }
283
+ return read;
284
+ }
285
+ /**
286
+ * The documents a files template names, by number.
287
+ *
288
+ * Walked from the template's literal base, skipping what a run skips. The
289
+ * project's `exclude` is not applied: it says what no rule reads, and a
290
+ * document it leaves out of the rules still exists to be cited. A document
291
+ * that cannot be read is still a document, with no status.
292
+ */
293
+ export async function findDocuments(family, root, io, defaultSkips) {
294
+ const numberOf = documentNumber(family.files);
295
+ const { base } = globBase(parseFilesTemplate(family.files).glob);
296
+ const found = [];
297
+ for await (const entry of walkPaths(path.resolve(root, base), { io, scope: createScope(defaultSkips) })) {
298
+ const file = base === '' ? entry.relativePath : `${base}/${entry.relativePath}`;
299
+ const spelled = numberOf(file);
300
+ if (spelled !== null)
301
+ found.push({ file, absolute: entry.absolutePath, spelled });
302
+ }
303
+ const sources = await readAll(io, found.map(({ absolute }) => absolute));
304
+ const documents = new Map();
305
+ found.forEach(({ file, spelled }, index) => {
306
+ const source = sources[index];
307
+ // A document that cannot be read is read as one with no title and no
308
+ // status, which the empty text is.
309
+ const text = source instanceof Error ? '' : source.toString('utf8');
310
+ const key = numberKey(spelled);
311
+ documents.set(key, [...(documents.get(key) ?? []), { file, spelled, title: parseTitle(text), status: parseStatus(text) }]);
312
+ });
313
+ return documents;
314
+ }
315
+ /* ----------------------------------------------------------------- defaults */
316
+ /** The extensions Markdown is written in, which spec-graph reads and this does not. */
317
+ const MARKDOWN = new Set(['.md', '.markdown', '.mdx']);
318
+ /**
319
+ * The families a project's specs imply, when it names none.
320
+ *
321
+ * A directory of spec files whose names begin with a number is a numbered
322
+ * series, and a series whose documents all title themselves with one id and
323
+ * that same number - `# ADR-0007: ...` in `0007-x.md` - says how it is cited.
324
+ * Anything short of that is not guessed at: a series whose titles disagree, or
325
+ * do not begin with an id, gets a note saying to configure `cites`.
326
+ */
327
+ export function deriveFamilies(documents) {
328
+ const series = new Map();
329
+ for (const { file, title } of documents) {
330
+ const slash = file.lastIndexOf('/');
331
+ const name = file.slice(slash + 1);
332
+ const digits = /^[0-9]+/.exec(name)?.[0];
333
+ if (digits === undefined)
334
+ continue;
335
+ const directory = file.slice(0, Math.max(slash, 0));
336
+ series.set(directory, [...(series.get(directory) ?? []), { name, digits, title }]);
337
+ }
338
+ const families = [];
339
+ const notes = [];
340
+ for (const [directory, members] of [...series].sort(([a], [b]) => comparePaths(a, b))) {
341
+ const prefixes = new Set(members.map(({ digits, title }) => {
342
+ const titled = /^([A-Za-z]+-)([0-9]+)(?![0-9A-Za-z_])/.exec(title ?? '');
343
+ return titled !== null && numberKey(titled[2]) === numberKey(digits) ? titled[1] : null;
344
+ }));
345
+ const where = directory === '' ? 'the root' : directory;
346
+ // A series has a member, so the set has at least one entry.
347
+ const prefix = [...prefixes][0];
348
+ if (prefixes.size !== 1 || prefix === null) {
349
+ notes.push(`${where} holds numbered specs whose titles do not all begin with one id and their own number, such as ADR-0001 in 0001-x.md, so how they are cited is not guessed; name them in "cites" to check citations of them`);
350
+ continue;
351
+ }
352
+ const extensions = new Set(members.map(({ name }) => path.posix.extname(name)));
353
+ const [extension] = extensions;
354
+ const glob = `${directory === '' ? '' : `${directory}/`}${NUMBER}*${extensions.size === 1 ? extension : ''}`;
355
+ families.push({ id: `${prefix}${NUMBER}`, files: glob });
356
+ }
357
+ return { families, notes };
358
+ }
359
+ /** A configuration no answer can be trusted under: the report is not written, and the command exits 2. */
360
+ export class CitesError extends Error {
361
+ }
362
+ /** The nearest ids a family has on either side of a number: what a typo most likely meant. */
363
+ function nearest(family, number) {
364
+ const wanted = BigInt(number);
365
+ // Numbers as big as a comment writes them, so compared as BigInt; the
366
+ // difference's sign is all a sort needs, and Number keeps it.
367
+ const values = [...family.documents.keys()].map((key) => BigInt(key)).sort((a, b) => Number(a - b));
368
+ // The cited number is no document's, so nothing equals it.
369
+ const sides = [values.filter((value) => value < wanted).pop(), values.find((value) => value > wanted)];
370
+ return sides
371
+ .filter((side) => side !== undefined)
372
+ .map((side) => idOf(family, family.documents.get(side.toString())[0].spelled));
373
+ }
374
+ /** Where a stale document's status line points, followed until a document in force, or null. */
375
+ function successorOf(document, own, families) {
376
+ const templates = families.map(({ template }) => template);
377
+ const seen = new Set([`${own.family}\u0000${own.number}`]);
378
+ const chain = [];
379
+ let current = document;
380
+ for (;;) {
381
+ // Only a stale document is followed, and a stale document has a status.
382
+ const label = current.status.label;
383
+ const next = scanCitations(label, templates).find((citation) => !seen.has(`${citation.family}\u0000${citation.number}`));
384
+ if (next === undefined)
385
+ return null;
386
+ seen.add(`${next.family}\u0000${next.number}`);
387
+ const family = families[next.family];
388
+ const [target] = family.documents.get(next.number) ?? [];
389
+ if (target === undefined)
390
+ return null;
391
+ const id = idOf(family, target.spelled);
392
+ chain.push(id);
393
+ if (!isStale(target.status?.value))
394
+ return { id, chain };
395
+ current = target;
396
+ }
397
+ }
398
+ /**
399
+ * Reads the comments of every source file in scope and reports each citation
400
+ * of a document that does not exist or is no longer in force.
401
+ *
402
+ * Throws `CitesError` when the answer could not be trusted: a family whose
403
+ * files match no document, which would make every citation of it a ghost.
404
+ */
405
+ export async function findCitations(options) {
406
+ const startedAt = performance.now();
407
+ const io = options.io ?? nodeIo;
408
+ const root = options.root;
409
+ const defaultSkips = options.defaultSkips ?? true;
410
+ const exclude = [...(options.exclude ?? [])];
411
+ const specs = await readSpecs(options.patterns, root, io);
412
+ const specFiles = new Set(specs.files);
413
+ const derived = options.families === undefined ? deriveFamilies(specs.documents.map(({ relativeFile, title }) => ({ file: relativeFile, title }))) : null;
414
+ const declared = options.families ?? derived.families;
415
+ const notes = derived === null ? [] : [...derived.notes];
416
+ const source = derived === null ? 'config' : 'derived';
417
+ const families = [];
418
+ for (const family of declared) {
419
+ const documents = await findDocuments(family, root, io, defaultSkips);
420
+ if (documents.size === 0) {
421
+ throw new CitesError(`no document matches ${family.files}, so every citation of ${family.id} would be reported as a ghost; check the files pattern against the documents' names`);
422
+ }
423
+ families.push({ ...family, source, template: parseIdTemplate(family.id), documents });
424
+ }
425
+ if (families.length === 0) {
426
+ notes.push(options.families === undefined
427
+ ? 'nothing to look for: "cites" names no documents, and no directory of numbered specs titles them with an id such as ADR-0001, so no citation was read; name them in "cites"'
428
+ : 'nothing to look for: "cites" is an empty list');
429
+ }
430
+ const cited = new Set(families.flatMap((family) => [...family.documents.values()].flat().map(({ file }) => file)));
431
+ const excluded = createExcludeMatcher(exclude);
432
+ const templates = families.map(({ template }) => template);
433
+ const scope = createScope(defaultSkips);
434
+ const unclassified = new Map();
435
+ const candidates = [];
436
+ const starts = options.paths?.map((entry) => (entry === '.' ? '' : entry)) ?? [''];
437
+ const seen = new Set();
438
+ // With nothing to look for, no path is walked, and every count stays at zero.
439
+ if (families.length > 0) {
440
+ for (const start of starts) {
441
+ const absoluteStart = path.resolve(root, start);
442
+ const stats = await io.stat(absoluteStart);
443
+ const entries = [];
444
+ if (stats?.isFile())
445
+ entries.push({ relativePath: start, absolutePath: absoluteStart });
446
+ else {
447
+ for await (const entry of walkPaths(absoluteStart, { io, scope })) {
448
+ entries.push({ relativePath: start === '' ? entry.relativePath : `${start}/${entry.relativePath}`, absolutePath: entry.absolutePath });
449
+ }
450
+ }
451
+ for (const { relativePath, absolutePath } of entries) {
452
+ if (seen.has(relativePath))
453
+ continue;
454
+ seen.add(relativePath);
455
+ const extension = path.posix.extname(relativePath).toLowerCase();
456
+ if (MARKDOWN.has(extension) || specFiles.has(absolutePath) || cited.has(relativePath) || excluded(relativePath))
457
+ continue;
458
+ const syntax = syntaxFor(relativePath);
459
+ if (syntax === null) {
460
+ const name = extension === '' ? '(none)' : extension;
461
+ unclassified.set(name, (unclassified.get(name) ?? 0) + 1);
462
+ continue;
463
+ }
464
+ // A format known to have no comments has no citations to read.
465
+ if (syntax.line.length === 0 && syntax.block.length === 0)
466
+ continue;
467
+ candidates.push({ file: relativePath, absolute: absolutePath });
468
+ }
469
+ }
470
+ }
471
+ candidates.sort((a, b) => comparePaths(a.file, b.file));
472
+ const strict = options.strict ?? false;
473
+ const findings = [];
474
+ const gaps = [];
475
+ let read = 0;
476
+ let citations = 0;
477
+ let others = 0;
478
+ const scan = (file, bytes) => {
479
+ if (bytes instanceof Error) {
480
+ gaps.push({ file, reason: 'unreadable', detail: `could not be read: ${bytes.message}` });
481
+ return;
482
+ }
483
+ if (!withinSizeLimit(bytes.length)) {
484
+ gaps.push({ file, reason: 'too-large', detail: 'is larger than 20 MB, which no search reads' });
485
+ return;
486
+ }
487
+ if (isBinary(bytes)) {
488
+ gaps.push({ file, reason: 'binary', detail: 'holds a NUL byte, so it is not text' });
489
+ return;
490
+ }
491
+ read += 1;
492
+ const text = bytes.toString('utf8');
493
+ const lexed = lexRanges(text, syntaxFor(file));
494
+ if (lexed.unterminated) {
495
+ gaps.push({ file, reason: 'lost-scan', detail: 'a string or comment was never closed, so what follows it may be misread' });
496
+ }
497
+ let lines;
498
+ const once = new Set();
499
+ for (const citation of inComments(scanCitations(text, templates), lexed.comments)) {
500
+ if (qualified(text, citation.start)) {
501
+ others += 1;
502
+ continue;
503
+ }
504
+ lines ??= lineStarts(text);
505
+ const { line, column } = locate(lines, citation.start);
506
+ const key = `${line}\u0000${citation.family}\u0000${citation.number}`;
507
+ if (once.has(key))
508
+ continue;
509
+ once.add(key);
510
+ citations += 1;
511
+ const finding = judge(citation, families, { file, line, column }, strict);
512
+ if (finding !== null)
513
+ findings.push(finding);
514
+ }
515
+ };
516
+ // A batch at a time, each scanned as soon as it is read, so that no more
517
+ // than one batch of a large tree is held in memory at once.
518
+ for (const pending = [...candidates]; pending.length > 0;) {
519
+ const batch = pending.splice(0, MAX_CONCURRENT_READS);
520
+ const sources = await readAll(io, batch.map(({ absolute }) => absolute));
521
+ batch.forEach(({ file }, index) => scan(file, sources[index]));
522
+ }
523
+ const ghosts = findings.filter((finding) => finding.rule === 'ghost-citation').length;
524
+ const stale = findings.length - ghosts;
525
+ const familyReports = families.map(({ id, files, source: from, documents }) => ({
526
+ id,
527
+ files,
528
+ source: from,
529
+ documents: [...documents.values()].reduce((total, list) => total + list.length, 0),
530
+ }));
531
+ return {
532
+ // Under --strict, anything short of every comment read and every citation
533
+ // in force fails: a stale citation, a file read in part, and a check that
534
+ // read nothing - which one that looked for nothing did not - since the
535
+ // family contract says a strict run refuses that rather than reports clean.
536
+ ok: ghosts === 0 && !(strict && (stale > 0 || gaps.length > 0 || read === 0)),
537
+ root: toPosix(root),
538
+ durationMs: performance.now() - startedAt,
539
+ families: familyReports,
540
+ summary: {
541
+ files: read,
542
+ citations,
543
+ ghosts,
544
+ stale,
545
+ qualified: others,
546
+ unclassified: [...unclassified.values()].reduce((total, count) => total + count, 0),
547
+ },
548
+ findings,
549
+ gaps,
550
+ unclassified: [...unclassified]
551
+ .map(([extension, files]) => ({ extension, files }))
552
+ .sort((a, b) => b.files - a.files || comparePaths(a.extension, b.extension)),
553
+ notes,
554
+ exclude,
555
+ };
556
+ }
557
+ /** What one citation found: nothing wrong, a ghost, or a stale document. */
558
+ function judge(citation, families, where, strict) {
559
+ const family = families[citation.family];
560
+ const documents = family.documents.get(citation.number);
561
+ const at = `${where.file}:${where.line}`;
562
+ if (documents === undefined) {
563
+ const near = nearest(family, citation.number);
564
+ return {
565
+ rule: 'ghost-citation',
566
+ severity: 'error',
567
+ ...where,
568
+ cited: citation.written,
569
+ family: family.id,
570
+ message: `${at} cites ${citation.written}, which no document defines`,
571
+ hint: `no document matching ${family.files} has the number ${citation.number}; the nearest ${near.length === 1 ? 'is' : 'are'} ${near.join(' and ')}`,
572
+ };
573
+ }
574
+ // Two documents with one number are one id, and it is in force while either is.
575
+ const document = documents.find((candidate) => !isStale(candidate.status?.value));
576
+ if (document !== undefined)
577
+ return null;
578
+ const stale = documents[0];
579
+ const status = stale.status.value;
580
+ const successor = successorOf(stale, citation, families);
581
+ const said = `${stale.file} says "${stale.status.label}"`;
582
+ return {
583
+ rule: 'stale-citation',
584
+ severity: strict ? 'error' : 'warning',
585
+ ...where,
586
+ cited: citation.written,
587
+ family: family.id,
588
+ document: stale.file,
589
+ status,
590
+ ...(successor === null ? {} : { successor: successor.id }),
591
+ message: `${at} cites ${citation.written}, which is ${status}${successor === null ? '' : ` - cite ${successor.id} instead`}`,
592
+ hint: successor === null
593
+ ? `${said}, and names no successor in force; cite the decision in force instead, or take the citation out`
594
+ : successor.chain.length > 1
595
+ ? `${said}; it was followed through ${successor.chain.slice(0, -1).join(', ')}, which ${successor.chain.length === 2 ? 'is' : 'are'} not in force either, to ${successor.id}`
596
+ : `${said}`,
597
+ };
598
+ }
599
+ //# sourceMappingURL=cites.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cites.js","sourceRoot":"","sources":["../src/cites.ts"],"names":[],"mappings":"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"}