@nielspeter/eess 0.2.2 → 0.4.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 +3 -3
- package/dist/assertion-advice.d.ts +26 -0
- package/dist/assertion-advice.d.ts.map +1 -0
- package/dist/assertion-advice.js +29 -0
- package/dist/assertion-advice.js.map +1 -0
- package/dist/baseline.d.ts +69 -4
- package/dist/baseline.d.ts.map +1 -1
- package/dist/baseline.js +119 -13
- package/dist/baseline.js.map +1 -1
- package/dist/cache-registry.d.ts +14 -0
- package/dist/cache-registry.d.ts.map +1 -0
- package/dist/cache-registry.js +37 -0
- package/dist/cache-registry.js.map +1 -0
- package/dist/cardinality.d.ts +35 -0
- package/dist/cardinality.d.ts.map +1 -0
- package/dist/cardinality.js +65 -0
- package/dist/cardinality.js.map +1 -0
- package/dist/check-options.d.ts +14 -0
- package/dist/check-options.d.ts.map +1 -1
- package/dist/comment-suppression.d.ts +60 -0
- package/dist/comment-suppression.d.ts.map +1 -0
- package/dist/comment-suppression.js +89 -0
- package/dist/comment-suppression.js.map +1 -0
- package/dist/condition.d.ts +6 -0
- package/dist/condition.d.ts.map +1 -1
- package/dist/correspondence-core.d.ts +35 -0
- package/dist/correspondence-core.d.ts.map +1 -0
- package/dist/correspondence-core.js +38 -0
- package/dist/correspondence-core.js.map +1 -0
- package/dist/correspondence.d.ts +27 -5
- package/dist/correspondence.d.ts.map +1 -1
- package/dist/correspondence.js +39 -5
- package/dist/correspondence.js.map +1 -1
- package/dist/dedupe-config-findings.d.ts +56 -0
- package/dist/dedupe-config-findings.d.ts.map +1 -0
- package/dist/dedupe-config-findings.js +74 -0
- package/dist/dedupe-config-findings.js.map +1 -0
- package/dist/define.d.ts +44 -2
- package/dist/define.d.ts.map +1 -1
- package/dist/define.js +45 -4
- package/dist/define.js.map +1 -1
- package/dist/diff-aware.d.ts +8 -0
- package/dist/diff-aware.d.ts.map +1 -1
- package/dist/diff-aware.js +11 -2
- package/dist/diff-aware.js.map +1 -1
- package/dist/diff-disclosure.d.ts +72 -0
- package/dist/diff-disclosure.d.ts.map +1 -0
- package/dist/diff-disclosure.js +110 -0
- package/dist/diff-disclosure.js.map +1 -0
- package/dist/disk-set.d.ts +27 -0
- package/dist/disk-set.d.ts.map +1 -0
- package/dist/disk-set.js +12 -0
- package/dist/disk-set.js.map +1 -0
- package/dist/edge-coverage.d.ts +96 -0
- package/dist/edge-coverage.d.ts.map +1 -0
- package/dist/edge-coverage.js +108 -0
- package/dist/edge-coverage.js.map +1 -0
- package/dist/errors.d.ts +25 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +32 -0
- package/dist/errors.js.map +1 -1
- package/dist/execute-rule.d.ts +2 -1
- package/dist/execute-rule.d.ts.map +1 -1
- package/dist/execute-rule.js +38 -6
- package/dist/execute-rule.js.map +1 -1
- package/dist/format-github.d.ts.map +1 -1
- package/dist/format-github.js +37 -5
- package/dist/format-github.js.map +1 -1
- package/dist/format-json.d.ts +83 -1
- package/dist/format-json.d.ts.map +1 -1
- package/dist/format-json.js +70 -9
- package/dist/format-json.js.map +1 -1
- package/dist/format.d.ts +4 -2
- package/dist/format.d.ts.map +1 -1
- package/dist/format.js +41 -19
- package/dist/format.js.map +1 -1
- package/dist/glob-site.d.ts +232 -0
- package/dist/glob-site.d.ts.map +1 -0
- package/dist/glob-site.js +156 -0
- package/dist/glob-site.js.map +1 -0
- package/dist/identity-root.d.ts +55 -0
- package/dist/identity-root.d.ts.map +1 -0
- package/dist/identity-root.js +170 -0
- package/dist/identity-root.js.map +1 -0
- package/dist/index.d.ts +41 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +33 -3
- package/dist/index.js.map +1 -1
- package/dist/owns-empty-discovery.d.ts +5 -0
- package/dist/owns-empty-discovery.d.ts.map +1 -0
- package/dist/owns-empty-discovery.js +77 -0
- package/dist/owns-empty-discovery.js.map +1 -0
- package/dist/path-universe.d.ts +44 -0
- package/dist/path-universe.d.ts.map +1 -0
- package/dist/path-universe.js +21 -0
- package/dist/path-universe.js.map +1 -0
- package/dist/predicate.d.ts +33 -0
- package/dist/predicate.d.ts.map +1 -1
- package/dist/preset-dispatch.d.ts +19 -0
- package/dist/preset-dispatch.d.ts.map +1 -1
- package/dist/preset-dispatch.js +43 -3
- package/dist/preset-dispatch.js.map +1 -1
- package/dist/project-relative.d.ts +25 -0
- package/dist/project-relative.d.ts.map +1 -0
- package/dist/project-relative.js +54 -0
- package/dist/project-relative.js.map +1 -0
- package/dist/report.d.ts +11 -5
- package/dist/report.d.ts.map +1 -1
- package/dist/report.js +17 -0
- package/dist/report.js.map +1 -1
- package/dist/rule-builder-like.d.ts +11 -0
- package/dist/rule-builder-like.d.ts.map +1 -0
- package/dist/rule-builder-like.js +2 -0
- package/dist/rule-builder-like.js.map +1 -0
- package/dist/rule-builder.d.ts +109 -84
- package/dist/rule-builder.d.ts.map +1 -1
- package/dist/rule-builder.js +202 -158
- package/dist/rule-builder.js.map +1 -1
- package/dist/rule-description.d.ts +33 -1
- package/dist/rule-description.d.ts.map +1 -1
- package/dist/rule-description.js +17 -1
- package/dist/rule-description.js.map +1 -1
- package/dist/rule-metadata.d.ts +20 -3
- package/dist/rule-metadata.d.ts.map +1 -1
- package/dist/selection-memo.d.ts +47 -0
- package/dist/selection-memo.d.ts.map +1 -0
- package/dist/selection-memo.js +68 -0
- package/dist/selection-memo.js.map +1 -0
- package/dist/shallow-clone.d.ts +20 -0
- package/dist/shallow-clone.d.ts.map +1 -0
- package/dist/shallow-clone.js +27 -0
- package/dist/shallow-clone.js.map +1 -0
- package/dist/stderr.d.ts +16 -0
- package/dist/stderr.d.ts.map +1 -0
- package/dist/stderr.js +73 -0
- package/dist/stderr.js.map +1 -0
- package/dist/terminal-builder.d.ts +209 -9
- package/dist/terminal-builder.d.ts.map +1 -1
- package/dist/terminal-builder.js +264 -20
- package/dist/terminal-builder.js.map +1 -1
- package/dist/type-guards.d.ts +38 -0
- package/dist/type-guards.d.ts.map +1 -0
- package/dist/type-guards.js +42 -0
- package/dist/type-guards.js.map +1 -0
- package/dist/unsuppressable.d.ts +54 -0
- package/dist/unsuppressable.d.ts.map +1 -0
- package/dist/unsuppressable.js +76 -0
- package/dist/unsuppressable.js.map +1 -0
- package/dist/vacuity-findings.d.ts +55 -0
- package/dist/vacuity-findings.d.ts.map +1 -0
- package/dist/vacuity-findings.js +124 -0
- package/dist/vacuity-findings.js.map +1 -0
- package/dist/violation.d.ts +152 -4
- package/dist/violation.d.ts.map +1 -1
- package/dist/violation.js +262 -1
- package/dist/violation.js.map +1 -1
- package/package.json +1 -1
package/dist/report.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAMtD;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;AAEpD,uEAAuE;AACvE,MAAM,WAAW,aAAa;IAC5B,+DAA+D;IAC/D,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAA;IAC9B,kDAAkD;IAClD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,sEAAsE;AACtE,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACxD,sCAAsC;IACtC,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,CAAA;CAC7B;
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAMtD;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;AAEpD,uEAAuE;AACvE,MAAM,WAAW,aAAa;IAC5B,+DAA+D;IAC/D,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAA;IAC9B,kDAAkD;IAClD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,sEAAsE;AACtE,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACxD,sCAAsC;IACtC,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,CAAA;CAC7B;AAWD;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C;AAED,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,aAAa,EAAE,EAAE,OAAO,GAAE,aAAkB,GAAG,IAAI,CAa/F;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,aAAa,EAAE,EAC3B,OAAO,GAAE,mBAAwB,GAChC,aAAa,EAAE,CAQjB"}
|
package/dist/report.js
CHANGED
|
@@ -9,9 +9,26 @@ import { formatViolationsGitHub } from './format-github.js';
|
|
|
9
9
|
* path) both delegate here, so the two reporting paths can no longer diverge
|
|
10
10
|
* (plan 0070). Emits nothing for an empty set.
|
|
11
11
|
*/
|
|
12
|
+
let violationsEmitted = 0;
|
|
13
|
+
/**
|
|
14
|
+
* How many violations this module has actually WRITTEN, ever.
|
|
15
|
+
*
|
|
16
|
+
* Read as a delta by a caller that aggregates reporting, to answer one question it
|
|
17
|
+
* cannot otherwise answer: *did something emit while I was loading that module?*
|
|
18
|
+
*
|
|
19
|
+
* The alternative a caller might reach for — counting the writes it SUPPRESSED and
|
|
20
|
+
* inferring "then nothing was written" — is a double negative and is unsound: a
|
|
21
|
+
* module that suppresses one terminal and leaks through another satisfies it while
|
|
22
|
+
* leaking. Measured on `eess-ts`, which shipped that inference and fell into
|
|
23
|
+
* exactly that case. Count emissions, not silences.
|
|
24
|
+
*/
|
|
25
|
+
export function violationsEmittedCount() {
|
|
26
|
+
return violationsEmitted;
|
|
27
|
+
}
|
|
12
28
|
export function reportViolations(violations, options = {}) {
|
|
13
29
|
if (violations.length === 0)
|
|
14
30
|
return;
|
|
31
|
+
violationsEmitted += violations.length;
|
|
15
32
|
const format = options.format ?? 'terminal';
|
|
16
33
|
if (format === 'json') {
|
|
17
34
|
process.stdout.write(formatViolationsJson(violations, options.reason) + '\n');
|
package/dist/report.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report.js","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAwB3D;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,UAA2B,EAAE,UAAyB,EAAE;IACvF,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAM;IACnC,MAAM,MAAM,GAAiB,OAAO,CAAC,MAAM,IAAI,UAAU,CAAA;IACzD,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAA;IAC/E,CAAC;SAAM,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,CAAC,UAAU,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAAA;IAC1E,CAAC;SAAM,CAAC;QACN,wEAAwE;QACxE,0DAA0D;QAC1D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAA;IAC3E,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAC1B,UAA2B,EAC3B,UAA+B,EAAE;IAEjC,MAAM,IAAI,GAAe,OAAO,CAAC,MAAM,IAAI,OAAO,CAAA;IAClD,IAAI,IAAI,KAAK,QAAQ;QAAE,OAAO,UAAU,CAAA;IACxC,gBAAgB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;IACrC,IAAI,IAAI,KAAK,OAAO,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,aAAa,CAAC,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;IACrD,CAAC;IACD,OAAO,UAAU,CAAA;AACnB,CAAC"}
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAwB3D;;;;;;GAMG;AACH,IAAI,iBAAiB,GAAG,CAAC,CAAA;AAEzB;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,sBAAsB;IACpC,OAAO,iBAAiB,CAAA;AAC1B,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,UAA2B,EAAE,UAAyB,EAAE;IACvF,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAM;IACnC,iBAAiB,IAAI,UAAU,CAAC,MAAM,CAAA;IACtC,MAAM,MAAM,GAAiB,OAAO,CAAC,MAAM,IAAI,UAAU,CAAA;IACzD,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAA;IAC/E,CAAC;SAAM,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,CAAC,UAAU,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAAA;IAC1E,CAAC;SAAM,CAAC;QACN,wEAAwE;QACxE,0DAA0D;QAC1D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAA;IAC3E,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAC1B,UAA2B,EAC3B,UAA+B,EAAE;IAEjC,MAAM,IAAI,GAAe,OAAO,CAAC,MAAM,IAAI,OAAO,CAAA;IAClD,IAAI,IAAI,KAAK,QAAQ;QAAE,OAAO,UAAU,CAAA;IACxC,gBAAgB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;IACrC,IAAI,IAAI,KAAK,OAAO,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,aAAa,CAAC,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;IACrD,CAAC;IACD,OAAO,UAAU,CAAA;AACnB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ArchViolation } from './violation.js';
|
|
2
|
+
/**
|
|
3
|
+
* Minimal shape the CLI runner and presets collect violations from: anything
|
|
4
|
+
* exposing a non-throwing, severity-stamped `.violations()`. Lives in core (not
|
|
5
|
+
* `cli/`) so presets can return `RuleBuilderLike[]` without depending on CLI
|
|
6
|
+
* infrastructure.
|
|
7
|
+
*/
|
|
8
|
+
export interface RuleBuilderLike {
|
|
9
|
+
violations: () => ArchViolation[];
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=rule-builder-like.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-builder-like.d.ts","sourceRoot":"","sources":["../src/rule-builder-like.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAEnD;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,aAAa,EAAE,CAAA;CAClC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-builder-like.js","sourceRoot":"","sources":["../src/rule-builder-like.ts"],"names":[],"mappings":""}
|
package/dist/rule-builder.d.ts
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import type { Predicate } from './predicate.js';
|
|
2
2
|
import type { Condition, ConditionContext } from './condition.js';
|
|
3
|
-
import type { ArchViolation } from './violation.js';
|
|
4
|
-
import type { CheckOptions } from './check-options.js';
|
|
5
|
-
import type { RuleMetadata } from './rule-metadata.js';
|
|
6
3
|
import type { RuleDescription } from './rule-description.js';
|
|
7
|
-
import type { SilentExclusion } from './silent-exclusion.js';
|
|
8
4
|
import type { Selection, ElementInfo } from './correspondence.js';
|
|
5
|
+
import type { GlobNode } from './glob-site.js';
|
|
6
|
+
import { TerminalBuilder, type CollectResult } from './terminal-builder.js';
|
|
9
7
|
/**
|
|
10
8
|
* Abstract base class for all rule builders.
|
|
11
9
|
*
|
|
@@ -15,20 +13,35 @@ import type { Selection, ElementInfo } from './correspondence.js';
|
|
|
15
13
|
* 3. Add condition methods that call `addCondition()`
|
|
16
14
|
*
|
|
17
15
|
* The builder accumulates predicates and conditions. Nothing executes
|
|
18
|
-
* until a terminal method (`.check()`, `.warn()`, `.severity()`) is called
|
|
16
|
+
* until a terminal method (`.check()`, `.warn()`, `.severity()`) is called —
|
|
17
|
+
* inherited from {@link TerminalBuilder} (plan 0088 Phase 4), which also
|
|
18
|
+
* supplies `because`/`rule`/`excluding`/`violations`/`expectEmpty`/
|
|
19
|
+
* `expectNonEmpty` and the ADR-010 evidence gate. `RuleBuilder` keeps its own
|
|
20
|
+
* `<T, P>` two-param generic — `P` is the dialect's project type, kept
|
|
21
|
+
* separate from `TerminalBuilder` (which has no project concept, since
|
|
22
|
+
* `correspondence()`, `SmellBuilder`, and the graphql builders don't share a
|
|
23
|
+
* uniform notion of "one project") — every builder across all five dialects
|
|
24
|
+
* depends on this exact two-param signature, so it is not replaced by the
|
|
25
|
+
* fold, only extended.
|
|
19
26
|
*/
|
|
20
|
-
export declare abstract class RuleBuilder<T, P = unknown> {
|
|
27
|
+
export declare abstract class RuleBuilder<T, P = unknown> extends TerminalBuilder {
|
|
21
28
|
protected readonly project: P;
|
|
22
29
|
protected _predicates: Predicate<T>[];
|
|
23
30
|
protected _conditions: Condition<T>[];
|
|
24
|
-
protected _reason?: string;
|
|
25
|
-
protected _metadata?: RuleMetadata;
|
|
26
|
-
protected _exclusions: (string | RegExp)[];
|
|
27
|
-
protected _silentIndices: Set<number>;
|
|
28
31
|
protected _phase: 'predicate' | 'condition';
|
|
32
|
+
/** Whether `.should()` was ever reached — bug 0155 state 3/4 vs state 1. */
|
|
33
|
+
protected _reachedShould: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Descriptions of predicate-only methods used AFTER `.should()` — bug 0155
|
|
36
|
+
* state 2. A dual-use method dispatches to a condition in that phase and
|
|
37
|
+
* never lands here, so anything recorded is genuinely a filter written where
|
|
38
|
+
* an assertion was meant.
|
|
39
|
+
*/
|
|
40
|
+
protected _misplaced: string[];
|
|
29
41
|
constructor(project: P);
|
|
30
42
|
/**
|
|
31
|
-
* Begin the predicate phase. Returns
|
|
43
|
+
* Begin the predicate phase. Returns a COPY — a held selection is never
|
|
44
|
+
* edited by narrowing it (see `TerminalBuilder.copy()`).
|
|
32
45
|
* Purely a readability marker — `.that().haveNameMatching(...)` reads like English.
|
|
33
46
|
* Explicitly resets phase to 'predicate' — defensive against `.should().that()` misuse.
|
|
34
47
|
*/
|
|
@@ -59,50 +72,6 @@ export declare abstract class RuleBuilder<T, P = unknown> {
|
|
|
59
72
|
* as a predicate; if it has `evaluate` it is treated as a condition.
|
|
60
73
|
*/
|
|
61
74
|
satisfy(custom: Predicate<T> | Condition<T>): this;
|
|
62
|
-
/**
|
|
63
|
-
* Attach a human-readable rationale to the rule.
|
|
64
|
-
* Included in violation messages when `.check()` throws.
|
|
65
|
-
*/
|
|
66
|
-
because(reason: string): this;
|
|
67
|
-
/**
|
|
68
|
-
* Attach rich metadata to the rule.
|
|
69
|
-
* Provides educational context in violation output: why, how to fix, docs link.
|
|
70
|
-
*
|
|
71
|
-
* If `metadata.because` is set, it also sets the reason (same as `.because()`).
|
|
72
|
-
*/
|
|
73
|
-
rule(metadata: RuleMetadata): this;
|
|
74
|
-
/**
|
|
75
|
-
* Exclude specific violations from reporting by matching against
|
|
76
|
-
* the violation's `element`, `file`, or `message` fields.
|
|
77
|
-
*
|
|
78
|
-
* Matched violations are silently suppressed. Use for permanent,
|
|
79
|
-
* intentional exceptions — not for temporary violations (use baseline for those).
|
|
80
|
-
*
|
|
81
|
-
* Patterns are matched against all three fields. Prefer anchored regexes
|
|
82
|
-
* or full string matches over short substrings, especially for `message`
|
|
83
|
-
* matching, to avoid accidentally suppressing unrelated violations whose
|
|
84
|
-
* messages happen to contain the same text.
|
|
85
|
-
*
|
|
86
|
-
* Emits a warning if an exclusion matches zero violations — so renamed
|
|
87
|
-
* or deleted exceptions don't silently stay in the rule.
|
|
88
|
-
*
|
|
89
|
-
* For narrowing a rule's scope at the predicate phase (so the rule never
|
|
90
|
-
* evaluates the excluded element), use `satisfy(not(<predicate>))` instead.
|
|
91
|
-
* See the "Excluding a file from a rule's scope" recipe in docs/recipes.md.
|
|
92
|
-
*
|
|
93
|
-
* @example
|
|
94
|
-
* // Exclude by element name (fully qualified)
|
|
95
|
-
* .excluding('Asset.getImageUrl')
|
|
96
|
-
*
|
|
97
|
-
* @example
|
|
98
|
-
* // Exclude by file path (regex anchored to suffix)
|
|
99
|
-
* .excluding(/repositories\/index\.ts$/)
|
|
100
|
-
*
|
|
101
|
-
* @example
|
|
102
|
-
* // Multiple exclusions, mixed forms
|
|
103
|
-
* .excluding('Asset.getImageUrl', /\/legacy\//, /generated/)
|
|
104
|
-
*/
|
|
105
|
-
excluding(...patterns: (string | RegExp | SilentExclusion)[]): this;
|
|
106
75
|
/**
|
|
107
76
|
* Return the predicate-filtered elements as a labelled `Selection<T>` for
|
|
108
77
|
* cross-validation (`correspondence()`). The set is exactly the elements this
|
|
@@ -121,38 +90,61 @@ export declare abstract class RuleBuilder<T, P = unknown> {
|
|
|
121
90
|
*/
|
|
122
91
|
describeRule(): RuleDescription;
|
|
123
92
|
/**
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
|
|
127
|
-
violations(): ArchViolation[];
|
|
128
|
-
/**
|
|
129
|
-
* Execute the rule and throw `ArchRuleError` if any violations are found.
|
|
130
|
-
* This is the primary terminal method — use in test assertions.
|
|
93
|
+
* ADR-010: is this rule's assertion satisfied by an empty selection, as a
|
|
94
|
+
* property of what its conditions assert (`.notExist()`) rather than a
|
|
95
|
+
* caller's `.expectEmpty()` declaration?
|
|
131
96
|
*
|
|
132
|
-
*
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
*
|
|
137
|
-
*
|
|
97
|
+
* `.every()`, not `.some()` — `.andShould()` ANDs, so a rule reading
|
|
98
|
+
* `.should().notExist().andShould().beExported()` still asserts something
|
|
99
|
+
* about subjects that exist, and exempting it on the strength of the one
|
|
100
|
+
* cardinality condition would silence the other. An empty condition list is
|
|
101
|
+
* NOT exempt: `[].every()` is vacuously `true`, and a rule with zero
|
|
102
|
+
* conditions is the assertion-less case `collectViolations()` now reports as
|
|
103
|
+
* a configuration finding (bug 0155; it used to be an unreachable stderr
|
|
104
|
+
* warning, which this comment named until that fix landed) — this override
|
|
105
|
+
* must not paper over it by also declaring it cardinality-satisfied.
|
|
138
106
|
*
|
|
139
|
-
*
|
|
107
|
+
* **Load-bearing:** for a DEAD selector this early return is the only thing
|
|
108
|
+
* between an assertion-less rule and a silent pass (the gate runs after the
|
|
109
|
+
* zero-examined branch). Pinned in `assertion-less-rules.test.ts`.
|
|
140
110
|
*/
|
|
141
|
-
warn(options?: CheckOptions): void;
|
|
142
111
|
/**
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
|
|
147
|
-
|
|
112
|
+
* Does this rule assert anything at all? — bug 0155.
|
|
113
|
+
*
|
|
114
|
+
* Conditions alone are not enough: a predicate-only method written *after*
|
|
115
|
+
* `.should()` silently shrank the set the conditions run over, possibly to
|
|
116
|
+
* empty, in which case they hold vacuously. That rule asserts nothing
|
|
117
|
+
* meaningful even though `_conditions` is non-empty.
|
|
118
|
+
*/
|
|
119
|
+
protected assertsSomething(): boolean;
|
|
120
|
+
protected assertionAdvice(): string;
|
|
121
|
+
protected assertsCardinality(): boolean;
|
|
122
|
+
/**
|
|
123
|
+
* ADR-010 part 3: did this rule's own underlying source (the project, a
|
|
124
|
+
* diagram, an SDL string — whatever `P` loads) produce nothing at all,
|
|
125
|
+
* before `getElements()`'s own domain-specific extraction or any
|
|
126
|
+
* predicate ran? Default `false` — the kernel has no way to know, since
|
|
127
|
+
* `P` is opaque here. A dialect's concrete builder, which knows `P`'s real
|
|
128
|
+
* shape (e.g. `ArchProject`), overrides this to check its own project's
|
|
129
|
+
* file count directly — never `getElements().length`, which conflates "the
|
|
130
|
+
* source is empty" with "this domain legitimately has nothing in a
|
|
131
|
+
* healthy project" (e.g. zero JSX elements in a backend-only codebase).
|
|
132
|
+
*/
|
|
133
|
+
protected sourceEmpty(): boolean;
|
|
134
|
+
/** Declared globs, position derived from `_phase`. Pure — no `P` needed. */
|
|
135
|
+
globs(): readonly GlobNode[];
|
|
136
|
+
/** This rule's own project, for `diagnose()`/`doctor` outside `.check()`. */
|
|
137
|
+
getProject(): P;
|
|
138
|
+
/** A `globs()` tree diagnosably dead, when zero examined — same shape as `sourceEmpty()`. */
|
|
139
|
+
protected deadGlobDiagnosis(): string | undefined;
|
|
148
140
|
/**
|
|
149
141
|
* Register a predicate. Called by concrete builder methods like
|
|
150
|
-
* `.haveNameMatching()`, `.extend()`, etc.
|
|
142
|
+
* `.haveNameMatching()`, `.extend()`, etc. Returns a COPY — see `copy()`.
|
|
151
143
|
*/
|
|
152
144
|
protected addPredicate(predicate: Predicate<T>): this;
|
|
153
145
|
/**
|
|
154
146
|
* Register a condition. Called by concrete builder methods like
|
|
155
|
-
* `.notContain()`, `.notExist()`, etc.
|
|
147
|
+
* `.notContain()`, `.notExist()`, etc. Returns a COPY — see `copy()`.
|
|
156
148
|
*/
|
|
157
149
|
protected addCondition(condition: Condition<T>): this;
|
|
158
150
|
/**
|
|
@@ -161,10 +153,31 @@ export declare abstract class RuleBuilder<T, P = unknown> {
|
|
|
161
153
|
*/
|
|
162
154
|
protected abstract getElements(): T[];
|
|
163
155
|
/**
|
|
164
|
-
*
|
|
165
|
-
*
|
|
156
|
+
* An independent copy, carrying **both** predicates and conditions.
|
|
157
|
+
* Extends `TerminalBuilder.copy()` with the fields this class adds.
|
|
166
158
|
*
|
|
167
|
-
* Subclasses with additional
|
|
159
|
+
* Subclasses with additional mutable-reference fields of their own (arrays,
|
|
160
|
+
* sets, maps a chain method pushes onto) MUST override this and call
|
|
161
|
+
* `super.copy()` first, the same reason `TerminalBuilder.copy()`'s own
|
|
162
|
+
* docstring gives — `Object.assign` shallow-copies a field, it does not
|
|
163
|
+
* give it independent identity.
|
|
164
|
+
*/
|
|
165
|
+
protected copy(): this;
|
|
166
|
+
/**
|
|
167
|
+
* A fork of this builder, carrying BOTH lists. Used by `.should()` to support
|
|
168
|
+
* named selections without mutation.
|
|
169
|
+
*
|
|
170
|
+
* **Nothing here clears the conditions** (bug 0156). It used to, and a second
|
|
171
|
+
* `.should()` therefore silently discarded the first assertion — a rule that
|
|
172
|
+
* asserted something turned into one that asserted less, by a chain method.
|
|
173
|
+
* `.should().X().should().Y()` now accumulates exactly as `.andShould()` does.
|
|
174
|
+
*
|
|
175
|
+
* Ported from `packages/ts/src/core/rule-builder.ts`, where the engine copy
|
|
176
|
+
* landed the fix and left the kernel behind. Found by the architect review of
|
|
177
|
+
* PR #72: `eess-md`, `eess-mermaid` and `eess-gherkin` all extend THIS class,
|
|
178
|
+
* so they carried the defect — and `check:corpus`, `check:ledger` and
|
|
179
|
+
* `check:diagram` are md/mermaid gates, meaning this repo's own corpus
|
|
180
|
+
* enforcement ran on the broken copy.
|
|
168
181
|
*/
|
|
169
182
|
protected fork(): this;
|
|
170
183
|
/**
|
|
@@ -172,10 +185,22 @@ export declare abstract class RuleBuilder<T, P = unknown> {
|
|
|
172
185
|
*/
|
|
173
186
|
private buildRuleDescription;
|
|
174
187
|
/**
|
|
175
|
-
* Execute the full pipeline: filter elements with predicates,
|
|
176
|
-
*
|
|
177
|
-
|
|
178
|
-
|
|
188
|
+
* Execute the full pipeline: filter elements with predicates, evaluate
|
|
189
|
+
* conditions, return violations plus the ADR-010 evidence — the
|
|
190
|
+
* post-predicate subject count, whatever it is. `TerminalBuilder.check()` /
|
|
191
|
+
* `.warn()` / `.violations()` decide what a zero count means (a
|
|
192
|
+
* configuration finding, unless `.expectEmpty()` was declared); this method
|
|
193
|
+
* only reports the count, never interprets it.
|
|
194
|
+
*
|
|
195
|
+
* `sourceEmpty` (ADR-010 part 3) is deliberately not `allElements.length
|
|
196
|
+
* === 0` — a domain's own `getElements()` legitimately returning nothing in
|
|
197
|
+
* a healthy, fully-loaded project (e.g. zero JSX elements in a
|
|
198
|
+
* backend-only codebase) is not brokenness, and conflating the two broke
|
|
199
|
+
* `.notExist()`'s cardinality exemption for exactly that case. Subclasses
|
|
200
|
+
* that can answer "did my underlying source load anything at all" override
|
|
201
|
+
* `sourceEmpty()`; the default assumes it did.
|
|
202
|
+
*/
|
|
203
|
+
protected collectViolations(): CollectResult;
|
|
179
204
|
/**
|
|
180
205
|
* Build the `ConditionContext` passed to each condition.
|
|
181
206
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rule-builder.d.ts","sourceRoot":"","sources":["../src/rule-builder.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"rule-builder.d.ts","sourceRoot":"","sources":["../src/rule-builder.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAEjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACjE,OAAO,KAAK,EAAgB,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAE5D,OAAO,EAAE,eAAe,EAAE,KAAK,aAAa,EAA0B,MAAM,uBAAuB,CAAA;AA6CnG;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,8BAAsB,WAAW,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,CAAE,SAAQ,eAAe;IAc3D,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;IAbzC,SAAS,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAK;IAC1C,SAAS,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAK;IAC1C,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,CAAc;IACzD,4EAA4E;IAC5E,SAAS,CAAC,cAAc,UAAQ;IAChC;;;;;OAKG;IACH,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,CAAK;gBAEJ,OAAO,EAAE,CAAC;IAMzC;;;;;OAKG;IACH,IAAI,IAAI,IAAI;IAMZ;;;OAGG;IACH,GAAG,IAAI,IAAI;IAIX;;;;OAIG;IACH,MAAM,IAAI,IAAI;IAOd;;;OAGG;IACH,SAAS,IAAI,IAAI;IAIjB;;;;;;;;OAQG;IACH,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI;IAelD;;;;;;;OAOG;IACH,MAAM,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,WAAW,CAAA;KAAE,GAAG,SAAS,CAAC,CAAC,CAAC;IAOpF;;;OAGG;IACH,YAAY,IAAI,eAAe;IAW/B;;;;;;;;;;;;;;;;;;OAkBG;IACH;;;;;;;OAOG;IACH,SAAS,CAAC,gBAAgB,IAAI,OAAO;IAIrC,SAAS,CAAC,eAAe,IAAI,MAAM;cAQhB,kBAAkB,IAAI,OAAO;IAKhD;;;;;;;;;;OAUG;IACH,SAAS,CAAC,WAAW,IAAI,OAAO;IAIhC,4EAA4E;IAC5E,KAAK,IAAI,SAAS,QAAQ,EAAE;IAI5B,6EAA6E;IAC7E,UAAU,IAAI,CAAC;IAIf,6FAA6F;IAC7F,SAAS,CAAC,iBAAiB,IAAI,MAAM,GAAG,SAAS;IAMjD;;;OAGG;IACH,SAAS,CAAC,YAAY,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI;IAWrD;;;OAGG;IACH,SAAS,CAAC,YAAY,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI;IAMrD;;;OAGG;IACH,SAAS,CAAC,QAAQ,CAAC,WAAW,IAAI,CAAC,EAAE;IAErC;;;;;;;;;OASG;cACgB,IAAI,IAAI,IAAI;IAQ/B;;;;;;;;;;;;;;;OAeG;IACH,SAAS,CAAC,IAAI,IAAI,IAAI;IAQtB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAS5B;;;;;;;;;;;;;;;OAeG;IACH,SAAS,CAAC,iBAAiB,IAAI,aAAa;IAuC5C;;;;;;OAMG;IACH,SAAS,CAAC,qBAAqB,IAAI,gBAAgB;CASpD"}
|