@inixiative/json-rules 2.19.6 → 2.19.8

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
@@ -534,6 +534,13 @@ compilers carry NULL rows explicitly:
534
534
  | `equals` / `notEquals` with `path: '$.other'` | `null === null` | `IS [NOT] DISTINCT FROM` | — |
535
535
  | `exists` / `notExists` | `!= null` / `== null` | `IS NOT NULL` / `IS NULL` | `{ not: null }` / `{ equals: null }` |
536
536
 
537
+ The **absent set** of a path is wider than a NULL leaf: an optional to-one hop can be NULL too,
538
+ and `{ rel: { col: { equals: null } } }` only matches when the relation exists. So every negation
539
+ also carries `{ rel: { is: null } }` for each optional to-one hop on the path (licensed by the
540
+ relation entry's `isRequired: false`) — `profile.bio notEquals 'x'` compiles to
541
+ `{ OR: [{ profile: { bio: { not: 'x' } } }, { profile: { bio: { equals: null } } }, { profile: { is: null } }] }`,
542
+ matching check() (a missing hop reads as `undefined`) and toSql (LEFT JOIN + `IS NULL`).
543
+
537
544
  `toPrisma()` can only add the null arm when it knows the column is nullable —
538
545
  an `equals: null` on a NOT NULL column is a Prisma validation error. Nullability
539
546
  comes from the field map: `FieldMapEntry.isRequired: false` (prisma-map emits it).
@@ -553,8 +560,8 @@ positive operator, ask for them:
553
560
  | --- | --- | --- | --- |
554
561
  | positive `dateOperator` (`before`, `between`, `dayIn`, …) | no match | `col < $1` (NULL never satisfies) | `{ col: { lt: … } }` |
555
562
  | `notAfter X` / `notBefore X` | matches | `(col <= $1 OR col IS NULL)` / `(col >= $1 OR col IS NULL)` | `{ OR: [{ col: { lte } }, { col: { equals: null } }] }` (nullable column) |
556
- | `notWithin { ago: { days: 30 } }` | matches | `(col NOT BETWEEN $1 AND $2 OR col IS NULL)` | `{ OR: [{ col: { NOT: { gte, lte } } }, { col: { equals: null } }] }` (nullable column) |
557
- | `notBetween` | matches | `(col NOT BETWEEN $1 AND $2 OR col IS NULL)` | `{ OR: [{ col: { NOT: … } }, { col: { equals: null } }] }` (nullable column, same field-map licensing as above) |
563
+ | `notWithin { ago: { days: 30 } }` | matches | `(col NOT BETWEEN $1 AND $2 OR col IS NULL)` | `{ OR: [{ NOT: { col: { gte, lte } } }, { col: { equals: null } }] }` (nullable column) |
564
+ | `notBetween` | matches | `(col NOT BETWEEN $1 AND $2 OR col IS NULL)` | `{ OR: [{ NOT: { col: … } }, { col: { equals: null } }] }` (nullable column, same field-map licensing as above) |
558
565
  | `dayNotIn` | matches | `(EXTRACT(DOW FROM col) <> ALL($1) OR col IS NULL)` | — (no Prisma output) |
559
566
  | `notExists` OR `before` | matches via the first arm | `(col IS NULL OR col < $1)` | `{ OR: [{ col: { equals: null } }, { col: { lt: … } }] }` |
560
567