@vantreeseba/drizzle-graphql 15.1.0 → 15.1.2
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 +39 -6
- package/dist/index.cjs +246 -64
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -4
- package/dist/index.d.ts +12 -4
- package/dist/index.js +246 -64
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -335,7 +335,9 @@ const { schema } = buildSchema(db, {
|
|
|
335
335
|
send it at all — the SDL itself says the column is server-owned. It stays readable on the
|
|
336
336
|
object type.
|
|
337
337
|
- Every insert stamps it, including rows created by a nested `create`.
|
|
338
|
-
- Updates never write it, so an update cannot hand a row to another owner.
|
|
338
|
+
- Updates never write it, so an update cannot hand a row to another owner. Neither does the
|
|
339
|
+
conflict branch of an upsert: it is left out of the default overwrite and of the columns
|
|
340
|
+
`onConflict.update` can name.
|
|
339
341
|
|
|
340
342
|
Together the two close the loop: `contextValues` decides which tenant a new row belongs to, and
|
|
341
343
|
`scope` decides which rows a request can see and change afterwards.
|
|
@@ -984,6 +986,9 @@ input StockItemIdLocationIdKey {
|
|
|
984
986
|
composes with column filters, relation filters, `OR` / `AND` / `NOT`
|
|
985
987
|
- Composite primary keys get a field like any other unique constraint
|
|
986
988
|
- Single-column constraints do not: `eq` on the column already names the row
|
|
989
|
+
- Partial unique indexes (`uniqueIndex().on(…).where(…)`) do not either: they are unique
|
|
990
|
+
only among the rows the predicate matches, so with soft-deleted rows included
|
|
991
|
+
(`deleted: INCLUDE`) the key can match more than one
|
|
987
992
|
- A field name a column or relation already holds is skipped, the same way a relation
|
|
988
993
|
yields to a same-named column
|
|
989
994
|
- It compiles to exactly the equalities you would have written by hand; the guarantee is in
|
|
@@ -1042,6 +1047,11 @@ The pattern operators are `like` / `notLike` / `ilike` / `notIlike`, the safe
|
|
|
1042
1047
|
`startsWith` / `endsWith` / `contains` and their `i`-prefixed forms, plus the `insensitive`
|
|
1043
1048
|
flag that modifies them.
|
|
1044
1049
|
|
|
1050
|
+
An operand of `null` leaves its operator out, as though it had not been sent. `false` is an
|
|
1051
|
+
ordinary value: `active: { eq: false }` matches the rows that are false, `ne: false` the rows
|
|
1052
|
+
that are true, and `has: false` the arrays holding a `false`. Only the flag operators —
|
|
1053
|
+
`isNull`, `isNotNull` and `isEmpty` — read `false` as "add no condition".
|
|
1054
|
+
|
|
1045
1055
|
The omissions are the cases where the operator cannot ask anything a caller means:
|
|
1046
1056
|
|
|
1047
1057
|
- **Pattern matching a timestamp, a boolean or an enum member** compares whatever the value
|
|
@@ -1479,7 +1489,12 @@ field, and passing it back as `after` resumes strictly after that row.
|
|
|
1479
1489
|
in `asc`), MySQL and SQLite smallest (first in `asc`). The predicate matches either way,
|
|
1480
1490
|
so rows with `NULL` in an ordered column are paged through, not skipped, and `nulls` is
|
|
1481
1491
|
part of the ordering a cursor is tied to
|
|
1482
|
-
- Dates and bigints round-trip losslessly through the cursor
|
|
1492
|
+
- Dates and bigints round-trip losslessly through the cursor, at the column's own precision:
|
|
1493
|
+
a PostgreSQL `timestamp` / `timestamptz` (microseconds unless declared `precision: 3` or
|
|
1494
|
+
less) or a MySQL `datetime` / `timestamp` with `fsp` above 3 holds more than the
|
|
1495
|
+
millisecond JS `Date` that `mode: 'date'` reads it into, so the cursor carries the
|
|
1496
|
+
database's own text of the value instead, and rows a microsecond apart are still distinct
|
|
1497
|
+
pages
|
|
1483
1498
|
- A cursor is only valid under the ordering it was issued for — reusing it with a
|
|
1484
1499
|
different `orderBy` (or a malformed/corrupted cursor) returns a `GraphQLError`
|
|
1485
1500
|
- `after` cannot be combined with `distinct`, with `matchFilterOrder`, or with an `orderBy`
|
|
@@ -1556,9 +1571,17 @@ mutation {
|
|
|
1556
1571
|
- Columns the request did not supply are never overwritten — a partial upsert does not null
|
|
1557
1572
|
out the rest of the row. Listing an unsupplied column in `update` is an error rather than
|
|
1558
1573
|
a silent no-op
|
|
1574
|
+
- That holds per row: a batch whose rows supply different columns is split into one
|
|
1575
|
+
statement per run of consecutive rows that write the same columns, run in one transaction,
|
|
1576
|
+
so a row that left a column out keeps it. The rows come back in the order they were sent
|
|
1559
1577
|
- `target` must match one of the table's unique constraints exactly; anything else is
|
|
1560
1578
|
rejected with the list of valid targets, instead of the database's opaque "no unique or
|
|
1561
1579
|
exclusion constraint matching" error
|
|
1580
|
+
- `target` can be a partial unique index — the `WHERE deleted_at IS NULL` companion of
|
|
1581
|
+
[soft delete](#soft-delete), say. Its predicate goes into `ON CONFLICT (…) WHERE …`, so a
|
|
1582
|
+
conflict is detected only against the rows the index covers
|
|
1583
|
+
- `contextValues` columns are never overwritten on conflict — see
|
|
1584
|
+
[columns the server owns](#columns-the-server-owns)
|
|
1562
1585
|
- `action: NOTHING` inserts nothing and returns nothing for the conflicting row. An `UPDATE`
|
|
1563
1586
|
with no columns left to write degrades to the same thing
|
|
1564
1587
|
- `values` is the same `Create<Type>Input` the insert mutations take, so turning `insert`
|
|
@@ -1593,7 +1616,9 @@ Dialect differences:
|
|
|
1593
1616
|
- **PostgreSQL** and **SQLite** — the full surface above. A table with no primary key and no
|
|
1594
1617
|
unique constraint has nothing to conflict on, so it gets no upsert mutations at all
|
|
1595
1618
|
- **MySQL** — `ON DUPLICATE KEY UPDATE` fires on whichever unique key was violated and takes
|
|
1596
|
-
no predicate, so `<Type>OnConflict` there has only `action` and `update`.
|
|
1619
|
+
no predicate, so `<Type>OnConflict` there has only `action` and `update`. Because the
|
|
1620
|
+
conflict can be on any unique key, the default overwrite leaves out the primary key as well
|
|
1621
|
+
— copying a new row's key over the conflicting row's would move it. `action: NOTHING`
|
|
1597
1622
|
becomes `INSERT IGNORE`, and the mutations return `MutationReturn` like every other MySQL
|
|
1598
1623
|
mutation
|
|
1599
1624
|
|
|
@@ -1891,6 +1916,10 @@ Two details worth stating plainly:
|
|
|
1891
1916
|
- **A rejection is the default because truncation lies.** Silently cutting a page down to
|
|
1892
1917
|
`maxLimit` tells a paginating client it has reached the end when it has not. `clampToMax:
|
|
1893
1918
|
true` opts into that when you would rather never fail a query.
|
|
1919
|
+
- **A negative `limit` or `offset` is always rejected** with `DRIZZLE_INVALID_INPUT_VALUE`,
|
|
1920
|
+
whether or not `limits` is configured — on root lists, single queries, relation fields and
|
|
1921
|
+
`resolveSelection`. SQLite reads `LIMIT -1` as "no limit", so a negative value would
|
|
1922
|
+
otherwise walk straight past `maxLimit`; `0` stays valid and returns no rows.
|
|
1894
1923
|
|
|
1895
1924
|
The policy applies to root list queries and to to-many relation fields, on both the eager and
|
|
1896
1925
|
the lazy relation paths. A relation takes the policy of the table it *reads*, not its parent's:
|
|
@@ -2114,7 +2143,8 @@ to match on prose:
|
|
|
2114
2143
|
`DrizzleErrorContext`.
|
|
2115
2144
|
|
|
2116
2145
|
A value the request could not supply is `DRIZZLE_INVALID_INPUT_VALUE` — a date that does not
|
|
2117
|
-
parse, a `BigInt` argument that is not an integer, a malformed JSON column value
|
|
2146
|
+
parse, a `BigInt` argument that is not an integer, a malformed JSON column value, a negative
|
|
2147
|
+
`limit` or `offset` — and a write
|
|
2118
2148
|
naming something that is not a column of its table is `DRIZZLE_UNKNOWN_COLUMN`. The mirror
|
|
2119
2149
|
image, a stored value the scalar transporting it cannot represent, is
|
|
2120
2150
|
`DRIZZLE_UNREPRESENTABLE_VALUE`; it says the data is out of range, not that the request was
|
|
@@ -2565,8 +2595,11 @@ It understands `values` (one object or a list), `where` (`eq` for one row, `inAr
|
|
|
2565
2595
|
many, an equality on every column of a composite key), and the per-entry `where` inside a
|
|
2566
2596
|
batch update's `updates`. Check `complete` before treating `rows` as the affected set: it
|
|
2567
2597
|
is `false` when the arguments do not pin the rows down — an insert whose key the database
|
|
2568
|
-
generates, a filter on something other than the primary key, an unbounded update,
|
|
2569
|
-
table with no primary key at all
|
|
2598
|
+
generates, a filter on something other than the primary key, an unbounded update, a
|
|
2599
|
+
table with no primary key at all, or an upsert whose `onConflict` targets another unique key
|
|
2600
|
+
or can skip a conflicting row (`action: NOTHING`, a `where`). On MySQL, where an upsert has
|
|
2601
|
+
no `target` and conflicts on whichever unique key it hits, `complete` assumes the primary
|
|
2602
|
+
key: do not rely on it for a table with other unique keys.
|
|
2570
2603
|
|
|
2571
2604
|
> [!NOTE]
|
|
2572
2605
|
> `extensions.drizzle` is stable API. The point of publishing it is that consumers stop
|