@nielspeter/eess-md 0.3.0 → 0.6.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/README.md +57 -8
- package/dist/builders/links.d.ts.map +1 -1
- package/dist/builders/links.js +2 -3
- package/dist/builders/links.js.map +1 -1
- package/dist/builders/pointers.d.ts.map +1 -1
- package/dist/builders/pointers.js +2 -3
- package/dist/builders/pointers.js.map +1 -1
- package/dist/builders/task-items.d.ts.map +1 -1
- package/dist/builders/task-items.js +2 -3
- package/dist/builders/task-items.js.map +1 -1
- package/dist/conditions/pointer-resolve.d.ts +8 -3
- package/dist/conditions/pointer-resolve.d.ts.map +1 -1
- package/dist/conditions/pointer-resolve.js +80 -35
- package/dist/conditions/pointer-resolve.js.map +1 -1
- package/dist/corpus.d.ts +10 -3
- package/dist/corpus.d.ts.map +1 -1
- package/dist/corpus.js +5 -27
- package/dist/corpus.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -1
- package/dist/model/by-document.d.ts +21 -0
- package/dist/model/by-document.d.ts.map +1 -0
- package/dist/model/by-document.js +19 -0
- package/dist/model/by-document.js.map +1 -0
- package/dist/model/document.d.ts +1 -1
- package/dist/model/document.d.ts.map +1 -1
- package/dist/model/links.d.ts.map +1 -1
- package/dist/model/links.js +1 -7
- package/dist/model/links.js.map +1 -1
- package/dist/model/task-items.d.ts.map +1 -1
- package/dist/model/task-items.js +1 -7
- package/dist/model/task-items.js.map +1 -1
- package/dist/model/text-of.d.ts +14 -0
- package/dist/model/text-of.d.ts.map +1 -0
- package/dist/model/text-of.js +19 -0
- package/dist/model/text-of.js.map +1 -0
- package/dist/rules/adr.d.ts +8 -0
- package/dist/rules/adr.d.ts.map +1 -1
- package/dist/rules/adr.js +18 -6
- package/dist/rules/adr.js.map +1 -1
- package/dist/rules/ledger.d.ts +120 -0
- package/dist/rules/ledger.d.ts.map +1 -1
- package/dist/rules/ledger.js +255 -41
- package/dist/rules/ledger.js.map +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# @nielspeter/eess-md
|
|
2
2
|
|
|
3
|
-
Architecture testing for a **Markdown corpus** — the Markdown dialect of the [eess](
|
|
3
|
+
Architecture testing for a **Markdown corpus** — the Markdown dialect of the [eess](https://github.com/nielspeter/eess/blob/main/README.md) family. _Specifications you can run._
|
|
4
4
|
|
|
5
|
-
A repo's markdown (docs, ADRs, plans) should stay honest: cross-links resolve, code pointers point at real lines, and — if you use them — ADRs declare how they're enforced. `eess-md` validates all of that on the shared [`@nielspeter/eess`](
|
|
5
|
+
A repo's markdown (docs, ADRs, plans) should stay honest: cross-links resolve, code pointers point at real lines, and — if you use them — ADRs declare how they're enforced. `eess-md` validates all of that on the shared [`@nielspeter/eess`](https://www.npmjs.com/package/@nielspeter/eess) kernel, so you write a declarative rules file, not a custom validator script.
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
@@ -19,7 +19,7 @@ import { corpus, docs, links, pointers } from '@nielspeter/eess-md'
|
|
|
19
19
|
|
|
20
20
|
const c = corpus({
|
|
21
21
|
roots: ['docs/**'],
|
|
22
|
-
frozen: ['**/completed/**', '**/archived/**'], // historical
|
|
22
|
+
frozen: ['**/completed/**', '**/archived/**'], // historical: links still checked, pointers not
|
|
23
23
|
})
|
|
24
24
|
|
|
25
25
|
// markdown-to-markdown links resolve
|
|
@@ -27,7 +27,9 @@ links(c).that().areInternal().should().resolve().check()
|
|
|
27
27
|
|
|
28
28
|
// `path:line` code pointers ground against real files
|
|
29
29
|
// (resolves by unique path-suffix: `admin/index.vue` matches the one file
|
|
30
|
-
// ending with it
|
|
30
|
+
// ending with it. A bare name matching SEVERAL files is a violation naming
|
|
31
|
+
// the candidates — it identifies none of them. Pass `{ paths: 'exact' }` to
|
|
32
|
+
// require full repo paths instead.)
|
|
31
33
|
pointers(c).that().areLive().should().resolve().check()
|
|
32
34
|
|
|
33
35
|
// documents have the sections/tables they should
|
|
@@ -38,6 +40,43 @@ docs(c).that().resideInFolder('docs/adr/**').should().haveSection('Context').che
|
|
|
38
40
|
`.that().should().check()` chain as every other eess dialect — with `.because()`,
|
|
39
41
|
`.warn()`, `.excluding()`, and baseline mode all working unchanged.
|
|
40
42
|
|
|
43
|
+
## What did the corpus actually load?
|
|
44
|
+
|
|
45
|
+
A green rule over an empty corpus is the failure mode this project exists to catch, so
|
|
46
|
+
`corpus()` will tell you what it found. The returned `Corpus` is inspectable, not just
|
|
47
|
+
something you pass to a builder:
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
import { corpus } from '@nielspeter/eess-md'
|
|
51
|
+
|
|
52
|
+
const c = corpus({ roots: ['docs/**'], frozen: ['**/archived/**'] })
|
|
53
|
+
|
|
54
|
+
// Every document the globs matched, parsed — the denominator behind your rules.
|
|
55
|
+
for (const d of c.documents()) {
|
|
56
|
+
console.log(d.relPath, d.frozen ? '(frozen)' : '', `${d.sections.length} sections`)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
console.log(c.documents().length) // 0 here means the globs matched nothing, not that all is well
|
|
60
|
+
console.log(c.root) // repo root the globs, links and `path:line` pointers resolve against
|
|
61
|
+
console.log(c.fileIndex.size) // every file under that root — what link/pointer resolution searches
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Each `MdDocument` carries `relPath`, `file`, `frozen`, `text`, `sections`, `tables`,
|
|
65
|
+
`codeBlocks` and the raw mdast `root`, so a one-off question about the corpus is a loop,
|
|
66
|
+
not a new rule.
|
|
67
|
+
|
|
68
|
+
Two things worth knowing:
|
|
69
|
+
|
|
70
|
+
- **`frozen` documents are loaded, not skipped.** They appear in `documents()` with
|
|
71
|
+
`frozen: true`; it is the rules that treat them as history. So `documents().length` is
|
|
72
|
+
the total, and `documents().filter((d) => !d.frozen).length` is what a gate will fail on.
|
|
73
|
+
- **`root` defaults to `process.cwd()`**, which is why a gate run from a subdirectory
|
|
74
|
+
silently resolves a different set. If a corpus comes back smaller than you expect, print
|
|
75
|
+
`c.root` first.
|
|
76
|
+
|
|
77
|
+
`@nielspeter/eess-gherkin`'s `features()` returns the same shape of answer — `root`,
|
|
78
|
+
`features()` and `scenarios()` — for the same reason.
|
|
79
|
+
|
|
41
80
|
## Binding a spec table to code: `rows()` + `correspondence()`
|
|
42
81
|
|
|
43
82
|
A markdown table is a **spec** — a package list, an ADR index, a field
|
|
@@ -47,8 +86,7 @@ selection into one side of a `correspondence()`. Bind a table to what it
|
|
|
47
86
|
describes and drift in either direction fails the build:
|
|
48
87
|
|
|
49
88
|
```typescript
|
|
50
|
-
import { corpus, rows } from '@nielspeter/eess-md'
|
|
51
|
-
import { correspondence } from '@nielspeter/eess'
|
|
89
|
+
import { corpus, rows, correspondence } from '@nielspeter/eess-md'
|
|
52
90
|
|
|
53
91
|
const c = corpus({ roots: ['README.md'] })
|
|
54
92
|
|
|
@@ -61,8 +99,15 @@ const packageRows = rows(c, {
|
|
|
61
99
|
identify: (r) => ({ name: r.get('pkg'), file: r.doc.relPath, line: r.line }),
|
|
62
100
|
})
|
|
63
101
|
|
|
64
|
-
// `workspacePackages` is a plain Selection you build from the filesystem
|
|
65
|
-
|
|
102
|
+
// `workspacePackages` is a plain Selection you build from the filesystem —
|
|
103
|
+
// keyBy omitted: it defaults to each side's own identify().name
|
|
104
|
+
const workspacePackages = {
|
|
105
|
+
elements: [] as { name: string }[],
|
|
106
|
+
label: 'workspace package',
|
|
107
|
+
identify: (p: { name: string }) => ({ name: p.name }),
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
correspondence({ left: packageRows, right: workspacePackages })
|
|
66
111
|
.should()
|
|
67
112
|
.beComplete({ direction: 'both' }) // every row has a package AND vice versa
|
|
68
113
|
.because('the README package table must not drift from the workspace')
|
|
@@ -91,6 +136,10 @@ of that, and **you don't need it to get value from `eess-md`** — links, pointe
|
|
|
91
136
|
sections, and tables all validate through the generic primitives above. Reach for
|
|
92
137
|
`adrEnforcement()` only if your ADRs follow the tier model; otherwise compose your
|
|
93
138
|
own gate from `haveSection` / `haveTable` / `haveTableRowsSatisfying` / `resolve`.
|
|
139
|
+
The same goes for a citation form the preset does not know — a rule id in your
|
|
140
|
+
own architecture tool, cited in a Mechanism cell: `rows()` over that column into
|
|
141
|
+
a `correspondence()` against the set you hold, both directions. The docs page's
|
|
142
|
+
"Citing something that is not a file or a test" section is the worked recipe.
|
|
94
143
|
|
|
95
144
|
```typescript
|
|
96
145
|
import { adrEnforcement } from '@nielspeter/eess-md/rules/adr'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"links.d.ts","sourceRoot":"","sources":["../../src/builders/links.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,kBAAkB,CAAA;AAC9D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAgB,KAAK,MAAM,EAAkB,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"links.d.ts","sourceRoot":"","sources":["../../src/builders/links.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,kBAAkB,CAAA;AAC9D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAgB,KAAK,MAAM,EAAkB,MAAM,mBAAmB,CAAA;AAE7E,OAAO,EAAgB,KAAK,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAEhF,YAAY,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAElE,sEAAsE;AACtE,YAAY,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAW/C;;GAEG;AACH,qBAAa,eAAgB,SAAQ,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC;IAC9D,SAAS,CAAC,WAAW,IAAI,MAAM,EAAE;IAIjC,8DAA8D;IAC9D,WAAW,IAAI,IAAI;IAInB,iFAAiF;IACjF,WAAW,IAAI,IAAI;IAInB;;;;OAIG;IACH,OAAO,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,IAAI;CAG5C;AAED,iEAAiE;AACjE,wBAAgB,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,CAErD"}
|
package/dist/builders/links.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { RuleBuilder } from '@nielspeter/eess';
|
|
2
2
|
import { collectLinks } from '../model/links.js';
|
|
3
|
+
import { stampedByDocument } from '../model/by-document.js';
|
|
3
4
|
import { linkResolves } from '../conditions/resolve.js';
|
|
4
5
|
const areInternal = () => ({
|
|
5
6
|
description: 'are internal',
|
|
@@ -14,9 +15,7 @@ const areExternal = () => ({
|
|
|
14
15
|
*/
|
|
15
16
|
export class LinkRuleBuilder extends RuleBuilder {
|
|
16
17
|
getElements() {
|
|
17
|
-
return this.project
|
|
18
|
-
.documents()
|
|
19
|
-
.flatMap((doc) => collectLinks(doc.root, doc.text).map((link) => ({ ...link, doc })));
|
|
18
|
+
return stampedByDocument(this.project, (doc) => collectLinks(doc.root, doc.text));
|
|
20
19
|
}
|
|
21
20
|
/** Filter to links that point within the repo (no scheme). */
|
|
22
21
|
areInternal() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"links.js","sourceRoot":"","sources":["../../src/builders/links.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,kBAAkB,CAAA;AAE9D,OAAO,EAAE,YAAY,EAA+B,MAAM,mBAAmB,CAAA;AAC7E,OAAO,EAAE,YAAY,EAA2B,MAAM,0BAA0B,CAAA;AAOhF,MAAM,WAAW,GAAG,GAAsB,EAAE,CAAC,CAAC;IAC5C,WAAW,EAAE,cAAc;IAC3B,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ;CACzB,CAAC,CAAA;AACF,MAAM,WAAW,GAAG,GAAsB,EAAE,CAAC,CAAC;IAC5C,WAAW,EAAE,cAAc;IAC3B,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ;CACxB,CAAC,CAAA;AAEF;;GAEG;AACH,MAAM,OAAO,eAAgB,SAAQ,WAA2B;IACpD,WAAW;QACnB,OAAO,IAAI,CAAC,OAAO
|
|
1
|
+
{"version":3,"file":"links.js","sourceRoot":"","sources":["../../src/builders/links.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,kBAAkB,CAAA;AAE9D,OAAO,EAAE,YAAY,EAA+B,MAAM,mBAAmB,CAAA;AAC7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,EAAE,YAAY,EAA2B,MAAM,0BAA0B,CAAA;AAOhF,MAAM,WAAW,GAAG,GAAsB,EAAE,CAAC,CAAC;IAC5C,WAAW,EAAE,cAAc;IAC3B,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ;CACzB,CAAC,CAAA;AACF,MAAM,WAAW,GAAG,GAAsB,EAAE,CAAC,CAAC;IAC5C,WAAW,EAAE,cAAc;IAC3B,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ;CACxB,CAAC,CAAA;AAEF;;GAEG;AACH,MAAM,OAAO,eAAgB,SAAQ,WAA2B;IACpD,WAAW;QACnB,OAAO,iBAAiB,CAAY,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAA;IAC9F,CAAC;IAED,8DAA8D;IAC9D,WAAW;QACT,OAAO,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,CAAA;IACzC,CAAC;IAED,iFAAiF;IACjF,WAAW;QACT,OAAO,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,CAAA;IACzC,CAAC;IAED;;;;OAIG;IACH,OAAO,CAAC,OAA4B;QAClC,OAAO,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAA;IAC/D,CAAC;CACF;AAED,iEAAiE;AACjE,MAAM,UAAU,KAAK,CAAC,MAAc;IAClC,OAAO,IAAI,eAAe,CAAC,MAAM,CAAC,CAAA;AACpC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pointers.d.ts","sourceRoot":"","sources":["../../src/builders/pointers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,kBAAkB,CAAA;AAC9D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAmB,KAAK,SAAS,EAAqB,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"pointers.d.ts","sourceRoot":"","sources":["../../src/builders/pointers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,kBAAkB,CAAA;AAC9D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAmB,KAAK,SAAS,EAAqB,MAAM,sBAAsB,CAAA;AAEzF,OAAO,EAAmB,KAAK,qBAAqB,EAAE,MAAM,kCAAkC,CAAA;AAE9F,iFAAiF;AACjF,YAAY,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAWrD;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,WAAW,CAAC,SAAS,EAAE,MAAM,CAAC;IACpE,SAAS,CAAC,WAAW,IAAI,SAAS,EAAE;IAMpC,qEAAqE;IACrE,OAAO,IAAI,IAAI;IAIf,mEAAmE;IACnE,SAAS,IAAI,IAAI;IAIjB;;;;;OAKG;IACH,OAAO,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,IAAI;CAG/C;AAED,gEAAgE;AAChE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,kBAAkB,CAE3D"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { RuleBuilder } from '@nielspeter/eess';
|
|
2
2
|
import { extractPointers } from '../model/pointers.js';
|
|
3
|
+
import { stampedByDocument } from '../model/by-document.js';
|
|
3
4
|
import { pointerResolves } from '../conditions/pointer-resolve.js';
|
|
4
5
|
const areLive = () => ({
|
|
5
6
|
description: 'are live (not in a frozen folder)',
|
|
@@ -14,9 +15,7 @@ const areFrozen = () => ({
|
|
|
14
15
|
*/
|
|
15
16
|
export class PointerRuleBuilder extends RuleBuilder {
|
|
16
17
|
getElements() {
|
|
17
|
-
return this.project
|
|
18
|
-
.documents()
|
|
19
|
-
.flatMap((doc) => extractPointers(doc.text, doc.root).map((p) => ({ ...p, doc })));
|
|
18
|
+
return stampedByDocument(this.project, (doc) => extractPointers(doc.text, doc.root));
|
|
20
19
|
}
|
|
21
20
|
/** Filter to pointers in live documents (not in a frozen folder). */
|
|
22
21
|
areLive() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pointers.js","sourceRoot":"","sources":["../../src/builders/pointers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,kBAAkB,CAAA;AAE9D,OAAO,EAAE,eAAe,EAAqC,MAAM,sBAAsB,CAAA;AACzF,OAAO,EAAE,eAAe,EAA8B,MAAM,kCAAkC,CAAA;AAK9F,MAAM,OAAO,GAAG,GAAyB,EAAE,CAAC,CAAC;IAC3C,WAAW,EAAE,mCAAmC;IAChD,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM;CAC3B,CAAC,CAAA;AACF,MAAM,SAAS,GAAG,GAAyB,EAAE,CAAC,CAAC;IAC7C,WAAW,EAAE,gCAAgC;IAC7C,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM;CAC1B,CAAC,CAAA;AAEF;;GAEG;AACH,MAAM,OAAO,kBAAmB,SAAQ,WAA8B;IAC1D,WAAW;QACnB,OAAO,IAAI,CAAC,OAAO
|
|
1
|
+
{"version":3,"file":"pointers.js","sourceRoot":"","sources":["../../src/builders/pointers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,kBAAkB,CAAA;AAE9D,OAAO,EAAE,eAAe,EAAqC,MAAM,sBAAsB,CAAA;AACzF,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,EAAE,eAAe,EAA8B,MAAM,kCAAkC,CAAA;AAK9F,MAAM,OAAO,GAAG,GAAyB,EAAE,CAAC,CAAC;IAC3C,WAAW,EAAE,mCAAmC;IAChD,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM;CAC3B,CAAC,CAAA;AACF,MAAM,SAAS,GAAG,GAAyB,EAAE,CAAC,CAAC;IAC7C,WAAW,EAAE,gCAAgC;IAC7C,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM;CAC1B,CAAC,CAAA;AAEF;;GAEG;AACH,MAAM,OAAO,kBAAmB,SAAQ,WAA8B;IAC1D,WAAW;QACnB,OAAO,iBAAiB,CAAe,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAC3D,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CACpC,CAAA;IACH,CAAC;IAED,qEAAqE;IACrE,OAAO;QACL,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,CAAA;IACrC,CAAC;IAED,mEAAmE;IACnE,SAAS;QACP,OAAO,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,CAAC,CAAA;IACvC,CAAC;IAED;;;;;OAKG;IACH,OAAO,CAAC,OAA+B;QACrC,OAAO,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAA;IAClE,CAAC;CACF;AAED,gEAAgE;AAChE,MAAM,UAAU,QAAQ,CAAC,MAAc;IACrC,OAAO,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAA;AACvC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-items.d.ts","sourceRoot":"","sources":["../../src/builders/task-items.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,kBAAkB,CAAA;AAC9D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"task-items.d.ts","sourceRoot":"","sources":["../../src/builders/task-items.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,kBAAkB,CAAA;AAC9D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAG7E,0EAA0E;AAC1E,MAAM,WAAW,UAAW,SAAQ,aAAa;IAC/C,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAA;CACzB;AAWD;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,WAAW,CAAC,UAAU,EAAE,MAAM,CAAC;IACtE,SAAS,CAAC,WAAW,IAAI,UAAU,EAAE;IAIrC,sCAAsC;IACtC,OAAO,IAAI,IAAI;IAIf,yCAAyC;IACzC,UAAU,IAAI,IAAI;CAGnB;AAED,kEAAkE;AAClE,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,mBAAmB,CAE7D"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { RuleBuilder } from '@nielspeter/eess';
|
|
2
2
|
import { collectTaskItems } from '../model/task-items.js';
|
|
3
|
+
import { stampedByDocument } from '../model/by-document.js';
|
|
3
4
|
const areOpen = () => ({
|
|
4
5
|
description: 'are open',
|
|
5
6
|
test: (t) => !t.checked,
|
|
@@ -13,9 +14,7 @@ const areChecked = () => ({
|
|
|
13
14
|
*/
|
|
14
15
|
export class TaskItemRuleBuilder extends RuleBuilder {
|
|
15
16
|
getElements() {
|
|
16
|
-
return this.project
|
|
17
|
-
.documents()
|
|
18
|
-
.flatMap((doc) => collectTaskItems(doc.root).map((t) => ({ ...t, doc })));
|
|
17
|
+
return stampedByDocument(this.project, (doc) => collectTaskItems(doc.root));
|
|
19
18
|
}
|
|
20
19
|
/** Filter to open boxes (`- [ ]`). */
|
|
21
20
|
areOpen() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-items.js","sourceRoot":"","sources":["../../src/builders/task-items.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,kBAAkB,CAAA;AAG9D,OAAO,EAAE,gBAAgB,EAAsB,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"task-items.js","sourceRoot":"","sources":["../../src/builders/task-items.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,kBAAkB,CAAA;AAG9D,OAAO,EAAE,gBAAgB,EAAsB,MAAM,wBAAwB,CAAA;AAC7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAO3D,MAAM,OAAO,GAAG,GAA0B,EAAE,CAAC,CAAC;IAC5C,WAAW,EAAE,UAAU;IACvB,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO;CACxB,CAAC,CAAA;AACF,MAAM,UAAU,GAAG,GAA0B,EAAE,CAAC,CAAC;IAC/C,WAAW,EAAE,aAAa;IAC1B,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO;CACvB,CAAC,CAAA;AAEF;;GAEG;AACH,MAAM,OAAO,mBAAoB,SAAQ,WAA+B;IAC5D,WAAW;QACnB,OAAO,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAA;IAC7E,CAAC;IAED,sCAAsC;IACtC,OAAO;QACL,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,CAAA;IACrC,CAAC;IAED,yCAAyC;IACzC,UAAU;QACR,OAAO,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,CAAC,CAAA;IACxC,CAAC;CACF;AAED,kEAAkE;AAClE,MAAM,UAAU,SAAS,CAAC,MAAc;IACtC,OAAO,IAAI,mBAAmB,CAAC,MAAM,CAAC,CAAA;AACxC,CAAC"}
|
|
@@ -7,7 +7,10 @@ export interface PointerResolveOptions {
|
|
|
7
7
|
* - `suffix` (default) — a pointer resolves to the one file whose repo-relative
|
|
8
8
|
* path *ends with* the pointer path on a `/` boundary. Bare basenames are the
|
|
9
9
|
* single-segment case, so `index.vue` and `admin/index.vue` resolve by the
|
|
10
|
-
* same rule. Multiple matches → ambiguous
|
|
10
|
+
* same rule. Multiple matches → ambiguous, which is a violation naming the
|
|
11
|
+
* candidates (bug 0254). `externalRoots` are tried first and win if the
|
|
12
|
+
* pointer grounds there; if they do not resolve it — including when none is
|
|
13
|
+
* present on disk — the ambiguity is reported rather than skipped.
|
|
11
14
|
* - `exact` — a pointer must be the exact repo-relative path; no suffix or
|
|
12
15
|
* basename leniency. Choose this when pointers are required to carry full
|
|
13
16
|
* paths (e.g. the external repo's `spec-check.ts` strictness).
|
|
@@ -37,8 +40,10 @@ export declare function presentExternalRoots(roots: readonly string[]): readonly
|
|
|
37
40
|
* Classification mirrors the hand-rolled `spec-check.ts`:
|
|
38
41
|
* - **broken** — no file matches the pointer path
|
|
39
42
|
* - **stale** — file exists but is shorter than the referenced line
|
|
40
|
-
* - **ambiguous** — a path-suffix matching several files
|
|
41
|
-
*
|
|
43
|
+
* - **ambiguous** — a path-suffix matching several files. It names none of
|
|
44
|
+
* them, so it is a violation like the others, and the message lists the
|
|
45
|
+
* candidates (bug 0254 — it used to be skipped silently while still counting
|
|
46
|
+
* toward the caller's denominator). No autofix: the repair is a choice.
|
|
42
47
|
* - **ok** — otherwise
|
|
43
48
|
*
|
|
44
49
|
* Resolution (default `suffix` mode): exact repo-relative path first, else the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pointer-resolve.d.ts","sourceRoot":"","sources":["../../src/conditions/pointer-resolve.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"pointer-resolve.d.ts","sourceRoot":"","sources":["../../src/conditions/pointer-resolve.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAEjD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAGrD,+DAA+D;AAC/D,MAAM,WAAW,qBAAqB;IACpC;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAA;IACnC;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAC3C;AAED,kFAAkF;AAClF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,MAAM,EAAE,CAShF;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,qBAA0B,GAClC,SAAS,CAAC,SAAS,CAAC,CAoLtB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readFileSync, statSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
|
+
import { pathSuffixIndex } from '@nielspeter/eess/internal';
|
|
3
4
|
import { mdViolation } from '../model/violation.js';
|
|
4
5
|
/** The subset of `roots` that actually exist on disk — for gate summary lines. */
|
|
5
6
|
export function presentExternalRoots(roots) {
|
|
@@ -20,8 +21,10 @@ export function presentExternalRoots(roots) {
|
|
|
20
21
|
* Classification mirrors the hand-rolled `spec-check.ts`:
|
|
21
22
|
* - **broken** — no file matches the pointer path
|
|
22
23
|
* - **stale** — file exists but is shorter than the referenced line
|
|
23
|
-
* - **ambiguous** — a path-suffix matching several files
|
|
24
|
-
*
|
|
24
|
+
* - **ambiguous** — a path-suffix matching several files. It names none of
|
|
25
|
+
* them, so it is a violation like the others, and the message lists the
|
|
26
|
+
* candidates (bug 0254 — it used to be skipped silently while still counting
|
|
27
|
+
* toward the caller's denominator). No autofix: the repair is a choice.
|
|
25
28
|
* - **ok** — otherwise
|
|
26
29
|
*
|
|
27
30
|
* Resolution (default `suffix` mode): exact repo-relative path first, else the
|
|
@@ -33,15 +36,13 @@ export function presentExternalRoots(roots) {
|
|
|
33
36
|
export function pointerResolves(corpus, options = {}) {
|
|
34
37
|
const mode = options.paths ?? 'suffix';
|
|
35
38
|
const externalRoots = options.externalRoots ?? [];
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
byBasename.set(base, [rel]);
|
|
44
|
-
}
|
|
39
|
+
// Bug 0257: one resolver, shared with `eess-crossvalidate`. This file used to
|
|
40
|
+
// carry its own basename index and its own three-way match type; both were the
|
|
41
|
+
// kernel's `pathSuffixIndex` written a second time, down to the exact-wins
|
|
42
|
+
// precedence. What stays here is the POLICY — what a `none` means, whether an
|
|
43
|
+
// `ambiguous` fails, when to consult external roots — which is genuinely this
|
|
44
|
+
// dialect's and differs from crossvalidate's.
|
|
45
|
+
const paths = pathSuffixIndex(corpus.fileIndex);
|
|
45
46
|
const lineCountCache = new Map();
|
|
46
47
|
const lineCount = (rel) => {
|
|
47
48
|
const cached = lineCountCache.get(rel);
|
|
@@ -55,34 +56,69 @@ export function pointerResolves(corpus, options = {}) {
|
|
|
55
56
|
description: 'resolve to a real file and line',
|
|
56
57
|
evaluate: (pointers, ctx) => pointers.flatMap((p) => {
|
|
57
58
|
const wanted = p.path.replace(/^\.?\//, '');
|
|
58
|
-
|
|
59
|
-
// Narrow by last segment, then confirm the full suffix.
|
|
60
|
-
const uniqueSuffix = () => {
|
|
61
|
-
const lastSeg = wanted.slice(wanted.lastIndexOf('/') + 1);
|
|
62
|
-
const matches = (byBasename.get(lastSeg) ?? []).filter((f) => f === wanted || f.endsWith('/' + wanted));
|
|
63
|
-
const only = matches[0];
|
|
64
|
-
if (matches.length === 1 && only !== undefined)
|
|
65
|
-
return { kind: 'unique', file: only };
|
|
66
|
-
if (matches.length > 1)
|
|
67
|
-
return { kind: 'ambiguous' };
|
|
68
|
-
return { kind: 'none' };
|
|
69
|
-
};
|
|
59
|
+
const match = paths.resolve(wanted);
|
|
70
60
|
let targetRel = null;
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
61
|
+
// Bug 0254: an ambiguous suffix used to `return []` here, commented
|
|
62
|
+
// "reported elsewhere, never failed". There was no elsewhere — nothing
|
|
63
|
+
// counted or printed them, and they were still inside the caller's
|
|
64
|
+
// denominator, so 16 of this repo's own 463 live pointers sat inside a
|
|
65
|
+
// summary reading "all ground in code" having grounded in nothing. A
|
|
66
|
+
// skip that reads as a pass is ADR-010's subject exactly.
|
|
67
|
+
//
|
|
68
|
+
// It falls through to the null-target path instead of returning here,
|
|
69
|
+
// so a corpus with `externalRoots` still gets to resolve it there — an
|
|
70
|
+
// in-repo ambiguity is not evidence about an external checkout.
|
|
71
|
+
//
|
|
72
|
+
// **That fall-through has to be complete, and the first version was not.**
|
|
73
|
+
// Review found both exits from the external-roots block swallowing the
|
|
74
|
+
// ambiguity: no root present on disk returned `[]` (the same silent skip
|
|
75
|
+
// this bug exists to close, through a door the fix left open), and a
|
|
76
|
+
// present-but-no-match returned "not in the repo" — false, since the
|
|
77
|
+
// pointer is in the repo twice, and it discards the candidates and the
|
|
78
|
+
// remedy. `ambiguousViolation()` below is now the fallback on every exit
|
|
79
|
+
// that would otherwise skip or misreport.
|
|
80
|
+
let ambiguousWith = [];
|
|
81
|
+
if (match.kind === 'exact') {
|
|
82
|
+
// Exact repo-relative path — preferred in both modes, and it beats an
|
|
83
|
+
// ambiguity it is itself part of.
|
|
84
|
+
targetRel = match.file;
|
|
74
85
|
}
|
|
75
86
|
else if (mode === 'suffix') {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
targetRel = m.kind === 'unique' ? m.file : null;
|
|
87
|
+
if (match.kind === 'ambiguous')
|
|
88
|
+
ambiguousWith = match.files;
|
|
89
|
+
targetRel = match.kind === 'unique' ? match.file : null;
|
|
80
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* The ambiguous finding, built once and used at every exit that would
|
|
93
|
+
* otherwise skip or misclassify it. `searched` names the external roots
|
|
94
|
+
* when there were any, so the reader can see the pointer was not simply
|
|
95
|
+
* unexamined.
|
|
96
|
+
*/
|
|
97
|
+
const ambiguousViolation = (searched = []) => [
|
|
98
|
+
mdViolation({
|
|
99
|
+
element: `${p.doc.relPath} → ${p.raw}`,
|
|
100
|
+
file: p.doc.file,
|
|
101
|
+
line: p.line,
|
|
102
|
+
message: `ambiguous code pointer: "${p.raw}" matches ${ambiguousWith.length} files ` +
|
|
103
|
+
`(${ambiguousWith.join(', ')}) — cite a longer suffix so it names one` +
|
|
104
|
+
(searched.length > 0
|
|
105
|
+
? `; also not under external root(s) ${searched.join(', ')}`
|
|
106
|
+
: ''),
|
|
107
|
+
sourceText: p.doc.text,
|
|
108
|
+
context: ctx,
|
|
109
|
+
}),
|
|
110
|
+
];
|
|
81
111
|
if (targetRel === null && externalRoots.length > 0) {
|
|
82
112
|
// Not in-repo, external roots configured (plan 0069 Phase 5).
|
|
83
113
|
const present = presentExternalRoots(externalRoots);
|
|
84
|
-
if (present.length === 0)
|
|
114
|
+
if (present.length === 0) {
|
|
115
|
+
// The documented skip (plan 0069) is for a pointer whose only hope
|
|
116
|
+
// was an absent checkout. An ambiguous one already failed in-repo,
|
|
117
|
+
// and that has nothing to do with the missing root.
|
|
118
|
+
if (ambiguousWith.length > 0)
|
|
119
|
+
return ambiguousViolation();
|
|
85
120
|
return []; // skipped, not passed — caller reports the scope
|
|
121
|
+
}
|
|
86
122
|
for (const rootDir of present) {
|
|
87
123
|
const abs = join(rootDir, wanted);
|
|
88
124
|
let external;
|
|
@@ -107,6 +143,8 @@ export function pointerResolves(corpus, options = {}) {
|
|
|
107
143
|
}
|
|
108
144
|
return []; // grounds in the external root
|
|
109
145
|
}
|
|
146
|
+
if (ambiguousWith.length > 0)
|
|
147
|
+
return ambiguousViolation(present);
|
|
110
148
|
return [
|
|
111
149
|
mdViolation({
|
|
112
150
|
element: `${p.doc.relPath} → ${p.raw}`,
|
|
@@ -118,18 +156,25 @@ export function pointerResolves(corpus, options = {}) {
|
|
|
118
156
|
}),
|
|
119
157
|
];
|
|
120
158
|
}
|
|
159
|
+
if (targetRel === null && ambiguousWith.length > 0) {
|
|
160
|
+
// Ambiguous: the path matches several files, so it names none of them.
|
|
161
|
+
// No autofix on purpose — the repair is a judgement about which file
|
|
162
|
+
// was meant, and a deterministic rewrite would pick whichever sorted
|
|
163
|
+
// first and call it fixed. Message carries the remedy because
|
|
164
|
+
// `because` is rule-level and one rule covers all three classes.
|
|
165
|
+
return ambiguousViolation();
|
|
166
|
+
}
|
|
121
167
|
if (targetRel === null) {
|
|
122
168
|
// Broken. If exactly one file uniquely resolves the shortened path, the
|
|
123
169
|
// repair is deterministic — attach an autofix that expands it to the
|
|
124
170
|
// full repo-relative path (plan 0066). Ambiguous → no fix.
|
|
125
|
-
const
|
|
126
|
-
const fix = m.kind === 'unique' && m.file !== wanted
|
|
171
|
+
const fix = match.kind === 'unique' && match.file !== wanted
|
|
127
172
|
? {
|
|
128
173
|
file: p.doc.file,
|
|
129
174
|
start: p.pathStart,
|
|
130
175
|
end: p.pathEnd,
|
|
131
|
-
replacement:
|
|
132
|
-
describe: `rewrite pointer "${p.path}" → "${
|
|
176
|
+
replacement: match.file,
|
|
177
|
+
describe: `rewrite pointer "${p.path}" → "${match.file}"`,
|
|
133
178
|
}
|
|
134
179
|
: undefined;
|
|
135
180
|
return [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pointer-resolve.js","sourceRoot":"","sources":["../../src/conditions/pointer-resolve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"pointer-resolve.js","sourceRoot":"","sources":["../../src/conditions/pointer-resolve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAA;AAG3D,OAAO,EAAE,WAAW,EAAsB,MAAM,uBAAuB,CAAA;AAiCvE,kFAAkF;AAClF,MAAM,UAAU,oBAAoB,CAAC,KAAwB;IAC3D,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QACxB,IAAI,CAAC;YACH,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAA;QAClC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,KAAK,GAAG,CAAA,CAAC,uDAAuD;YAChE,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,eAAe,CAC7B,MAAc,EACd,UAAiC,EAAE;IAEnC,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,IAAI,QAAQ,CAAA;IACtC,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,EAAE,CAAA;IACjD,8EAA8E;IAC9E,+EAA+E;IAC/E,2EAA2E;IAC3E,8EAA8E;IAC9E,8EAA8E;IAC9E,8CAA8C;IAC9C,MAAM,KAAK,GAAG,eAAe,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;IAE/C,MAAM,cAAc,GAAG,IAAI,GAAG,EAAkB,CAAA;IAChD,MAAM,SAAS,GAAG,CAAC,GAAW,EAAU,EAAE;QACxC,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACtC,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,MAAM,CAAA;QACvC,MAAM,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAA;QACzE,cAAc,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;QAC1B,OAAO,CAAC,CAAA;IACV,CAAC,CAAA;IAED,OAAO;QACL,WAAW,EAAE,iCAAiC;QAC9C,QAAQ,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,CAC1B,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;YACrB,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;YAC3C,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;YAEnC,IAAI,SAAS,GAAkB,IAAI,CAAA;YACnC,oEAAoE;YACpE,uEAAuE;YACvE,mEAAmE;YACnE,uEAAuE;YACvE,qEAAqE;YACrE,0DAA0D;YAC1D,EAAE;YACF,sEAAsE;YACtE,uEAAuE;YACvE,gEAAgE;YAChE,EAAE;YACF,2EAA2E;YAC3E,uEAAuE;YACvE,yEAAyE;YACzE,qEAAqE;YACrE,qEAAqE;YACrE,uEAAuE;YACvE,yEAAyE;YACzE,0CAA0C;YAC1C,IAAI,aAAa,GAAsB,EAAE,CAAA;YACzC,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBAC3B,sEAAsE;gBACtE,kCAAkC;gBAClC,SAAS,GAAG,KAAK,CAAC,IAAI,CAAA;YACxB,CAAC;iBAAM,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC7B,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW;oBAAE,aAAa,GAAG,KAAK,CAAC,KAAK,CAAA;gBAC3D,SAAS,GAAG,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAA;YACzD,CAAC;YAED;;;;;eAKG;YACH,MAAM,kBAAkB,GAAG,CAAC,WAA8B,EAAE,EAAmB,EAAE,CAAC;gBAChF,WAAW,CAAC;oBACV,OAAO,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC,GAAG,EAAE;oBACtC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI;oBAChB,IAAI,EAAE,CAAC,CAAC,IAAI;oBACZ,OAAO,EACL,4BAA4B,CAAC,CAAC,GAAG,aAAa,aAAa,CAAC,MAAM,SAAS;wBAC3E,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,0CAA0C;wBACtE,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC;4BAClB,CAAC,CAAC,qCAAqC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;4BAC5D,CAAC,CAAC,EAAE,CAAC;oBACT,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI;oBACtB,OAAO,EAAE,GAAG;iBACb,CAAC;aACH,CAAA;YAED,IAAI,SAAS,KAAK,IAAI,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACnD,8DAA8D;gBAC9D,MAAM,OAAO,GAAG,oBAAoB,CAAC,aAAa,CAAC,CAAA;gBACnD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACzB,mEAAmE;oBACnE,mEAAmE;oBACnE,oDAAoD;oBACpD,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC;wBAAE,OAAO,kBAAkB,EAAE,CAAA;oBACzD,OAAO,EAAE,CAAA,CAAC,iDAAiD;gBAC7D,CAAC;gBACD,KAAK,MAAM,OAAO,IAAI,OAAO,EAAE,CAAC;oBAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;oBACjC,IAAI,QAAgB,CAAA;oBACpB,IAAI,CAAC;wBACH,QAAQ,GAAG,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAA;oBACzD,CAAC;oBAAC,OAAO,GAAG,EAAE,CAAC;wBACb,KAAK,GAAG,CAAA,CAAC,qDAAqD;wBAC9D,SAAQ;oBACV,CAAC;oBACD,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,QAAQ,EAAE,CAAC;wBAChD,OAAO;4BACL,WAAW,CAAC;gCACV,OAAO,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC,GAAG,EAAE;gCACtC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI;gCAChB,IAAI,EAAE,CAAC,CAAC,IAAI;gCACZ,OAAO,EAAE,uBAAuB,OAAO,IAAI,MAAM,QAAQ,QAAQ,YAAY,CAAC,CAAC,GAAG,qBAAqB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE;gCACzI,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI;gCACtB,OAAO,EAAE,GAAG;6BACb,CAAC;yBACH,CAAA;oBACH,CAAC;oBACD,OAAO,EAAE,CAAA,CAAC,+BAA+B;gBAC3C,CAAC;gBACD,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC;oBAAE,OAAO,kBAAkB,CAAC,OAAO,CAAC,CAAA;gBAChE,OAAO;oBACL,WAAW,CAAC;wBACV,OAAO,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC,GAAG,EAAE;wBACtC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI;wBAChB,IAAI,EAAE,CAAC,CAAC,IAAI;wBACZ,OAAO,EAAE,yBAAyB,CAAC,CAAC,GAAG,uDAAuD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;wBAClH,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI;wBACtB,OAAO,EAAE,GAAG;qBACb,CAAC;iBACH,CAAA;YACH,CAAC;YAED,IAAI,SAAS,KAAK,IAAI,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACnD,uEAAuE;gBACvE,qEAAqE;gBACrE,qEAAqE;gBACrE,8DAA8D;gBAC9D,iEAAiE;gBACjE,OAAO,kBAAkB,EAAE,CAAA;YAC7B,CAAC;YAED,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;gBACvB,wEAAwE;gBACxE,qEAAqE;gBACrE,2DAA2D;gBAC3D,MAAM,GAAG,GACP,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM;oBAC9C,CAAC,CAAC;wBACE,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI;wBAChB,KAAK,EAAE,CAAC,CAAC,SAAS;wBAClB,GAAG,EAAE,CAAC,CAAC,OAAO;wBACd,WAAW,EAAE,KAAK,CAAC,IAAI;wBACvB,QAAQ,EAAE,oBAAoB,CAAC,CAAC,IAAI,QAAQ,KAAK,CAAC,IAAI,GAAG;qBAC1D;oBACH,CAAC,CAAC,SAAS,CAAA;gBACf,OAAO;oBACL,WAAW,CAAC;wBACV,OAAO,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC,GAAG,EAAE;wBACtC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI;wBAChB,IAAI,EAAE,CAAC,CAAC,IAAI;wBACZ,OAAO,EAAE,yBAAyB,CAAC,CAAC,GAAG,8BAA8B;wBACrE,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI;wBACtB,GAAG;wBACH,OAAO,EAAE,GAAG;qBACb,CAAC;iBACH,CAAA;YACH,CAAC;YAED,MAAM,KAAK,GAAG,SAAS,CAAC,SAAS,CAAC,CAAA;YAClC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,KAAK,EAAE,CAAC;gBAC7C,OAAO;oBACL,WAAW,CAAC;wBACV,OAAO,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC,GAAG,EAAE;wBACtC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI;wBAChB,IAAI,EAAE,CAAC,CAAC,IAAI;wBACZ,OAAO,EAAE,uBAAuB,SAAS,QAAQ,KAAK,YAAY,CAAC,CAAC,GAAG,qBAAqB,IAAI,CAAC,GAAG,CAClG,CAAC,CAAC,SAAS,EACX,CAAC,CAAC,OAAO,CACV,EAAE;wBACH,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI;wBACtB,OAAO,EAAE,GAAG;qBACb,CAAC;iBACH,CAAA;YACH,CAAC;YACD,OAAO,EAAE,CAAA;QACX,CAAC,CAAC;KACL,CAAA;AACH,CAAC"}
|
package/dist/corpus.d.ts
CHANGED
|
@@ -6,9 +6,16 @@ export interface CorpusOptions {
|
|
|
6
6
|
/** Globs (repo-relative, POSIX) selecting the markdown files to load, e.g. `['docs/**']`. */
|
|
7
7
|
readonly roots: readonly string[];
|
|
8
8
|
/**
|
|
9
|
-
* Globs marking frozen folders — historical records
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* Globs marking frozen folders — historical records held to their own time
|
|
10
|
+
* rather than to today's code.
|
|
11
|
+
*
|
|
12
|
+
* What this actually does, stated after the previous wording was measured
|
|
13
|
+
* false (bug 0253): a frozen document's LINKS are still checked, and its code
|
|
14
|
+
* pointers are excluded from `pointers().areLive()` — so they are not examined
|
|
15
|
+
* at all. They are not "reported but never failed"; nothing reports them.
|
|
16
|
+
*
|
|
17
|
+
* Defaults to the near-universal `completed`/`archived`; extend for your
|
|
18
|
+
* project's lifecycle folders (`delivered`, `wont-do`, …).
|
|
12
19
|
*/
|
|
13
20
|
readonly frozen?: readonly string[];
|
|
14
21
|
/**
|
package/dist/corpus.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"corpus.d.ts","sourceRoot":"","sources":["../src/corpus.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"corpus.d.ts","sourceRoot":"","sources":["../src/corpus.ts"],"names":[],"mappings":"AAOA,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAEpE;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,6FAA6F;IAC7F,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACnC;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACnC,qFAAqF;IACrF,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,MAAM;IACrB,4BAA4B;IAC5B,SAAS,IAAI,UAAU,EAAE,CAAA;IACzB,6CAA6C;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,gGAAgG;IAChG,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;CACxC;AAKD;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAwCrD"}
|
package/dist/corpus.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { walkFiles } from '@nielspeter/eess/internal';
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
3
4
|
import { fromMarkdown } from 'mdast-util-from-markdown';
|
|
4
5
|
import { gfm } from 'micromark-extension-gfm';
|
|
5
6
|
import { gfmFromMarkdown } from 'mdast-util-gfm';
|
|
@@ -7,30 +8,6 @@ import picomatch from 'picomatch';
|
|
|
7
8
|
import { buildDocument } from './model/document.js';
|
|
8
9
|
const DEFAULT_FROZEN = ['**/completed/**', '**/archived/**'];
|
|
9
10
|
const BUILTIN_IGNORE = ['node_modules', '.git', 'dist', 'coverage', '.output', '.nuxt', '.vercel'];
|
|
10
|
-
function toPosix(p) {
|
|
11
|
-
return sep === '/' ? p : p.split(sep).join('/');
|
|
12
|
-
}
|
|
13
|
-
function walk(dir, root, ignoreDirs, acc) {
|
|
14
|
-
let entries;
|
|
15
|
-
try {
|
|
16
|
-
entries = readdirSync(dir, { withFileTypes: true });
|
|
17
|
-
}
|
|
18
|
-
catch (err) {
|
|
19
|
-
void err; // unreadable dir (permissions, dangling symlink) — deliberately skipped
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
for (const e of entries) {
|
|
23
|
-
const abs = join(dir, e.name);
|
|
24
|
-
if (e.isDirectory()) {
|
|
25
|
-
if (ignoreDirs.has(e.name))
|
|
26
|
-
continue;
|
|
27
|
-
walk(abs, root, ignoreDirs, acc);
|
|
28
|
-
}
|
|
29
|
-
else if (e.isFile()) {
|
|
30
|
-
acc.push(toPosix(relative(root, abs)));
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
11
|
/**
|
|
35
12
|
* Load a markdown corpus. Walks `roots` from `cwd`, parses each `.md` file with
|
|
36
13
|
* GFM enabled, and records frozen membership per file. The full repo file tree
|
|
@@ -40,7 +17,8 @@ export function corpus(options) {
|
|
|
40
17
|
const root = options.cwd ?? process.cwd();
|
|
41
18
|
const ignoreDirs = new Set(BUILTIN_IGNORE);
|
|
42
19
|
const allFiles = [];
|
|
43
|
-
|
|
20
|
+
const allFilesWalked = walkFiles(root, root, ignoreDirs);
|
|
21
|
+
allFiles.push(...allFilesWalked);
|
|
44
22
|
const matchesRoot = picomatch([...options.roots]);
|
|
45
23
|
const matchesFrozen = picomatch([...(options.frozen ?? DEFAULT_FROZEN)]);
|
|
46
24
|
const matchesIgnore = options.ignore && options.ignore.length > 0 ? picomatch([...options.ignore]) : () => false;
|
package/dist/corpus.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"corpus.js","sourceRoot":"","sources":["../src/corpus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"corpus.js","sourceRoot":"","sources":["../src/corpus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AACvD,OAAO,EAAE,GAAG,EAAE,MAAM,yBAAyB,CAAA;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,SAAS,MAAM,WAAW,CAAA;AACjC,OAAO,EAAE,aAAa,EAAmB,MAAM,qBAAqB,CAAA;AA2CpE,MAAM,cAAc,GAAG,CAAC,iBAAiB,EAAE,gBAAgB,CAAC,CAAA;AAC5D,MAAM,cAAc,GAAG,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,CAAC,CAAA;AAElG;;;;GAIG;AACH,MAAM,UAAU,MAAM,CAAC,OAAsB;IAC3C,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAA;IACzC,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,CAAA;IAE1C,MAAM,QAAQ,GAAa,EAAE,CAAA;IAC7B,MAAM,cAAc,GAAG,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC,CAAA;IACxD,QAAQ,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,CAAA;IAEhC,MAAM,WAAW,GAAG,SAAS,CAAC,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAA;IACjD,MAAM,aAAa,GAAG,SAAS,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,cAAc,CAAC,CAAC,CAAC,CAAA;IACxE,MAAM,aAAa,GACjB,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,KAAK,CAAA;IAE5F,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAA;IACnC,MAAM,MAAM,GAAG,GAAG,EAAE,CAAA;IACpB,MAAM,QAAQ,GAAG,eAAe,EAAE,CAAA;IAElC,MAAM,SAAS,GAAiB,QAAQ;SACrC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;SAC/E,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACX,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QAC3B,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;QACtC,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE;YAC9B,UAAU,EAAE,CAAC,MAAM,CAAC;YACpB,eAAe,EAAE,CAAC,QAAQ,CAAC;SAC5B,CAAC,CAAA;QACF,OAAO,aAAa,CAAC;YACnB,IAAI,EAAE,GAAG;YACT,OAAO,EAAE,GAAG;YACZ,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC;YAC1B,IAAI;YACJ,IAAI,EAAE,IAAI;SACX,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEJ,OAAO;QACL,SAAS,EAAE,GAAG,EAAE,CAAC,SAAS;QAC1B,IAAI;QACJ,SAAS;KACV,CAAA;AACH,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
export { corpus } from './corpus.js';
|
|
2
2
|
export type { CorpusOptions, Corpus } from './corpus.js';
|
|
3
|
+
export type { Predicate, Condition, ConditionContext, ArchFix, PresetReportOptions, PresetBaseOptions, } from '@nielspeter/eess';
|
|
4
|
+
export { RuleBuilder, finishPreset, generateCodeFrame, not, dispatchRule, validateOverrides, reportViolations, isArchConfigError, } from '@nielspeter/eess';
|
|
5
|
+
export { correspondence, CorrespondenceBuilder } from '@nielspeter/eess';
|
|
6
|
+
export { collectResult, mergeCollectResults, hasEvidence } from '@nielspeter/eess';
|
|
7
|
+
export type { CollectResult } from '@nielspeter/eess';
|
|
8
|
+
export type { CorrespondenceOptions, RelationSpec, KeyBy } from '@nielspeter/eess';
|
|
3
9
|
export type { MdDocument, MdSection, MdTable, MdCodeBlock } from './model/document.js';
|
|
4
10
|
export type { MdRow, ColumnSpec, RowMatchOptions, RowMatchMode } from './model/rows.js';
|
|
5
11
|
export { matchTableRows } from './model/rows.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,YAAY,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,YAAY,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAOxD,YAAY,EACV,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,OAAO,EACP,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,GAAG,EACH,YAAY,EACZ,iBAAiB,EAMjB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,kBAAkB,CAAA;AASzB,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAA;AAOxE,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAClF,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAMrD,YAAY,EAAE,qBAAqB,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAGlF,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACtF,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACvF,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAChD,YAAY,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAGzD,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAC1D,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAC5D,YAAY,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AACjD,YAAY,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AACjE,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AACrE,YAAY,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAA;AACtE,YAAY,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAA;AAC5E,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAC1D,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AACzE,YAAY,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,YAAY,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAC1D,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAC7E,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAGnG,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AAClE,YAAY,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAA;AACpE,YAAY,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,29 @@
|
|
|
6
6
|
// from `@nielspeter/eess-md/rules/adr`.
|
|
7
7
|
// Corpus loader
|
|
8
8
|
export { corpus } from './corpus.js';
|
|
9
|
+
export { RuleBuilder, finishPreset, generateCodeFrame, not, dispatchRule, validateOverrides,
|
|
10
|
+
// Bug 0276, second pass. `finishPreset` was already here; its siblings were
|
|
11
|
+
// not, so a standalone consumer could finish a preset and neither report
|
|
12
|
+
// without throwing nor catch what the seam throws. ADR-008 names
|
|
13
|
+
// `reportViolations` as the one emitter, and ADR-014's configuration findings
|
|
14
|
+
// arrive as an `ArchConfigError` a caller has to recognise.
|
|
15
|
+
reportViolations, isArchConfigError, } from '@nielspeter/eess';
|
|
16
|
+
// `correspondence`/`CorrespondenceBuilder`: not touched by this package's
|
|
17
|
+
// OWN source (so the family.rules.ts code-import scan can't see this gap —
|
|
18
|
+
// review found it manually), but this README's own "Binding a spec table to
|
|
19
|
+
// code" example, and docs/markdown.md's equivalent, both teach
|
|
20
|
+
// `rows()` + `correspondence()` as the flagship way to bind a markdown table
|
|
21
|
+
// to code — without this re-export, that documented example does not
|
|
22
|
+
// compile against @nielspeter/eess-md alone, the exact second-install this
|
|
23
|
+
// plan exists to close.
|
|
24
|
+
export { correspondence, CorrespondenceBuilder } from '@nielspeter/eess';
|
|
25
|
+
// ADR-014's receipt: this package's own rules merge with it, so a standalone
|
|
26
|
+
// `eess-md` consumer must reach it without a second kernel install (plan 0089).
|
|
27
|
+
//
|
|
28
|
+
// Bug 0276: the merge was here and the CONSTRUCTOR was not, which is the same
|
|
29
|
+
// gap the other way round. A consumer handed a receipt could combine two and not
|
|
30
|
+
// build one. Import-driven `check:family` owed nothing here either.
|
|
31
|
+
export { collectResult, mergeCollectResults, hasEvidence } from '@nielspeter/eess';
|
|
9
32
|
export { matchTableRows } from './model/rows.js';
|
|
10
33
|
// Entry points
|
|
11
34
|
export { docs, DocsRuleBuilder } from './builders/docs.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,EAAE;AACF,iFAAiF;AACjF,gFAAgF;AAChF,gFAAgF;AAChF,wCAAwC;AAExC,gBAAgB;AAChB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,EAAE;AACF,iFAAiF;AACjF,gFAAgF;AAChF,gFAAgF;AAChF,wCAAwC;AAExC,gBAAgB;AAChB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAgBpC,OAAO,EACL,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,GAAG,EACH,YAAY,EACZ,iBAAiB;AACjB,4EAA4E;AAC5E,yEAAyE;AACzE,iEAAiE;AACjE,8EAA8E;AAC9E,4DAA4D;AAC5D,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,kBAAkB,CAAA;AACzB,0EAA0E;AAC1E,2EAA2E;AAC3E,4EAA4E;AAC5E,+DAA+D;AAC/D,6EAA6E;AAC7E,qEAAqE;AACrE,2EAA2E;AAC3E,wBAAwB;AACxB,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAA;AACxE,6EAA6E;AAC7E,gFAAgF;AAChF,EAAE;AACF,8EAA8E;AAC9E,iFAAiF;AACjF,oEAAoE;AACpE,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAYlF,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAGhD,eAAe;AACf,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAC1D,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAG5D,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAErE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAA;AAEtE,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAC1D,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAEzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAExD,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAG7E,oDAAoD;AACpD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AAElE,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAA"}
|