@vantreeseba/drizzle-graphql 14.0.0 → 15.0.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
@@ -2,17 +2,19 @@
2
2
 
3
3
  Automatically create GraphQL schema or customizable schema config fields from Drizzle ORM schema
4
4
 
5
+ Site: [cubicecho.github.io/drizzle-graphql](https://cubicecho.github.io/drizzle-graphql/)
6
+
5
7
  ## Usage
6
8
 
7
9
  - Pass your drizzle database instance and schema into builder to generate `{ schema, entities }` object
8
- - Use `schema` if pre-built schema already satisfies all your neeeds. It's compatible witn any server that consumes `GraphQLSchema` class instance
10
+ - Use `schema` if pre-built schema already satisfies all your needs. It's compatible with any server that consumes `GraphQLSchema` class instance
9
11
 
10
12
  Example: hosting schema using [GraphQL Yoga](https://the-guild.dev/graphql/yoga-server)
11
13
 
12
14
  ```Typescript
13
15
  import { createServer } from 'node:http'
14
16
  import { createYoga } from 'graphql-yoga'
15
- import { buildSchema } from 'drizzle-graphql'
17
+ import { buildSchema } from '@vantreeseba/drizzle-graphql'
16
18
 
17
19
  // db - your drizzle instance
18
20
  import { db } from './database'
@@ -20,6 +22,7 @@ Automatically create GraphQL schema or customizable schema config fields from Dr
20
22
  const { schema } = buildSchema(db)
21
23
 
22
24
  const yoga = createYoga({ schema })
25
+ const server = createServer(yoga)
23
26
 
24
27
  server.listen(4000, () => {
25
28
  console.info('Server is running on http://localhost:4000/graphql')
@@ -32,7 +35,7 @@ Automatically create GraphQL schema or customizable schema config fields from Dr
32
35
  import { createServer } from 'node:http'
33
36
  import { GraphQLList, GraphQLNonNull, GraphQLObjectType, GraphQLSchema } from 'graphql'
34
37
  import { createYoga } from 'graphql-yoga'
35
- import { buildSchema } from 'drizzle-graphql'
38
+ import { buildSchema } from '@vantreeseba/drizzle-graphql'
36
39
 
37
40
  // Schema contains 'Users' and 'Customers' tables
38
41
  import { db } from './database'
@@ -118,7 +121,7 @@ to leave that table with the default naming. The preset is exported as `singular
118
121
  so it can be wrapped:
119
122
 
120
123
  ```Typescript
121
- import { buildSchema, singularizeMapper } from 'drizzle-graphql'
124
+ import { buildSchema, singularizeMapper } from '@vantreeseba/drizzle-graphql'
122
125
 
123
126
  const { schema } = buildSchema(db, {
124
127
  typeNameMapper: (table) => (table === 'auditLog' ? undefined : singularizeMapper(table)),
@@ -606,8 +609,9 @@ generated SDL says what a field actually holds instead of falling back to `Strin
606
609
  | `json` / `jsonb` (and `mode: 'json'`) | `JSON` | the parsed value |
607
610
  | `bigint` (and `mode: 'bigint'`) | `BigInt` | a decimal string |
608
611
  | `uuid` | `UUID` | a validated UUID string |
609
- | `timestamp` / `datetime` | `DateTime` | an ISO-8601 string |
610
- | `date` | `Date` | a `YYYY-MM-DD` string |
612
+ | `timestamp` / `datetime` (either `mode`) | `DateTime` | an ISO-8601 string |
613
+ | SQLite `integer({ mode: 'timestamp' })` / `'timestamp_ms'` | `DateTime` | an ISO-8601 string |
614
+ | `date` (either `mode`) | `Date` | a `YYYY-MM-DD` string |
611
615
 
612
616
  ```graphql
613
617
  mutation {
@@ -625,15 +629,98 @@ mutation {
625
629
  `Number.MAX_SAFE_INTEGER` survive the round-trip. Integer literals are accepted on input;
626
630
  floats and non-numeric strings are rejected
627
631
  - **`UUID`** validates the format on the way in, including inside `where` filters
632
+ - **`Date`** is a calendar day — no time, no offset — and is the same type in every position
633
+ a `date` column appears in: the object field, the create and update inputs, the
634
+ `DateFilter` operands, aggregate `min` / `max` and group keys. It takes and returns an
635
+ RFC 3339 `full-date` (`2026-09-15`) whichever `mode` the column is declared with; a
636
+ `mode: 'date'` column is read back from its JS `Date` as the UTC day, so no server timezone
637
+ shifts it. Input must name a real day: `2026-02-30`, `2026-13-45` and datetime strings like
638
+ `2026-09-15T10:00:00Z` are rejected. With `graphql-codegen`, map it as
639
+ `scalars: { Date: 'string' }`
640
+ - **`DateTime`** is an instant, and is likewise the same type in every position a Postgres
641
+ `timestamp`, MySQL `timestamp` / `datetime` or SQLite integer timestamp column appears in, with `DateTimeFilter` in
642
+ filters, whichever `mode` the column is declared with. It returns an ISO-8601 string in UTC.
643
+ MySQL stores these columns without an offset; the value is written and read as UTC
644
+ (`2026-09-15T10:00:00Z` is stored as `2026-09-15 10:00:00`) whatever the Node process's
645
+ timezone, the way drizzle itself treats them. Postgres `timestamp` without time zone is
646
+ treated the same way, in both modes; `timestamptz` stores the instant, and its text in
647
+ `mode: 'string'` (`2026-09-15 04:00:00-06`) is returned as the same instant in UTC. The
648
+ scalar carries milliseconds, so a `timestamp(6)` value's microseconds are truncated on read
649
+ and on write. A SQLite `integer({ mode: 'timestamp' })` or `integer({ mode: 'timestamp_ms' })`
650
+ column is `DateTime` too; it stores the instant as epoch seconds or milliseconds. Seconds
651
+ mode cannot hold a fraction, so it is floored (never rounded) on write —
652
+ `2026-09-15T10:00:00.999Z` is stored as `1789466400` and reads back as
653
+ `2026-09-15T10:00:00.000Z` — and filter operands on such a column are floored the same way,
654
+ so `eq` with the value you wrote finds the row you wrote it to
628
655
 
629
656
  The scalars are exported if you need them in a hand-written schema:
630
657
 
631
658
  ```Typescript
632
- import { GraphQLBigIntString, GraphQLDate, GraphQLDateTime, GraphQLJSON, GraphQLUUID } from 'drizzle-graphql'
659
+ import { GraphQLBigIntString, GraphQLDate, GraphQLDateTime, GraphQLJSON, GraphQLUUID } from '@vantreeseba/drizzle-graphql'
633
660
  ```
634
661
 
635
662
  `GraphQLBigIntString` is the `BigInt` scalar — named for what it does rather than what it is
636
- called in SDL, to avoid clashing with the language's own `BigInt`.
663
+ called in SDL, to avoid clashing with the language's own `BigInt`. `GraphQLDate` is this
664
+ library's own `Date` scalar, not `graphql-scalars`' (whose `parseValue` returns a JS `Date`).
665
+
666
+ > **Upgrading — `date` columns.** A `date` column used to be typed differently depending on
667
+ > where it appeared and which `mode` it was declared with. Both modes are now `Date` everywhere:
668
+ >
669
+ > | Drizzle column | position | before | now |
670
+ > | --- | --- | --- | --- |
671
+ > | `date(…, { mode: 'string' })` | output | `Date` | `Date` |
672
+ > | | create / update input | `String` | `Date` |
673
+ > | | filter | `StringFilter` | `DateFilter` |
674
+ > | `date(…)` / `{ mode: 'date' }` (Postgres) | output, input, min/max, group keys | `DateTime` | `Date` |
675
+ > | | filter | `DateTimeFilter` | `DateFilter` |
676
+ > | `date(…, { mode: 'date' })` (MySQL) | output, input, min/max, group keys | `JSON` | `Date` |
677
+ > | | filter | `JSONFilter` | `DateFilter` |
678
+ > | `date(…, { mode: 'string' })` (MySQL) | output, input, min/max, group keys | `String` | `Date` |
679
+ > | | filter | `StringFilter` | `DateFilter` |
680
+ >
681
+ > What to change:
682
+ >
683
+ > - Variables typed `String` or `DateTime` for a date field become `Date`; filters on it are
684
+ > `DateFilter`, which has the `DateTimeFilter` operators (`eq` / `ne` / `lt` / `lte` / `gt` /
685
+ > `gte` / `inArray` / `notInArray` / `isNull` / `isNotNull`) and none of the string ones
686
+ > - Send `YYYY-MM-DD`. A datetime string such as `2026-09-15T00:00:00.000Z` used to be
687
+ > truncated to its date and is now rejected
688
+ > - A `mode: 'date'` column read `2026-09-15T00:00:00.000Z` and now reads `2026-09-15`
689
+ > - In `graphql-codegen`, map `scalars: { Date: 'string' }` — the value is a string in both
690
+ > directions
691
+ > - If you passed `graphql-scalars`' `GraphQLDate` as a column override, pass this library's
692
+ > exported `GraphQLDate` instead. They share the name `Date`, so a schema holding both
693
+ > fails to build with graphql's "multiple types named Date" error
694
+
695
+ > **Upgrading — MySQL `timestamp` / `datetime` columns.** These used to fall through to
696
+ > `JSON` in `mode: 'date'` and to `String` in `mode: 'string'`. All four are now `DateTime`, as
697
+ > Postgres `timestamp` already was:
698
+ >
699
+ > | Drizzle column (MySQL) | position | before | now |
700
+ > | --- | --- | --- | --- |
701
+ > | `timestamp(…)` / `datetime(…)` (`mode: 'date'`) | output, input, min/max, group keys | `JSON` | `DateTime` |
702
+ > | | filter | `JSONFilter` | `DateTimeFilter` |
703
+ > | `timestamp(…)` / `datetime(…)` with `{ mode: 'string' }` | output, input, min/max, group keys | `String` | `DateTime` |
704
+ > | | filter | `StringFilter` | `DateTimeFilter` |
705
+ >
706
+ > Variables for these fields become `DateTime` and their filters `DateTimeFilter`, which has no
707
+ > `JSONFilter` / `StringFilter` operators such as `contains` or `like`. Input must be an ISO-8601
708
+ > date-time (`2026-09-15T10:00:00Z`, or with an offset). A `mode: 'string'` column used to read
709
+ > MySQL's own `2026-09-15 10:00:00` and now reads `2026-09-15T10:00:00.000Z`. In
710
+ > `graphql-codegen`, map `DateTime` the way you already do for Postgres timestamps.
711
+
712
+ > **Upgrading — SQLite integer timestamps.** `integer({ mode: 'timestamp' })` and
713
+ > `integer({ mode: 'timestamp_ms' })` used to fall through to `JSON`. Both are now `DateTime`:
714
+ >
715
+ > | Drizzle column (SQLite) | position | before | now |
716
+ > | --- | --- | --- | --- |
717
+ > | `integer(…, { mode: 'timestamp' })` / `{ mode: 'timestamp_ms' }` | output, input, min/max, group keys | `JSON` | `DateTime` |
718
+ > | | filter | `JSONFilter` | `DateTimeFilter` |
719
+ >
720
+ > Variables for these fields become `DateTime`, and their filters `DateTimeFilter`, which swaps
721
+ > the JSON `path` operator for `lt` / `lte` / `gt` / `gte` / `inArray` / `notInArray`. Input must
722
+ > be an ISO-8601 date-time; a JSON value such as a bare number is rejected. Reads are unchanged:
723
+ > they were already ISO-8601 strings in UTC. The stored integers are unchanged too.
637
724
 
638
725
  ### Overriding a column's scalar
639
726
 
@@ -911,7 +998,7 @@ no others. The set follows the column's data type, never its name:
911
998
  | column type | `eq` `ne` `inArray` `notInArray` `isNull` `isNotNull` | `lt` `lte` `gt` `gte` | pattern operators + `insensitive` |
912
999
  | --- | --- | --- | --- |
913
1000
  | text / varchar | yes | yes | yes |
914
- | timestamp, date | yes | yes | — |
1001
+ | timestamp (`DateTimeFilter`), date (`DateFilter`) | yes | yes | — |
915
1002
  | int, float, bigint, decimal | yes | yes | — |
916
1003
  | uuid | yes | yes | — |
917
1004
  | boolean | yes | — | — |
@@ -2062,7 +2149,7 @@ To control the boundary yourself, open a transaction and put it on the GraphQL c
2062
2149
  the exported `drizzleExecutorKey`:
2063
2150
 
2064
2151
  ```Typescript
2065
- import { buildSchema, drizzleExecutorKey } from 'drizzle-graphql'
2152
+ import { buildSchema, drizzleExecutorKey } from '@vantreeseba/drizzle-graphql'
2066
2153
 
2067
2154
  const { schema } = buildSchema(db)
2068
2155