lanekeep 0.7.0 → 0.8.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/index.d.ts +65 -2
- package/package.json +5 -5
package/index.d.ts
CHANGED
|
@@ -78,8 +78,27 @@ export interface RuleCard {
|
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
/** Cheap rejections applied before a file is parsed. */
|
|
81
|
+
/** Cheap rejections applied before a file is read or parsed. */
|
|
82
82
|
export interface Gates {
|
|
83
|
+
/**
|
|
84
|
+
* Glob patterns a file's path must match for the rule to consider it.
|
|
85
|
+
*
|
|
86
|
+
* The path is relative to the project root, and the pattern must match the whole path —
|
|
87
|
+
* anchored, not a substring search. Patterns use the `globset` dialect, matched
|
|
88
|
+
* case-sensitively: `*` matches any run of characters (including `/`), `?` any single
|
|
89
|
+
* character, `[ab]`/`[!ab]` character classes and `{a,b}` alternates work, and `**`
|
|
90
|
+
* recurses directories — `src/**` admits everything under `src`, and `**` in front
|
|
91
|
+
* of `*.test.ts` admits a test file at any depth.
|
|
92
|
+
*/
|
|
93
|
+
pathMatches?: string[]
|
|
94
|
+
/**
|
|
95
|
+
* Glob patterns that skip a file — a path matching any of these is never parsed. Checked
|
|
96
|
+
* before `pathMatches` and winning over it: a path a `pathMatches` pattern would have
|
|
97
|
+
* admitted is still skipped when a `pathNotMatches` pattern matches it.
|
|
98
|
+
*
|
|
99
|
+
* Same dialect and anchoring as `pathMatches`.
|
|
100
|
+
*/
|
|
101
|
+
pathNotMatches?: string[]
|
|
83
102
|
/**
|
|
84
103
|
* Literal substrings a file's raw bytes must contain. A file missing any one of them is
|
|
85
104
|
* never parsed.
|
|
@@ -90,6 +109,12 @@ export interface Gates {
|
|
|
90
109
|
* form; omit the gate when no single substring covers every case.
|
|
91
110
|
*/
|
|
92
111
|
fileContains?: string[]
|
|
112
|
+
/**
|
|
113
|
+
* Literal substrings that skip a file — a file whose raw bytes contain **any** of them is
|
|
114
|
+
* never parsed. The mirror image of `fileContains`'s *and*: where that gate requires every
|
|
115
|
+
* listed substring, this one rejects on the first that is present.
|
|
116
|
+
*/
|
|
117
|
+
fileNotContains?: string[]
|
|
93
118
|
}
|
|
94
119
|
|
|
95
120
|
/** A replacement a rule offers for a violation. */
|
|
@@ -151,6 +176,21 @@ export interface NodeLocation {
|
|
|
151
176
|
column: number
|
|
152
177
|
}
|
|
153
178
|
|
|
179
|
+
/**
|
|
180
|
+
* A subtree's structural fingerprint: identifiers and literal values erased.
|
|
181
|
+
*
|
|
182
|
+
* Computed host-side in one walk, so a rule does not pay a per-node boundary crossing to
|
|
183
|
+
* inspect a tree's shape. Two functions differing only in identifier names, literal values
|
|
184
|
+
* or comments hash identically; differing in an operator or a statement, differently. A
|
|
185
|
+
* dead handle yields `undefined`, like `kind` and `loc`.
|
|
186
|
+
*/
|
|
187
|
+
export interface StructureFingerprint {
|
|
188
|
+
/** blake3 of the normalized fold, lowercase hex. */
|
|
189
|
+
hash: string
|
|
190
|
+
/** How many nodes the fold covered — the thresholding input. */
|
|
191
|
+
nodes: number
|
|
192
|
+
}
|
|
193
|
+
|
|
154
194
|
/** A rule's RuleContext surface. */
|
|
155
195
|
export interface RuleContext {
|
|
156
196
|
readonly filePath: string
|
|
@@ -165,6 +205,7 @@ export interface RuleContext {
|
|
|
165
205
|
children(n: Node): Node[]
|
|
166
206
|
namedChildren(n: Node): Node[]
|
|
167
207
|
ancestors(n: Node): Node[]
|
|
208
|
+
structureFingerprint(n: Node): StructureFingerprint | undefined
|
|
168
209
|
resolvesToImport(n: Node, module: string, name?: string): boolean
|
|
169
210
|
isImportedFrom(n: Node, pattern: string): boolean
|
|
170
211
|
bindingKind(n: Node): BindingKind | undefined
|
|
@@ -227,8 +268,21 @@ export interface Rule {
|
|
|
227
268
|
* Rust matches it across a single shared parse and only matches reach `check`, which is
|
|
228
269
|
* what keeps a JavaScript rule affordable. Write the narrowest query that captures what
|
|
229
270
|
* you need; `check` then only refines.
|
|
271
|
+
*
|
|
272
|
+
* A single string applies to every declared language. An object maps each declared
|
|
273
|
+
* language to its own query — required when the grammars do not share node vocabulary
|
|
274
|
+
* (Python spells a call `call`, the other supported grammars say `call_expression`).
|
|
275
|
+
* Every declared language must have an entry and every entry must name a declared
|
|
276
|
+
* language; a mismatch is a config-load error naming the language.
|
|
277
|
+
*
|
|
278
|
+
* Text predicates filter matches in Rust before the handler, so a predicate can only
|
|
279
|
+
* narrow, never widen, what `check` sees: `#eq?`, `#not-eq?`, `#match?`, `#not-match?`,
|
|
280
|
+
* `#any-of?` and `#not-any-of?` are supported (plus the `any-` forms of `eq?`/`match?`).
|
|
281
|
+
* `#match?`/`#not-match?` run on the `regex` crate, which is deterministic and supports
|
|
282
|
+
* no backreferences or lookaround. `#is?`, `#is-not?`, `#set!`, or an operator the
|
|
283
|
+
* binding does not know is refused at compile time.
|
|
230
284
|
*/
|
|
231
|
-
query: string
|
|
285
|
+
query: string | Partial<Record<LanguageId, string>>
|
|
232
286
|
/** A per-invocation budget overriding the default, in milliseconds. */
|
|
233
287
|
timeout?: number
|
|
234
288
|
/** Called once per query match. */
|
|
@@ -254,6 +308,15 @@ export interface Config {
|
|
|
254
308
|
/** Wall-clock, for the whole run. */
|
|
255
309
|
global?: number
|
|
256
310
|
}
|
|
311
|
+
/** Policy for suppression directives. All off by default. */
|
|
312
|
+
suppressions?: {
|
|
313
|
+
/** A valid directive with no `expires:` is reported. */
|
|
314
|
+
requireExpiry?: boolean
|
|
315
|
+
/** An expiry more than this many days after today is reported. */
|
|
316
|
+
maxExpiryDays?: number
|
|
317
|
+
/** Any whole-file directive is reported. */
|
|
318
|
+
forbidFileScope?: boolean
|
|
319
|
+
}
|
|
257
320
|
/** The rules to run, in order. */
|
|
258
321
|
rules: Rule[]
|
|
259
322
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lanekeep",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Deterministic, AST-based architectural conformance checking",
|
|
5
5
|
"license": "MIT OR Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -23,10 +23,10 @@
|
|
|
23
23
|
"node": ">=18"
|
|
24
24
|
},
|
|
25
25
|
"optionalDependencies": {
|
|
26
|
-
"@lanekeep/darwin-arm64": "0.
|
|
27
|
-
"@lanekeep/linux-arm64": "0.
|
|
28
|
-
"@lanekeep/linux-x64": "0.
|
|
29
|
-
"@lanekeep/win32-x64": "0.
|
|
26
|
+
"@lanekeep/darwin-arm64": "0.8.0",
|
|
27
|
+
"@lanekeep/linux-arm64": "0.8.0",
|
|
28
|
+
"@lanekeep/linux-x64": "0.8.0",
|
|
29
|
+
"@lanekeep/win32-x64": "0.8.0"
|
|
30
30
|
},
|
|
31
31
|
"main": "index.js",
|
|
32
32
|
"types": "index.d.ts",
|