@inixiative/json-rules 2.18.4 → 2.19.1
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 +36 -0
- package/dist/index.cjs +5 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -494,6 +494,42 @@ Not every backend supports every rule shape.
|
|
|
494
494
|
| Windowing (`orderBy` / `take` / `skip`) | Yes | Extremal (`take:1`, aligned) | No |
|
|
495
495
|
| `path: '$.field'` current-element / same-row refs | Yes | No | Yes |
|
|
496
496
|
|
|
497
|
+
### NULL Semantics
|
|
498
|
+
|
|
499
|
+
A negated operator is the complement of its positive form — the same answer
|
|
500
|
+
`check()` gives, where `null !== 'x'` is simply true. SQL's three-valued logic
|
|
501
|
+
disagrees (`col <> 'x'` is NULL, never true, for a NULL column), so the
|
|
502
|
+
compilers carry NULL rows explicitly:
|
|
503
|
+
|
|
504
|
+
| Rule | `check()` on `{ col: null }` | `toSql()` | `toPrisma()` (nullable column) |
|
|
505
|
+
| --- | --- | --- | --- |
|
|
506
|
+
| `notEquals 'x'` / `notContains` / `notMatches` / `notBetween` | matches | `(col <> $1 OR col IS NULL)` | `{ OR: [{ col: { not: 'x' } }, { col: { equals: null } }] }` |
|
|
507
|
+
| `notIn ['x']` | matches | `(col <> ALL($1) OR col IS NULL)` | `{ OR: [{ col: { notIn: ['x'] } }, { col: { equals: null } }] }` |
|
|
508
|
+
| `in ['x', null]` | matches | `(col = ANY($1) OR col IS NULL)` | `{ OR: [{ col: { in: ['x'] } }, { col: { equals: null } }] }` |
|
|
509
|
+
| `notIn ['x', null]` | no match | `(col <> ALL($1) AND col IS NOT NULL)` | `{ AND: [{ col: { notIn: ['x'] } }, { col: { not: null } }] }` |
|
|
510
|
+
| `equals` / `notEquals` with `path: '$.other'` | `null === null` | `IS [NOT] DISTINCT FROM` | — |
|
|
511
|
+
| `exists` / `notExists` | `!= null` / `== null` | `IS NOT NULL` / `IS NULL` | `{ not: null }` / `{ equals: null }` |
|
|
512
|
+
|
|
513
|
+
`toPrisma()` can only add the null arm when it knows the column is nullable —
|
|
514
|
+
an `equals: null` on a NOT NULL column is a Prisma validation error. Nullability
|
|
515
|
+
comes from the field map: `FieldMapEntry.isRequired: false` (prisma-map emits it).
|
|
516
|
+
Without `{ map, model }`, or on an entry that doesn't declare it, the bare
|
|
517
|
+
`not` / `notIn` is emitted and NULL rows fall out, as they always did.
|
|
518
|
+
|
|
519
|
+
Date rules answer the same way on both rails, from the other direction: a bare
|
|
520
|
+
boundary is not something a NULL column satisfies, so `check()` reports the rule's
|
|
521
|
+
ordinary non-match (honoring `error`) for a null or absent field, and the compilers
|
|
522
|
+
keep the bare `<` / `NOT BETWEEN`. To match the never-seen rows too, ask for them:
|
|
523
|
+
`{ any: [{ field, operator: 'notExists' }, { field, dateOperator: 'before', … }] }`.
|
|
524
|
+
|
|
525
|
+
| Rule | `check()` on `{ col: null }` | `toSql()` | `toPrisma()` |
|
|
526
|
+
| --- | --- | --- | --- |
|
|
527
|
+
| any `dateOperator` | no match | `col < $1` (NULL never satisfies) | `{ col: { lt: … } }` |
|
|
528
|
+
| `notExists` OR `before` | matches via the first arm | `(col IS NULL OR col < $1)` | `{ OR: [{ col: { equals: null } }, { col: { lt: … } }] }` |
|
|
529
|
+
|
|
530
|
+
`0` is an instant (1970-01-01) and compares; `''` is malformed data and raises
|
|
531
|
+
`"is not a valid date"`.
|
|
532
|
+
|
|
497
533
|
### Prisma Limitations
|
|
498
534
|
|
|
499
535
|
- `matches` and `notMatches` are not supported by Prisma output
|