@inixiative/json-rules 2.19.4 → 2.19.6
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 +17 -3
- package/dist/index.cjs +5 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -101,7 +101,10 @@ Supported comparison operators for aggregate rules: `equals`, `notEquals`, `less
|
|
|
101
101
|
- `after`
|
|
102
102
|
- `onOrBefore`
|
|
103
103
|
- `onOrAfter`
|
|
104
|
+
- `notBefore`
|
|
105
|
+
- `notAfter`
|
|
104
106
|
- `within`
|
|
107
|
+
- `notWithin`
|
|
105
108
|
- `between`
|
|
106
109
|
- `notBetween`
|
|
107
110
|
- `dayIn`
|
|
@@ -220,13 +223,18 @@ absolute date. Magnitudes are always **positive** — direction lives in the key
|
|
|
220
223
|
Units are dayjs words: `day`, `week`, `isoWeek`, `month`, `quarter`, `year`,
|
|
221
224
|
`hour`, `minute`, `second`.
|
|
222
225
|
|
|
223
|
-
**Point expressions** — pair with `before` / `after` / `onOrBefore` / `onOrAfter
|
|
226
|
+
**Point expressions** — pair with `before` / `after` / `onOrBefore` / `onOrAfter` /
|
|
227
|
+
`notBefore` / `notAfter`,
|
|
224
228
|
or as `between` endpoints:
|
|
225
229
|
|
|
226
230
|
```ts
|
|
227
231
|
// "more than 30 days ago"
|
|
228
232
|
{ field: 'completedAt', dateOperator: DateOperator.before, value: { ago: { days: 30 } } }
|
|
229
233
|
|
|
234
|
+
// "not since 30 days ago" — on/before the point OR never (notAfter is the null-carrying
|
|
235
|
+
// complement of after; onOrBefore is positive and skips NULL). Takes a literal date too.
|
|
236
|
+
{ field: 'lastLoginAt', dateOperator: DateOperator.notAfter, value: { ago: { days: 30 } } }
|
|
237
|
+
|
|
230
238
|
// "within the next 2 months"
|
|
231
239
|
{ field: 'dueAt', dateOperator: DateOperator.after, value: { ahead: { months: 2 } } }
|
|
232
240
|
|
|
@@ -234,7 +242,7 @@ or as `between` endpoints:
|
|
|
234
242
|
{ field: 'completedAt', dateOperator: DateOperator.before, value: { end: { last: 'month' } } }
|
|
235
243
|
```
|
|
236
244
|
|
|
237
|
-
**Range expressions** — pair with
|
|
245
|
+
**Range expressions** — pair with `within` / `notWithin`:
|
|
238
246
|
|
|
239
247
|
```ts
|
|
240
248
|
// "this month"
|
|
@@ -245,6 +253,10 @@ or as `between` endpoints:
|
|
|
245
253
|
|
|
246
254
|
// rolling window: "within the last 30 days" → [now - 30d, now]
|
|
247
255
|
{ field: 'completedAt', dateOperator: DateOperator.within, value: { ago: { days: 30 } } }
|
|
256
|
+
|
|
257
|
+
// its complement: "not in the last 30 days" — a never-set date is not in the window, so
|
|
258
|
+
// NULL matches (see NULL Semantics). The dormancy rule, in one leaf.
|
|
259
|
+
{ field: 'lastLoginAt', dateOperator: DateOperator.notWithin, value: { ago: { days: 30 } } }
|
|
248
260
|
```
|
|
249
261
|
|
|
250
262
|
A **bare period** with `before` / `after` resolves to the only sensible edge —
|
|
@@ -531,7 +543,7 @@ Without `{ map, model }`, or on an entry that doesn't declare it, the bare
|
|
|
531
543
|
Date rules follow the same split. The positive operators answer non-match on both
|
|
532
544
|
rails — a bare boundary is not something a NULL column satisfies, so `check()`
|
|
533
545
|
reports the rule's ordinary non-match (honoring `error`) and the compilers keep the
|
|
534
|
-
bare `<` / `BETWEEN`. The negative-flavored ones (`notBetween`, `dayNotIn`) follow
|
|
546
|
+
bare `<` / `BETWEEN`. The negative-flavored ones (`notBefore`, `notAfter`, `notWithin`, `notBetween`, `dayNotIn`) follow
|
|
535
547
|
the negation ruling instead: a never-set date is not in the range, so a null column
|
|
536
548
|
MATCHES, and the compilers carry the `IS NULL` arm. To match never-seen rows under a
|
|
537
549
|
positive operator, ask for them:
|
|
@@ -540,6 +552,8 @@ positive operator, ask for them:
|
|
|
540
552
|
| Rule | `check()` on `{ col: null }` | `toSql()` | `toPrisma()` |
|
|
541
553
|
| --- | --- | --- | --- |
|
|
542
554
|
| positive `dateOperator` (`before`, `between`, `dayIn`, …) | no match | `col < $1` (NULL never satisfies) | `{ col: { lt: … } }` |
|
|
555
|
+
| `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) |
|
|
543
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) |
|
|
544
558
|
| `dayNotIn` | matches | `(EXTRACT(DOW FROM col) <> ALL($1) OR col IS NULL)` | — (no Prisma output) |
|
|
545
559
|
| `notExists` OR `before` | matches via the first arm | `(col IS NULL OR col < $1)` | `{ OR: [{ col: { equals: null } }, { col: { lt: … } }] }` |
|