lanekeep 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.d.ts +44 -4
  2. package/package.json +5 -5
package/index.d.ts CHANGED
@@ -8,12 +8,14 @@
8
8
  * Node: `defineRule` and `defineConfig` are identity functions whose only job is to give the
9
9
  * compiler something to check against, and `RuleContext` is provided by lanekeep at run time.
10
10
  * The world is the single source of truth for every member the renderer emits straight from it.
11
- * Two members deviate from the world on purpose, and both are QuickJS-shaped: `today` is
11
+ * Three members deviate from the world on purpose, and all three are QuickJS-shaped: `today` is
12
12
  * omitted from `RuleContext` because QuickJS exposes it as a conditional property rather than a
13
- * callable, a shape this renderer cannot state honestly from the world; and `types` is added
13
+ * callable, a shape this renderer cannot state honestly from the world; `types` is added
14
14
  * to `RuleContext` because `ctx.types` — the bounded
15
15
  * type oracle — is QuickJS-only and has no presence in `world.wit` at all: a component rule
16
- * cannot declare `requires`, so there is nothing for the world to say about it. Nothing else is
16
+ * cannot declare `requires`, so there is nothing for the world to say about it; and `flow` is
17
+ * added to `RuleContext` for the same reason — `ctx.flow`, the taint-analysis completeness
18
+ * surface, is QuickJS-only too and has no presence in `world.wit` either. Nothing else is
17
19
  * added or omitted by hand.
18
20
  */
19
21
 
@@ -374,6 +376,18 @@ export interface TypeApi {
374
376
  complete(): boolean
375
377
  }
376
378
 
379
+ /**
380
+ * The taint-analysis completeness surface, present on `ctx.flow` for a rule that declares
381
+ * `flow`. Answers whether the analysis saw through every construct in the file being checked
382
+ * — so a rule can say "I could not verify this file" rather than nothing.
383
+ */
384
+ export interface FlowApi {
385
+ /** `true` iff the analysis dropped no construct in this file (`dropped === 0`). */
386
+ complete(): boolean
387
+ /** How many constructs the analysis could not see through in this file. */
388
+ readonly dropped: number
389
+ }
390
+
377
391
  /** A rule's RuleContext surface. */
378
392
  export interface RuleContext {
379
393
  readonly filePath: string
@@ -413,6 +427,11 @@ export interface RuleContext {
413
427
  * deliberate.
414
428
  */
415
429
  types: TypeApi
430
+ /**
431
+ * The taint-analysis completeness surface, present only in the flow phase
432
+ * of a rule that declares `flow` (inside `checkFlow` / `checkFile`).
433
+ */
434
+ flow: FlowApi
416
435
  }
417
436
 
418
437
  /** A violation the reduce phase reports, which has no node to point at. */
@@ -463,8 +482,18 @@ export type ObligationSpec = {
463
482
  /**
464
483
  * `'function'` — every path out of the enclosing function, `return`/`throw` included.
465
484
  * `'block'` — every path out of the block the acquire is in.
485
+ * `'module'` — a matching-`@key` release must exist somewhere in the file.
486
+ * `'class'` — a matching-`@key` release must exist in the same class.
487
+ * `'component'` — a matching-`@key` release must exist in the same React function component.
466
488
  */
467
- scope: 'function' | 'block'
489
+ scope: 'function' | 'block' | 'module' | 'class' | 'component'
490
+ /**
491
+ * How a `@key` correlates an acquire with a release. `'text'` (default) — exact captured
492
+ * text. `'binding'` — shared value origin (follows copies/wrappers/ternaries); requires
493
+ * `@key`. Note: `'binding'` does not correlate distinct per-frame parameters — use `'text'`
494
+ * for the sibling-callback pattern.
495
+ */
496
+ keyBy?: 'text' | 'binding'
468
497
  }
469
498
 
470
499
  /** An acquire some path leaves undischarged, passed to `checkObligation`. */
@@ -474,6 +503,11 @@ export type UnmetObligation = {
474
503
  readonly exit: Node
475
504
  /** Whether any path *did* discharge it: partial coverage reads differently to none. */
476
505
  readonly partial: boolean
506
+ /**
507
+ * The acquire's `@key` capture, when the rule's acquire/release queries bind one — so a
508
+ * report can name the value. Absent for an un-keyed obligation.
509
+ */
510
+ readonly key?: Node
477
511
  }
478
512
 
479
513
  /** A rule, as `defineRule` takes it. */
@@ -557,6 +591,12 @@ export interface Rule {
557
591
  obligation?: ObligationSpec
558
592
  /** Called once per value left with an unmet obligation at the end of its scope. */
559
593
  checkObligation?(ctx: RuleContext, unmet: UnmetObligation): void
594
+ /**
595
+ * Called once per file the rule's flow phase examined, including files with no flow.
596
+ * Read `ctx.flow.complete()` / `ctx.flow.dropped` and report at `ctx.root` when the taint
597
+ * analysis could not see through every construct. Requires `flow`.
598
+ */
599
+ checkFile?(ctx: RuleContext): void
560
600
  }
561
601
 
562
602
  /** A lanekeep configuration, as `defineConfig` takes it. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lanekeep",
3
- "version": "0.10.0",
3
+ "version": "0.11.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.10.0",
27
- "@lanekeep/linux-arm64": "0.10.0",
28
- "@lanekeep/linux-x64": "0.10.0",
29
- "@lanekeep/win32-x64": "0.10.0"
26
+ "@lanekeep/darwin-arm64": "0.11.0",
27
+ "@lanekeep/linux-arm64": "0.11.0",
28
+ "@lanekeep/linux-x64": "0.11.0",
29
+ "@lanekeep/win32-x64": "0.11.0"
30
30
  },
31
31
  "main": "index.js",
32
32
  "types": "index.d.ts",