@vantreeseba/drizzle-graphql 1.0.3 → 3.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 +465 -0
- package/dist/README.md +465 -0
- package/dist/index.cjs +2494 -886
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +323 -19
- package/dist/index.d.ts +323 -19
- package/dist/index.js +2508 -890
- package/dist/index.js.map +1 -1
- package/dist/package.json +5 -5
- package/package.json +5 -5
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
1
|
-
import { Table, Column,
|
|
1
|
+
import { Table, Column, Relation, SQL, One, Many } from 'drizzle-orm';
|
|
2
2
|
import { MySqlDatabase } from 'drizzle-orm/mysql-core';
|
|
3
3
|
import { PgAsyncDatabase } from 'drizzle-orm/pg-core';
|
|
4
4
|
import { BaseSQLiteDatabase } from 'drizzle-orm/sqlite-core';
|
|
5
|
-
import { GraphQLResolveInfo, GraphQLSchema, GraphQLInputObjectType, GraphQLObjectType, GraphQLNonNull, GraphQLList, GraphQLScalarType } from 'graphql';
|
|
5
|
+
import { GraphQLFieldResolver, GraphQLResolveInfo, GraphQLSchema, GraphQLInputObjectType, GraphQLObjectType, GraphQLNonNull, GraphQLList, GraphQLScalarType, GraphQLEnumType } from 'graphql';
|
|
6
|
+
export { GraphQLDate, GraphQLDateTime, GraphQLJSON, GraphQLUUID } from 'graphql-scalars';
|
|
6
7
|
|
|
8
|
+
type TableNamedRelations = {
|
|
9
|
+
relation: Relation;
|
|
10
|
+
targetTableName: string;
|
|
11
|
+
/**
|
|
12
|
+
* Property names of the target table's primary key, resolved at build time (composite
|
|
13
|
+
* keys included, via the dialect's getTableConfig). Used to default paginated relations
|
|
14
|
+
* to a deterministic PK order. Empty when the target has no detectable primary key.
|
|
15
|
+
*/
|
|
16
|
+
targetPkNames?: readonly string[];
|
|
17
|
+
};
|
|
7
18
|
type ColTypeIsNull<TColumn extends Column, TColType> = TColumn['_']['notNull'] extends true ? TColType : TColType | null;
|
|
8
19
|
type ColTypeIsNullOrUndefinedWithDefault<TColumn extends Column, TColType> = TColumn['_']['notNull'] extends true ? TColumn['_']['hasDefault'] extends true ? TColType | null | undefined : TColumn['defaultFn'] extends undefined ? TColType : TColType | null | undefined : TColType | null | undefined;
|
|
9
20
|
type GetColumnGqlDataType<TColumn extends Column> = TColumn['dataType'] extends 'boolean' ? ColTypeIsNull<TColumn, boolean> : TColumn['dataType'] extends 'json' ? TColumn['_']['columnType'] extends 'PgGeometryObject' ? ColTypeIsNull<TColumn, {
|
|
@@ -62,8 +73,83 @@ type OrderByArgs<TTable extends Table> = {
|
|
|
62
73
|
};
|
|
63
74
|
};
|
|
64
75
|
|
|
76
|
+
/**
|
|
77
|
+
* Extracts the join column info from a drizzle-orm v1 Relation object.
|
|
78
|
+
* Returns the JS property name of the local column on the parent table and the
|
|
79
|
+
* Column object for the foreign column on the target table, or undefined if the
|
|
80
|
+
* relation internals are not accessible.
|
|
81
|
+
*/
|
|
82
|
+
declare const extractRelationJoinColumns: (relEntry: TableNamedRelations, parentTable: Table, targetTable: Table) => {
|
|
83
|
+
localColPropName: string;
|
|
84
|
+
foreignCol: Column;
|
|
85
|
+
foreignColPropName: string;
|
|
86
|
+
} | undefined;
|
|
87
|
+
type RelationResolverFactory = (params: {
|
|
88
|
+
tableName: string;
|
|
89
|
+
relationName: string;
|
|
90
|
+
relEntry: TableNamedRelations;
|
|
91
|
+
isOne: boolean;
|
|
92
|
+
}) => GraphQLFieldResolver<any, any> | undefined;
|
|
93
|
+
/**
|
|
94
|
+
* Key on the GraphQL context object under which a caller can place a Drizzle transaction
|
|
95
|
+
* (or any other executor: a pooled connection, a logging proxy). Every generated resolver
|
|
96
|
+
* reads it at resolve time and runs its statements there instead of on the database the
|
|
97
|
+
* schema was built from, which is what lets several mutations in one request share a
|
|
98
|
+
* transaction and lets a query see that transaction's uncommitted rows:
|
|
99
|
+
*
|
|
100
|
+
* ```ts
|
|
101
|
+
* await db.transaction(async (tx) => {
|
|
102
|
+
* await graphql({ schema, source, contextValue: { [drizzleExecutorKey]: tx } });
|
|
103
|
+
* });
|
|
104
|
+
* ```
|
|
105
|
+
*
|
|
106
|
+
* Registered with `Symbol.for` so the ESM and CJS builds of this package agree on it when
|
|
107
|
+
* both end up loaded in one process.
|
|
108
|
+
*/
|
|
109
|
+
declare const drizzleExecutorKey: unique symbol;
|
|
110
|
+
/**
|
|
111
|
+
* Creates a RelationResolverFactory that generates field-level resolvers for each relation.
|
|
112
|
+
* Each resolver:
|
|
113
|
+
* 1. Returns pre-fetched data if the parent resolver already included it (eager path, zero cost).
|
|
114
|
+
* 2. When limit/offset args are present, falls back to a direct per-item query.
|
|
115
|
+
* 3. Otherwise batches all sibling resolver calls within the same GraphQL execution tick
|
|
116
|
+
* into a single IN-clause query, eliminating N+1 database round-trips.
|
|
117
|
+
*/
|
|
118
|
+
declare const createRelationResolverFactory: (db: any, tables: Record<string, Table>, filterCtx?: RelationFilterBase) => RelationResolverFactory;
|
|
65
119
|
declare const extractOrderBy: <TTable extends Table, TArgs extends OrderByArgs<any> = OrderByArgs<TTable>>(table: TTable, orderArgs: TArgs) => SQL[];
|
|
66
|
-
|
|
120
|
+
/**
|
|
121
|
+
* Everything `extractFilters` needs to turn a relation key in a `where` argument into a
|
|
122
|
+
* correlated subquery. Omitted by callers that don't generate relation filters, in which case
|
|
123
|
+
* relation keys can't appear in the input to begin with.
|
|
124
|
+
*/
|
|
125
|
+
interface RelationFilterContext {
|
|
126
|
+
/** Every table in the schema, keyed by its schema key. */
|
|
127
|
+
tables: Record<string, Table>;
|
|
128
|
+
/** Relations keyed by table schema key, then relation name. */
|
|
129
|
+
relationMap: Record<string, Record<string, TableNamedRelations>>;
|
|
130
|
+
/**
|
|
131
|
+
* Schema key of the table being filtered. Not always the same as the `tableName` label
|
|
132
|
+
* used in error messages (relation `where` callbacks pass the relation name there).
|
|
133
|
+
*/
|
|
134
|
+
tableKey: string;
|
|
135
|
+
/** Shared counter making every subquery alias unique within one extraction. */
|
|
136
|
+
aliases?: {
|
|
137
|
+
n: number;
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* The build-scoped half of {@link RelationFilterContext}. Created once per generated schema and
|
|
142
|
+
* handed to every resolver, which adds the table it is filtering.
|
|
143
|
+
*/
|
|
144
|
+
type RelationFilterBase = Pick<RelationFilterContext, 'tables' | 'relationMap'>;
|
|
145
|
+
declare const extractFilters: <TTable extends Table>(table: TTable, tableName: string, filters: Filters<TTable>, relationCtx?: RelationFilterContext) => SQL | undefined;
|
|
146
|
+
/**
|
|
147
|
+
* Default for `config.onError`: keeps drizzle-graphql's own errors, which are written for
|
|
148
|
+
* the client, and replaces driver/database errors with a generic message. Their text names
|
|
149
|
+
* tables, columns, constraints and offending values, none of which belongs in a response.
|
|
150
|
+
* The original is preserved on `originalError` for server-side logging.
|
|
151
|
+
*/
|
|
152
|
+
declare const defaultErrorMapper: (error: unknown) => unknown;
|
|
67
153
|
|
|
68
154
|
type Relations<TTable extends string = string, TConfig extends Record<string, Relation> = Record<string, Relation>> = {
|
|
69
155
|
table: {
|
|
@@ -108,6 +194,22 @@ type UpdateArgs<TTable extends Table> = Partial<{
|
|
|
108
194
|
set: GetRemappedTableUpdateDataType<TTable>;
|
|
109
195
|
where?: Filters<TTable>;
|
|
110
196
|
}>;
|
|
197
|
+
/**
|
|
198
|
+
* The `onConflict` argument of the generated upsert mutations.
|
|
199
|
+
*
|
|
200
|
+
* `target` and `where` exist on PostgreSQL and SQLite only: MySQL's
|
|
201
|
+
* `ON DUPLICATE KEY UPDATE` fires on whichever unique key was violated and takes no
|
|
202
|
+
* predicate, so neither field is generated there.
|
|
203
|
+
*/
|
|
204
|
+
type UpsertConflictArgs<TTable extends Table> = {
|
|
205
|
+
action?: 'UPDATE' | 'NOTHING';
|
|
206
|
+
target?: string[];
|
|
207
|
+
update?: string[];
|
|
208
|
+
where?: Filters<TTable>;
|
|
209
|
+
};
|
|
210
|
+
type UpsertArgs<TTable extends Table, isSingle extends boolean> = InsertArgs<TTable, isSingle> & {
|
|
211
|
+
onConflict?: UpsertConflictArgs<TTable>;
|
|
212
|
+
};
|
|
111
213
|
type DeleteArgs<TTable extends Table> = {
|
|
112
214
|
where?: Filters<TTable>;
|
|
113
215
|
};
|
|
@@ -120,6 +222,18 @@ type SelectSingleResolver<TTable extends Table, TTables extends Record<string, T
|
|
|
120
222
|
type InsertResolver<TTable extends Table, IsReturnless extends boolean> = (source: any, args: Partial<InsertArgs<TTable, false>>, context: any, info: GraphQLResolveInfo) => Promise<IsReturnless extends false ? Array<GetRemappedTableDataType<TTable>> : MutationReturnlessResult>;
|
|
121
223
|
type InsertArrResolver<TTable extends Table, IsReturnless extends boolean> = (source: any, args: Partial<InsertArgs<TTable, true>>, context: any, info: GraphQLResolveInfo) => Promise<IsReturnless extends false ? GetRemappedTableDataType<TTable> | undefined : MutationReturnlessResult>;
|
|
122
224
|
type UpdateResolver<TTable extends Table, IsReturnless extends boolean> = (source: any, args: UpdateArgs<TTable>, context: any, info: GraphQLResolveInfo) => Promise<IsReturnless extends false ? GetRemappedTableDataType<TTable> | undefined : MutationReturnlessResult>;
|
|
225
|
+
/** Resolver for `upsert<Table>Single`. */
|
|
226
|
+
type UpsertResolver<TTable extends Table, IsReturnless extends boolean> = (source: any, args: Partial<UpsertArgs<TTable, true>>, context: any, info: GraphQLResolveInfo) => Promise<IsReturnless extends false ? GetRemappedTableDataType<TTable> | undefined : MutationReturnlessResult>;
|
|
227
|
+
/** Resolver for `upsert<Table>`. */
|
|
228
|
+
type UpsertArrResolver<TTable extends Table, IsReturnless extends boolean> = (source: any, args: Partial<UpsertArgs<TTable, false>>, context: any, info: GraphQLResolveInfo) => Promise<IsReturnless extends false ? Array<GetRemappedTableDataType<TTable>> : MutationReturnlessResult>;
|
|
229
|
+
/**
|
|
230
|
+
* Resolver for a table's generated aggregate query (`<plural>Aggregate`).
|
|
231
|
+
* Returns only the requested aggregations: `count` plus per-column `avg` / `sum`
|
|
232
|
+
* (numeric columns, as Float) and `min` / `max` (orderable columns, as the column's type).
|
|
233
|
+
*/
|
|
234
|
+
type AggregateResolver<TTable extends Table> = (source: any, args: {
|
|
235
|
+
where?: Filters<TTable>;
|
|
236
|
+
}, context: any, info: GraphQLResolveInfo) => Promise<Record<string, any>>;
|
|
123
237
|
type DeleteResolver<TTable extends Table, IsReturnless extends boolean> = (source: any, args: DeleteArgs<TTable>, context: any, info: GraphQLResolveInfo) => Promise<IsReturnless extends false ? GetRemappedTableDataType<TTable> | undefined : MutationReturnlessResult>;
|
|
124
238
|
type QueriesCore<TSchemaTables extends Record<string, Table>, TSchemaRelations extends Record<string, Relations>, TInputs extends Record<string, GraphQLInputObjectType>, TOutputs extends Record<string, GraphQLObjectType>> = {
|
|
125
239
|
[TName in keyof TSchemaTables as TName extends string ? `${Uncapitalize<TName>}` : never]: TName extends string ? {
|
|
@@ -137,6 +251,9 @@ type QueriesCore<TSchemaTables extends Record<string, Table>, TSchemaRelations e
|
|
|
137
251
|
where: {
|
|
138
252
|
type: TInputs[`${Capitalize<TName>}Filters`] extends GraphQLInputObjectType ? TInputs[`${Capitalize<TName>}Filters`] : never;
|
|
139
253
|
};
|
|
254
|
+
distinct: {
|
|
255
|
+
type: GraphQLList<GraphQLNonNull<GraphQLEnumType>>;
|
|
256
|
+
};
|
|
140
257
|
};
|
|
141
258
|
resolve: SelectResolver<TSchemaTables[TName], TSchemaTables, ExtractTableRelations<TSchemaTables[TName], TSchemaRelations> extends infer R ? R[keyof R] : never>;
|
|
142
259
|
} : never;
|
|
@@ -156,9 +273,19 @@ type QueriesCore<TSchemaTables extends Record<string, Table>, TSchemaRelations e
|
|
|
156
273
|
};
|
|
157
274
|
resolve: SelectSingleResolver<TSchemaTables[TName], TSchemaTables, ExtractTableRelations<TSchemaTables[TName], TSchemaRelations> extends infer R ? R[keyof R] : never>;
|
|
158
275
|
} : never;
|
|
276
|
+
} & {
|
|
277
|
+
[TName in keyof TSchemaTables as TName extends string ? `${Uncapitalize<TName>}Aggregate` : never]: TName extends string ? {
|
|
278
|
+
type: GraphQLNonNull<TOutputs[`${Capitalize<TName>}Aggregate`] extends GraphQLObjectType ? TOutputs[`${Capitalize<TName>}Aggregate`] : GraphQLObjectType>;
|
|
279
|
+
args: {
|
|
280
|
+
where: {
|
|
281
|
+
type: TInputs[`${Capitalize<TName>}Filters`] extends GraphQLInputObjectType ? TInputs[`${Capitalize<TName>}Filters`] : never;
|
|
282
|
+
};
|
|
283
|
+
};
|
|
284
|
+
resolve: AggregateResolver<TSchemaTables[TName]>;
|
|
285
|
+
} : never;
|
|
159
286
|
};
|
|
160
287
|
type MutationsCore<TSchemaTables extends Record<string, Table>, TInputs extends Record<string, GraphQLInputObjectType>, TOutputs extends Record<string, GraphQLObjectType>, IsReturnless extends boolean> = {
|
|
161
|
-
[TName in keyof TSchemaTables as TName extends string ? `
|
|
288
|
+
[TName in keyof TSchemaTables as TName extends string ? `create${Capitalize<TName>}` : never]: TName extends string ? {
|
|
162
289
|
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : GraphQLNonNull<GraphQLList<GraphQLNonNull<TOutputs[`${Capitalize<TName>}Item`]>>>;
|
|
163
290
|
args: {
|
|
164
291
|
values: {
|
|
@@ -168,7 +295,7 @@ type MutationsCore<TSchemaTables extends Record<string, Table>, TInputs extends
|
|
|
168
295
|
resolve: InsertArrResolver<TSchemaTables[TName], IsReturnless>;
|
|
169
296
|
} : never;
|
|
170
297
|
} & {
|
|
171
|
-
[TName in keyof TSchemaTables as TName extends string ? `
|
|
298
|
+
[TName in keyof TSchemaTables as TName extends string ? `create${Capitalize<TName>}Single` : never]: TName extends string ? {
|
|
172
299
|
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : TOutputs[`${Capitalize<TName>}Item`];
|
|
173
300
|
args: {
|
|
174
301
|
values: {
|
|
@@ -177,6 +304,32 @@ type MutationsCore<TSchemaTables extends Record<string, Table>, TInputs extends
|
|
|
177
304
|
};
|
|
178
305
|
resolve: InsertResolver<TSchemaTables[TName], IsReturnless>;
|
|
179
306
|
} : never;
|
|
307
|
+
} & {
|
|
308
|
+
[TName in keyof TSchemaTables as TName extends string ? `upsert${Capitalize<TName>}` : never]?: TName extends string ? {
|
|
309
|
+
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : GraphQLNonNull<GraphQLList<GraphQLNonNull<TOutputs[`${Capitalize<TName>}Item`]>>>;
|
|
310
|
+
args: {
|
|
311
|
+
values: {
|
|
312
|
+
type: GraphQLNonNull<GraphQLList<GraphQLNonNull<TInputs[`${Capitalize<TName>}InsertInput`]>>>;
|
|
313
|
+
};
|
|
314
|
+
onConflict: {
|
|
315
|
+
type: GraphQLInputObjectType;
|
|
316
|
+
};
|
|
317
|
+
};
|
|
318
|
+
resolve: UpsertArrResolver<TSchemaTables[TName], IsReturnless>;
|
|
319
|
+
} : never;
|
|
320
|
+
} & {
|
|
321
|
+
[TName in keyof TSchemaTables as TName extends string ? `upsert${Capitalize<TName>}Single` : never]?: TName extends string ? {
|
|
322
|
+
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : TOutputs[`${Capitalize<TName>}Item`];
|
|
323
|
+
args: {
|
|
324
|
+
values: {
|
|
325
|
+
type: GraphQLNonNull<TInputs[`${Capitalize<TName>}InsertInput`]>;
|
|
326
|
+
};
|
|
327
|
+
onConflict: {
|
|
328
|
+
type: GraphQLInputObjectType;
|
|
329
|
+
};
|
|
330
|
+
};
|
|
331
|
+
resolve: UpsertResolver<TSchemaTables[TName], IsReturnless>;
|
|
332
|
+
} : never;
|
|
180
333
|
} & {
|
|
181
334
|
[TName in keyof TSchemaTables as TName extends string ? `update${Capitalize<TName>}` : never]: TName extends string ? {
|
|
182
335
|
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : GraphQLNonNull<GraphQLList<GraphQLNonNull<TOutputs[`${Capitalize<TName>}Item`]>>>;
|
|
@@ -191,7 +344,7 @@ type MutationsCore<TSchemaTables extends Record<string, Table>, TInputs extends
|
|
|
191
344
|
resolve: UpdateResolver<TSchemaTables[TName], IsReturnless>;
|
|
192
345
|
} : never;
|
|
193
346
|
} & {
|
|
194
|
-
[TName in keyof TSchemaTables as TName extends string ? `
|
|
347
|
+
[TName in keyof TSchemaTables as TName extends string ? `delete${Capitalize<TName>}` : never]: TName extends string ? {
|
|
195
348
|
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : GraphQLNonNull<GraphQLList<GraphQLNonNull<TOutputs[`${Capitalize<TName>}Item`]>>>;
|
|
196
349
|
args: {
|
|
197
350
|
where: {
|
|
@@ -212,6 +365,8 @@ type GeneratedInputs<TSchema extends Record<string, Table>> = {
|
|
|
212
365
|
};
|
|
213
366
|
type GeneratedOutputs<TSchema extends Record<string, Table>, IsReturnless extends boolean> = {
|
|
214
367
|
[TName in keyof TSchema as TName extends string ? `${Capitalize<TName>}SelectItem` : never]: GraphQLObjectType;
|
|
368
|
+
} & {
|
|
369
|
+
[TName in keyof TSchema as TName extends string ? `${Capitalize<TName>}Aggregate` : never]: GraphQLObjectType;
|
|
215
370
|
} & (IsReturnless extends true ? {
|
|
216
371
|
MutationReturn: GraphQLObjectType;
|
|
217
372
|
} : {
|
|
@@ -222,11 +377,46 @@ type GeneratedEntities<TDatabase extends AnyDrizzleDB<TSchema>, TSchema extends
|
|
|
222
377
|
mutations: MutationsCore<TSchemaTables, TInputs, TOutputs, TDatabase extends MySqlDatabase<any, any, any, any> ? true : false>;
|
|
223
378
|
inputs: TInputs;
|
|
224
379
|
types: TOutputs;
|
|
380
|
+
/**
|
|
381
|
+
* Field-level resolvers for each relation on each table.
|
|
382
|
+
* Each resolver handles both the eager path (data pre-fetched by the parent query)
|
|
383
|
+
* and the lazy path (data fetched on demand with N+1 protection via request-scoped batching).
|
|
384
|
+
* Keyed as `fieldResolvers[tableSchemaKey][relationName]`.
|
|
385
|
+
*/
|
|
386
|
+
fieldResolvers: {
|
|
387
|
+
[TName in keyof TSchemaTables as TName extends string ? TName : never]?: Record<string, (source: any, args: any, context: any, info: GraphQLResolveInfo) => Promise<any>>;
|
|
388
|
+
};
|
|
225
389
|
};
|
|
226
390
|
type GeneratedData<TDatabase extends AnyDrizzleDB<any>> = {
|
|
227
391
|
schema: GraphQLSchema;
|
|
228
392
|
entities: GeneratedEntities<TDatabase>;
|
|
229
393
|
};
|
|
394
|
+
/**
|
|
395
|
+
* Per-feature switches for what `buildSchema` generates. Every flag defaults to `true`.
|
|
396
|
+
* See {@link BuildSchemaConfig.features}.
|
|
397
|
+
*/
|
|
398
|
+
type SchemaFeatures = {
|
|
399
|
+
/** `<plural>Aggregate` root queries and the aggregate output types. @default true */
|
|
400
|
+
aggregates?: boolean;
|
|
401
|
+
/** `<relation>Aggregate` fields on object types, for to-many relations. @default true */
|
|
402
|
+
relationAggregates?: boolean;
|
|
403
|
+
/** The `distinct` argument on list queries. @default true */
|
|
404
|
+
distinct?: boolean;
|
|
405
|
+
/** `create<Table>` / `create<Table>Single` mutations. @default true */
|
|
406
|
+
insert?: boolean;
|
|
407
|
+
/** `update<Table>` mutations. @default true */
|
|
408
|
+
update?: boolean;
|
|
409
|
+
/** `delete<Table>` mutations. @default true */
|
|
410
|
+
delete?: boolean;
|
|
411
|
+
/**
|
|
412
|
+
* `upsert<Table>` / `upsert<Table>Single` mutations — insert, or update the row that
|
|
413
|
+
* already holds the same unique key. Off unless asked for, so an existing schema does
|
|
414
|
+
* not grow new mutations on upgrade.
|
|
415
|
+
*
|
|
416
|
+
* @default false
|
|
417
|
+
*/
|
|
418
|
+
upsert?: boolean;
|
|
419
|
+
};
|
|
230
420
|
type BuildSchemaConfig = {
|
|
231
421
|
/**
|
|
232
422
|
* Determines whether generated mutations will be passed to returned schema.
|
|
@@ -237,29 +427,39 @@ type BuildSchemaConfig = {
|
|
|
237
427
|
*/
|
|
238
428
|
mutations?: boolean;
|
|
239
429
|
/**
|
|
240
|
-
* Limits depth of
|
|
430
|
+
* Limits depth of relation-field generation.
|
|
241
431
|
*
|
|
242
|
-
* Expects non-negative integer or undefined
|
|
432
|
+
* Expects a non-negative integer or `undefined`.
|
|
243
433
|
*
|
|
244
|
-
*
|
|
434
|
+
* `undefined` (default) — no limit; all relations are generated recursively
|
|
435
|
+
* until a cycle is detected.
|
|
245
436
|
*
|
|
246
|
-
*
|
|
437
|
+
* `0` — no relation fields are generated on any type. Useful for a flat,
|
|
438
|
+
* columns-only schema.
|
|
247
439
|
*
|
|
248
|
-
*
|
|
440
|
+
* `N > 0` — each table's own direct relations are still generated (every
|
|
441
|
+
* table's root type is processed at depth 0, which is always < N). The
|
|
442
|
+
* depth limit controls how deep the generation RECURSES when traversing
|
|
443
|
+
* related types; because all types share a single instance via the type
|
|
444
|
+
* cache, setting N > 0 currently behaves the same as `undefined` for the
|
|
445
|
+
* final schema shape. The principal useful values are `0` (no relations)
|
|
446
|
+
* and `undefined` (unlimited).
|
|
249
447
|
*/
|
|
250
448
|
relationsDepthLimit?: number;
|
|
251
449
|
/**
|
|
252
450
|
* Customizes query name prefixes for generated GraphQL operations.
|
|
253
451
|
*
|
|
254
|
-
* @default {
|
|
452
|
+
* @default { insert: 'create', delete: 'delete', update: 'update', upsert: 'upsert' }
|
|
255
453
|
*/
|
|
256
454
|
prefixes?: {
|
|
257
|
-
/** Prefix for insert mutations (e.g., 'users' -> '
|
|
455
|
+
/** Prefix for insert mutations (e.g., 'users' -> 'createUsers') */
|
|
258
456
|
insert?: string;
|
|
259
|
-
/** Prefix for delete mutations (e.g., 'users' -> '
|
|
457
|
+
/** Prefix for delete mutations (e.g., 'users' -> 'deleteUsers') */
|
|
260
458
|
delete?: string;
|
|
261
459
|
/** Prefix for update mutations (e.g., 'users' -> 'updateUsers') */
|
|
262
460
|
update?: string;
|
|
461
|
+
/** Prefix for upsert mutations (e.g., 'users' -> 'upsertUsers') */
|
|
462
|
+
upsert?: string;
|
|
263
463
|
};
|
|
264
464
|
/**
|
|
265
465
|
* Customizes query name suffixes for generated GraphQL operations.
|
|
@@ -275,17 +475,121 @@ type BuildSchemaConfig = {
|
|
|
275
475
|
/**
|
|
276
476
|
* When true, insert mutations will use onConflictDoNothing() to silently
|
|
277
477
|
* ignore duplicate key violations. Defaults to false (conflicts throw errors).
|
|
478
|
+
*
|
|
479
|
+
* PostgreSQL and SQLite only — MySQL's insert builder has no equivalent, so the flag is
|
|
480
|
+
* ignored there and conflicts keep throwing.
|
|
481
|
+
*
|
|
482
|
+
* @deprecated Build-wide and unconditional: a request cannot opt out of it, and a
|
|
483
|
+
* swallowed insert returns `null` with no indication why. Turn on `features.upsert` and
|
|
484
|
+
* pass `onConflict: { action: NOTHING }` per request instead. This flag keeps working
|
|
485
|
+
* until the next major.
|
|
278
486
|
*/
|
|
279
487
|
conflictDoNothing?: boolean;
|
|
280
488
|
/**
|
|
281
|
-
*
|
|
282
|
-
*
|
|
489
|
+
* Turns individual generated features off.
|
|
490
|
+
*
|
|
491
|
+
* Every flag defaults to `true` except `upsert`, which is opt-in: a build with no
|
|
492
|
+
* `features` block generates exactly what it generated before this option existed.
|
|
493
|
+
* Turning one off removes both the schema surface it adds and the work behind it.
|
|
494
|
+
*
|
|
495
|
+
* ```ts
|
|
496
|
+
* buildSchema(db, {
|
|
497
|
+
* features: {
|
|
498
|
+
* aggregates: false, // no `<plural>Aggregate` root queries
|
|
499
|
+
* relationAggregates: false, // no `<relation>Aggregate` fields on object types
|
|
500
|
+
* distinct: false, // no `distinct` argument on list queries
|
|
501
|
+
* delete: false, // no delete mutations
|
|
502
|
+
* upsert: true, // opt in to `upsert<Table>` mutations
|
|
503
|
+
* },
|
|
504
|
+
* });
|
|
505
|
+
* ```
|
|
506
|
+
*
|
|
507
|
+
* Turning off every mutation feature omits the `Mutation` type entirely, exactly as
|
|
508
|
+
* `mutations: false` does. Query-side features can all be off — the list and single
|
|
509
|
+
* queries are always generated, so `Query` is never empty.
|
|
510
|
+
*/
|
|
511
|
+
features?: SchemaFeatures;
|
|
512
|
+
/**
|
|
513
|
+
* Optional mapper from table key to singular/plural name pair.
|
|
514
|
+
* When provided for a table, overrides the default (table key) naming for GraphQL type names,
|
|
515
|
+
* query field names, and mutation field names.
|
|
516
|
+
* Return `undefined` for tables that should use the default naming.
|
|
283
517
|
*
|
|
284
|
-
*
|
|
518
|
+
* Example: `(name) => name === 'users' ? { singular: 'user', plural: 'users' } : undefined`
|
|
519
|
+
* produces type `User`, queries `users` / `user`, mutations `createUsers` / `createUser` for
|
|
520
|
+
* the `users` table, and leaves other tables with their default names.
|
|
285
521
|
*/
|
|
286
|
-
|
|
522
|
+
typeNameMapper?: (tableName: string) => {
|
|
523
|
+
singular: string;
|
|
524
|
+
plural: string;
|
|
525
|
+
} | undefined;
|
|
526
|
+
/**
|
|
527
|
+
* Controls whether a relation is eagerly pre-fetched via Drizzle's `with:` clause
|
|
528
|
+
* when its parent is loaded through a generated query or mutation.
|
|
529
|
+
*
|
|
530
|
+
* `true` (default) — every selected relation is eager-loaded in the parent's query.
|
|
531
|
+
*
|
|
532
|
+
* `false` — no relation is ever eager-loaded; all relations resolve lazily through
|
|
533
|
+
* their (request-batched) field resolvers.
|
|
534
|
+
*
|
|
535
|
+
* `(tableName, relationName) => boolean` — decide per relation. Return `false` to
|
|
536
|
+
* exclude that relation from `with:` (and from the mutation eager re-fetch).
|
|
537
|
+
*
|
|
538
|
+
* Opting a relation out does NOT remove its field resolver — it still resolves
|
|
539
|
+
* lazily via the request-scoped batch loader. This is the hook for overriding a
|
|
540
|
+
* relation's resolver (e.g. via `@graphql-tools/schema`'s `addResolversToSchema`)
|
|
541
|
+
* without the eager `with:` query also fetching it from the database:
|
|
542
|
+
*
|
|
543
|
+
* ```ts
|
|
544
|
+
* const { schema } = buildSchema(db, {
|
|
545
|
+
* eagerLoadRelations: (t, r) => !(t === 'Users' && r === 'posts'),
|
|
546
|
+
* });
|
|
547
|
+
* const finalSchema = addResolversToSchema({
|
|
548
|
+
* schema,
|
|
549
|
+
* resolvers: { Users: { posts: (parent) => myLoader.load(parent.id) } },
|
|
550
|
+
* });
|
|
551
|
+
* ```
|
|
552
|
+
*
|
|
553
|
+
* Table and relation names are the Drizzle schema keys (e.g. `Users`, `posts`),
|
|
554
|
+
* matching the keys of `entities.fieldResolvers`.
|
|
555
|
+
*
|
|
556
|
+
* @default true
|
|
557
|
+
*/
|
|
558
|
+
eagerLoadRelations?: boolean | ((tableName: string, relationName: string) => boolean);
|
|
559
|
+
/**
|
|
560
|
+
* Called for every error thrown by a generated resolver, before it reaches the client.
|
|
561
|
+
*
|
|
562
|
+
* Return an error to surface that one instead. Return nothing to fall through to the
|
|
563
|
+
* default handling, which makes this a pure logging hook:
|
|
564
|
+
*
|
|
565
|
+
* ```ts
|
|
566
|
+
* buildSchema(db, { onError: (error) => { logger.error(error) } })
|
|
567
|
+
* ```
|
|
568
|
+
*
|
|
569
|
+
* The default passes through errors drizzle-graphql raises itself (bad filter, missing
|
|
570
|
+
* values, invalid date, …) and replaces everything else — driver and database errors —
|
|
571
|
+
* with a generic `Internal server error`, keeping the original on `originalError` so it
|
|
572
|
+
* is still available to server-side logging. Database messages routinely name tables,
|
|
573
|
+
* columns, constraints and the values that violated them, which is not something a
|
|
574
|
+
* public API should hand back.
|
|
575
|
+
*
|
|
576
|
+
* To surface raw database errors instead (useful in development):
|
|
577
|
+
*
|
|
578
|
+
* ```ts
|
|
579
|
+
* buildSchema(db, { onError: (error) => error as Error })
|
|
580
|
+
* ```
|
|
581
|
+
*/
|
|
582
|
+
onError?: (error: unknown) => unknown;
|
|
287
583
|
};
|
|
288
584
|
|
|
585
|
+
/**
|
|
586
|
+
* A 64-bit integer. Always transported as a decimal string, in both directions, so no value
|
|
587
|
+
* is ever silently rounded by JSON's double-precision numbers. `graphql-scalars`' own
|
|
588
|
+
* `GraphQLBigInt` is deliberately not used: it emits numbers for safe integers and strings
|
|
589
|
+
* for everything else, so a client cannot know which it will get.
|
|
590
|
+
*/
|
|
591
|
+
declare const GraphQLBigIntString: GraphQLScalarType<string, string>;
|
|
592
|
+
|
|
289
593
|
declare const buildSchema: <TDbClient extends AnyDrizzleDB<any>>(db: TDbClient, config?: BuildSchemaConfig) => GeneratedData<TDbClient>;
|
|
290
594
|
|
|
291
|
-
export { type AnyDrizzleDB, type BuildSchemaConfig, type DeleteResolver, type ExtractRelations, type ExtractTableByName, type ExtractTableRelations, type ExtractTables, type GeneratedData, type GeneratedEntities, type GeneratedInputs, type GeneratedOutputs, type InsertArrResolver, type InsertResolver, type MutationReturnlessResult, type MutationsCore, type QueriesCore, type SelectResolver, type SelectSingleResolver, type UpdateResolver, buildSchema, extractFilters, extractOrderBy };
|
|
595
|
+
export { type AggregateResolver, type AnyDrizzleDB, type BuildSchemaConfig, type DeleteResolver, type ExtractRelations, type ExtractTableByName, type ExtractTableRelations, type ExtractTables, type GeneratedData, type GeneratedEntities, type GeneratedInputs, type GeneratedOutputs, GraphQLBigIntString, type InsertArrResolver, type InsertResolver, type MutationReturnlessResult, type MutationsCore, type QueriesCore, type RelationResolverFactory, type SchemaFeatures, type SelectResolver, type SelectSingleResolver, type TableNamedRelations, type UpdateResolver, type UpsertArgs, type UpsertArrResolver, type UpsertConflictArgs, type UpsertResolver, buildSchema, createRelationResolverFactory, defaultErrorMapper, drizzleExecutorKey, extractFilters, extractOrderBy, extractRelationJoinColumns };
|