@vantreeseba/drizzle-graphql 7.9.1 → 8.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 +270 -6
- package/dist/README.md +270 -6
- package/dist/index.cjs +6389 -7159
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +555 -263
- package/dist/index.d.ts +555 -263
- package/dist/index.js +6466 -7233
- package/dist/index.js.map +1 -1
- package/dist/package.json +2 -1
- package/package.json +2 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,11 +1,214 @@
|
|
|
1
|
-
import { Column, Table, Relation, SQL, One, Many } from 'drizzle-orm';
|
|
1
|
+
import { Column, Table, Relation, SQL, TablesRelationalConfig, 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 { GraphQLScalarType, GraphQLOutputType, GraphQLInputType, GraphQLFieldResolver, GraphQLResolveInfo, GraphQLSchema, GraphQLInputObjectType, GraphQLObjectType, GraphQLNonNull, GraphQLList, GraphQLEnumType } from 'graphql';
|
|
5
|
+
import { GraphQLError, GraphQLScalarType, GraphQLOutputType, GraphQLInputType, GraphQLFieldResolver, GraphQLResolveInfo, GraphQLSchema, GraphQLInputObjectType, GraphQLObjectType, GraphQLNonNull, GraphQLList, GraphQLEnumType } from 'graphql';
|
|
6
6
|
import { ResolveTree } from 'graphql-parse-resolve-info';
|
|
7
7
|
export { GraphQLDate, GraphQLDateTime, GraphQLJSON, GraphQLUUID } from 'graphql-scalars';
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* The identity a generated field publishes about itself, under `extensions.drizzle`.
|
|
11
|
+
*
|
|
12
|
+
* Every field this library generates carries one, so a wrapper — `graphql-middleware`,
|
|
13
|
+
* envelop, `graphql-shield`, an audit log, a cache invalidator — can ask the schema what a
|
|
14
|
+
* field is instead of reverse-engineering its name. Names are configurable (`prefixes`,
|
|
15
|
+
* `suffixes`, `typeNameMapper`), so name parsing is ambiguous by construction; this is not.
|
|
16
|
+
*
|
|
17
|
+
* This shape is stable API: fields are only ever added to it, never removed or repurposed.
|
|
18
|
+
*/
|
|
19
|
+
/** What family of field this is. */
|
|
20
|
+
type DrizzleFieldKind = 'query' | 'mutation' | 'relation' | 'aggregate' | 'type';
|
|
21
|
+
/**
|
|
22
|
+
* What the field does. Arity is carried separately by `single`, so `select` covers both
|
|
23
|
+
* the list query and its `…Single` sibling rather than being spelled twice.
|
|
24
|
+
*/
|
|
25
|
+
type DrizzleFieldOperation = 'select' | 'insert' | 'update' | 'updateMany' | 'upsert' | 'delete' | 'restore' | 'aggregate' | 'groupBy' | 'relation' | 'relationAggregate';
|
|
26
|
+
/** The argument holding the rows a field is about, when it has one. */
|
|
27
|
+
type DrizzleTargetArg = 'where' | 'values' | 'updates';
|
|
28
|
+
/** `extensions.drizzle` on a generated field. */
|
|
29
|
+
type DrizzleFieldExtension = {
|
|
30
|
+
/** The Drizzle schema key of the table the field reads or writes. */
|
|
31
|
+
table: string;
|
|
32
|
+
kind: Exclude<DrizzleFieldKind, 'type'>;
|
|
33
|
+
operation: DrizzleFieldOperation;
|
|
34
|
+
/** Whether the field resolves to one row (or one aggregate) rather than a list. */
|
|
35
|
+
single: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Which argument names the rows: `where` for select/update/delete/aggregate, `values`
|
|
38
|
+
* for insert and upsert, `updates` for the batch update's per-entry `{ where, set }`.
|
|
39
|
+
* Absent when the field takes no such argument.
|
|
40
|
+
*/
|
|
41
|
+
targetArg?: DrizzleTargetArg;
|
|
42
|
+
/**
|
|
43
|
+
* Primary-key property names of `table`, in schema order. Empty when the table declares
|
|
44
|
+
* no primary key. Carried here so {@link identifyRows} works from the field alone.
|
|
45
|
+
*/
|
|
46
|
+
primaryKey: readonly string[];
|
|
47
|
+
/**
|
|
48
|
+
* For `operation: 'delete'` on a soft-deleting table that opted into `hardDelete`: the
|
|
49
|
+
* field takes a `hard` argument that issues a real `DELETE` rather than writing the marker.
|
|
50
|
+
* Absent everywhere else, so a wrapper can gate purging without parsing arguments.
|
|
51
|
+
*/
|
|
52
|
+
hardDelete?: boolean;
|
|
53
|
+
/** For `kind: 'relation'` and `operation: 'relationAggregate'`: the relation's name. */
|
|
54
|
+
relation?: string;
|
|
55
|
+
/** For `kind: 'relation'` and `operation: 'relationAggregate'`: the table it hangs off. */
|
|
56
|
+
parentTable?: string;
|
|
57
|
+
};
|
|
58
|
+
/** `extensions.drizzle` on a generated object type. */
|
|
59
|
+
type DrizzleTypeExtension = {
|
|
60
|
+
/** The Drizzle schema key this type was generated from. */
|
|
61
|
+
table: string;
|
|
62
|
+
kind: 'type';
|
|
63
|
+
/** Primary-key property names of `table`, in schema order. Empty when there is none. */
|
|
64
|
+
primaryKey: readonly string[];
|
|
65
|
+
};
|
|
66
|
+
type DrizzleExtension = DrizzleFieldExtension | DrizzleTypeExtension;
|
|
67
|
+
/** Anything carrying GraphQL `extensions` — a field config, a field, or a named type. */
|
|
68
|
+
type WithExtensions = {
|
|
69
|
+
extensions?: {
|
|
70
|
+
drizzle?: unknown;
|
|
71
|
+
} | null;
|
|
72
|
+
} | null | undefined;
|
|
73
|
+
/**
|
|
74
|
+
* Reads the `drizzle` extension off a field or type, typed. Returns `undefined` for
|
|
75
|
+
* anything this library did not generate, which is the check a wrapper wants before it
|
|
76
|
+
* treats a field as one of ours.
|
|
77
|
+
*/
|
|
78
|
+
declare const drizzleExtension: (target: WithExtensions) => DrizzleExtension | undefined;
|
|
79
|
+
/** Narrows to the field form — object types carry `kind: 'type'` and no operation. */
|
|
80
|
+
declare const isDrizzleFieldExtension: (value: DrizzleExtension | undefined) => value is DrizzleFieldExtension;
|
|
81
|
+
/** The rows a field's arguments name. */
|
|
82
|
+
type IdentifiedRows = {
|
|
83
|
+
/** The Drizzle schema key of the table being read or written. */
|
|
84
|
+
table: string;
|
|
85
|
+
/** Primary-key property names, in schema order. */
|
|
86
|
+
primaryKey: readonly string[];
|
|
87
|
+
/** One entry per identified row: the primary-key values, keyed by property name. */
|
|
88
|
+
rows: Record<string, unknown>[];
|
|
89
|
+
/**
|
|
90
|
+
* Whether `rows` is exactly the set the operation affects.
|
|
91
|
+
*
|
|
92
|
+
* `false` means the arguments do not pin the rows down — an insert whose key the
|
|
93
|
+
* database generates, a `where` that filters on something other than the primary key,
|
|
94
|
+
* a plural update with no filter at all, or a table with no primary key. `rows` is then
|
|
95
|
+
* a best-effort subset-free superset: every entry in it is a row the key values name,
|
|
96
|
+
* but other filters may narrow the real set further, and it may be empty.
|
|
97
|
+
*/
|
|
98
|
+
complete: boolean;
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* The rows a generated field's arguments are about, as primary-key values.
|
|
102
|
+
*
|
|
103
|
+
* The row identity of a mutation lives in a different argument for every operation —
|
|
104
|
+
* `where` for update and delete, `values` for insert and upsert, a per-entry `where` inside
|
|
105
|
+
* `updates` for the batch update — and each of those has both a one-row and a many-row
|
|
106
|
+
* spelling. This reads whichever one applies:
|
|
107
|
+
*
|
|
108
|
+
* ```ts
|
|
109
|
+
* const field = info.parentType.getFields()[info.fieldName];
|
|
110
|
+
* const target = identifyRows(field, args);
|
|
111
|
+
* if (target?.complete) await invalidate(target.table, target.rows);
|
|
112
|
+
* ```
|
|
113
|
+
*
|
|
114
|
+
* Returns `undefined` for a field this library did not generate, or an object type. Check
|
|
115
|
+
* `complete` before treating `rows` as the affected set — see {@link IdentifiedRows}.
|
|
116
|
+
*/
|
|
117
|
+
declare const identifyRows: (field: WithExtensions, args: Record<string, unknown> | undefined) => IdentifiedRows | undefined;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* The classification of an error drizzle-graphql raised itself, published as
|
|
121
|
+
* `extensions.code`. A consumer maps these onto its own vocabulary; the prose is written for
|
|
122
|
+
* a client to read and may be reworded in any release, so it is not something to match on.
|
|
123
|
+
*/
|
|
124
|
+
type DrizzleErrorCode =
|
|
125
|
+
/** A `Single` write's `where` matched more than one row, so nothing was written. */
|
|
126
|
+
'DRIZZLE_MULTI_ROW_MATCH'
|
|
127
|
+
/** A write that refuses to run unbounded was given no `where`, or one matching every row. */
|
|
128
|
+
| 'DRIZZLE_WHERE_REQUIRED'
|
|
129
|
+
/** The requested `limit` is above the maximum the field's limit policy allows. */
|
|
130
|
+
| 'DRIZZLE_LIMIT_EXCEEDED'
|
|
131
|
+
/** A write's `values` / `set` carried nothing to write. */
|
|
132
|
+
| 'DRIZZLE_NO_VALUES'
|
|
133
|
+
/** An insert reported no row back, so there is nothing to return or attach. */
|
|
134
|
+
| 'DRIZZLE_NO_ROW_RETURNED'
|
|
135
|
+
/** The driver reported no row count for a returnless write. */
|
|
136
|
+
| 'DRIZZLE_ROW_COUNT_UNAVAILABLE'
|
|
137
|
+
/** A nested write was passed to a field that cannot run one. */
|
|
138
|
+
| 'DRIZZLE_NESTED_WRITES_UNSUPPORTED'
|
|
139
|
+
/** A nested `create` / `connect` / `disconnect` / `set` operand was not usable. */
|
|
140
|
+
| 'DRIZZLE_NESTED_WRITE_INVALID'
|
|
141
|
+
/** A `groupBy` named no column, or one that cannot be grouped by. */
|
|
142
|
+
| 'DRIZZLE_INVALID_GROUP_BY'
|
|
143
|
+
/** An `after` cursor did not decode, or was issued for a different ordering. */
|
|
144
|
+
| 'DRIZZLE_INVALID_CURSOR'
|
|
145
|
+
/** A `where` key was not a filter of the table, or a relation was used as one. */
|
|
146
|
+
| 'DRIZZLE_INVALID_FILTER'
|
|
147
|
+
/** A column's update operations input held none, or more than one. */
|
|
148
|
+
| 'DRIZZLE_INVALID_UPDATE_OPERATION'
|
|
149
|
+
/** A configured `scope` hook returned something that is not a predicate. */
|
|
150
|
+
| 'DRIZZLE_INVALID_SCOPE'
|
|
151
|
+
/** An `orderBy` named something that cannot be ordered by in this query. */
|
|
152
|
+
| 'DRIZZLE_INVALID_ORDER_BY'
|
|
153
|
+
/** `distinct` was asked for where it cannot be applied. */
|
|
154
|
+
| 'DRIZZLE_INVALID_DISTINCT'
|
|
155
|
+
/** An `onConflict` named a target or update column the upsert cannot use. */
|
|
156
|
+
| 'DRIZZLE_INVALID_ON_CONFLICT'
|
|
157
|
+
/** The request's shared mutation transaction was rolled back, so this field never ran. */
|
|
158
|
+
| 'DRIZZLE_TRANSACTION_ABORTED';
|
|
159
|
+
/**
|
|
160
|
+
* What an error was about, published as `extensions.drizzle` beside the code — the runtime
|
|
161
|
+
* half of the `extensions.drizzle` markers a generated field carries.
|
|
162
|
+
*
|
|
163
|
+
* `field` is the **generated** field name, which is why it is data rather than prose: a build
|
|
164
|
+
* that republishes these fields under other names (`RenameRootFields`, a stitched gateway, a
|
|
165
|
+
* hand-written façade) would otherwise be telling a client about a field it has never heard
|
|
166
|
+
* of. The name the client asked for is already in the error's `path`.
|
|
167
|
+
*/
|
|
168
|
+
type DrizzleErrorContext = {
|
|
169
|
+
/** The Drizzle schema key of the table the field reads or writes. */
|
|
170
|
+
table?: string;
|
|
171
|
+
operation?: DrizzleFieldOperation;
|
|
172
|
+
/** The generated field's own name, pre-rename. */
|
|
173
|
+
field?: string;
|
|
174
|
+
/** For a relation field: the relation's name. */
|
|
175
|
+
relation?: string;
|
|
176
|
+
};
|
|
177
|
+
/**
|
|
178
|
+
* A `GraphQLError` carrying its context as data. The message says what went wrong, in prose
|
|
179
|
+
* meant for a client; `extensions.code` classifies it and `extensions.drizzle` says which
|
|
180
|
+
* table, operation and generated field it came from.
|
|
181
|
+
*/
|
|
182
|
+
declare const drizzleError: (message: string, { code, ...context }: DrizzleErrorContext & {
|
|
183
|
+
code: DrizzleErrorCode;
|
|
184
|
+
}) => GraphQLError;
|
|
185
|
+
/**
|
|
186
|
+
* Default for `config.onError`: keeps drizzle-graphql's own errors, which are written for
|
|
187
|
+
* the client, and replaces driver/database errors with a generic message. Their text names
|
|
188
|
+
* tables, columns, constraints and offending values, none of which belongs in a response.
|
|
189
|
+
* The original is preserved on `originalError` for server-side logging.
|
|
190
|
+
*/
|
|
191
|
+
declare const defaultErrorMapper: (error: unknown) => unknown;
|
|
192
|
+
|
|
193
|
+
/** {@link BuildSchemaConfig.limits} resolved for one table. `undefined` means no policy. */
|
|
194
|
+
type ResolvedLimitPolicy = {
|
|
195
|
+
defaultLimit: number | undefined;
|
|
196
|
+
maxLimit: number | undefined;
|
|
197
|
+
clampToMax: boolean;
|
|
198
|
+
};
|
|
199
|
+
/**
|
|
200
|
+
* Looks up the limit policy for a table by its Drizzle schema key. Built once per schema by
|
|
201
|
+
* `buildSchema`; `undefined` for a table the caller left unbounded.
|
|
202
|
+
*/
|
|
203
|
+
type LimitPolicyFor = (tableName: string) => ResolvedLimitPolicy | undefined;
|
|
204
|
+
/**
|
|
205
|
+
* {@link BuildSchemaConfig.defaults} resolved for one table: the `orderBy` a read falls back
|
|
206
|
+
* to when the request passes none, already in the shape the generated argument has.
|
|
207
|
+
* `undefined` means the table declares no default and keeps whatever order the database
|
|
208
|
+
* returns.
|
|
209
|
+
*/
|
|
210
|
+
type DefaultOrderByFor = (tableName: string) => Record<string, any> | undefined;
|
|
211
|
+
|
|
9
212
|
/**
|
|
10
213
|
* A scalar override for one column. A bare scalar applies to both directions; the object form
|
|
11
214
|
* lets output (object type, aggregate min/max) and input (create/update inputs, filter operands)
|
|
@@ -171,6 +374,12 @@ type FilterColumnOperatorsCore<TColumn extends Column, TColType = GetColumnGqlDa
|
|
|
171
374
|
isEmpty: boolean;
|
|
172
375
|
isNull: boolean;
|
|
173
376
|
isNotNull: boolean;
|
|
377
|
+
/**
|
|
378
|
+
* String columns: compares every operator in this object case-insensitively
|
|
379
|
+
* (`lower(column)` against `lower(operand)`). Applies to the operators beside it only —
|
|
380
|
+
* a nested `AND`/`OR`/`NOT` branch sets its own.
|
|
381
|
+
*/
|
|
382
|
+
insensitive: boolean;
|
|
174
383
|
}>;
|
|
175
384
|
type FiltersCore<TTable extends Table> = Partial<{
|
|
176
385
|
[Column in keyof TTable['_']['columns']]: FilterColumnOperatorsCore<TTable['_']['columns'][Column]>;
|
|
@@ -198,133 +407,55 @@ type OrderByArgs<TTable extends Table> = {
|
|
|
198
407
|
};
|
|
199
408
|
};
|
|
200
409
|
|
|
201
|
-
/** Optional mapper from table key to singular/plural name pair. Return undefined to use default naming for a table. */
|
|
202
|
-
type TypeNameMapper = (tableName: string) => {
|
|
203
|
-
singular: string;
|
|
204
|
-
plural: string;
|
|
205
|
-
} | undefined;
|
|
206
410
|
/**
|
|
207
|
-
*
|
|
208
|
-
*
|
|
209
|
-
* Column object for the foreign column on the target table, or undefined if the
|
|
210
|
-
* relation internals are not accessible.
|
|
211
|
-
*/
|
|
212
|
-
declare const extractRelationJoinColumns: (relEntry: TableNamedRelations, parentTable: Table, targetTable: Table) => {
|
|
213
|
-
localColPropName: string;
|
|
214
|
-
foreignCol: Column;
|
|
215
|
-
foreignColPropName: string;
|
|
216
|
-
} | undefined;
|
|
217
|
-
type RelationResolverFactory = (params: {
|
|
218
|
-
tableName: string;
|
|
219
|
-
relationName: string;
|
|
220
|
-
relEntry: TableNamedRelations;
|
|
221
|
-
isOne: boolean;
|
|
222
|
-
}) => GraphQLFieldResolver<any, any> | undefined;
|
|
223
|
-
/**
|
|
224
|
-
* Key on the GraphQL context object under which a caller can place a Drizzle transaction
|
|
225
|
-
* (or any other executor: a pooled connection, a logging proxy). Every generated resolver
|
|
226
|
-
* reads it at resolve time and runs its statements there instead of on the database the
|
|
227
|
-
* schema was built from, which is what lets several mutations in one request share a
|
|
228
|
-
* transaction and lets a query see that transaction's uncommitted rows:
|
|
229
|
-
*
|
|
230
|
-
* ```ts
|
|
231
|
-
* await db.transaction(async (tx) => {
|
|
232
|
-
* await graphql({ schema, source, contextValue: { [drizzleExecutorKey]: tx } });
|
|
233
|
-
* });
|
|
234
|
-
* ```
|
|
411
|
+
* What a generated type is, so a name mapper can answer for one kind without matching on the
|
|
412
|
+
* spelling of the default name.
|
|
235
413
|
*
|
|
236
|
-
*
|
|
237
|
-
*
|
|
414
|
+
* - `object` — a table's row type, the one `typeNameMapper` already names
|
|
415
|
+
* - `filter` / `listRelationFilter` — `<Type>Filters` and the `some`/`none`/`every` wrapper
|
|
416
|
+
* - `orderBy` — `<Type>OrderBy`
|
|
417
|
+
* - `createInput` / `updateInput` / `updateManyInput` / `nestedWriteInput` / `fieldUpdateInput`
|
|
418
|
+
* — the write inputs
|
|
419
|
+
* - `aggregate` — `<Type>Aggregate` and its per-operation children (`operation` names which)
|
|
420
|
+
* - `having` / `groupBy` / `groupKeys` — the group-by family
|
|
421
|
+
* - `onConflict` — the upsert's conflict input
|
|
422
|
+
* - `uniqueKey` — a compound unique constraint's key input
|
|
423
|
+
* - `columnEnum` — an enum naming a table's columns (`distinct`, conflict target, …)
|
|
424
|
+
* - `columnFilter` — a shared per-scalar filter (`StringFilter`, `IntFilter`, …), not per table
|
|
425
|
+
* - `shared` — everything else the build creates once (`OrderNulls`, `DeletedFilter`, …)
|
|
238
426
|
*/
|
|
239
|
-
|
|
240
|
-
/**
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
position: 'before' | 'after';
|
|
249
|
-
/** Whether the field writes a single row (`createUsersSingle`) or a list. */
|
|
250
|
-
single: boolean;
|
|
251
|
-
/** The field's GraphQL arguments, exactly as the resolver received them. */
|
|
252
|
-
args: any;
|
|
427
|
+
type GeneratedTypeKind = 'object' | 'filter' | 'listRelationFilter' | 'orderBy' | 'createInput' | 'updateInput' | 'updateManyInput' | 'nestedWriteInput' | 'fieldUpdateInput' | 'aggregate' | 'having' | 'groupBy' | 'groupKeys' | 'onConflict' | 'uniqueKey' | 'columnEnum' | 'columnFilter' | 'shared';
|
|
428
|
+
/** What a name mapper is told about the type it is being asked to name. */
|
|
429
|
+
interface GeneratedTypeInfo {
|
|
430
|
+
/** Which kind of generated type this is. */
|
|
431
|
+
kind: GeneratedTypeKind;
|
|
432
|
+
/** The name the library would use, before any prefix or suffix. */
|
|
433
|
+
defaultName: string;
|
|
434
|
+
/** The table key the type belongs to, where it belongs to one. */
|
|
435
|
+
table?: string;
|
|
253
436
|
/**
|
|
254
|
-
* The
|
|
255
|
-
*
|
|
256
|
-
*
|
|
437
|
+
* The narrower thing the type is for, where the kind alone does not say: the aggregate
|
|
438
|
+
* operation (`sum`, `avg`, …), the relation a nested-write input is for, the scalar a
|
|
439
|
+
* column filter covers, the columns of a unique key.
|
|
257
440
|
*/
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
info: any;
|
|
261
|
-
/** The executor the mutation itself ran on. Throwing from the hook rolls it back. */
|
|
262
|
-
tx: any;
|
|
263
|
-
};
|
|
264
|
-
type WriteHook = (payload: WriteHookPayload) => void | Promise<void>;
|
|
265
|
-
type WriteHookPositions = {
|
|
266
|
-
before?: WriteHook;
|
|
267
|
-
after?: WriteHook;
|
|
268
|
-
};
|
|
269
|
-
type WriteHooks = WriteHook | WriteHookPositions;
|
|
270
|
-
/** Resolved, per-field hooks: `undefined` when the table registered none. */
|
|
271
|
-
type ResolvedWriteHooks = {
|
|
272
|
-
before?: WriteHook;
|
|
273
|
-
after?: WriteHook;
|
|
274
|
-
};
|
|
275
|
-
/** Build-time lookup of a table's hooks, installed on {@link TablePolicies}. */
|
|
276
|
-
type WriteHookFor = (tableName: string, operation: WriteOperation) => ResolvedWriteHooks | undefined;
|
|
277
|
-
/**
|
|
278
|
-
* Creates a RelationResolverFactory that generates field-level resolvers for each relation.
|
|
279
|
-
* Each resolver:
|
|
280
|
-
* 1. Returns pre-fetched data if the parent resolver already included it (eager path, zero cost).
|
|
281
|
-
* 2. When limit/offset args are present, falls back to a direct per-item query.
|
|
282
|
-
* 3. Otherwise batches all sibling resolver calls within the same GraphQL execution tick
|
|
283
|
-
* into a single IN-clause query, eliminating N+1 database round-trips.
|
|
284
|
-
*
|
|
285
|
-
* `nullOrdering` is the dialect's native `ORDER BY` placement for `NULL` — the keyset
|
|
286
|
-
* predicate behind a relation's `after` argument has to match it, or rows with a `NULL` in an
|
|
287
|
-
* ordered column would be skipped instead of paged through. It has no sensible default, so
|
|
288
|
-
* each dialect builder states it: `'nulls-largest'` for PostgreSQL, `'nulls-smallest'` for
|
|
289
|
-
* MySQL and SQLite.
|
|
290
|
-
*/
|
|
291
|
-
declare const createRelationResolverFactory: (db: any, tables: Record<string, Table>, nullOrdering: NullOrdering, filterCtx?: RelationFilterBase, limits?: LimitPolicyFor, policies?: TablePolicies) => RelationResolverFactory;
|
|
292
|
-
/** {@link BuildSchemaConfig.limits} resolved for one table. `undefined` means no policy. */
|
|
293
|
-
type ResolvedLimitPolicy = {
|
|
294
|
-
defaultLimit: number | undefined;
|
|
295
|
-
maxLimit: number | undefined;
|
|
296
|
-
clampToMax: boolean;
|
|
297
|
-
};
|
|
298
|
-
/**
|
|
299
|
-
* Looks up the limit policy for a table by its Drizzle schema key. Built once per schema by
|
|
300
|
-
* `buildSchema`; `undefined` for a table the caller left unbounded.
|
|
301
|
-
*/
|
|
302
|
-
type LimitPolicyFor = (tableName: string) => ResolvedLimitPolicy | undefined;
|
|
441
|
+
operation?: string;
|
|
442
|
+
}
|
|
303
443
|
/**
|
|
304
|
-
*
|
|
305
|
-
*
|
|
306
|
-
*
|
|
307
|
-
* returns.
|
|
444
|
+
* Renames a generated type. Return `undefined` — or the same name — to keep the default,
|
|
445
|
+
* which is what an unlisted kind should do; anything returned is used verbatim, without the
|
|
446
|
+
* build's prefix or suffix.
|
|
308
447
|
*/
|
|
309
|
-
type
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
*
|
|
321
|
-
* An entry may instead set `matchFilterOrder`, which sorts by the column's position in the
|
|
322
|
-
* `inArray` list the same request's `where` gives it — `whereArgs` is that `where`.
|
|
323
|
-
*
|
|
324
|
-
* `ctx` supplies the tables and relation map that relation ordering needs; callers whose
|
|
325
|
-
* inputs cannot contain relation keys may omit it.
|
|
326
|
-
*/
|
|
327
|
-
declare const extractOrderBy: <TTable extends Table, TArgs extends OrderByArgs<any> = OrderByArgs<TTable>>(table: TTable, orderArgs: TArgs, ctx?: RelationFilterContext, whereArgs?: Record<string, any>) => SQL[];
|
|
448
|
+
type DerivedTypeNameMapper = (info: GeneratedTypeInfo) => string | undefined;
|
|
449
|
+
|
|
450
|
+
/** Optional mapper from table key to singular/plural name pair. Return undefined to use default naming for a table. */
|
|
451
|
+
type TypeNameMapper = (tableName: string) => {
|
|
452
|
+
singular: string;
|
|
453
|
+
plural: string;
|
|
454
|
+
} | undefined;
|
|
455
|
+
|
|
456
|
+
/** A table's unique-key `where` fields: field name → the constraint's member property names. */
|
|
457
|
+
type UniqueKeyMap = Record<string, readonly string[]>;
|
|
458
|
+
|
|
328
459
|
/**
|
|
329
460
|
* Everything `extractFilters` needs to turn a relation key in a `where` argument into a
|
|
330
461
|
* correlated subquery. Omitted by callers that don't generate relation filters, in which case
|
|
@@ -344,13 +475,58 @@ interface RelationFilterContext {
|
|
|
344
475
|
aliases?: {
|
|
345
476
|
n: number;
|
|
346
477
|
};
|
|
478
|
+
/**
|
|
479
|
+
* The compound-unique-key `where` fields of each table, keyed by table schema key. Only
|
|
480
|
+
* populated when `features.uniqueKeyFilters` generated them — a key field the build did not
|
|
481
|
+
* generate is an unknown filter key like any other.
|
|
482
|
+
*/
|
|
483
|
+
uniqueKeys?: Record<string, UniqueKeyMap>;
|
|
347
484
|
}
|
|
348
485
|
/**
|
|
349
486
|
* The build-scoped half of {@link RelationFilterContext}. Created once per generated schema and
|
|
350
487
|
* handed to every resolver, which adds the table it is filtering.
|
|
351
488
|
*/
|
|
352
|
-
type RelationFilterBase = Pick<RelationFilterContext, 'tables' | 'relationMap'>;
|
|
489
|
+
type RelationFilterBase = Pick<RelationFilterContext, 'tables' | 'relationMap' | 'uniqueKeys'>;
|
|
353
490
|
declare const extractFilters: <TTable extends Table>(table: TTable, tableName: string, filters: Filters<TTable>, relationCtx?: RelationFilterContext) => SQL | undefined;
|
|
491
|
+
|
|
492
|
+
/** The write a hook is attached to. `restore` only exists for a soft-deleting table. */
|
|
493
|
+
type WriteOperation = 'insert' | 'update' | 'updateMany' | 'upsert' | 'delete' | 'restore';
|
|
494
|
+
/** What a write hook is handed. See {@link BuildSchemaConfig.onWrite}. */
|
|
495
|
+
type WriteHookPayload = {
|
|
496
|
+
/** Drizzle schema key of the table being written. */
|
|
497
|
+
table: string;
|
|
498
|
+
operation: WriteOperation;
|
|
499
|
+
/** `'before'` runs ahead of the statement, `'after'` once it has returned. */
|
|
500
|
+
position: 'before' | 'after';
|
|
501
|
+
/** Whether the field writes a single row (`createUsersSingle`) or a list. */
|
|
502
|
+
single: boolean;
|
|
503
|
+
/** The field's GraphQL arguments, exactly as the resolver received them. */
|
|
504
|
+
args: any;
|
|
505
|
+
/**
|
|
506
|
+
* The rows the write produced, as the database returned them — before the output mapper,
|
|
507
|
+
* so values are database-shaped. Empty at the `before` position, and on MySQL, whose
|
|
508
|
+
* mutations return no rows.
|
|
509
|
+
*/
|
|
510
|
+
rows: any[];
|
|
511
|
+
context: any;
|
|
512
|
+
info: any;
|
|
513
|
+
/** The executor the mutation itself ran on. Throwing from the hook rolls it back. */
|
|
514
|
+
tx: any;
|
|
515
|
+
};
|
|
516
|
+
type WriteHook = (payload: WriteHookPayload) => void | Promise<void>;
|
|
517
|
+
type WriteHookPositions = {
|
|
518
|
+
before?: WriteHook;
|
|
519
|
+
after?: WriteHook;
|
|
520
|
+
};
|
|
521
|
+
type WriteHooks = WriteHook | WriteHookPositions;
|
|
522
|
+
/** Resolved, per-field hooks: `undefined` when the table registered none. */
|
|
523
|
+
type ResolvedWriteHooks = {
|
|
524
|
+
before?: WriteHook;
|
|
525
|
+
after?: WriteHook;
|
|
526
|
+
};
|
|
527
|
+
/** Build-time lookup of a table's hooks, installed on {@link TablePolicies}. */
|
|
528
|
+
type WriteHookFor = (tableName: string, operation: WriteOperation) => ResolvedWriteHooks | undefined;
|
|
529
|
+
|
|
354
530
|
/**
|
|
355
531
|
* A table's row-level scope: the predicate every generated read, update and delete on that
|
|
356
532
|
* table is narrowed by. See `BuildSchemaConfig.scope`.
|
|
@@ -368,10 +544,11 @@ type ScopeFor = (tableName: string) => ScopeHook | undefined;
|
|
|
368
544
|
/**
|
|
369
545
|
* One table's soft-delete convention, resolved against the real column at build time.
|
|
370
546
|
*
|
|
371
|
-
* `
|
|
372
|
-
*
|
|
373
|
-
*
|
|
374
|
-
*
|
|
547
|
+
* `marker` picks the shape of the predicate. When the config names a constant that means
|
|
548
|
+
* deleted, the predicate compares against it (`isDeleted = true`); otherwise the column marks
|
|
549
|
+
* a row deleted by holding a value at all (`deletedAt IS NOT NULL`), the common timestamp
|
|
550
|
+
* form. A NOT NULL column has no "absent" state, so it must have a marker; a nullable one
|
|
551
|
+
* takes the NULL-means-alive reading only when no marker was configured.
|
|
375
552
|
*/
|
|
376
553
|
type SoftDeleteInfo = {
|
|
377
554
|
/** Property name of the column on the drizzle table — also the key on an aliased proxy. */
|
|
@@ -382,8 +559,22 @@ type SoftDeleteInfo = {
|
|
|
382
559
|
writeDeleted: () => any;
|
|
383
560
|
/** Written by the restore mutation. */
|
|
384
561
|
writeRestored: any;
|
|
385
|
-
/**
|
|
562
|
+
/**
|
|
563
|
+
* The constant that means "this row is deleted", when the config named one. Required on a
|
|
564
|
+
* NOT NULL column; optional on a nullable one, which otherwise reads NULL as alive.
|
|
565
|
+
*/
|
|
386
566
|
marker?: any;
|
|
567
|
+
/**
|
|
568
|
+
* Which reads hide marked rows by default — `'all'` (the table's own fields and every
|
|
569
|
+
* relation pointing at it) or `'root'` (its own fields only). See
|
|
570
|
+
* {@link relationDeletedDefault}.
|
|
571
|
+
*/
|
|
572
|
+
scope: 'root' | 'all';
|
|
573
|
+
/**
|
|
574
|
+
* Whether the delete mutations take a `hard` argument that issues a real `DELETE`. Off
|
|
575
|
+
* unless the table opts in, so the generated schema says which tables can be purged.
|
|
576
|
+
*/
|
|
577
|
+
hardDelete: boolean;
|
|
387
578
|
};
|
|
388
579
|
/** Build-time lookup: the soft-delete convention of a table, if it declares one. */
|
|
389
580
|
type SoftDeleteFor = (tableName: string) => SoftDeleteInfo | undefined;
|
|
@@ -409,6 +600,26 @@ type TablePolicies = {
|
|
|
409
600
|
/** See `BuildSchemaConfig.defaults`. */
|
|
410
601
|
defaultOrderBy?: DefaultOrderByFor;
|
|
411
602
|
};
|
|
603
|
+
|
|
604
|
+
/**
|
|
605
|
+
* Compiles an `orderBy` argument into ORDER BY expressions, highest priority first.
|
|
606
|
+
*
|
|
607
|
+
* A key naming one of the table's columns orders by that column. A key naming a to-one
|
|
608
|
+
* relation takes the target table's own OrderBy input and orders by the related row's
|
|
609
|
+
* column(s), compiled as a correlated scalar subquery — reusing the aliased-join machinery
|
|
610
|
+
* the relation filters are built on — so it works identically on all three dialects and
|
|
611
|
+
* inside the relational query builder's aliased CTEs. Priorities share one global space
|
|
612
|
+
* across relation boundaries. Each entry may also carry `nulls: first | last`
|
|
613
|
+
* (see {@link orderExpressions} for how MySQL emulates it).
|
|
614
|
+
*
|
|
615
|
+
* An entry may instead set `matchFilterOrder`, which sorts by the column's position in the
|
|
616
|
+
* `inArray` list the same request's `where` gives it — `whereArgs` is that `where`.
|
|
617
|
+
*
|
|
618
|
+
* `ctx` supplies the tables and relation map that relation ordering needs; callers whose
|
|
619
|
+
* inputs cannot contain relation keys may omit it.
|
|
620
|
+
*/
|
|
621
|
+
declare const extractOrderBy: <TTable extends Table, TArgs extends OrderByArgs<any> = OrderByArgs<TTable>>(table: TTable, orderArgs: TArgs, ctx?: RelationFilterContext, whereArgs?: Record<string, any>) => SQL[];
|
|
622
|
+
|
|
412
623
|
/**
|
|
413
624
|
* Where a dialect's default sort places NULLs relative to non-NULL values:
|
|
414
625
|
* - `nulls-largest` — PostgreSQL: NULLs sort as the largest values (last in ASC, first in DESC).
|
|
@@ -417,13 +628,58 @@ type TablePolicies = {
|
|
|
417
628
|
* The keyset predicate has to agree with the dialect's ORDER BY, so each builder passes its own.
|
|
418
629
|
*/
|
|
419
630
|
type NullOrdering = 'nulls-largest' | 'nulls-smallest';
|
|
631
|
+
|
|
420
632
|
/**
|
|
421
|
-
*
|
|
422
|
-
*
|
|
423
|
-
*
|
|
424
|
-
*
|
|
633
|
+
* Key on the GraphQL context object under which a caller can place a Drizzle transaction
|
|
634
|
+
* (or any other executor: a pooled connection, a logging proxy). Every generated resolver
|
|
635
|
+
* reads it at resolve time and runs its statements there instead of on the database the
|
|
636
|
+
* schema was built from, which is what lets several mutations in one request share a
|
|
637
|
+
* transaction and lets a query see that transaction's uncommitted rows:
|
|
638
|
+
*
|
|
639
|
+
* ```ts
|
|
640
|
+
* await db.transaction(async (tx) => {
|
|
641
|
+
* await graphql({ schema, source, contextValue: { [drizzleExecutorKey]: tx } });
|
|
642
|
+
* });
|
|
643
|
+
* ```
|
|
644
|
+
*
|
|
645
|
+
* Registered with `Symbol.for` so the ESM and CJS builds of this package agree on it when
|
|
646
|
+
* both end up loaded in one process.
|
|
425
647
|
*/
|
|
426
|
-
declare const
|
|
648
|
+
declare const drizzleExecutorKey: unique symbol;
|
|
649
|
+
|
|
650
|
+
/**
|
|
651
|
+
* Extracts the join column info from a drizzle-orm v1 Relation object.
|
|
652
|
+
* Returns the JS property name of the local column on the parent table and the
|
|
653
|
+
* Column object for the foreign column on the target table, or undefined if the
|
|
654
|
+
* relation internals are not accessible.
|
|
655
|
+
*/
|
|
656
|
+
declare const extractRelationJoinColumns: (relEntry: TableNamedRelations, parentTable: Table, targetTable: Table) => {
|
|
657
|
+
localColPropName: string;
|
|
658
|
+
foreignCol: Column;
|
|
659
|
+
foreignColPropName: string;
|
|
660
|
+
} | undefined;
|
|
661
|
+
type RelationResolverFactory = (params: {
|
|
662
|
+
tableName: string;
|
|
663
|
+
relationName: string;
|
|
664
|
+
relEntry: TableNamedRelations;
|
|
665
|
+
isOne: boolean;
|
|
666
|
+
}) => GraphQLFieldResolver<any, any> | undefined;
|
|
667
|
+
|
|
668
|
+
/**
|
|
669
|
+
* Creates a RelationResolverFactory that generates field-level resolvers for each relation.
|
|
670
|
+
* Each resolver:
|
|
671
|
+
* 1. Returns pre-fetched data if the parent resolver already included it (eager path, zero cost).
|
|
672
|
+
* 2. When limit/offset args are present, falls back to a direct per-item query.
|
|
673
|
+
* 3. Otherwise batches all sibling resolver calls within the same GraphQL execution tick
|
|
674
|
+
* into a single IN-clause query, eliminating N+1 database round-trips.
|
|
675
|
+
*
|
|
676
|
+
* `nullOrdering` is the dialect's native `ORDER BY` placement for `NULL` — the keyset
|
|
677
|
+
* predicate behind a relation's `after` argument has to match it, or rows with a `NULL` in an
|
|
678
|
+
* ordered column would be skipped instead of paged through. It has no sensible default, so
|
|
679
|
+
* each dialect builder states it: `'nulls-largest'` for PostgreSQL, `'nulls-smallest'` for
|
|
680
|
+
* MySQL and SQLite.
|
|
681
|
+
*/
|
|
682
|
+
declare const createRelationResolverFactory: (db: any, tables: Record<string, Table>, nullOrdering: NullOrdering, filterCtx?: RelationFilterBase, limits?: LimitPolicyFor, policies?: TablePolicies) => RelationResolverFactory;
|
|
427
683
|
|
|
428
684
|
type Relations<TTable extends string = string, TConfig extends Record<string, Relation> = Record<string, Relation>> = {
|
|
429
685
|
table: {
|
|
@@ -435,7 +691,19 @@ type Relations<TTable extends string = string, TConfig extends Record<string, Re
|
|
|
435
691
|
};
|
|
436
692
|
|
|
437
693
|
type AnyDrizzleDB<TSchema extends Record<string, any>> = PgAsyncDatabase<any, TSchema> | BaseSQLiteDatabase<any, any, TSchema> | MySqlDatabase<any, any, TSchema>;
|
|
438
|
-
|
|
694
|
+
/**
|
|
695
|
+
* The tables a database handle knows about, keyed by their schema key.
|
|
696
|
+
*
|
|
697
|
+
* Two shapes reach this type, because drizzle-orm v1 changed what a database's generic slot
|
|
698
|
+
* holds. SQLite and MySQL handles still carry the schema module itself, so the tables are
|
|
699
|
+
* picked out of it directly. PostgreSQL handles carry only the relations config built by
|
|
700
|
+
* `buildRelations` — a `Record<string, { table; name; relations }>` — so the tables are read
|
|
701
|
+
* off its `table` members instead. Without the second branch every PG-derived type collapses
|
|
702
|
+
* to `never`.
|
|
703
|
+
*/
|
|
704
|
+
type ExtractTables<TSchema extends Record<string, Table | unknown>> = TSchema extends TablesRelationalConfig ? {
|
|
705
|
+
[K in keyof TSchema]: TSchema[K]['table'] extends infer TTable extends Table ? TTable : never;
|
|
706
|
+
} : {
|
|
439
707
|
[K in keyof TSchema as TSchema[K] extends Table ? K : never]: TSchema[K] extends Table ? TSchema[K] : never;
|
|
440
708
|
};
|
|
441
709
|
type ExtractRelations<TSchema extends Record<string, Table | unknown>> = {
|
|
@@ -550,7 +818,7 @@ type DeleteResolver<TTable extends Table, IsReturnless extends boolean> = (sourc
|
|
|
550
818
|
type DeleteSingleResolver<TTable extends Table, IsReturnless extends boolean> = (source: any, args: DeleteSingleArgs<TTable>, context: any, info: GraphQLResolveInfo) => Promise<IsReturnless extends false ? GetRemappedTableDataType<TTable> | undefined : MutationReturnlessResult>;
|
|
551
819
|
type QueriesCore<TSchemaTables extends Record<string, Table>, TSchemaRelations extends Record<string, Relations>, TInputs extends Record<string, GraphQLInputObjectType>, TOutputs extends Record<string, GraphQLObjectType>> = {
|
|
552
820
|
[TName in keyof TSchemaTables as TName extends string ? `${Uncapitalize<TName>}` : never]: TName extends string ? {
|
|
553
|
-
type: GraphQLNonNull<GraphQLList<GraphQLNonNull<TOutputs[
|
|
821
|
+
type: GraphQLNonNull<GraphQLList<GraphQLNonNull<TOutputs[Capitalize<TName>]>>>;
|
|
554
822
|
args: {
|
|
555
823
|
offset: {
|
|
556
824
|
type: GraphQLScalarType<number, number>;
|
|
@@ -572,7 +840,7 @@ type QueriesCore<TSchemaTables extends Record<string, Table>, TSchemaRelations e
|
|
|
572
840
|
} : never;
|
|
573
841
|
} & {
|
|
574
842
|
[TName in keyof TSchemaTables as TName extends string ? `${Uncapitalize<TName>}Single` : never]: TName extends string ? {
|
|
575
|
-
type: TOutputs[
|
|
843
|
+
type: TOutputs[Capitalize<TName>];
|
|
576
844
|
args: {
|
|
577
845
|
offset: {
|
|
578
846
|
type: GraphQLScalarType<number, number>;
|
|
@@ -599,30 +867,30 @@ type QueriesCore<TSchemaTables extends Record<string, Table>, TSchemaRelations e
|
|
|
599
867
|
};
|
|
600
868
|
type MutationsCore<TSchemaTables extends Record<string, Table>, TInputs extends Record<string, GraphQLInputObjectType>, TOutputs extends Record<string, GraphQLObjectType>, IsReturnless extends boolean> = {
|
|
601
869
|
[TName in keyof TSchemaTables as TName extends string ? `create${Capitalize<TName>}` : never]: TName extends string ? {
|
|
602
|
-
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : GraphQLNonNull<GraphQLList<GraphQLNonNull<TOutputs[
|
|
870
|
+
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : GraphQLNonNull<GraphQLList<GraphQLNonNull<TOutputs[Capitalize<TName>]>>>;
|
|
603
871
|
args: {
|
|
604
872
|
values: {
|
|
605
|
-
type: GraphQLNonNull<GraphQLList<GraphQLNonNull<TInputs[
|
|
873
|
+
type: GraphQLNonNull<GraphQLList<GraphQLNonNull<TInputs[`Create${Capitalize<TName>}Input`]>>>;
|
|
606
874
|
};
|
|
607
875
|
};
|
|
608
876
|
resolve: InsertArrResolver<TSchemaTables[TName], IsReturnless>;
|
|
609
877
|
} : never;
|
|
610
878
|
} & {
|
|
611
879
|
[TName in keyof TSchemaTables as TName extends string ? `create${Capitalize<TName>}Single` : never]: TName extends string ? {
|
|
612
|
-
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : TOutputs[
|
|
880
|
+
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : TOutputs[Capitalize<TName>];
|
|
613
881
|
args: {
|
|
614
882
|
values: {
|
|
615
|
-
type: GraphQLNonNull<TInputs[
|
|
883
|
+
type: GraphQLNonNull<TInputs[`Create${Capitalize<TName>}Input`]>;
|
|
616
884
|
};
|
|
617
885
|
};
|
|
618
886
|
resolve: InsertResolver<TSchemaTables[TName], IsReturnless>;
|
|
619
887
|
} : never;
|
|
620
888
|
} & {
|
|
621
889
|
[TName in keyof TSchemaTables as TName extends string ? `upsert${Capitalize<TName>}` : never]?: TName extends string ? {
|
|
622
|
-
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : GraphQLNonNull<GraphQLList<GraphQLNonNull<TOutputs[
|
|
890
|
+
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : GraphQLNonNull<GraphQLList<GraphQLNonNull<TOutputs[Capitalize<TName>]>>>;
|
|
623
891
|
args: {
|
|
624
892
|
values: {
|
|
625
|
-
type: GraphQLNonNull<GraphQLList<GraphQLNonNull<TInputs[
|
|
893
|
+
type: GraphQLNonNull<GraphQLList<GraphQLNonNull<TInputs[`Create${Capitalize<TName>}Input`]>>>;
|
|
626
894
|
};
|
|
627
895
|
onConflict: {
|
|
628
896
|
type: GraphQLInputObjectType;
|
|
@@ -632,10 +900,10 @@ type MutationsCore<TSchemaTables extends Record<string, Table>, TInputs extends
|
|
|
632
900
|
} : never;
|
|
633
901
|
} & {
|
|
634
902
|
[TName in keyof TSchemaTables as TName extends string ? `upsert${Capitalize<TName>}Single` : never]?: TName extends string ? {
|
|
635
|
-
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : TOutputs[
|
|
903
|
+
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : TOutputs[Capitalize<TName>];
|
|
636
904
|
args: {
|
|
637
905
|
values: {
|
|
638
|
-
type: GraphQLNonNull<TInputs[
|
|
906
|
+
type: GraphQLNonNull<TInputs[`Create${Capitalize<TName>}Input`]>;
|
|
639
907
|
};
|
|
640
908
|
onConflict: {
|
|
641
909
|
type: GraphQLInputObjectType;
|
|
@@ -645,10 +913,10 @@ type MutationsCore<TSchemaTables extends Record<string, Table>, TInputs extends
|
|
|
645
913
|
} : never;
|
|
646
914
|
} & {
|
|
647
915
|
[TName in keyof TSchemaTables as TName extends string ? `update${Capitalize<TName>}` : never]: TName extends string ? {
|
|
648
|
-
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : GraphQLNonNull<GraphQLList<GraphQLNonNull<TOutputs[
|
|
916
|
+
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : GraphQLNonNull<GraphQLList<GraphQLNonNull<TOutputs[Capitalize<TName>]>>>;
|
|
649
917
|
args: {
|
|
650
918
|
set: {
|
|
651
|
-
type: GraphQLNonNull<TInputs[
|
|
919
|
+
type: GraphQLNonNull<TInputs[`Update${Capitalize<TName>}Input`]>;
|
|
652
920
|
};
|
|
653
921
|
where: {
|
|
654
922
|
type: TInputs[`${Capitalize<TName>}Filters`] extends GraphQLInputObjectType ? TInputs[`${Capitalize<TName>}Filters`] : never;
|
|
@@ -658,20 +926,20 @@ type MutationsCore<TSchemaTables extends Record<string, Table>, TInputs extends
|
|
|
658
926
|
} : never;
|
|
659
927
|
} & {
|
|
660
928
|
[TName in keyof TSchemaTables as TName extends string ? `update${Capitalize<TName>}Many` : never]: TName extends string ? {
|
|
661
|
-
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : GraphQLNonNull<GraphQLList<TOutputs[
|
|
929
|
+
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : GraphQLNonNull<GraphQLList<TOutputs[Capitalize<TName>]>>;
|
|
662
930
|
args: {
|
|
663
931
|
updates: {
|
|
664
|
-
type: GraphQLNonNull<GraphQLList<GraphQLNonNull<TInputs[
|
|
932
|
+
type: GraphQLNonNull<GraphQLList<GraphQLNonNull<TInputs[`Update${Capitalize<TName>}ManyInput`]>>>;
|
|
665
933
|
};
|
|
666
934
|
};
|
|
667
935
|
resolve: UpdateManyResolver<TSchemaTables[TName], IsReturnless>;
|
|
668
936
|
} : never;
|
|
669
937
|
} & {
|
|
670
938
|
[TName in keyof TSchemaTables as TName extends string ? `update${Capitalize<TName>}Single` : never]: TName extends string ? {
|
|
671
|
-
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : TOutputs[
|
|
939
|
+
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : TOutputs[Capitalize<TName>];
|
|
672
940
|
args: {
|
|
673
941
|
set: {
|
|
674
|
-
type: GraphQLNonNull<TInputs[
|
|
942
|
+
type: GraphQLNonNull<TInputs[`Update${Capitalize<TName>}Input`]>;
|
|
675
943
|
};
|
|
676
944
|
where: {
|
|
677
945
|
type: GraphQLNonNull<TInputs[`${Capitalize<TName>}Filters`] extends GraphQLInputObjectType ? TInputs[`${Capitalize<TName>}Filters`] : never>;
|
|
@@ -681,7 +949,7 @@ type MutationsCore<TSchemaTables extends Record<string, Table>, TInputs extends
|
|
|
681
949
|
} : never;
|
|
682
950
|
} & {
|
|
683
951
|
[TName in keyof TSchemaTables as TName extends string ? `delete${Capitalize<TName>}` : never]: TName extends string ? {
|
|
684
|
-
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : GraphQLNonNull<GraphQLList<GraphQLNonNull<TOutputs[
|
|
952
|
+
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : GraphQLNonNull<GraphQLList<GraphQLNonNull<TOutputs[Capitalize<TName>]>>>;
|
|
685
953
|
args: {
|
|
686
954
|
where: {
|
|
687
955
|
type: TInputs[`${Capitalize<TName>}Filters`] extends GraphQLInputObjectType ? TInputs[`${Capitalize<TName>}Filters`] : never;
|
|
@@ -691,7 +959,7 @@ type MutationsCore<TSchemaTables extends Record<string, Table>, TInputs extends
|
|
|
691
959
|
} : never;
|
|
692
960
|
} & {
|
|
693
961
|
[TName in keyof TSchemaTables as TName extends string ? `delete${Capitalize<TName>}Single` : never]: TName extends string ? {
|
|
694
|
-
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : TOutputs[
|
|
962
|
+
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : TOutputs[Capitalize<TName>];
|
|
695
963
|
args: {
|
|
696
964
|
where: {
|
|
697
965
|
type: GraphQLNonNull<TInputs[`${Capitalize<TName>}Filters`] extends GraphQLInputObjectType ? TInputs[`${Capitalize<TName>}Filters`] : never>;
|
|
@@ -700,25 +968,42 @@ type MutationsCore<TSchemaTables extends Record<string, Table>, TInputs extends
|
|
|
700
968
|
resolve: DeleteSingleResolver<TSchemaTables[TName], IsReturnless>;
|
|
701
969
|
} : never;
|
|
702
970
|
};
|
|
971
|
+
/**
|
|
972
|
+
* Keys of `entities.inputs`, which is keyed by generated GraphQL input type name.
|
|
973
|
+
*
|
|
974
|
+
* The write inputs are named from the configured `prefixes`, so these keys describe a build
|
|
975
|
+
* that uses the defaults (`insert: 'create'`, `update: 'update'`); a build that overrides a
|
|
976
|
+
* prefix produces correspondingly different keys. Inputs that only exist when a feature is
|
|
977
|
+
* enabled — `${Table}OnConflict` for upsert, `${Table}Having` for group-by — are not listed,
|
|
978
|
+
* since whether they were generated is a runtime decision.
|
|
979
|
+
*/
|
|
703
980
|
type GeneratedInputs<TSchema extends Record<string, Table>> = {
|
|
704
|
-
[TName in keyof TSchema as TName extends string ?
|
|
981
|
+
[TName in keyof TSchema as TName extends string ? `Create${Capitalize<TName>}Input` : never]: GraphQLInputObjectType;
|
|
705
982
|
} & {
|
|
706
|
-
[TName in keyof TSchema as TName extends string ?
|
|
983
|
+
[TName in keyof TSchema as TName extends string ? `Update${Capitalize<TName>}Input` : never]: GraphQLInputObjectType;
|
|
707
984
|
} & {
|
|
708
|
-
[TName in keyof TSchema as TName extends string ?
|
|
985
|
+
[TName in keyof TSchema as TName extends string ? `Update${Capitalize<TName>}ManyInput` : never]: GraphQLInputObjectType;
|
|
709
986
|
} & {
|
|
710
987
|
[TName in keyof TSchema as TName extends string ? `${Capitalize<TName>}OrderBy` : never]: GraphQLInputObjectType;
|
|
711
988
|
} & {
|
|
712
989
|
[TName in keyof TSchema as TName extends string ? `${Capitalize<TName>}Filters` : never]: GraphQLInputObjectType;
|
|
713
990
|
};
|
|
991
|
+
/**
|
|
992
|
+
* Keys of `entities.types`, which is keyed by generated GraphQL type name.
|
|
993
|
+
*
|
|
994
|
+
* This build emits ONE object type per table (`Users`) used for both selects and mutation
|
|
995
|
+
* returns — upstream drizzle-graphql emitted two (`UsersSelectItem` / `UsersItem`), and this
|
|
996
|
+
* type kept those names long after the generator stopped producing them. MySQL still has a
|
|
997
|
+
* shared `MutationReturn` instead of per-table return types, because its writes return no rows.
|
|
998
|
+
*/
|
|
714
999
|
type GeneratedOutputs<TSchema extends Record<string, Table>, IsReturnless extends boolean> = {
|
|
715
|
-
[TName in keyof TSchema as TName extends string ?
|
|
1000
|
+
[TName in keyof TSchema as TName extends string ? Capitalize<TName> : never]: GraphQLObjectType;
|
|
716
1001
|
} & {
|
|
717
1002
|
[TName in keyof TSchema as TName extends string ? `${Capitalize<TName>}Aggregate` : never]: GraphQLObjectType;
|
|
718
1003
|
} & (IsReturnless extends true ? {
|
|
719
1004
|
MutationReturn: GraphQLObjectType;
|
|
720
1005
|
} : {
|
|
721
|
-
[TName in keyof TSchema as TName extends string ?
|
|
1006
|
+
[TName in keyof TSchema as TName extends string ? Capitalize<TName> : never]: GraphQLObjectType;
|
|
722
1007
|
});
|
|
723
1008
|
type GeneratedEntities<TDatabase extends AnyDrizzleDB<TSchema>, TSchema extends Record<string, unknown> = TDatabase extends AnyDrizzleDB<infer ISchema> ? ISchema : never, TSchemaTables extends ExtractTables<TSchema> = ExtractTables<TSchema>, TSchemaRelations extends ExtractRelations<TSchema> = ExtractRelations<TSchema>, TInputs extends GeneratedInputs<TSchemaTables> = GeneratedInputs<TSchemaTables>, TOutputs extends GeneratedOutputs<TSchemaTables, TDatabase extends MySqlDatabase<any, any, any, any> ? true : false> = GeneratedOutputs<TSchemaTables, TDatabase extends MySqlDatabase<any, any, any, any> ? true : false>> = {
|
|
724
1009
|
queries: QueriesCore<TSchemaTables, TSchemaRelations, TInputs, TOutputs>;
|
|
@@ -750,7 +1035,8 @@ type GeneratedData<TDatabase extends AnyDrizzleDB<any>> = {
|
|
|
750
1035
|
type FeatureSwitch = boolean | ((tableName: string) => boolean);
|
|
751
1036
|
/**
|
|
752
1037
|
* Per-feature switches for what `buildSchema` generates. Every flag defaults to `true` except
|
|
753
|
-
* `upsert`, `nestedWrites`, `fieldUpdateOperations`, `countMutations` and
|
|
1038
|
+
* `upsert`, `nestedWrites`, `fieldUpdateOperations`, `countMutations`, `requireWhere` and
|
|
1039
|
+
* `uniqueKeyFilters`.
|
|
754
1040
|
* Each one takes a boolean or a per-table predicate, apart from `nestedWrites`, which is
|
|
755
1041
|
* build-wide.
|
|
756
1042
|
* See {@link BuildSchemaConfig.features}.
|
|
@@ -885,6 +1171,29 @@ type SchemaFeatures = {
|
|
|
885
1171
|
* @default false
|
|
886
1172
|
*/
|
|
887
1173
|
requireWhere?: FeatureSwitch;
|
|
1174
|
+
/**
|
|
1175
|
+
* One `where` field per compound unique constraint, so a lookup by a natural key names the
|
|
1176
|
+
* key instead of restating its columns:
|
|
1177
|
+
*
|
|
1178
|
+
* ```graphql
|
|
1179
|
+
* stockSingle(where: { itemId_locationId: { itemId: "i1", locationId: "l1" } }) { quantity }
|
|
1180
|
+
* ```
|
|
1181
|
+
*
|
|
1182
|
+
* The field is named after its member columns and every member is non-null, so a half-
|
|
1183
|
+
* supplied key fails query validation rather than becoming a broader filter that returns
|
|
1184
|
+
* whichever row happens to come first. It compiles to the same equalities the columns would
|
|
1185
|
+
* have — the guarantee is in the input type.
|
|
1186
|
+
*
|
|
1187
|
+
* Single-column constraints get no field (`eq` on the column already says it), and a
|
|
1188
|
+
* constraint whose field name is taken by a column or a relation is skipped. The fields live
|
|
1189
|
+
* on `<Type>Filters`, so they are accepted wherever a filter is: the `Single` reads and
|
|
1190
|
+
* writes they are meant for, but also list queries, relation filters and `onConflict.where`.
|
|
1191
|
+
*
|
|
1192
|
+
* Off unless asked for: it adds an input type per compound constraint.
|
|
1193
|
+
*
|
|
1194
|
+
* @default false
|
|
1195
|
+
*/
|
|
1196
|
+
uniqueKeyFilters?: FeatureSwitch;
|
|
888
1197
|
};
|
|
889
1198
|
/**
|
|
890
1199
|
* Per-field cost hints for `graphql-query-complexity` (or any estimator that reads
|
|
@@ -995,6 +1304,33 @@ type SoftDeleteColumn = string | {
|
|
|
995
1304
|
* for a NOT NULL boolean; required for any other NOT NULL column.
|
|
996
1305
|
*/
|
|
997
1306
|
restoredValue?: any;
|
|
1307
|
+
/**
|
|
1308
|
+
* Which generated reads hide marked rows by default.
|
|
1309
|
+
*
|
|
1310
|
+
* - `'all'` (the default) — the table's own query fields and every relation field that
|
|
1311
|
+
* points at it. A *required* to-one relation is the one exception: hiding the row
|
|
1312
|
+
* there can only produce "Cannot return null for non-nullable field", never a usable
|
|
1313
|
+
* result, so it reads `INCLUDE` unless the request says otherwise.
|
|
1314
|
+
* - `'root'` — only the table's own query fields. Relation fields read marked rows,
|
|
1315
|
+
* which is what "retired, not erased" usually means: keep the row off the pickers and
|
|
1316
|
+
* the lists, keep rendering it on the historical rows that reference it.
|
|
1317
|
+
*
|
|
1318
|
+
* The `deleted` argument is generated either way, so either default can be overridden
|
|
1319
|
+
* per request.
|
|
1320
|
+
*/
|
|
1321
|
+
scope?: 'root' | 'all';
|
|
1322
|
+
/**
|
|
1323
|
+
* Whether the table's delete mutations accept `hard: Boolean = false`, which issues a
|
|
1324
|
+
* real `DELETE` instead of writing the marker — emptying the trash, reclaiming a unique
|
|
1325
|
+
* key, clearing a table. Opt-in per table, and the argument is only generated when it is
|
|
1326
|
+
* on, so the schema itself says which tables can be purged.
|
|
1327
|
+
*
|
|
1328
|
+
* A hard delete reads at `INCLUDE`: it reaches already-marked rows, which is the case it
|
|
1329
|
+
* mostly exists for. A `scope` still confines it, exactly as it confines every other write.
|
|
1330
|
+
*
|
|
1331
|
+
* @default false
|
|
1332
|
+
*/
|
|
1333
|
+
hardDelete?: boolean;
|
|
998
1334
|
};
|
|
999
1335
|
|
|
1000
1336
|
/**
|
|
@@ -1466,6 +1802,58 @@ type BuildSchemaConfig = {
|
|
|
1466
1802
|
singular: string;
|
|
1467
1803
|
plural: string;
|
|
1468
1804
|
} | undefined);
|
|
1805
|
+
/**
|
|
1806
|
+
* Renames the types generated *around* a table — the filter, the write inputs, the
|
|
1807
|
+
* order-by, the aggregate family, the group-by types, the conflict input, the shared scalar
|
|
1808
|
+
* filters. `typeNameMapper` names a table's object type and its root fields; those derived
|
|
1809
|
+
* names follow from it by a fixed rule, and this is the hook that overrides the rule.
|
|
1810
|
+
*
|
|
1811
|
+
* Asked once per generated type, with the kind, the name the library would use, and the
|
|
1812
|
+
* table it belongs to where it belongs to one. Return `undefined` — or the same name — to
|
|
1813
|
+
* keep the default, so a mapper that answers for one kind leaves everything else alone:
|
|
1814
|
+
*
|
|
1815
|
+
* ```ts
|
|
1816
|
+
* buildSchema(db, {
|
|
1817
|
+
* derivedTypeNameMapper: ({ kind, table, operation, defaultName }) =>
|
|
1818
|
+
* kind === 'aggregate' && operation ? `${table}Aggregate${operation}` : undefined,
|
|
1819
|
+
* });
|
|
1820
|
+
* ```
|
|
1821
|
+
*
|
|
1822
|
+
* A returned name is used verbatim — {@link BuildSchemaConfig.typeNamePrefix} and
|
|
1823
|
+
* {@link BuildSchemaConfig.typeNameSuffix} do not wrap it, since the more specific of the
|
|
1824
|
+
* two knobs wins.
|
|
1825
|
+
*
|
|
1826
|
+
* The point of it is stitching: a schema merged with a second generator over the same
|
|
1827
|
+
* tables collides on the derived names constantly, because both derive them from the model
|
|
1828
|
+
* name by the same obvious rule. Renaming them here means the collision never exists, rather
|
|
1829
|
+
* than being papered over by a `RenameTypes` transform on the way out.
|
|
1830
|
+
*/
|
|
1831
|
+
derivedTypeNameMapper?: DerivedTypeNameMapper;
|
|
1832
|
+
/**
|
|
1833
|
+
* Prepended to every generated type name — object types, filters, write inputs, the
|
|
1834
|
+
* aggregate family, the shared scalar filters, everything — that
|
|
1835
|
+
* {@link BuildSchemaConfig.derivedTypeNameMapper} did not answer for. The one-line way to
|
|
1836
|
+
* make a whole subschema collision-free before stitching it:
|
|
1837
|
+
*
|
|
1838
|
+
* ```ts
|
|
1839
|
+
* buildSchema(db, { typeNamePrefix: 'Db' });
|
|
1840
|
+
* // type DbUsers, input DbUsersFilters, input DbStringFilter, enum DbOrderNulls, …
|
|
1841
|
+
* ```
|
|
1842
|
+
*
|
|
1843
|
+
* Custom scalars, database enum types and `PgGeometryObject` keep their own names: their
|
|
1844
|
+
* definition does not vary between builds, so a gateway merges them rather than colliding
|
|
1845
|
+
* on them. Field and argument names are untouched too — only type names move, so a client's
|
|
1846
|
+
* queries are unaffected apart from the names it spells in variable declarations.
|
|
1847
|
+
*
|
|
1848
|
+
* Must be a valid GraphQL name start (`/^[_A-Za-z][_0-9A-Za-z]*$/`); anything else throws.
|
|
1849
|
+
*/
|
|
1850
|
+
typeNamePrefix?: string;
|
|
1851
|
+
/**
|
|
1852
|
+
* Appended to every generated type name that {@link BuildSchemaConfig.derivedTypeNameMapper}
|
|
1853
|
+
* did not answer for. The counterpart of {@link BuildSchemaConfig.typeNamePrefix}; both may
|
|
1854
|
+
* be given at once.
|
|
1855
|
+
*/
|
|
1856
|
+
typeNameSuffix?: string;
|
|
1469
1857
|
/**
|
|
1470
1858
|
* Controls whether a relation is eagerly pre-fetched via Drizzle's `with:` clause
|
|
1471
1859
|
* when its parent is loaded through a generated query or mutation.
|
|
@@ -1682,110 +2070,6 @@ declare const singularizeMapper: (tableName: string) => {
|
|
|
1682
2070
|
plural: string;
|
|
1683
2071
|
};
|
|
1684
2072
|
|
|
1685
|
-
/**
|
|
1686
|
-
* The identity a generated field publishes about itself, under `extensions.drizzle`.
|
|
1687
|
-
*
|
|
1688
|
-
* Every field this library generates carries one, so a wrapper — `graphql-middleware`,
|
|
1689
|
-
* envelop, `graphql-shield`, an audit log, a cache invalidator — can ask the schema what a
|
|
1690
|
-
* field is instead of reverse-engineering its name. Names are configurable (`prefixes`,
|
|
1691
|
-
* `suffixes`, `typeNameMapper`), so name parsing is ambiguous by construction; this is not.
|
|
1692
|
-
*
|
|
1693
|
-
* This shape is stable API: fields are only ever added to it, never removed or repurposed.
|
|
1694
|
-
*/
|
|
1695
|
-
/** What family of field this is. */
|
|
1696
|
-
type DrizzleFieldKind = 'query' | 'mutation' | 'relation' | 'aggregate' | 'type';
|
|
1697
|
-
/**
|
|
1698
|
-
* What the field does. Arity is carried separately by `single`, so `select` covers both
|
|
1699
|
-
* the list query and its `…Single` sibling rather than being spelled twice.
|
|
1700
|
-
*/
|
|
1701
|
-
type DrizzleFieldOperation = 'select' | 'insert' | 'update' | 'updateMany' | 'upsert' | 'delete' | 'restore' | 'aggregate' | 'groupBy' | 'relation' | 'relationAggregate';
|
|
1702
|
-
/** The argument holding the rows a field is about, when it has one. */
|
|
1703
|
-
type DrizzleTargetArg = 'where' | 'values' | 'updates';
|
|
1704
|
-
/** `extensions.drizzle` on a generated field. */
|
|
1705
|
-
type DrizzleFieldExtension = {
|
|
1706
|
-
/** The Drizzle schema key of the table the field reads or writes. */
|
|
1707
|
-
table: string;
|
|
1708
|
-
kind: Exclude<DrizzleFieldKind, 'type'>;
|
|
1709
|
-
operation: DrizzleFieldOperation;
|
|
1710
|
-
/** Whether the field resolves to one row (or one aggregate) rather than a list. */
|
|
1711
|
-
single: boolean;
|
|
1712
|
-
/**
|
|
1713
|
-
* Which argument names the rows: `where` for select/update/delete/aggregate, `values`
|
|
1714
|
-
* for insert and upsert, `updates` for the batch update's per-entry `{ where, set }`.
|
|
1715
|
-
* Absent when the field takes no such argument.
|
|
1716
|
-
*/
|
|
1717
|
-
targetArg?: DrizzleTargetArg;
|
|
1718
|
-
/**
|
|
1719
|
-
* Primary-key property names of `table`, in schema order. Empty when the table declares
|
|
1720
|
-
* no primary key. Carried here so {@link identifyRows} works from the field alone.
|
|
1721
|
-
*/
|
|
1722
|
-
primaryKey: readonly string[];
|
|
1723
|
-
/** For `kind: 'relation'` and `operation: 'relationAggregate'`: the relation's name. */
|
|
1724
|
-
relation?: string;
|
|
1725
|
-
/** For `kind: 'relation'` and `operation: 'relationAggregate'`: the table it hangs off. */
|
|
1726
|
-
parentTable?: string;
|
|
1727
|
-
};
|
|
1728
|
-
/** `extensions.drizzle` on a generated object type. */
|
|
1729
|
-
type DrizzleTypeExtension = {
|
|
1730
|
-
/** The Drizzle schema key this type was generated from. */
|
|
1731
|
-
table: string;
|
|
1732
|
-
kind: 'type';
|
|
1733
|
-
/** Primary-key property names of `table`, in schema order. Empty when there is none. */
|
|
1734
|
-
primaryKey: readonly string[];
|
|
1735
|
-
};
|
|
1736
|
-
type DrizzleExtension = DrizzleFieldExtension | DrizzleTypeExtension;
|
|
1737
|
-
/** Anything carrying GraphQL `extensions` — a field config, a field, or a named type. */
|
|
1738
|
-
type WithExtensions = {
|
|
1739
|
-
extensions?: {
|
|
1740
|
-
drizzle?: unknown;
|
|
1741
|
-
} | null;
|
|
1742
|
-
} | null | undefined;
|
|
1743
|
-
/**
|
|
1744
|
-
* Reads the `drizzle` extension off a field or type, typed. Returns `undefined` for
|
|
1745
|
-
* anything this library did not generate, which is the check a wrapper wants before it
|
|
1746
|
-
* treats a field as one of ours.
|
|
1747
|
-
*/
|
|
1748
|
-
declare const drizzleExtension: (target: WithExtensions) => DrizzleExtension | undefined;
|
|
1749
|
-
/** Narrows to the field form — object types carry `kind: 'type'` and no operation. */
|
|
1750
|
-
declare const isDrizzleFieldExtension: (value: DrizzleExtension | undefined) => value is DrizzleFieldExtension;
|
|
1751
|
-
/** The rows a field's arguments name. */
|
|
1752
|
-
type IdentifiedRows = {
|
|
1753
|
-
/** The Drizzle schema key of the table being read or written. */
|
|
1754
|
-
table: string;
|
|
1755
|
-
/** Primary-key property names, in schema order. */
|
|
1756
|
-
primaryKey: readonly string[];
|
|
1757
|
-
/** One entry per identified row: the primary-key values, keyed by property name. */
|
|
1758
|
-
rows: Record<string, unknown>[];
|
|
1759
|
-
/**
|
|
1760
|
-
* Whether `rows` is exactly the set the operation affects.
|
|
1761
|
-
*
|
|
1762
|
-
* `false` means the arguments do not pin the rows down — an insert whose key the
|
|
1763
|
-
* database generates, a `where` that filters on something other than the primary key,
|
|
1764
|
-
* a plural update with no filter at all, or a table with no primary key. `rows` is then
|
|
1765
|
-
* a best-effort subset-free superset: every entry in it is a row the key values name,
|
|
1766
|
-
* but other filters may narrow the real set further, and it may be empty.
|
|
1767
|
-
*/
|
|
1768
|
-
complete: boolean;
|
|
1769
|
-
};
|
|
1770
|
-
/**
|
|
1771
|
-
* The rows a generated field's arguments are about, as primary-key values.
|
|
1772
|
-
*
|
|
1773
|
-
* The row identity of a mutation lives in a different argument for every operation —
|
|
1774
|
-
* `where` for update and delete, `values` for insert and upsert, a per-entry `where` inside
|
|
1775
|
-
* `updates` for the batch update — and each of those has both a one-row and a many-row
|
|
1776
|
-
* spelling. This reads whichever one applies:
|
|
1777
|
-
*
|
|
1778
|
-
* ```ts
|
|
1779
|
-
* const field = info.parentType.getFields()[info.fieldName];
|
|
1780
|
-
* const target = identifyRows(field, args);
|
|
1781
|
-
* if (target?.complete) await invalidate(target.table, target.rows);
|
|
1782
|
-
* ```
|
|
1783
|
-
*
|
|
1784
|
-
* Returns `undefined` for a field this library did not generate, or an object type. Check
|
|
1785
|
-
* `complete` before treating `rows` as the affected set — see {@link IdentifiedRows}.
|
|
1786
|
-
*/
|
|
1787
|
-
declare const identifyRows: (field: WithExtensions, args: Record<string, unknown> | undefined) => IdentifiedRows | undefined;
|
|
1788
|
-
|
|
1789
2073
|
/**
|
|
1790
2074
|
* A 64-bit integer. Always transported as a decimal string, in both directions, so no value
|
|
1791
2075
|
* is ever silently rounded by JSON's double-precision numbers. `graphql-scalars`' own
|
|
@@ -1813,6 +2097,14 @@ type SelectionOptions = {
|
|
|
1813
2097
|
* pass the same mapper here or nothing will match.
|
|
1814
2098
|
*/
|
|
1815
2099
|
typeNameMapper?: TypeNameMapper;
|
|
2100
|
+
/**
|
|
2101
|
+
* The `derivedTypeNameMapper` / `typeNamePrefix` / `typeNameSuffix` the schema was built
|
|
2102
|
+
* with, when any were configured. Same reason as `typeNameMapper`: the translation matches
|
|
2103
|
+
* selections against the names the build actually published.
|
|
2104
|
+
*/
|
|
2105
|
+
derivedTypeNameMapper?: DerivedTypeNameMapper;
|
|
2106
|
+
typeNamePrefix?: string;
|
|
2107
|
+
typeNameSuffix?: string;
|
|
1816
2108
|
};
|
|
1817
2109
|
/**
|
|
1818
2110
|
* Translates a GraphQL selection set into the relational query builder's `with` tree — the
|
|
@@ -1872,4 +2164,4 @@ declare const resolveSelection: (info: GraphQLResolveInfo | ResolveTree, options
|
|
|
1872
2164
|
|
|
1873
2165
|
declare const buildSchema: <TDbClient extends AnyDrizzleDB<any>>(db: TDbClient, config?: BuildSchemaConfig) => GeneratedData<TDbClient>;
|
|
1874
2166
|
|
|
1875
|
-
export { type AggregateResolver, type AnyDrizzleDB, type BuildSchemaConfig, type ColumnDeprecator, type ColumnDescriber, type ColumnDocInfo, type ColumnTypeMapper, type ColumnTypeMapperInfo, type ComplexityConfig, type ContextValuesConfig, type DefaultOrderByEntry, type DefaultsConfig, type DeleteResolver, type DeleteSingleResolver, type DrizzleExtension, type DrizzleFieldExtension, type DrizzleFieldKind, type DrizzleFieldOperation, type DrizzleTargetArg, type DrizzleTypeExtension, type EnumNameInfo, type EnumNameMapper, type ExtractRelations, type ExtractTableByName, type ExtractTableRelations, type ExtractTables, type FeatureSwitch, type GeneratedData, type GeneratedEntities, type GeneratedInputs, type GeneratedOutputs, GraphQLBigIntString, GraphQLDecimalString, type IdentifiedRows, type InsertArrResolver, type InsertResolver, type LimitsConfig, type MutationReturnlessResult, type MutationsCore, type OnWriteConfig, type QueriesCore, type RelationDescriber, type RelationResolverFactory, type ResolveSelectionOptions, type RowScope, type RowScopeFilter, type ScalarOverride, type ScalarOverridesConfig, type SchemaDocs, type SchemaExclusions, type SchemaFeatures, type ScopeConfig, type SelectResolver, type SelectSingleResolver, type SelectionOptions, type SoftDeleteColumn, type SoftDeleteConfig, type TableDefaults, type TableDescriber, type TableLimitPolicy, type TableNamedRelations, type UpdateManyArgs, type UpdateManyEntry, type UpdateManyResolver, type UpdateResolver, type UpdateSingleResolver, type UpsertArgs, type UpsertArrResolver, type UpsertConflictArgs, type UpsertResolver, type WriteHook, type WriteHookPayload, type WriteHookPositions, type WriteHooks, type WriteOperation, buildSchema, createRelationResolverFactory, defaultErrorMapper, drizzleExecutorKey, drizzleExtension, extractFilters, extractOrderBy, extractRelationJoinColumns, identifyRows, isDrizzleFieldExtension, resolveSelection, selectionToWith, singularizeMapper };
|
|
2167
|
+
export { type AggregateResolver, type AnyDrizzleDB, type BuildSchemaConfig, type ColumnDeprecator, type ColumnDescriber, type ColumnDocInfo, type ColumnTypeMapper, type ColumnTypeMapperInfo, type ComplexityConfig, type ContextValuesConfig, type DefaultOrderByEntry, type DefaultsConfig, type DeleteResolver, type DeleteSingleResolver, type DrizzleErrorCode, type DrizzleErrorContext, type DrizzleExtension, type DrizzleFieldExtension, type DrizzleFieldKind, type DrizzleFieldOperation, type DrizzleTargetArg, type DrizzleTypeExtension, type EnumNameInfo, type EnumNameMapper, type ExtractRelations, type ExtractTableByName, type ExtractTableRelations, type ExtractTables, type FeatureSwitch, type GeneratedData, type GeneratedEntities, type GeneratedInputs, type GeneratedOutputs, GraphQLBigIntString, GraphQLDecimalString, type IdentifiedRows, type InsertArrResolver, type InsertResolver, type LimitsConfig, type MutationReturnlessResult, type MutationsCore, type OnWriteConfig, type QueriesCore, type RelationDescriber, type RelationResolverFactory, type ResolveSelectionOptions, type RowScope, type RowScopeFilter, type ScalarOverride, type ScalarOverridesConfig, type SchemaDocs, type SchemaExclusions, type SchemaFeatures, type ScopeConfig, type SelectResolver, type SelectSingleResolver, type SelectionOptions, type SoftDeleteColumn, type SoftDeleteConfig, type TableDefaults, type TableDescriber, type TableLimitPolicy, type TableNamedRelations, type UpdateManyArgs, type UpdateManyEntry, type UpdateManyResolver, type UpdateResolver, type UpdateSingleResolver, type UpsertArgs, type UpsertArrResolver, type UpsertConflictArgs, type UpsertResolver, type WriteHook, type WriteHookPayload, type WriteHookPositions, type WriteHooks, type WriteOperation, buildSchema, createRelationResolverFactory, defaultErrorMapper, drizzleError, drizzleExecutorKey, drizzleExtension, extractFilters, extractOrderBy, extractRelationJoinColumns, identifyRows, isDrizzleFieldExtension, resolveSelection, selectionToWith, singularizeMapper };
|