@inixiative/json-rules 2.22.0 → 2.24.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 CHANGED
@@ -46,7 +46,7 @@ check(rule, { age: 16 }); // "Must be 18 or older"
46
46
  - ordered windowing — first/last `N` with `orderBy` / `take` / `skip` (check-only)
47
47
  - date comparisons with timezone-aware runtime evaluation
48
48
  - relative & calendar date expressions — "last 30 days", "this month" — via `within` and `ago`/`ahead`/`this`/`last`/`next`
49
- - relative value references via `path`
49
+ - relative value references via `path`, and `$$.` scope refs up through nested arrays
50
50
  - custom error messages on every rule
51
51
  - compilation to Prisma and PostgreSQL for supported subsets
52
52
 
@@ -332,22 +332,43 @@ In runtime validation, a plain path is resolved from the root context:
332
332
  }
333
333
  ```
334
334
 
335
- ### Current Array Element Reference
335
+ ### Scope References
336
336
 
337
- Inside array conditions, `$.` means "read from the current element":
337
+ Inside an array operator's `condition` or `filter`, `$.` reads from the current element.
338
+ Each additional `$` reaches one enclosing element further out: `$$.` is the element of the
339
+ enclosing array operator, `$$$.` the one above that, up to the root row. Logical
340
+ combinators (`all` / `any` / `if`) never add a level — only array and aggregate rules do.
341
+
342
+ Both `field` and `path` take the prefix. A bare `field` is always the current element; a
343
+ bare `path` is always the root context (`options.context`, defaulting to the root row).
338
344
 
339
345
  ```ts
340
346
  {
341
347
  field: 'orders',
342
348
  arrayOperator: ArrayOperator.all,
343
349
  condition: {
344
- field: 'total',
345
- operator: Operator.lessThanEquals,
346
- path: '$.maxBudget'
347
- }
350
+ field: 'lineItems',
351
+ arrayOperator: ArrayOperator.all,
352
+ condition: {
353
+ all: [
354
+ // line item qty against its order's cap
355
+ { field: 'qty', operator: Operator.lessThanEquals, path: '$$.maxQty' },
356
+ // order cap against the root row's limit — neither side is the line item
357
+ { field: '$$.maxQty', operator: Operator.lessThanEquals, path: '$$$.orgLimit' },
358
+ ],
359
+ },
360
+ },
348
361
  }
349
362
  ```
350
363
 
364
+ A ref deeper than the nesting (`$$.` at the top level, `$$$.` one array deep) throws in
365
+ `check()`, is a `scope_out_of_bounds` issue from `validateRule`, and a violation from
366
+ `checkRuleAgainstLens`. A reachable ancestor that lacks the named key fails the comparison
367
+ like any absent field.
368
+
369
+ `toSql()` keeps `path: '$.x'` as a same-row column comparison. Every other scope ref — a
370
+ `$$.` path or any prefixed `field` — is check-only; both compilers throw.
371
+
351
372
  ## Rule Introspection
352
373
 
353
374
  Reading a stored rule's own content — which values it names, which bindings it needs — is
@@ -525,6 +546,7 @@ Not every backend supports every rule shape.
525
546
  | `dayIn` / `dayNotIn` | Yes | No | Yes |
526
547
  | Windowing (`orderBy` / `take` / `skip`) | Yes | Extremal (`take:1`, aligned) | No |
527
548
  | `path: '$.field'` current-element / same-row refs | Yes | No | Yes |
549
+ | `$$.` scope refs and `$`-prefixed `field` | Yes | No | No |
528
550
 
529
551
  ### NULL Semantics
530
552
 
@@ -580,7 +602,7 @@ positive operator, ask for them:
580
602
 
581
603
  - `matches` and `notMatches` are not supported by Prisma output
582
604
  - `dayIn` and `dayNotIn` are not supported by Prisma output
583
- - `path: '$.field'` column-to-column comparisons are not supported by Prisma `WHERE`
605
+ - `path: '$.field'` column-to-column comparisons are not supported by Prisma `WHERE`; no scope ref (`$$.` path, prefixed `field`) compiles
584
606
  - count-based and aggregate relation operators require `{ map, model }`
585
607
  - aggregate rules with `notBetween` are not supported by Prisma output
586
608
  - aggregate rules on JSON/native stored arrays are not supported by Prisma — use `toSql()` or `check()` for those