@drizzle-graphql-suite/schema 0.8.3 → 0.9.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 +5 -489
- package/index.d.ts +1 -32
- package/index.js +1 -2054
- package/package.json +5 -19
- package/adapters/pg.d.ts +0 -10
- package/adapters/types.d.ts +0 -11
- package/case-ops.d.ts +0 -2
- package/codegen.d.ts +0 -12
- package/data-mappers.d.ts +0 -12
- package/graphql/scalars.d.ts +0 -2
- package/graphql/type-builder.d.ts +0 -7
- package/permissions.d.ts +0 -25
- package/row-security.d.ts +0 -21
- package/schema-builder.d.ts +0 -72
- package/types.d.ts +0 -253
package/README.md
CHANGED
|
@@ -1,495 +1,11 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Deprecated
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
> See also: [`client`](https://github.com/annexare/drizzle-graphql-suite/tree/main/packages/client) | [`query`](https://github.com/annexare/drizzle-graphql-suite/tree/main/packages/query)
|
|
3
|
+
This package has been renamed to `@graphql-suite/schema`.
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
## Installation
|
|
9
|
-
|
|
10
|
-
```bash
|
|
11
|
-
bun add @drizzle-graphql-suite/schema
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
```bash
|
|
15
|
-
npm install @drizzle-graphql-suite/schema
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
Or install the full suite:
|
|
5
|
+
Please update your dependencies:
|
|
19
6
|
|
|
20
7
|
```bash
|
|
21
|
-
bun add
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
npm install drizzle-graphql-suite
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## Motivation
|
|
29
|
-
|
|
30
|
-
Inspired by [`drizzle-graphql`](https://github.com/drizzle-team/drizzle-graphql), this package is a purpose-built replacement focused on PostgreSQL. Key improvements:
|
|
31
|
-
|
|
32
|
-
- **Small generated schema** — the generated schema stays compact even when supporting self-relations and deeply nested relations, thanks to configurable depth limiting (`limitRelationDepth`, `limitSelfRelationDepth`), per-relation pruning (`pruneRelations`), and per-table control (`tables.exclude`, per-table `queries`/`mutations` toggles) — up to 90% schema size reduction when tuned
|
|
33
|
-
- **Native PostgreSQL JSON/JSONB support** — `json` and `jsonb` columns map to a custom `JSON` GraphQL scalar, so structured data passes through without manual type wiring
|
|
34
|
-
- **Relation-level filtering** with EXISTS subqueries (`some`/`every`/`none` quantifiers)
|
|
35
|
-
- **Runtime permissions** — `withPermissions()` builds filtered schemas per role, fully reflected in introspection
|
|
36
|
-
- **Row-level security helpers** — `withRowSecurity()` + `mergeHooks()` for composable auth
|
|
37
|
-
- **Per-operation hooks system** (before/after/resolve) for auth, audit, and custom logic
|
|
38
|
-
- **Count queries** with full filter support
|
|
39
|
-
- **`buildEntities()`** for composable schema building (avoids redundant schema validation)
|
|
40
|
-
- **Configurable query/mutation suffixes** for naming customization
|
|
41
|
-
- **Self-relation depth limiting** — separate from general depth, prevents exponential type growth
|
|
42
|
-
- **Relation pruning** — `false`, `'leaf'`, or `{ only: [...] }` per relation
|
|
43
|
-
- **`buildSchemaFromDrizzle()`** — no database connection needed (for codegen/introspection)
|
|
44
|
-
- **Code generation** — `generateSDL`, `generateTypes`, `generateEntityDefs`
|
|
45
|
-
- **Architecture** — TypeScript source, PostgreSQL-only, `SchemaBuilder` class, type caching, lazy thunks for circular relations
|
|
46
|
-
- **Bug fixes** — relation filter join conditions (Drizzle v0.44+), operator map replacements, `catch (e: unknown)` narrowing
|
|
47
|
-
|
|
48
|
-
## API Reference
|
|
49
|
-
|
|
50
|
-
### `buildSchema(db, config?)`
|
|
51
|
-
|
|
52
|
-
Builds a complete `GraphQLSchema` with all CRUD operations from a Drizzle database instance. Returns `{ schema, entities, withPermissions }`.
|
|
53
|
-
|
|
54
|
-
```ts
|
|
55
|
-
import { buildSchema } from 'drizzle-graphql-suite/schema'
|
|
56
|
-
import { createYoga } from 'graphql-yoga'
|
|
57
|
-
import { db } from './db'
|
|
58
|
-
|
|
59
|
-
const { schema, entities, withPermissions } = buildSchema(db, {
|
|
60
|
-
limitRelationDepth: 3,
|
|
61
|
-
tables: { exclude: ['session'] },
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
const yoga = createYoga({ schema })
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
See [Runtime Permissions](#runtime-permissions) for `withPermissions` usage.
|
|
68
|
-
|
|
69
|
-
#### Framework Integration
|
|
70
|
-
|
|
71
|
-
**Next.js App Router**
|
|
72
|
-
|
|
73
|
-
```ts
|
|
74
|
-
// app/api/graphql/route.ts
|
|
75
|
-
import { createYoga } from 'graphql-yoga'
|
|
76
|
-
import { schema } from '@/lib/schema' // from buildSchema() above
|
|
77
|
-
|
|
78
|
-
const { handleRequest } = createYoga({
|
|
79
|
-
schema,
|
|
80
|
-
graphqlEndpoint: '/api/graphql',
|
|
81
|
-
fetchAPI: { Response },
|
|
82
|
-
})
|
|
83
|
-
|
|
84
|
-
export { handleRequest as GET, handleRequest as POST }
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
**ElysiaJS**
|
|
88
|
-
|
|
89
|
-
```ts
|
|
90
|
-
// server.ts
|
|
91
|
-
import { Elysia } from 'elysia'
|
|
92
|
-
import { yoga } from '@elysiajs/graphql-yoga'
|
|
93
|
-
import { schema } from './schema' // from buildSchema() above
|
|
94
|
-
|
|
95
|
-
new Elysia()
|
|
96
|
-
.use(yoga({ schema }))
|
|
97
|
-
.listen(3000)
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
### `buildEntities(db, config?)`
|
|
101
|
-
|
|
102
|
-
Returns `GeneratedEntities` only — queries, mutations, inputs, and types — without constructing a `GraphQLSchema`. Use this when composing into a larger schema (e.g., Pothos) to avoid redundant schema validation.
|
|
103
|
-
|
|
104
|
-
```ts
|
|
105
|
-
import { buildEntities } from 'drizzle-graphql-suite/schema'
|
|
106
|
-
|
|
107
|
-
const entities = buildEntities(db, { mutations: false })
|
|
108
|
-
// entities.queries, entities.mutations, entities.inputs, entities.types
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
### `buildSchemaFromDrizzle(drizzleSchema, config?)`
|
|
112
|
-
|
|
113
|
-
Builds a schema directly from Drizzle schema exports — no database connection or `.env` required. Resolvers are stubs. Intended for schema introspection and code generation.
|
|
114
|
-
|
|
115
|
-
```ts
|
|
116
|
-
import { buildSchemaFromDrizzle } from 'drizzle-graphql-suite/schema'
|
|
117
|
-
import * as schema from './db/schema'
|
|
118
|
-
|
|
119
|
-
const { schema: graphqlSchema } = buildSchemaFromDrizzle(schema)
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
## Configuration
|
|
123
|
-
|
|
124
|
-
`BuildSchemaConfig` controls all aspects of schema generation:
|
|
125
|
-
|
|
126
|
-
### `mutations`
|
|
127
|
-
|
|
128
|
-
Enable or disable mutation generation globally.
|
|
129
|
-
|
|
130
|
-
- **Type**: `boolean`
|
|
131
|
-
- **Default**: `true`
|
|
132
|
-
|
|
133
|
-
### `limitRelationDepth`
|
|
134
|
-
|
|
135
|
-
Maximum depth of nested relation fields on queries. Set to `0` to omit relations, `undefined` for no limit.
|
|
136
|
-
|
|
137
|
-
- **Type**: `number | undefined`
|
|
138
|
-
- **Default**: `3`
|
|
139
|
-
|
|
140
|
-
### `limitSelfRelationDepth`
|
|
141
|
-
|
|
142
|
-
Maximum occurrences of the same table via direct self-relations (e.g., `asset.template → asset`). At `1`, self-relation fields are omitted entirely. At `2`, one level of expansion is allowed. Cross-table paths that revisit a table reset the counter and use `limitRelationDepth` instead.
|
|
143
|
-
|
|
144
|
-
- **Type**: `number`
|
|
145
|
-
- **Default**: `1`
|
|
146
|
-
|
|
147
|
-
### `suffixes`
|
|
148
|
-
|
|
149
|
-
Customize query field name suffixes for list and single queries.
|
|
150
|
-
|
|
151
|
-
- **Type**: `{ list?: string; single?: string }`
|
|
152
|
-
- **Default**: `{ list: '', single: 'Single' }`
|
|
153
|
-
|
|
154
|
-
### `tables`
|
|
155
|
-
|
|
156
|
-
Per-table schema control:
|
|
157
|
-
|
|
158
|
-
```ts
|
|
159
|
-
{
|
|
160
|
-
tables: {
|
|
161
|
-
// Remove tables entirely (relations to them are silently skipped)
|
|
162
|
-
exclude: ['session', 'verification'],
|
|
163
|
-
// Per-table operation overrides
|
|
164
|
-
config: {
|
|
165
|
-
auditLog: { queries: true, mutations: false },
|
|
166
|
-
user: { mutations: false },
|
|
167
|
-
},
|
|
168
|
-
},
|
|
169
|
-
}
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
- `exclude` — `string[]` — tables removed from the schema entirely
|
|
173
|
-
- `config` — `Record<string, TableOperations>` — per-table `queries` and `mutations` booleans
|
|
174
|
-
|
|
175
|
-
### `pruneRelations`
|
|
176
|
-
|
|
177
|
-
Fine-grained per-relation pruning. Keys are `tableName.relationName`:
|
|
178
|
-
|
|
179
|
-
```ts
|
|
180
|
-
{
|
|
181
|
-
pruneRelations: {
|
|
182
|
-
// Omit this relation field entirely
|
|
183
|
-
'asset.childAssets': false,
|
|
184
|
-
// Expand with scalar columns only (no nested relations)
|
|
185
|
-
'user.posts': 'leaf',
|
|
186
|
-
// Expand with only the listed child relations
|
|
187
|
-
'post.comments': { only: ['author'] },
|
|
188
|
-
},
|
|
189
|
-
}
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
- `false` — relation field omitted entirely from parent type
|
|
193
|
-
- `'leaf'` — relation expands with scalar columns only
|
|
194
|
-
- `{ only: string[] }` — relation expands with only the listed child relation fields
|
|
195
|
-
|
|
196
|
-
### `hooks`
|
|
197
|
-
|
|
198
|
-
Per-table, per-operation hooks. See [Hooks System](#hooks-system).
|
|
199
|
-
|
|
200
|
-
### `debug`
|
|
201
|
-
|
|
202
|
-
Enable diagnostic logging for schema size and relation tree.
|
|
203
|
-
|
|
204
|
-
- **Type**: `boolean | { schemaSize?: boolean; relationTree?: boolean }`
|
|
205
|
-
- **Default**: `undefined`
|
|
206
|
-
|
|
207
|
-
## Runtime Permissions
|
|
208
|
-
|
|
209
|
-
Build filtered `GraphQLSchema` variants per role or user — introspection fully reflects what each role can see and do.
|
|
210
|
-
|
|
211
|
-
```ts
|
|
212
|
-
import { buildSchema, permissive, restricted, readOnly } from 'drizzle-graphql-suite/schema'
|
|
213
|
-
|
|
214
|
-
const { schema, withPermissions } = buildSchema(db)
|
|
215
|
-
|
|
216
|
-
// Full schema (admin)
|
|
217
|
-
const adminSchema = schema
|
|
218
|
-
|
|
219
|
-
// Permissive: everything allowed except audit (excluded) and users (read-only)
|
|
220
|
-
const maintainerSchema = withPermissions(
|
|
221
|
-
permissive('maintainer', { audit: false, users: readOnly() }),
|
|
222
|
-
)
|
|
223
|
-
|
|
224
|
-
// Restricted: nothing allowed except posts and comments (queries only)
|
|
225
|
-
const userSchema = withPermissions(
|
|
226
|
-
restricted('user', { posts: { query: true }, comments: { query: true } }),
|
|
227
|
-
)
|
|
228
|
-
|
|
229
|
-
// Restricted with nothing granted — only Query { _empty: Boolean }
|
|
230
|
-
const anonSchema = withPermissions(restricted('anon'))
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
Schemas are cached by `id` — calling `withPermissions` with the same `id` returns the same `GraphQLSchema` instance.
|
|
234
|
-
|
|
235
|
-
### Permission Helpers
|
|
236
|
-
|
|
237
|
-
| Helper | Description |
|
|
238
|
-
|--------|-------------|
|
|
239
|
-
| `permissive(id, tables?)` | All tables allowed by default; overrides deny |
|
|
240
|
-
| `restricted(id, tables?)` | Nothing allowed by default; overrides grant |
|
|
241
|
-
| `readOnly()` | Shorthand for `{ query: true, insert: false, update: false, delete: false }` |
|
|
242
|
-
|
|
243
|
-
### Table Access
|
|
244
|
-
|
|
245
|
-
Each table can be set to `true` (all operations), `false` (excluded entirely), or a `TableAccess` object:
|
|
246
|
-
|
|
247
|
-
```ts
|
|
248
|
-
type TableAccess = {
|
|
249
|
-
query?: boolean // list + single + count
|
|
250
|
-
insert?: boolean // insert + insertSingle
|
|
251
|
-
update?: boolean
|
|
252
|
-
delete?: boolean
|
|
253
|
-
}
|
|
254
|
-
```
|
|
255
|
-
|
|
256
|
-
In **permissive** mode, omitted fields default to `true`. In **restricted** mode, omitted fields default to `false`.
|
|
257
|
-
|
|
258
|
-
### Introspection Behavior
|
|
259
|
-
|
|
260
|
-
- `false` (excluded table) — removed from everywhere: no entry points, no relation fields on other types, no filter fields
|
|
261
|
-
- `readOnly()` — table types exist (accessible via relations), but only query entry points; no mutations
|
|
262
|
-
- Granular control — e.g. `{ query: true, insert: true, delete: false }` removes only `deleteFrom{Table}` mutation
|
|
263
|
-
|
|
264
|
-
## Row-Level Security
|
|
265
|
-
|
|
266
|
-
Generate hooks that inject WHERE clauses for row-level filtering. Compose with other hooks using `mergeHooks`.
|
|
267
|
-
|
|
268
|
-
```ts
|
|
269
|
-
import { buildSchema, withRowSecurity, mergeHooks } from 'drizzle-graphql-suite/schema'
|
|
270
|
-
|
|
271
|
-
const { schema } = buildSchema(db, {
|
|
272
|
-
hooks: mergeHooks(
|
|
273
|
-
withRowSecurity({
|
|
274
|
-
posts: (context) => ({ authorId: { eq: context.user.id } }),
|
|
275
|
-
}),
|
|
276
|
-
myOtherHooks,
|
|
277
|
-
),
|
|
278
|
-
})
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
### `withRowSecurity(rules)`
|
|
282
|
-
|
|
283
|
-
Generates a `HooksConfig` with `before` hooks on `query`, `querySingle`, `count`, `update`, and `delete` operations. Each rule is a function that receives the GraphQL context and returns a WHERE filter object.
|
|
284
|
-
|
|
285
|
-
### `mergeHooks(...configs)`
|
|
286
|
-
|
|
287
|
-
Deep-merges multiple `HooksConfig` objects:
|
|
288
|
-
|
|
289
|
-
- **`before` hooks** — chained sequentially; each receives the previous hook's modified args
|
|
290
|
-
- **`after` hooks** — chained sequentially; each receives the previous hook's result
|
|
291
|
-
- **`resolve` hooks** — last one wins (cannot be composed)
|
|
292
|
-
|
|
293
|
-
## Hooks System
|
|
294
|
-
|
|
295
|
-
Hooks intercept operations for auth, validation, audit logging, or custom resolution.
|
|
296
|
-
|
|
297
|
-
### Hook Types
|
|
298
|
-
|
|
299
|
-
Each operation supports either **before/after** hooks or a **resolve** hook (not both):
|
|
300
|
-
|
|
301
|
-
| Hook | Timing | Use Case |
|
|
302
|
-
|------|--------|----------|
|
|
303
|
-
| `before` | Before default resolver | Auth checks, argument transformation, pass data to `after` |
|
|
304
|
-
| `after` | After default resolver | Audit logging, result transformation |
|
|
305
|
-
| `resolve` | Replaces default resolver | Full control, custom data sources |
|
|
306
|
-
|
|
307
|
-
### Operations
|
|
308
|
-
|
|
309
|
-
| Operation | Type | Description |
|
|
310
|
-
|-----------|------|-------------|
|
|
311
|
-
| `query` | Read | List query |
|
|
312
|
-
| `querySingle` | Read | Single record query |
|
|
313
|
-
| `count` | Read | Count query |
|
|
314
|
-
| `insert` | Write | Batch insert |
|
|
315
|
-
| `insertSingle` | Write | Single record insert |
|
|
316
|
-
| `update` | Write | Update mutation |
|
|
317
|
-
| `delete` | Write | Delete mutation |
|
|
318
|
-
|
|
319
|
-
### Example
|
|
320
|
-
|
|
321
|
-
```ts
|
|
322
|
-
buildSchema(db, {
|
|
323
|
-
hooks: {
|
|
324
|
-
user: {
|
|
325
|
-
query: {
|
|
326
|
-
before: async ({ args, context }) => {
|
|
327
|
-
if (!context.user) throw new Error('Unauthorized')
|
|
328
|
-
// Optionally modify args or pass data to after hook
|
|
329
|
-
return { args, data: { startTime: Date.now() } }
|
|
330
|
-
},
|
|
331
|
-
after: async ({ result, beforeData }) => {
|
|
332
|
-
console.log(`Query took ${Date.now() - beforeData.startTime}ms`)
|
|
333
|
-
return result
|
|
334
|
-
},
|
|
335
|
-
},
|
|
336
|
-
delete: {
|
|
337
|
-
resolve: async ({ args, context, defaultResolve }) => {
|
|
338
|
-
// Soft delete instead of hard delete
|
|
339
|
-
return defaultResolve({ ...args, set: { deletedAt: new Date() } })
|
|
340
|
-
},
|
|
341
|
-
},
|
|
342
|
-
},
|
|
343
|
-
},
|
|
344
|
-
})
|
|
345
|
-
```
|
|
346
|
-
|
|
347
|
-
## Relation Filtering
|
|
348
|
-
|
|
349
|
-
Filter by related rows using EXISTS subqueries with `some`, `every`, and `none` quantifiers.
|
|
350
|
-
|
|
351
|
-
```graphql
|
|
352
|
-
query {
|
|
353
|
-
users(where: {
|
|
354
|
-
posts: {
|
|
355
|
-
some: { published: { eq: true } }
|
|
356
|
-
none: { flagged: { eq: true } }
|
|
357
|
-
}
|
|
358
|
-
}) {
|
|
359
|
-
id
|
|
360
|
-
name
|
|
361
|
-
posts {
|
|
362
|
-
title
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
```
|
|
367
|
-
|
|
368
|
-
- **`some`** — at least one related row matches
|
|
369
|
-
- **`every`** — all related rows match
|
|
370
|
-
- **`none`** — no related rows match
|
|
371
|
-
|
|
372
|
-
For one-to-one relations, filters apply directly (no quantifiers needed):
|
|
373
|
-
|
|
374
|
-
```graphql
|
|
375
|
-
query {
|
|
376
|
-
posts(where: {
|
|
377
|
-
author: { role: { eq: "admin" } }
|
|
378
|
-
}) {
|
|
379
|
-
title
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
```
|
|
383
|
-
|
|
384
|
-
## Generated Operations
|
|
385
|
-
|
|
386
|
-
| Pattern | Example (`user` table) | Type |
|
|
387
|
-
|---------|----------------------|------|
|
|
388
|
-
| `{table}` | `user` | Single query |
|
|
389
|
-
| `{table}{listSuffix}` | `users` | List query |
|
|
390
|
-
| `{table}Count` | `userCount` | Count query |
|
|
391
|
-
| `insertInto{Table}` | `insertIntoUser` | Batch insert |
|
|
392
|
-
| `insertInto{Table}Single` | `insertIntoUserSingle` | Single insert |
|
|
393
|
-
| `update{Table}` | `updateUser` | Update |
|
|
394
|
-
| `deleteFrom{Table}` | `deleteFromUser` | Delete |
|
|
395
|
-
|
|
396
|
-
## Column Type Mapping
|
|
397
|
-
|
|
398
|
-
| Drizzle Type | GraphQL Type |
|
|
399
|
-
|-------------|--------------|
|
|
400
|
-
| `boolean` | `Boolean` |
|
|
401
|
-
| `text`, `varchar`, `char` | `String` |
|
|
402
|
-
| `integer`, `smallint`, `serial`, `smallserial`, `bigserial` | `Int` |
|
|
403
|
-
| `real`, `doublePrecision`, `numeric` | `Float` |
|
|
404
|
-
| `bigint` | `String` |
|
|
405
|
-
| `date`, `timestamp`, `time` | `String` |
|
|
406
|
-
| `json`, `jsonb` | `JSON` (custom scalar) |
|
|
407
|
-
| `bytea` | `[Int!]` |
|
|
408
|
-
| `vector` | `[Float!]` |
|
|
409
|
-
| `geometry` | `PgGeometryObject { x, y }` |
|
|
410
|
-
| `enum` | Generated `GraphQLEnumType` |
|
|
411
|
-
|
|
412
|
-
## Code Generation
|
|
413
|
-
|
|
414
|
-
> **When to use:** Only when the client is in a separate repository that cannot import the Drizzle schema directly. For same-repo setups, [`createDrizzleClient`](https://github.com/annexare/drizzle-graphql-suite/tree/main/packages/client) infers all types automatically — no codegen needed.
|
|
415
|
-
|
|
416
|
-
Three code generation functions for producing static artifacts from a GraphQL schema:
|
|
417
|
-
|
|
418
|
-
### `generateSDL(schema)`
|
|
419
|
-
|
|
420
|
-
Generates the GraphQL Schema Definition Language string.
|
|
421
|
-
|
|
422
|
-
```ts
|
|
423
|
-
import { buildSchemaFromDrizzle, generateSDL } from 'drizzle-graphql-suite/schema'
|
|
424
|
-
import * as drizzleSchema from './db/schema'
|
|
425
|
-
import { writeFileSync } from 'node:fs'
|
|
426
|
-
|
|
427
|
-
const { schema } = buildSchemaFromDrizzle(drizzleSchema)
|
|
428
|
-
writeFileSync('schema.graphql', generateSDL(schema))
|
|
429
|
-
```
|
|
430
|
-
|
|
431
|
-
### `generateTypes(schema, options?)`
|
|
432
|
-
|
|
433
|
-
Generates TypeScript types: wire format types (Date → string), filter types, insert/update input types, and orderBy types. Optionally imports Drizzle types for precise wire format derivation.
|
|
434
|
-
|
|
435
|
-
```ts
|
|
436
|
-
import { generateTypes } from 'drizzle-graphql-suite/schema'
|
|
437
|
-
|
|
438
|
-
const types = generateTypes(schema, {
|
|
439
|
-
drizzle: {
|
|
440
|
-
importPath: '@myapp/db/schema',
|
|
441
|
-
typeNames: { userProfile: 'UserProfile' },
|
|
442
|
-
},
|
|
443
|
-
})
|
|
444
|
-
writeFileSync('generated/types.ts', types)
|
|
445
|
-
```
|
|
446
|
-
|
|
447
|
-
### `generateEntityDefs(schema, options?)`
|
|
448
|
-
|
|
449
|
-
Generates a runtime schema descriptor object and `EntityDefs` type for the client package. Use this instead of `createDrizzleClient` when the client is in a separate repo and can't import the Drizzle schema.
|
|
450
|
-
|
|
451
|
-
```ts
|
|
452
|
-
import { generateEntityDefs } from 'drizzle-graphql-suite/schema'
|
|
453
|
-
|
|
454
|
-
const entityDefs = generateEntityDefs(schema, {
|
|
455
|
-
drizzle: { importPath: '@myapp/db/schema' },
|
|
456
|
-
})
|
|
457
|
-
writeFileSync('generated/entity-defs.ts', entityDefs)
|
|
458
|
-
```
|
|
459
|
-
|
|
460
|
-
### Full Codegen Script
|
|
461
|
-
|
|
462
|
-
```ts
|
|
463
|
-
import { buildSchemaFromDrizzle, generateSDL, generateTypes, generateEntityDefs } from 'drizzle-graphql-suite/schema'
|
|
464
|
-
import * as drizzleSchema from './db/schema'
|
|
465
|
-
import { writeFileSync, mkdirSync } from 'node:fs'
|
|
466
|
-
|
|
467
|
-
const { schema } = buildSchemaFromDrizzle(drizzleSchema)
|
|
468
|
-
|
|
469
|
-
mkdirSync('generated', { recursive: true })
|
|
470
|
-
writeFileSync('generated/schema.graphql', generateSDL(schema))
|
|
471
|
-
writeFileSync('generated/types.ts', generateTypes(schema, {
|
|
472
|
-
drizzle: { importPath: '@myapp/db/schema' },
|
|
473
|
-
}))
|
|
474
|
-
writeFileSync('generated/entity-defs.ts', generateEntityDefs(schema, {
|
|
475
|
-
drizzle: { importPath: '@myapp/db/schema' },
|
|
476
|
-
}))
|
|
477
|
-
```
|
|
478
|
-
|
|
479
|
-
## `GeneratedEntities` Type
|
|
480
|
-
|
|
481
|
-
The return type from `buildEntities()` and `buildSchema()`:
|
|
482
|
-
|
|
483
|
-
```ts
|
|
484
|
-
type GeneratedEntities = {
|
|
485
|
-
queries: Record<string, GraphQLFieldConfig<any, any>>
|
|
486
|
-
mutations: Record<string, GraphQLFieldConfig<any, any>>
|
|
487
|
-
inputs: Record<string, GraphQLInputObjectType>
|
|
488
|
-
types: Record<string, GraphQLObjectType>
|
|
489
|
-
}
|
|
8
|
+
bun add @graphql-suite/schema
|
|
490
9
|
```
|
|
491
10
|
|
|
492
|
-
-
|
|
493
|
-
- **`mutations`** — all generated mutation field configs
|
|
494
|
-
- **`inputs`** — filter, insert, update, and orderBy input types by name
|
|
495
|
-
- **`types`** — output object types by table name
|
|
11
|
+
Documentation: https://graphql-suite.annexare.com
|
package/index.d.ts
CHANGED
|
@@ -1,32 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import type { GraphQLSchema } from 'graphql';
|
|
3
|
-
import type { BuildSchemaConfig, GeneratedEntities, PermissionConfig } from './types';
|
|
4
|
-
export { GraphQLJSON } from './graphql/scalars';
|
|
5
|
-
export declare const buildSchema: (db: PgDatabase<any, any, any>, config?: BuildSchemaConfig) => {
|
|
6
|
-
schema: GraphQLSchema;
|
|
7
|
-
entities: GeneratedEntities;
|
|
8
|
-
withPermissions: (permissions: PermissionConfig) => GraphQLSchema;
|
|
9
|
-
clearPermissionCache: (id?: string) => void;
|
|
10
|
-
};
|
|
11
|
-
export declare const buildEntities: (db: PgDatabase<any, any, any>, config?: BuildSchemaConfig) => GeneratedEntities;
|
|
12
|
-
/**
|
|
13
|
-
* Build a GraphQL schema directly from Drizzle schema exports — no database
|
|
14
|
-
* connection or `.env` required. Creates a lightweight mock db instance that
|
|
15
|
-
* satisfies `SchemaBuilder`'s metadata needs (table definitions, relations,
|
|
16
|
-
* table name mapping) without an actual connection.
|
|
17
|
-
*
|
|
18
|
-
* Resolver functions on the returned entities are stubs — this is intended
|
|
19
|
-
* for schema introspection and code generation, not query execution.
|
|
20
|
-
*/
|
|
21
|
-
export declare const buildSchemaFromDrizzle: (drizzleSchema: Record<string, unknown>, config?: BuildSchemaConfig) => {
|
|
22
|
-
schema: GraphQLSchema;
|
|
23
|
-
entities: GeneratedEntities;
|
|
24
|
-
withPermissions: (permissions: PermissionConfig) => GraphQLSchema;
|
|
25
|
-
clearPermissionCache: (id?: string) => void;
|
|
26
|
-
};
|
|
27
|
-
export type { CodegenOptions } from './codegen';
|
|
28
|
-
export { generateEntityDefs, generateSDL, generateTypes } from './codegen';
|
|
29
|
-
export { permissive, readOnly, restricted } from './permissions';
|
|
30
|
-
export { mergeHooks, withRowSecurity } from './row-security';
|
|
31
|
-
export { SchemaBuilder } from './schema-builder';
|
|
32
|
-
export * from './types';
|
|
1
|
+
export * from '@graphql-suite/schema'
|