@nielspeter/eess 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +26 -0
- package/dist/ansi.d.ts +7 -0
- package/dist/ansi.d.ts.map +1 -0
- package/dist/ansi.js +16 -0
- package/dist/ansi.js.map +1 -0
- package/dist/apply-fixes.d.ts +25 -0
- package/dist/apply-fixes.d.ts.map +1 -0
- package/dist/apply-fixes.js +52 -0
- package/dist/apply-fixes.js.map +1 -0
- package/dist/baseline-generator.d.ts +18 -0
- package/dist/baseline-generator.d.ts.map +1 -0
- package/dist/baseline-generator.js +29 -0
- package/dist/baseline-generator.js.map +1 -0
- package/dist/baseline.d.ts +83 -0
- package/dist/baseline.d.ts.map +1 -0
- package/dist/baseline.js +115 -0
- package/dist/baseline.js.map +1 -0
- package/dist/check-options.d.ts +47 -0
- package/dist/check-options.d.ts.map +1 -0
- package/dist/check-options.js +2 -0
- package/dist/check-options.js.map +1 -0
- package/dist/code-frame.d.ts +17 -0
- package/dist/code-frame.d.ts.map +1 -0
- package/dist/code-frame.js +32 -0
- package/dist/code-frame.js.map +1 -0
- package/dist/combinators.d.ts +55 -0
- package/dist/combinators.d.ts.map +1 -0
- package/dist/combinators.js +43 -0
- package/dist/combinators.js.map +1 -0
- package/dist/condition.d.ts +56 -0
- package/dist/condition.d.ts.map +1 -0
- package/dist/condition.js +2 -0
- package/dist/condition.js.map +1 -0
- package/dist/correspondence.d.ts +78 -0
- package/dist/correspondence.d.ts.map +1 -0
- package/dist/correspondence.js +127 -0
- package/dist/correspondence.js.map +1 -0
- package/dist/define.d.ts +41 -0
- package/dist/define.d.ts.map +1 -0
- package/dist/define.js +42 -0
- package/dist/define.js.map +1 -0
- package/dist/diff-aware.d.ts +37 -0
- package/dist/diff-aware.d.ts.map +1 -0
- package/dist/diff-aware.js +69 -0
- package/dist/diff-aware.js.map +1 -0
- package/dist/environment.d.ts +14 -0
- package/dist/environment.d.ts.map +1 -0
- package/dist/environment.js +20 -0
- package/dist/environment.js.map +1 -0
- package/dist/errors.d.ts +14 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +21 -0
- package/dist/errors.js.map +1 -0
- package/dist/exclusion-comments.d.ts +52 -0
- package/dist/exclusion-comments.d.ts.map +1 -0
- package/dist/exclusion-comments.js +183 -0
- package/dist/exclusion-comments.js.map +1 -0
- package/dist/execute-rule.d.ts +31 -0
- package/dist/execute-rule.d.ts.map +1 -0
- package/dist/execute-rule.js +119 -0
- package/dist/execute-rule.js.map +1 -0
- package/dist/format-github.d.ts +25 -0
- package/dist/format-github.d.ts.map +1 -0
- package/dist/format-github.js +44 -0
- package/dist/format-github.js.map +1 -0
- package/dist/format-json.d.ts +12 -0
- package/dist/format-json.d.ts.map +1 -0
- package/dist/format-json.js +30 -0
- package/dist/format-json.js.map +1 -0
- package/dist/format.d.ts +25 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +66 -0
- package/dist/format.js.map +1 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +40 -0
- package/dist/index.js.map +1 -0
- package/dist/matching.d.ts +31 -0
- package/dist/matching.d.ts.map +1 -0
- package/dist/matching.js +64 -0
- package/dist/matching.js.map +1 -0
- package/dist/predicate.d.ts +11 -0
- package/dist/predicate.d.ts.map +1 -0
- package/dist/predicate.js +2 -0
- package/dist/predicate.js.map +1 -0
- package/dist/preset-dispatch.d.ts +46 -0
- package/dist/preset-dispatch.d.ts.map +1 -0
- package/dist/preset-dispatch.js +48 -0
- package/dist/preset-dispatch.js.map +1 -0
- package/dist/report.d.ts +38 -0
- package/dist/report.d.ts.map +1 -0
- package/dist/report.js +45 -0
- package/dist/report.js.map +1 -0
- package/dist/rule-builder.d.ts +188 -0
- package/dist/rule-builder.d.ts.map +1 -0
- package/dist/rule-builder.js +323 -0
- package/dist/rule-builder.js.map +1 -0
- package/dist/rule-description.d.ts +12 -0
- package/dist/rule-description.d.ts.map +1 -0
- package/dist/rule-description.js +2 -0
- package/dist/rule-description.js.map +1 -0
- package/dist/rule-metadata.d.ts +17 -0
- package/dist/rule-metadata.d.ts.map +1 -0
- package/dist/rule-metadata.js +2 -0
- package/dist/rule-metadata.js.map +1 -0
- package/dist/silent-exclusion.d.ts +38 -0
- package/dist/silent-exclusion.d.ts.map +1 -0
- package/dist/silent-exclusion.js +30 -0
- package/dist/silent-exclusion.js.map +1 -0
- package/dist/terminal-builder.d.ts +83 -0
- package/dist/terminal-builder.d.ts.map +1 -0
- package/dist/terminal-builder.js +134 -0
- package/dist/terminal-builder.js.map +1 -0
- package/dist/violation.d.ts +51 -0
- package/dist/violation.d.ts.map +1 -0
- package/dist/violation.js +2 -0
- package/dist/violation.js.map +1 -0
- package/package.json +40 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export type { Predicate } from './predicate.js';
|
|
2
|
+
export type { Condition, ConditionContext } from './condition.js';
|
|
3
|
+
export { not, and, or } from './combinators.js';
|
|
4
|
+
export type { Matcher } from './combinators.js';
|
|
5
|
+
export type { ArchViolation, ArchFix } from './violation.js';
|
|
6
|
+
export { applyFixes } from './apply-fixes.js';
|
|
7
|
+
export type { ApplyResult } from './apply-fixes.js';
|
|
8
|
+
export { RuleBuilder } from './rule-builder.js';
|
|
9
|
+
export { TerminalBuilder } from './terminal-builder.js';
|
|
10
|
+
export { ArchRuleError } from './errors.js';
|
|
11
|
+
export type { RuleMetadata } from './rule-metadata.js';
|
|
12
|
+
export type { RuleDescription } from './rule-description.js';
|
|
13
|
+
export { generateCodeFrame } from './code-frame.js';
|
|
14
|
+
export type { CodeFrameOptions } from './code-frame.js';
|
|
15
|
+
export { formatViolations, formatViolationsPlain } from './format.js';
|
|
16
|
+
export type { FormatOptions } from './format.js';
|
|
17
|
+
export { formatViolationsJson } from './format-json.js';
|
|
18
|
+
export { formatViolationsGitHub } from './format-github.js';
|
|
19
|
+
export type { CheckOptions, OutputFormat, BaselineFilter, DiffFilterLike } from './check-options.js';
|
|
20
|
+
export { detectFormat, isCI } from './environment.js';
|
|
21
|
+
export { definePredicate, defineCondition } from './define.js';
|
|
22
|
+
export { dispatchRule, validateOverrides, throwIfViolations } from './preset-dispatch.js';
|
|
23
|
+
export { reportViolations, finishPreset } from './report.js';
|
|
24
|
+
export type { ReportMode, ReportOptions, PresetReportOptions } from './report.js';
|
|
25
|
+
export type { RuleSeverity, PresetBaseOptions } from './preset-dispatch.js';
|
|
26
|
+
export { matchSelections } from './matching.js';
|
|
27
|
+
export type { Pair, MatchResult, MatchOptions } from './matching.js';
|
|
28
|
+
export { correspondence, CorrespondenceBuilder } from './correspondence.js';
|
|
29
|
+
export type { Selection, ElementInfo, Direction, RelationSpec, CorrespondenceOptions, KeyBy, } from './correspondence.js';
|
|
30
|
+
export { applyFilters } from './execute-rule.js';
|
|
31
|
+
export { escapeGitHub } from './format-github.js';
|
|
32
|
+
export { hashViolation } from './baseline.js';
|
|
33
|
+
export { bold, red, dim, yellow, cyan, gray } from './ansi.js';
|
|
34
|
+
export { parseExclusionComments, isExcludedByComment } from './exclusion-comments.js';
|
|
35
|
+
export type { ExclusionComment, ExclusionWarning, ParseResult } from './exclusion-comments.js';
|
|
36
|
+
export { silent } from './silent-exclusion.js';
|
|
37
|
+
export type { SilentExclusion } from './silent-exclusion.js';
|
|
38
|
+
export { withBaseline, generateBaseline, Baseline } from './baseline.js';
|
|
39
|
+
export type { BaselineEntry, BaselineFile } from './baseline.js';
|
|
40
|
+
export { collectViolations } from './baseline-generator.js';
|
|
41
|
+
export { diffAware, DiffFilter } from './diff-aware.js';
|
|
42
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// @nielspeter/eess — the dialect-independent kernel.
|
|
2
|
+
//
|
|
3
|
+
// RuleBuilder<T, P>, Predicate<T>, Condition<T>, the violation model, baseline
|
|
4
|
+
// and diff-aware machinery, exclusions, formatters, and the definePredicate /
|
|
5
|
+
// defineCondition extension points. Nothing here depends on ts-morph or any
|
|
6
|
+
// dialect-specific parser.
|
|
7
|
+
export { not, and, or } from './combinators.js';
|
|
8
|
+
export { applyFixes } from './apply-fixes.js';
|
|
9
|
+
// Rule builder, terminal builder, error
|
|
10
|
+
export { RuleBuilder } from './rule-builder.js';
|
|
11
|
+
export { TerminalBuilder } from './terminal-builder.js';
|
|
12
|
+
export { ArchRuleError } from './errors.js';
|
|
13
|
+
// Code frame & formatting
|
|
14
|
+
export { generateCodeFrame } from './code-frame.js';
|
|
15
|
+
export { formatViolations, formatViolationsPlain } from './format.js';
|
|
16
|
+
export { formatViolationsJson } from './format-json.js';
|
|
17
|
+
export { formatViolationsGitHub } from './format-github.js';
|
|
18
|
+
export { detectFormat, isCI } from './environment.js';
|
|
19
|
+
// Custom predicate/condition factories
|
|
20
|
+
export { definePredicate, defineCondition } from './define.js';
|
|
21
|
+
// Preset dispatch — generic per-rule severity/override infrastructure for presets
|
|
22
|
+
export { dispatchRule, validateOverrides, throwIfViolations } from './preset-dispatch.js';
|
|
23
|
+
export { reportViolations, finishPreset } from './report.js';
|
|
24
|
+
// Matching engine — shared by correspondence() and eess-ts's crossLayer
|
|
25
|
+
export { matchSelections } from './matching.js';
|
|
26
|
+
// Cross-validation — bind two element Selections and assert they correspond
|
|
27
|
+
export { correspondence, CorrespondenceBuilder } from './correspondence.js';
|
|
28
|
+
// Lower-level building blocks (used by dialects and covered by kernel tests)
|
|
29
|
+
export { applyFilters } from './execute-rule.js';
|
|
30
|
+
export { escapeGitHub } from './format-github.js';
|
|
31
|
+
export { hashViolation } from './baseline.js';
|
|
32
|
+
export { bold, red, dim, yellow, cyan, gray } from './ansi.js';
|
|
33
|
+
// Exclusions
|
|
34
|
+
export { parseExclusionComments, isExcludedByComment } from './exclusion-comments.js';
|
|
35
|
+
export { silent } from './silent-exclusion.js';
|
|
36
|
+
// Baseline & diff-aware
|
|
37
|
+
export { withBaseline, generateBaseline, Baseline } from './baseline.js';
|
|
38
|
+
export { collectViolations } from './baseline-generator.js';
|
|
39
|
+
export { diffAware, DiffFilter } from './diff-aware.js';
|
|
40
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,+EAA+E;AAC/E,8EAA8E;AAC9E,4EAA4E;AAC5E,2BAA2B;AAK3B,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAA;AAK/C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAG7C,wCAAwC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAI3C,0BAA0B;AAC1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAEnD,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAErE,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAI3D,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAErD,uCAAuC;AACvC,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE9D,kFAAkF;AAClF,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AACzF,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAI5D,wEAAwE;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAG/C,4EAA4E;AAC5E,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAU3E,6EAA6E;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAE9D,aAAa;AACb,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAErF,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAG9C,wBAAwB;AACxB,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAExE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single matching engine shared by `correspondence()` and `eess-ts`'s
|
|
3
|
+
* `crossLayer` — "given two element sets and how to match them, which pairs
|
|
4
|
+
* form and which elements are left unmatched." Extracting this removes the
|
|
5
|
+
* duplicate pair-matching implementations the two builders used to carry.
|
|
6
|
+
*/
|
|
7
|
+
export interface Pair<L, R> {
|
|
8
|
+
readonly left: L;
|
|
9
|
+
readonly right: R;
|
|
10
|
+
}
|
|
11
|
+
export interface MatchResult<L, R> {
|
|
12
|
+
/** Every matched (left, right) pair. */
|
|
13
|
+
readonly pairs: Pair<L, R>[];
|
|
14
|
+
/** Left elements with no matching right. */
|
|
15
|
+
readonly leftUnmatched: L[];
|
|
16
|
+
/** Right elements with no matching left. */
|
|
17
|
+
readonly rightUnmatched: R[];
|
|
18
|
+
/** Left elements that matched more than one right (ambiguous correspondence). */
|
|
19
|
+
readonly leftAmbiguous: L[];
|
|
20
|
+
}
|
|
21
|
+
export interface MatchOptions<L, R> {
|
|
22
|
+
/** Arbitrary predicate — O(n×m) Cartesian matching. */
|
|
23
|
+
readonly matchBy?: (left: L, right: R) => boolean;
|
|
24
|
+
/** Join key per left element — O(n+m) indexed matching (with `rightKey`). */
|
|
25
|
+
readonly leftKey?: (element: L) => string;
|
|
26
|
+
/** Join key per right element. */
|
|
27
|
+
readonly rightKey?: (element: R) => string;
|
|
28
|
+
}
|
|
29
|
+
/** Match two element sets by key (fast) or predicate (fallback). */
|
|
30
|
+
export declare function matchSelections<L, R>(left: readonly L[], right: readonly R[], opts: MatchOptions<L, R>): MatchResult<L, R>;
|
|
31
|
+
//# sourceMappingURL=matching.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matching.d.ts","sourceRoot":"","sources":["../src/matching.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,IAAI,CAAC,CAAC,EAAE,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;IAChB,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;CAClB;AAED,MAAM,WAAW,WAAW,CAAC,CAAC,EAAE,CAAC;IAC/B,wCAAwC;IACxC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAA;IAC5B,4CAA4C;IAC5C,QAAQ,CAAC,aAAa,EAAE,CAAC,EAAE,CAAA;IAC3B,4CAA4C;IAC5C,QAAQ,CAAC,cAAc,EAAE,CAAC,EAAE,CAAA;IAC5B,iFAAiF;IACjF,QAAQ,CAAC,aAAa,EAAE,CAAC,EAAE,CAAA;CAC5B;AAED,MAAM,WAAW,YAAY,CAAC,CAAC,EAAE,CAAC;IAChC,uDAAuD;IACvD,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,OAAO,CAAA;IACjD,6EAA6E;IAC7E,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,MAAM,CAAA;IACzC,kCAAkC;IAClC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,MAAM,CAAA;CAC3C;AAaD,oEAAoE;AACpE,wBAAgB,eAAe,CAAC,CAAC,EAAE,CAAC,EAClC,IAAI,EAAE,SAAS,CAAC,EAAE,EAClB,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,IAAI,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,GACvB,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CA4CnB"}
|
package/dist/matching.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single matching engine shared by `correspondence()` and `eess-ts`'s
|
|
3
|
+
* `crossLayer` — "given two element sets and how to match them, which pairs
|
|
4
|
+
* form and which elements are left unmatched." Extracting this removes the
|
|
5
|
+
* duplicate pair-matching implementations the two builders used to carry.
|
|
6
|
+
*/
|
|
7
|
+
function indexByKey(elements, key) {
|
|
8
|
+
const map = new Map();
|
|
9
|
+
for (const el of elements) {
|
|
10
|
+
const k = key(el);
|
|
11
|
+
const list = map.get(k);
|
|
12
|
+
if (list)
|
|
13
|
+
list.push(el);
|
|
14
|
+
else
|
|
15
|
+
map.set(k, [el]);
|
|
16
|
+
}
|
|
17
|
+
return map;
|
|
18
|
+
}
|
|
19
|
+
/** Match two element sets by key (fast) or predicate (fallback). */
|
|
20
|
+
export function matchSelections(left, right, opts) {
|
|
21
|
+
if (opts.matchBy) {
|
|
22
|
+
const matchBy = opts.matchBy;
|
|
23
|
+
const pairs = [];
|
|
24
|
+
const matchedLeft = new Set();
|
|
25
|
+
const matchedRight = new Set();
|
|
26
|
+
const leftMatchCount = new Map();
|
|
27
|
+
for (const l of left) {
|
|
28
|
+
for (const r of right) {
|
|
29
|
+
if (matchBy(l, r)) {
|
|
30
|
+
pairs.push({ left: l, right: r });
|
|
31
|
+
matchedLeft.add(l);
|
|
32
|
+
matchedRight.add(r);
|
|
33
|
+
leftMatchCount.set(l, (leftMatchCount.get(l) ?? 0) + 1);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
pairs,
|
|
39
|
+
leftUnmatched: left.filter((l) => !matchedLeft.has(l)),
|
|
40
|
+
rightUnmatched: right.filter((r) => !matchedRight.has(r)),
|
|
41
|
+
leftAmbiguous: left.filter((l) => (leftMatchCount.get(l) ?? 0) > 1),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
const leftKey = opts.leftKey;
|
|
45
|
+
const rightKey = opts.rightKey;
|
|
46
|
+
if (!leftKey || !rightKey) {
|
|
47
|
+
throw new TypeError('matchSelections requires either matchBy or both leftKey and rightKey');
|
|
48
|
+
}
|
|
49
|
+
const rightByKey = indexByKey(right, rightKey);
|
|
50
|
+
const leftByKey = indexByKey(left, leftKey);
|
|
51
|
+
const pairs = [];
|
|
52
|
+
for (const l of left) {
|
|
53
|
+
for (const r of rightByKey.get(leftKey(l)) ?? []) {
|
|
54
|
+
pairs.push({ left: l, right: r });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
pairs,
|
|
59
|
+
leftUnmatched: left.filter((l) => (rightByKey.get(leftKey(l))?.length ?? 0) === 0),
|
|
60
|
+
rightUnmatched: right.filter((r) => (leftByKey.get(rightKey(r))?.length ?? 0) === 0),
|
|
61
|
+
leftAmbiguous: left.filter((l) => (rightByKey.get(leftKey(l))?.length ?? 0) > 1),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=matching.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matching.js","sourceRoot":"","sources":["../src/matching.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A predicate that tests whether an architectural element matches a condition.
|
|
3
|
+
* Used in `.that()` clauses to filter elements before rule evaluation.
|
|
4
|
+
*/
|
|
5
|
+
export interface Predicate<T> {
|
|
6
|
+
/** Human-readable description for violation messages, e.g. "have name matching /^parse/" */
|
|
7
|
+
readonly description: string;
|
|
8
|
+
/** Returns true if the element matches this predicate. */
|
|
9
|
+
test(element: T): boolean;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=predicate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"predicate.d.ts","sourceRoot":"","sources":["../src/predicate.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,SAAS,CAAC,CAAC;IAC1B,4FAA4F;IAC5F,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,0DAA0D;IAC1D,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,OAAO,CAAA;CAC1B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"predicate.js","sourceRoot":"","sources":["../src/predicate.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { ArchViolation } from './violation.js';
|
|
2
|
+
import type { RuleMetadata } from './rule-metadata.js';
|
|
3
|
+
import { type PresetReportOptions } from './report.js';
|
|
4
|
+
/** Per-rule severity within a preset. */
|
|
5
|
+
export type RuleSeverity = 'error' | 'warn' | 'off';
|
|
6
|
+
/**
|
|
7
|
+
* Base options every preset accepts: per-rule severity overrides, plus the
|
|
8
|
+
* reporting controls (`report` / `format`) from ADR-008 — so every preset that
|
|
9
|
+
* extends this can `{ report: 'return' }` without its own plumbing.
|
|
10
|
+
*/
|
|
11
|
+
export interface PresetBaseOptions extends PresetReportOptions {
|
|
12
|
+
overrides?: Record<string, RuleSeverity>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Anything with `.rule()` and `.violations()` — works with both
|
|
16
|
+
* `RuleBuilder<T, P>` and `TerminalBuilder` hierarchies, across all dialects.
|
|
17
|
+
*/
|
|
18
|
+
interface Dispatchable {
|
|
19
|
+
rule(m: RuleMetadata): {
|
|
20
|
+
violations(): ArchViolation[];
|
|
21
|
+
};
|
|
22
|
+
violations(): ArchViolation[];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Dispatch a single rule within a preset.
|
|
26
|
+
*
|
|
27
|
+
* - `'off'`: skip entirely
|
|
28
|
+
* - `'warn'`: log violations to stderr, do not collect for aggregated throw
|
|
29
|
+
* - `'error'`: collect violations for aggregated throw
|
|
30
|
+
*/
|
|
31
|
+
export declare function dispatchRule(builder: Dispatchable, ruleId: string, defaultSeverity: RuleSeverity, overrides: Record<string, RuleSeverity> | undefined): ArchViolation[];
|
|
32
|
+
/**
|
|
33
|
+
* Validate override keys against known rule IDs. Warns for unrecognized keys
|
|
34
|
+
* (likely typos).
|
|
35
|
+
*/
|
|
36
|
+
export declare function validateOverrides(overrides: Record<string, RuleSeverity> | undefined, knownIds: string[]): void;
|
|
37
|
+
/**
|
|
38
|
+
* Emit (stderr text) and throw a single `ArchRuleError` with all aggregated
|
|
39
|
+
* violations, if any. Kept for backward compatibility; it is now `finishPreset`
|
|
40
|
+
* in the default `throw` mode. New presets take `PresetReportOptions` and call
|
|
41
|
+
* `finishPreset` so a caller can opt into `report: 'return'` / `--format json`
|
|
42
|
+
* (plan 0070).
|
|
43
|
+
*/
|
|
44
|
+
export declare function throwIfViolations(violations: ArchViolation[]): void;
|
|
45
|
+
export {};
|
|
46
|
+
//# sourceMappingURL=preset-dispatch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preset-dispatch.d.ts","sourceRoot":"","sources":["../src/preset-dispatch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEtD,OAAO,EAAgB,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAEpE,yCAAyC;AACzC,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,CAAA;AAEnD;;;;GAIG;AACH,MAAM,WAAW,iBAAkB,SAAQ,mBAAmB;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;CACzC;AAED;;;GAGG;AACH,UAAU,YAAY;IACpB,IAAI,CAAC,CAAC,EAAE,YAAY,GAAG;QAAE,UAAU,IAAI,aAAa,EAAE,CAAA;KAAE,CAAA;IACxD,UAAU,IAAI,aAAa,EAAE,CAAA;CAC9B;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,MAAM,EACd,eAAe,EAAE,YAAY,EAC7B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,SAAS,GAClD,aAAa,EAAE,CAcjB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,SAAS,EACnD,QAAQ,EAAE,MAAM,EAAE,GACjB,IAAI,CAWN;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,aAAa,EAAE,GAAG,IAAI,CAEnE"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { formatViolations } from './format.js';
|
|
2
|
+
import { finishPreset } from './report.js';
|
|
3
|
+
/**
|
|
4
|
+
* Dispatch a single rule within a preset.
|
|
5
|
+
*
|
|
6
|
+
* - `'off'`: skip entirely
|
|
7
|
+
* - `'warn'`: log violations to stderr, do not collect for aggregated throw
|
|
8
|
+
* - `'error'`: collect violations for aggregated throw
|
|
9
|
+
*/
|
|
10
|
+
export function dispatchRule(builder, ruleId, defaultSeverity, overrides) {
|
|
11
|
+
const effective = overrides?.[ruleId] ?? defaultSeverity;
|
|
12
|
+
if (effective === 'off')
|
|
13
|
+
return [];
|
|
14
|
+
const violations = builder.rule({ id: ruleId }).violations();
|
|
15
|
+
if (effective === 'warn') {
|
|
16
|
+
if (violations.length > 0) {
|
|
17
|
+
console.warn(formatViolations(violations));
|
|
18
|
+
}
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
return violations;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Validate override keys against known rule IDs. Warns for unrecognized keys
|
|
25
|
+
* (likely typos).
|
|
26
|
+
*/
|
|
27
|
+
export function validateOverrides(overrides, knownIds) {
|
|
28
|
+
if (!overrides)
|
|
29
|
+
return;
|
|
30
|
+
const knownSet = new Set(knownIds);
|
|
31
|
+
for (const key of Object.keys(overrides)) {
|
|
32
|
+
if (!knownSet.has(key)) {
|
|
33
|
+
console.warn(`[eess] Override key '${key}' does not match any rule in this preset. ` +
|
|
34
|
+
`Available rules: ${knownIds.join(', ')}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Emit (stderr text) and throw a single `ArchRuleError` with all aggregated
|
|
40
|
+
* violations, if any. Kept for backward compatibility; it is now `finishPreset`
|
|
41
|
+
* in the default `throw` mode. New presets take `PresetReportOptions` and call
|
|
42
|
+
* `finishPreset` so a caller can opt into `report: 'return'` / `--format json`
|
|
43
|
+
* (plan 0070).
|
|
44
|
+
*/
|
|
45
|
+
export function throwIfViolations(violations) {
|
|
46
|
+
finishPreset(violations, { report: 'throw' });
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=preset-dispatch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preset-dispatch.js","sourceRoot":"","sources":["../src/preset-dispatch.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,EAAE,YAAY,EAA4B,MAAM,aAAa,CAAA;AAuBpE;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAC1B,OAAqB,EACrB,MAAc,EACd,eAA6B,EAC7B,SAAmD;IAEnD,MAAM,SAAS,GAAG,SAAS,EAAE,CAAC,MAAM,CAAC,IAAI,eAAe,CAAA;IACxD,IAAI,SAAS,KAAK,KAAK;QAAE,OAAO,EAAE,CAAA;IAElC,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,UAAU,EAAE,CAAA;IAE5D,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;QACzB,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAAA;QAC5C,CAAC;QACD,OAAO,EAAE,CAAA;IACX,CAAC;IAED,OAAO,UAAU,CAAA;AACnB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,SAAmD,EACnD,QAAkB;IAElB,IAAI,CAAC,SAAS;QAAE,OAAM;IACtB,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAA;IAClC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QACzC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,IAAI,CACV,wBAAwB,GAAG,4CAA4C;gBACrE,oBAAoB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC5C,CAAA;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,UAA2B;IAC3D,YAAY,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAA;AAC/C,CAAC"}
|
package/dist/report.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ArchViolation } from './violation.js';
|
|
2
|
+
import type { OutputFormat } from './check-options.js';
|
|
3
|
+
/**
|
|
4
|
+
* How a preset delivers its violations (plan 0070, ADR-008):
|
|
5
|
+
* - `throw` (default) — emit, then throw `ArchRuleError` (today's behavior)
|
|
6
|
+
* - `return` — return the violations, emit nothing (the caller owns reporting)
|
|
7
|
+
* - `warn` — emit as a report, but do not throw
|
|
8
|
+
*/
|
|
9
|
+
export type ReportMode = 'throw' | 'return' | 'warn';
|
|
10
|
+
/** Emission options shared by the reporter and the preset finisher. */
|
|
11
|
+
export interface ReportOptions {
|
|
12
|
+
/** Output format. Default `terminal` (rich text to stderr). */
|
|
13
|
+
readonly format?: OutputFormat;
|
|
14
|
+
/** Rationale threaded into the emitted output. */
|
|
15
|
+
readonly reason?: string;
|
|
16
|
+
}
|
|
17
|
+
/** Reporting controls a preset accepts, on top of its own options. */
|
|
18
|
+
export interface PresetReportOptions extends ReportOptions {
|
|
19
|
+
/** Delivery mode. Default `throw`. */
|
|
20
|
+
readonly report?: ReportMode;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The single place that knows how to *emit* violations — text (stderr), JSON,
|
|
24
|
+
* or GitHub annotations (stdout). No throw, no filtering, no control flow: just
|
|
25
|
+
* emission. `executeCheck` (the `.check()` path) and `finishPreset` (the preset
|
|
26
|
+
* path) both delegate here, so the two reporting paths can no longer diverge
|
|
27
|
+
* (plan 0070). Emits nothing for an empty set.
|
|
28
|
+
*/
|
|
29
|
+
export declare function reportViolations(violations: ArchViolation[], options?: ReportOptions): void;
|
|
30
|
+
/**
|
|
31
|
+
* Finish a preset: deliver its aggregated violations per the requested mode
|
|
32
|
+
* (plan 0070). `throw` (default) emits then throws — backward-compatible with
|
|
33
|
+
* `throwIfViolations`; `return` hands the violations back untouched (the caller
|
|
34
|
+
* owns emission and control flow); `warn` emits without throwing. Always
|
|
35
|
+
* returns the violations, so a caller can inspect them regardless of mode.
|
|
36
|
+
*/
|
|
37
|
+
export declare function finishPreset(violations: ArchViolation[], options?: PresetReportOptions): ArchViolation[];
|
|
38
|
+
//# sourceMappingURL=report.d.ts.map
|
|
@@ -0,0 +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;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,aAAa,EAAE,EAAE,OAAO,GAAE,aAAkB,GAAG,IAAI,CAY/F;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,aAAa,EAAE,EAC3B,OAAO,GAAE,mBAAwB,GAChC,aAAa,EAAE,CAQjB"}
|
package/dist/report.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { ArchRuleError } from './errors.js';
|
|
2
|
+
import { formatViolations } from './format.js';
|
|
3
|
+
import { formatViolationsJson } from './format-json.js';
|
|
4
|
+
import { formatViolationsGitHub } from './format-github.js';
|
|
5
|
+
/**
|
|
6
|
+
* The single place that knows how to *emit* violations — text (stderr), JSON,
|
|
7
|
+
* or GitHub annotations (stdout). No throw, no filtering, no control flow: just
|
|
8
|
+
* emission. `executeCheck` (the `.check()` path) and `finishPreset` (the preset
|
|
9
|
+
* path) both delegate here, so the two reporting paths can no longer diverge
|
|
10
|
+
* (plan 0070). Emits nothing for an empty set.
|
|
11
|
+
*/
|
|
12
|
+
export function reportViolations(violations, options = {}) {
|
|
13
|
+
if (violations.length === 0)
|
|
14
|
+
return;
|
|
15
|
+
const format = options.format ?? 'terminal';
|
|
16
|
+
if (format === 'json') {
|
|
17
|
+
process.stdout.write(formatViolationsJson(violations, options.reason) + '\n');
|
|
18
|
+
}
|
|
19
|
+
else if (format === 'github') {
|
|
20
|
+
process.stdout.write(formatViolationsGitHub(violations, 'error') + '\n');
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
// Rich text to stderr — test runners show the plain-text Error message,
|
|
24
|
+
// while stderr carries the colorized Why/Fix/Docs output.
|
|
25
|
+
process.stderr.write(formatViolations(violations, options.reason) + '\n');
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Finish a preset: deliver its aggregated violations per the requested mode
|
|
30
|
+
* (plan 0070). `throw` (default) emits then throws — backward-compatible with
|
|
31
|
+
* `throwIfViolations`; `return` hands the violations back untouched (the caller
|
|
32
|
+
* owns emission and control flow); `warn` emits without throwing. Always
|
|
33
|
+
* returns the violations, so a caller can inspect them regardless of mode.
|
|
34
|
+
*/
|
|
35
|
+
export function finishPreset(violations, options = {}) {
|
|
36
|
+
const mode = options.report ?? 'throw';
|
|
37
|
+
if (mode === 'return')
|
|
38
|
+
return violations;
|
|
39
|
+
reportViolations(violations, options);
|
|
40
|
+
if (mode === 'throw' && violations.length > 0) {
|
|
41
|
+
throw new ArchRuleError(violations, options.reason);
|
|
42
|
+
}
|
|
43
|
+
return violations;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=report.js.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import type { Predicate } from './predicate.js';
|
|
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
|
+
import type { RuleDescription } from './rule-description.js';
|
|
7
|
+
import type { SilentExclusion } from './silent-exclusion.js';
|
|
8
|
+
import type { Selection, ElementInfo } from './correspondence.js';
|
|
9
|
+
/**
|
|
10
|
+
* Abstract base class for all rule builders.
|
|
11
|
+
*
|
|
12
|
+
* Concrete entry points (plans 0007+) extend this and:
|
|
13
|
+
* 1. Implement `getElements()` to return the elements to check
|
|
14
|
+
* 2. Add predicate methods that call `addPredicate()`
|
|
15
|
+
* 3. Add condition methods that call `addCondition()`
|
|
16
|
+
*
|
|
17
|
+
* The builder accumulates predicates and conditions. Nothing executes
|
|
18
|
+
* until a terminal method (`.check()`, `.warn()`, `.severity()`) is called.
|
|
19
|
+
*/
|
|
20
|
+
export declare abstract class RuleBuilder<T, P = unknown> {
|
|
21
|
+
protected readonly project: P;
|
|
22
|
+
protected _predicates: Predicate<T>[];
|
|
23
|
+
protected _conditions: Condition<T>[];
|
|
24
|
+
protected _reason?: string;
|
|
25
|
+
protected _metadata?: RuleMetadata;
|
|
26
|
+
protected _exclusions: (string | RegExp)[];
|
|
27
|
+
protected _silentIndices: Set<number>;
|
|
28
|
+
protected _phase: 'predicate' | 'condition';
|
|
29
|
+
constructor(project: P);
|
|
30
|
+
/**
|
|
31
|
+
* Begin the predicate phase. Returns `this` for chaining.
|
|
32
|
+
* Purely a readability marker — `.that().haveNameMatching(...)` reads like English.
|
|
33
|
+
* Explicitly resets phase to 'predicate' — defensive against `.should().that()` misuse.
|
|
34
|
+
*/
|
|
35
|
+
that(): this;
|
|
36
|
+
/**
|
|
37
|
+
* Add another predicate (AND). Returns `this` for chaining.
|
|
38
|
+
* `.that().extend('Base').and().resideInFolder('src/repos/**')` means both must match.
|
|
39
|
+
*/
|
|
40
|
+
and(): this;
|
|
41
|
+
/**
|
|
42
|
+
* Begin the condition phase. Returns a forked builder for named selection safety.
|
|
43
|
+
* Creates a fresh builder with the same predicates but empty conditions.
|
|
44
|
+
* Sets phase to 'condition' so dual-use methods dispatch correctly.
|
|
45
|
+
*/
|
|
46
|
+
should(): this;
|
|
47
|
+
/**
|
|
48
|
+
* Add another condition that must ALSO pass (AND).
|
|
49
|
+
* `.should().notContain(call('x')).andShould().notContain(call('y'))` means both must hold.
|
|
50
|
+
*/
|
|
51
|
+
andShould(): this;
|
|
52
|
+
/**
|
|
53
|
+
* Plug in a custom predicate or condition.
|
|
54
|
+
*
|
|
55
|
+
* After `.that()` — pass a `Predicate<T>` to filter elements.
|
|
56
|
+
* After `.should()` — pass a `Condition<T>` to assert against filtered elements.
|
|
57
|
+
*
|
|
58
|
+
* Dispatch is structural: if the object has a `test` method it is treated
|
|
59
|
+
* as a predicate; if it has `evaluate` it is treated as a condition.
|
|
60
|
+
*/
|
|
61
|
+
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
|
+
/**
|
|
107
|
+
* Return the predicate-filtered elements as a labelled `Selection<T>` for
|
|
108
|
+
* cross-validation (`correspondence()`). The set is exactly the elements this
|
|
109
|
+
* rule would evaluate — the same filtering `.check()` applies.
|
|
110
|
+
*
|
|
111
|
+
* @param opts.label - human-readable name of this side ("diagram class")
|
|
112
|
+
* @param opts.identify - map an element to its message metadata (name/file/line)
|
|
113
|
+
*/
|
|
114
|
+
select(opts: {
|
|
115
|
+
label: string;
|
|
116
|
+
identify: (element: T) => ElementInfo;
|
|
117
|
+
}): Selection<T>;
|
|
118
|
+
/**
|
|
119
|
+
* Return a structured description of this rule without executing it.
|
|
120
|
+
* Used by the `explain` CLI subcommand.
|
|
121
|
+
*/
|
|
122
|
+
describeRule(): RuleDescription;
|
|
123
|
+
/**
|
|
124
|
+
* Execute the rule and return violations after exclusion filtering.
|
|
125
|
+
* Does not throw — use for programmatic access (presets, aggregation).
|
|
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.
|
|
131
|
+
*
|
|
132
|
+
* @param options - Optional baseline and diff filtering
|
|
133
|
+
*/
|
|
134
|
+
check(options?: CheckOptions): void;
|
|
135
|
+
/**
|
|
136
|
+
* Execute the rule and log violations to stderr. Does not throw.
|
|
137
|
+
* Use for rules that should warn but not fail CI.
|
|
138
|
+
*
|
|
139
|
+
* @param options - Optional baseline and diff filtering
|
|
140
|
+
*/
|
|
141
|
+
warn(options?: CheckOptions): void;
|
|
142
|
+
/**
|
|
143
|
+
* Execute the rule with the given severity.
|
|
144
|
+
* `.severity('error')` is equivalent to `.check()`.
|
|
145
|
+
* `.severity('warn')` is equivalent to `.warn()`.
|
|
146
|
+
*/
|
|
147
|
+
severity(level: 'error' | 'warn'): void;
|
|
148
|
+
/**
|
|
149
|
+
* Register a predicate. Called by concrete builder methods like
|
|
150
|
+
* `.haveNameMatching()`, `.extend()`, etc.
|
|
151
|
+
*/
|
|
152
|
+
protected addPredicate(predicate: Predicate<T>): this;
|
|
153
|
+
/**
|
|
154
|
+
* Register a condition. Called by concrete builder methods like
|
|
155
|
+
* `.notContain()`, `.notExist()`, etc.
|
|
156
|
+
*/
|
|
157
|
+
protected addCondition(condition: Condition<T>): this;
|
|
158
|
+
/**
|
|
159
|
+
* Subclasses implement this to return the elements to check.
|
|
160
|
+
* Called lazily during `.check()` / `.warn()`.
|
|
161
|
+
*/
|
|
162
|
+
protected abstract getElements(): T[];
|
|
163
|
+
/**
|
|
164
|
+
* Create a fork of this builder with the same predicates but empty conditions.
|
|
165
|
+
* Used by `.should()` to support named selections without mutation.
|
|
166
|
+
*
|
|
167
|
+
* Subclasses with additional constructor args MUST override this method.
|
|
168
|
+
*/
|
|
169
|
+
protected fork(): this;
|
|
170
|
+
/**
|
|
171
|
+
* Build the rule description from predicates and conditions.
|
|
172
|
+
*/
|
|
173
|
+
private buildRuleDescription;
|
|
174
|
+
/**
|
|
175
|
+
* Execute the full pipeline: filter elements with predicates,
|
|
176
|
+
* evaluate conditions, return violations.
|
|
177
|
+
*/
|
|
178
|
+
private evaluate;
|
|
179
|
+
/**
|
|
180
|
+
* Build the `ConditionContext` passed to each condition.
|
|
181
|
+
*
|
|
182
|
+
* Subclasses with builder-specific context fields (e.g. `CallRuleBuilder`'s
|
|
183
|
+
* `_identifyByArgument`) override this to extend the base context.
|
|
184
|
+
* Call `super.buildConditionContext()` and spread the result.
|
|
185
|
+
*/
|
|
186
|
+
protected buildConditionContext(): ConditionContext;
|
|
187
|
+
}
|
|
188
|
+
//# sourceMappingURL=rule-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-builder.d.ts","sourceRoot":"","sources":["../src/rule-builder.ts"],"names":[],"mappings":"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"}
|