@vantreeseba/drizzle-graphql 7.9.1 → 8.1.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 +282 -6
- package/dist/README.md +282 -6
- package/dist/index.cjs +6623 -7788
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +563 -263
- package/dist/index.d.ts +563 -263
- package/dist/index.js +6595 -7757
- 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,222 @@
|
|
|
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 { ASTNode, 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
|
+
/** A written value could not be converted to what its column stores. */
|
|
158
|
+
| 'DRIZZLE_INVALID_INPUT_VALUE'
|
|
159
|
+
/** A write's input named a key that is not a column of the table. */
|
|
160
|
+
| 'DRIZZLE_UNKNOWN_COLUMN'
|
|
161
|
+
/** A stored value could not be represented by the scalar that transports it. */
|
|
162
|
+
| 'DRIZZLE_UNREPRESENTABLE_VALUE'
|
|
163
|
+
/** The request's shared mutation transaction was rolled back, so this field never ran. */
|
|
164
|
+
| 'DRIZZLE_TRANSACTION_ABORTED';
|
|
165
|
+
/**
|
|
166
|
+
* What an error was about, published as `extensions.drizzle` beside the code — the runtime
|
|
167
|
+
* half of the `extensions.drizzle` markers a generated field carries.
|
|
168
|
+
*
|
|
169
|
+
* `field` is the **generated** field name, which is why it is data rather than prose: a build
|
|
170
|
+
* that republishes these fields under other names (`RenameRootFields`, a stitched gateway, a
|
|
171
|
+
* hand-written façade) would otherwise be telling a client about a field it has never heard
|
|
172
|
+
* of. The name the client asked for is already in the error's `path`.
|
|
173
|
+
*/
|
|
174
|
+
type DrizzleErrorContext = {
|
|
175
|
+
/** The Drizzle schema key of the table the field reads or writes. */
|
|
176
|
+
table?: string;
|
|
177
|
+
operation?: DrizzleFieldOperation;
|
|
178
|
+
/** The generated field's own name, pre-rename. */
|
|
179
|
+
field?: string;
|
|
180
|
+
/** For a relation field: the relation's name. */
|
|
181
|
+
relation?: string;
|
|
182
|
+
};
|
|
183
|
+
/**
|
|
184
|
+
* A `GraphQLError` carrying its context as data. The message says what went wrong, in prose
|
|
185
|
+
* meant for a client; `extensions.code` classifies it and `extensions.drizzle` says which
|
|
186
|
+
* table, operation and generated field it came from.
|
|
187
|
+
*/
|
|
188
|
+
declare const drizzleError: (message: string, { code, nodes, ...context }: DrizzleErrorContext & {
|
|
189
|
+
code: DrizzleErrorCode;
|
|
190
|
+
/** The AST the error is about, where the throw site has one — it becomes the `locations`. */
|
|
191
|
+
nodes?: ASTNode | readonly ASTNode[];
|
|
192
|
+
}) => GraphQLError;
|
|
193
|
+
/**
|
|
194
|
+
* Default for `config.onError`: keeps drizzle-graphql's own errors, which are written for
|
|
195
|
+
* the client, and replaces driver/database errors with a generic message. Their text names
|
|
196
|
+
* tables, columns, constraints and offending values, none of which belongs in a response.
|
|
197
|
+
* The original is preserved on `originalError` for server-side logging.
|
|
198
|
+
*/
|
|
199
|
+
declare const defaultErrorMapper: (error: unknown) => unknown;
|
|
200
|
+
|
|
201
|
+
/** {@link BuildSchemaConfig.limits} resolved for one table. `undefined` means no policy. */
|
|
202
|
+
type ResolvedLimitPolicy = {
|
|
203
|
+
defaultLimit: number | undefined;
|
|
204
|
+
maxLimit: number | undefined;
|
|
205
|
+
clampToMax: boolean;
|
|
206
|
+
};
|
|
207
|
+
/**
|
|
208
|
+
* Looks up the limit policy for a table by its Drizzle schema key. Built once per schema by
|
|
209
|
+
* `buildSchema`; `undefined` for a table the caller left unbounded.
|
|
210
|
+
*/
|
|
211
|
+
type LimitPolicyFor = (tableName: string) => ResolvedLimitPolicy | undefined;
|
|
212
|
+
/**
|
|
213
|
+
* {@link BuildSchemaConfig.defaults} resolved for one table: the `orderBy` a read falls back
|
|
214
|
+
* to when the request passes none, already in the shape the generated argument has.
|
|
215
|
+
* `undefined` means the table declares no default and keeps whatever order the database
|
|
216
|
+
* returns.
|
|
217
|
+
*/
|
|
218
|
+
type DefaultOrderByFor = (tableName: string) => Record<string, any> | undefined;
|
|
219
|
+
|
|
9
220
|
/**
|
|
10
221
|
* A scalar override for one column. A bare scalar applies to both directions; the object form
|
|
11
222
|
* lets output (object type, aggregate min/max) and input (create/update inputs, filter operands)
|
|
@@ -171,6 +382,12 @@ type FilterColumnOperatorsCore<TColumn extends Column, TColType = GetColumnGqlDa
|
|
|
171
382
|
isEmpty: boolean;
|
|
172
383
|
isNull: boolean;
|
|
173
384
|
isNotNull: boolean;
|
|
385
|
+
/**
|
|
386
|
+
* String columns: compares every operator in this object case-insensitively
|
|
387
|
+
* (`lower(column)` against `lower(operand)`). Applies to the operators beside it only —
|
|
388
|
+
* a nested `AND`/`OR`/`NOT` branch sets its own.
|
|
389
|
+
*/
|
|
390
|
+
insensitive: boolean;
|
|
174
391
|
}>;
|
|
175
392
|
type FiltersCore<TTable extends Table> = Partial<{
|
|
176
393
|
[Column in keyof TTable['_']['columns']]: FilterColumnOperatorsCore<TTable['_']['columns'][Column]>;
|
|
@@ -198,133 +415,55 @@ type OrderByArgs<TTable extends Table> = {
|
|
|
198
415
|
};
|
|
199
416
|
};
|
|
200
417
|
|
|
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
418
|
/**
|
|
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
|
-
* ```
|
|
419
|
+
* What a generated type is, so a name mapper can answer for one kind without matching on the
|
|
420
|
+
* spelling of the default name.
|
|
235
421
|
*
|
|
236
|
-
*
|
|
237
|
-
*
|
|
422
|
+
* - `object` — a table's row type, the one `typeNameMapper` already names
|
|
423
|
+
* - `filter` / `listRelationFilter` — `<Type>Filters` and the `some`/`none`/`every` wrapper
|
|
424
|
+
* - `orderBy` — `<Type>OrderBy`
|
|
425
|
+
* - `createInput` / `updateInput` / `updateManyInput` / `nestedWriteInput` / `fieldUpdateInput`
|
|
426
|
+
* — the write inputs
|
|
427
|
+
* - `aggregate` — `<Type>Aggregate` and its per-operation children (`operation` names which)
|
|
428
|
+
* - `having` / `groupBy` / `groupKeys` — the group-by family
|
|
429
|
+
* - `onConflict` — the upsert's conflict input
|
|
430
|
+
* - `uniqueKey` — a compound unique constraint's key input
|
|
431
|
+
* - `columnEnum` — an enum naming a table's columns (`distinct`, conflict target, …)
|
|
432
|
+
* - `columnFilter` — a shared per-scalar filter (`StringFilter`, `IntFilter`, …), not per table
|
|
433
|
+
* - `shared` — everything else the build creates once (`OrderNulls`, `DeletedFilter`, …)
|
|
238
434
|
*/
|
|
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;
|
|
435
|
+
type GeneratedTypeKind = 'object' | 'filter' | 'listRelationFilter' | 'orderBy' | 'createInput' | 'updateInput' | 'updateManyInput' | 'nestedWriteInput' | 'fieldUpdateInput' | 'aggregate' | 'having' | 'groupBy' | 'groupKeys' | 'onConflict' | 'uniqueKey' | 'columnEnum' | 'columnFilter' | 'shared';
|
|
436
|
+
/** What a name mapper is told about the type it is being asked to name. */
|
|
437
|
+
interface GeneratedTypeInfo {
|
|
438
|
+
/** Which kind of generated type this is. */
|
|
439
|
+
kind: GeneratedTypeKind;
|
|
440
|
+
/** The name the library would use, before any prefix or suffix. */
|
|
441
|
+
defaultName: string;
|
|
442
|
+
/** The table key the type belongs to, where it belongs to one. */
|
|
443
|
+
table?: string;
|
|
253
444
|
/**
|
|
254
|
-
* The
|
|
255
|
-
*
|
|
256
|
-
*
|
|
445
|
+
* The narrower thing the type is for, where the kind alone does not say: the aggregate
|
|
446
|
+
* operation (`sum`, `avg`, …), the relation a nested-write input is for, the scalar a
|
|
447
|
+
* column filter covers, the columns of a unique key.
|
|
257
448
|
*/
|
|
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;
|
|
449
|
+
operation?: string;
|
|
450
|
+
}
|
|
303
451
|
/**
|
|
304
|
-
*
|
|
305
|
-
*
|
|
306
|
-
*
|
|
307
|
-
* returns.
|
|
452
|
+
* Renames a generated type. Return `undefined` — or the same name — to keep the default,
|
|
453
|
+
* which is what an unlisted kind should do; anything returned is used verbatim, without the
|
|
454
|
+
* build's prefix or suffix.
|
|
308
455
|
*/
|
|
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[];
|
|
456
|
+
type DerivedTypeNameMapper = (info: GeneratedTypeInfo) => string | undefined;
|
|
457
|
+
|
|
458
|
+
/** Optional mapper from table key to singular/plural name pair. Return undefined to use default naming for a table. */
|
|
459
|
+
type TypeNameMapper = (tableName: string) => {
|
|
460
|
+
singular: string;
|
|
461
|
+
plural: string;
|
|
462
|
+
} | undefined;
|
|
463
|
+
|
|
464
|
+
/** A table's unique-key `where` fields: field name → the constraint's member property names. */
|
|
465
|
+
type UniqueKeyMap = Record<string, readonly string[]>;
|
|
466
|
+
|
|
328
467
|
/**
|
|
329
468
|
* Everything `extractFilters` needs to turn a relation key in a `where` argument into a
|
|
330
469
|
* correlated subquery. Omitted by callers that don't generate relation filters, in which case
|
|
@@ -344,13 +483,58 @@ interface RelationFilterContext {
|
|
|
344
483
|
aliases?: {
|
|
345
484
|
n: number;
|
|
346
485
|
};
|
|
486
|
+
/**
|
|
487
|
+
* The compound-unique-key `where` fields of each table, keyed by table schema key. Only
|
|
488
|
+
* populated when `features.uniqueKeyFilters` generated them — a key field the build did not
|
|
489
|
+
* generate is an unknown filter key like any other.
|
|
490
|
+
*/
|
|
491
|
+
uniqueKeys?: Record<string, UniqueKeyMap>;
|
|
347
492
|
}
|
|
348
493
|
/**
|
|
349
494
|
* The build-scoped half of {@link RelationFilterContext}. Created once per generated schema and
|
|
350
495
|
* handed to every resolver, which adds the table it is filtering.
|
|
351
496
|
*/
|
|
352
|
-
type RelationFilterBase = Pick<RelationFilterContext, 'tables' | 'relationMap'>;
|
|
497
|
+
type RelationFilterBase = Pick<RelationFilterContext, 'tables' | 'relationMap' | 'uniqueKeys'>;
|
|
353
498
|
declare const extractFilters: <TTable extends Table>(table: TTable, tableName: string, filters: Filters<TTable>, relationCtx?: RelationFilterContext) => SQL | undefined;
|
|
499
|
+
|
|
500
|
+
/** The write a hook is attached to. `restore` only exists for a soft-deleting table. */
|
|
501
|
+
type WriteOperation = 'insert' | 'update' | 'updateMany' | 'upsert' | 'delete' | 'restore';
|
|
502
|
+
/** What a write hook is handed. See {@link BuildSchemaConfig.onWrite}. */
|
|
503
|
+
type WriteHookPayload = {
|
|
504
|
+
/** Drizzle schema key of the table being written. */
|
|
505
|
+
table: string;
|
|
506
|
+
operation: WriteOperation;
|
|
507
|
+
/** `'before'` runs ahead of the statement, `'after'` once it has returned. */
|
|
508
|
+
position: 'before' | 'after';
|
|
509
|
+
/** Whether the field writes a single row (`createUsersSingle`) or a list. */
|
|
510
|
+
single: boolean;
|
|
511
|
+
/** The field's GraphQL arguments, exactly as the resolver received them. */
|
|
512
|
+
args: any;
|
|
513
|
+
/**
|
|
514
|
+
* The rows the write produced, as the database returned them — before the output mapper,
|
|
515
|
+
* so values are database-shaped. Empty at the `before` position, and on MySQL, whose
|
|
516
|
+
* mutations return no rows.
|
|
517
|
+
*/
|
|
518
|
+
rows: any[];
|
|
519
|
+
context: any;
|
|
520
|
+
info: any;
|
|
521
|
+
/** The executor the mutation itself ran on. Throwing from the hook rolls it back. */
|
|
522
|
+
tx: any;
|
|
523
|
+
};
|
|
524
|
+
type WriteHook = (payload: WriteHookPayload) => void | Promise<void>;
|
|
525
|
+
type WriteHookPositions = {
|
|
526
|
+
before?: WriteHook;
|
|
527
|
+
after?: WriteHook;
|
|
528
|
+
};
|
|
529
|
+
type WriteHooks = WriteHook | WriteHookPositions;
|
|
530
|
+
/** Resolved, per-field hooks: `undefined` when the table registered none. */
|
|
531
|
+
type ResolvedWriteHooks = {
|
|
532
|
+
before?: WriteHook;
|
|
533
|
+
after?: WriteHook;
|
|
534
|
+
};
|
|
535
|
+
/** Build-time lookup of a table's hooks, installed on {@link TablePolicies}. */
|
|
536
|
+
type WriteHookFor = (tableName: string, operation: WriteOperation) => ResolvedWriteHooks | undefined;
|
|
537
|
+
|
|
354
538
|
/**
|
|
355
539
|
* A table's row-level scope: the predicate every generated read, update and delete on that
|
|
356
540
|
* table is narrowed by. See `BuildSchemaConfig.scope`.
|
|
@@ -368,10 +552,11 @@ type ScopeFor = (tableName: string) => ScopeHook | undefined;
|
|
|
368
552
|
/**
|
|
369
553
|
* One table's soft-delete convention, resolved against the real column at build time.
|
|
370
554
|
*
|
|
371
|
-
* `
|
|
372
|
-
*
|
|
373
|
-
*
|
|
374
|
-
*
|
|
555
|
+
* `marker` picks the shape of the predicate. When the config names a constant that means
|
|
556
|
+
* deleted, the predicate compares against it (`isDeleted = true`); otherwise the column marks
|
|
557
|
+
* a row deleted by holding a value at all (`deletedAt IS NOT NULL`), the common timestamp
|
|
558
|
+
* form. A NOT NULL column has no "absent" state, so it must have a marker; a nullable one
|
|
559
|
+
* takes the NULL-means-alive reading only when no marker was configured.
|
|
375
560
|
*/
|
|
376
561
|
type SoftDeleteInfo = {
|
|
377
562
|
/** Property name of the column on the drizzle table — also the key on an aliased proxy. */
|
|
@@ -382,8 +567,22 @@ type SoftDeleteInfo = {
|
|
|
382
567
|
writeDeleted: () => any;
|
|
383
568
|
/** Written by the restore mutation. */
|
|
384
569
|
writeRestored: any;
|
|
385
|
-
/**
|
|
570
|
+
/**
|
|
571
|
+
* The constant that means "this row is deleted", when the config named one. Required on a
|
|
572
|
+
* NOT NULL column; optional on a nullable one, which otherwise reads NULL as alive.
|
|
573
|
+
*/
|
|
386
574
|
marker?: any;
|
|
575
|
+
/**
|
|
576
|
+
* Which reads hide marked rows by default — `'all'` (the table's own fields and every
|
|
577
|
+
* relation pointing at it) or `'root'` (its own fields only). See
|
|
578
|
+
* {@link relationDeletedDefault}.
|
|
579
|
+
*/
|
|
580
|
+
scope: 'root' | 'all';
|
|
581
|
+
/**
|
|
582
|
+
* Whether the delete mutations take a `hard` argument that issues a real `DELETE`. Off
|
|
583
|
+
* unless the table opts in, so the generated schema says which tables can be purged.
|
|
584
|
+
*/
|
|
585
|
+
hardDelete: boolean;
|
|
387
586
|
};
|
|
388
587
|
/** Build-time lookup: the soft-delete convention of a table, if it declares one. */
|
|
389
588
|
type SoftDeleteFor = (tableName: string) => SoftDeleteInfo | undefined;
|
|
@@ -409,6 +608,26 @@ type TablePolicies = {
|
|
|
409
608
|
/** See `BuildSchemaConfig.defaults`. */
|
|
410
609
|
defaultOrderBy?: DefaultOrderByFor;
|
|
411
610
|
};
|
|
611
|
+
|
|
612
|
+
/**
|
|
613
|
+
* Compiles an `orderBy` argument into ORDER BY expressions, highest priority first.
|
|
614
|
+
*
|
|
615
|
+
* A key naming one of the table's columns orders by that column. A key naming a to-one
|
|
616
|
+
* relation takes the target table's own OrderBy input and orders by the related row's
|
|
617
|
+
* column(s), compiled as a correlated scalar subquery — reusing the aliased-join machinery
|
|
618
|
+
* the relation filters are built on — so it works identically on all three dialects and
|
|
619
|
+
* inside the relational query builder's aliased CTEs. Priorities share one global space
|
|
620
|
+
* across relation boundaries. Each entry may also carry `nulls: first | last`
|
|
621
|
+
* (see {@link orderExpressions} for how MySQL emulates it).
|
|
622
|
+
*
|
|
623
|
+
* An entry may instead set `matchFilterOrder`, which sorts by the column's position in the
|
|
624
|
+
* `inArray` list the same request's `where` gives it — `whereArgs` is that `where`.
|
|
625
|
+
*
|
|
626
|
+
* `ctx` supplies the tables and relation map that relation ordering needs; callers whose
|
|
627
|
+
* inputs cannot contain relation keys may omit it.
|
|
628
|
+
*/
|
|
629
|
+
declare const extractOrderBy: <TTable extends Table, TArgs extends OrderByArgs<any> = OrderByArgs<TTable>>(table: TTable, orderArgs: TArgs, ctx?: RelationFilterContext, whereArgs?: Record<string, any>) => SQL[];
|
|
630
|
+
|
|
412
631
|
/**
|
|
413
632
|
* Where a dialect's default sort places NULLs relative to non-NULL values:
|
|
414
633
|
* - `nulls-largest` — PostgreSQL: NULLs sort as the largest values (last in ASC, first in DESC).
|
|
@@ -417,13 +636,58 @@ type TablePolicies = {
|
|
|
417
636
|
* The keyset predicate has to agree with the dialect's ORDER BY, so each builder passes its own.
|
|
418
637
|
*/
|
|
419
638
|
type NullOrdering = 'nulls-largest' | 'nulls-smallest';
|
|
639
|
+
|
|
420
640
|
/**
|
|
421
|
-
*
|
|
422
|
-
*
|
|
423
|
-
*
|
|
424
|
-
*
|
|
641
|
+
* Key on the GraphQL context object under which a caller can place a Drizzle transaction
|
|
642
|
+
* (or any other executor: a pooled connection, a logging proxy). Every generated resolver
|
|
643
|
+
* reads it at resolve time and runs its statements there instead of on the database the
|
|
644
|
+
* schema was built from, which is what lets several mutations in one request share a
|
|
645
|
+
* transaction and lets a query see that transaction's uncommitted rows:
|
|
646
|
+
*
|
|
647
|
+
* ```ts
|
|
648
|
+
* await db.transaction(async (tx) => {
|
|
649
|
+
* await graphql({ schema, source, contextValue: { [drizzleExecutorKey]: tx } });
|
|
650
|
+
* });
|
|
651
|
+
* ```
|
|
652
|
+
*
|
|
653
|
+
* Registered with `Symbol.for` so the ESM and CJS builds of this package agree on it when
|
|
654
|
+
* both end up loaded in one process.
|
|
425
655
|
*/
|
|
426
|
-
declare const
|
|
656
|
+
declare const drizzleExecutorKey: unique symbol;
|
|
657
|
+
|
|
658
|
+
/**
|
|
659
|
+
* Extracts the join column info from a drizzle-orm v1 Relation object.
|
|
660
|
+
* Returns the JS property name of the local column on the parent table and the
|
|
661
|
+
* Column object for the foreign column on the target table, or undefined if the
|
|
662
|
+
* relation internals are not accessible.
|
|
663
|
+
*/
|
|
664
|
+
declare const extractRelationJoinColumns: (relEntry: TableNamedRelations, parentTable: Table, targetTable: Table) => {
|
|
665
|
+
localColPropName: string;
|
|
666
|
+
foreignCol: Column;
|
|
667
|
+
foreignColPropName: string;
|
|
668
|
+
} | undefined;
|
|
669
|
+
type RelationResolverFactory = (params: {
|
|
670
|
+
tableName: string;
|
|
671
|
+
relationName: string;
|
|
672
|
+
relEntry: TableNamedRelations;
|
|
673
|
+
isOne: boolean;
|
|
674
|
+
}) => GraphQLFieldResolver<any, any> | undefined;
|
|
675
|
+
|
|
676
|
+
/**
|
|
677
|
+
* Creates a RelationResolverFactory that generates field-level resolvers for each relation.
|
|
678
|
+
* Each resolver:
|
|
679
|
+
* 1. Returns pre-fetched data if the parent resolver already included it (eager path, zero cost).
|
|
680
|
+
* 2. When limit/offset args are present, falls back to a direct per-item query.
|
|
681
|
+
* 3. Otherwise batches all sibling resolver calls within the same GraphQL execution tick
|
|
682
|
+
* into a single IN-clause query, eliminating N+1 database round-trips.
|
|
683
|
+
*
|
|
684
|
+
* `nullOrdering` is the dialect's native `ORDER BY` placement for `NULL` — the keyset
|
|
685
|
+
* predicate behind a relation's `after` argument has to match it, or rows with a `NULL` in an
|
|
686
|
+
* ordered column would be skipped instead of paged through. It has no sensible default, so
|
|
687
|
+
* each dialect builder states it: `'nulls-largest'` for PostgreSQL, `'nulls-smallest'` for
|
|
688
|
+
* MySQL and SQLite.
|
|
689
|
+
*/
|
|
690
|
+
declare const createRelationResolverFactory: (db: any, tables: Record<string, Table>, nullOrdering: NullOrdering, filterCtx?: RelationFilterBase, limits?: LimitPolicyFor, policies?: TablePolicies) => RelationResolverFactory;
|
|
427
691
|
|
|
428
692
|
type Relations<TTable extends string = string, TConfig extends Record<string, Relation> = Record<string, Relation>> = {
|
|
429
693
|
table: {
|
|
@@ -435,7 +699,19 @@ type Relations<TTable extends string = string, TConfig extends Record<string, Re
|
|
|
435
699
|
};
|
|
436
700
|
|
|
437
701
|
type AnyDrizzleDB<TSchema extends Record<string, any>> = PgAsyncDatabase<any, TSchema> | BaseSQLiteDatabase<any, any, TSchema> | MySqlDatabase<any, any, TSchema>;
|
|
438
|
-
|
|
702
|
+
/**
|
|
703
|
+
* The tables a database handle knows about, keyed by their schema key.
|
|
704
|
+
*
|
|
705
|
+
* Two shapes reach this type, because drizzle-orm v1 changed what a database's generic slot
|
|
706
|
+
* holds. SQLite and MySQL handles still carry the schema module itself, so the tables are
|
|
707
|
+
* picked out of it directly. PostgreSQL handles carry only the relations config built by
|
|
708
|
+
* `buildRelations` — a `Record<string, { table; name; relations }>` — so the tables are read
|
|
709
|
+
* off its `table` members instead. Without the second branch every PG-derived type collapses
|
|
710
|
+
* to `never`.
|
|
711
|
+
*/
|
|
712
|
+
type ExtractTables<TSchema extends Record<string, Table | unknown>> = TSchema extends TablesRelationalConfig ? {
|
|
713
|
+
[K in keyof TSchema]: TSchema[K]['table'] extends infer TTable extends Table ? TTable : never;
|
|
714
|
+
} : {
|
|
439
715
|
[K in keyof TSchema as TSchema[K] extends Table ? K : never]: TSchema[K] extends Table ? TSchema[K] : never;
|
|
440
716
|
};
|
|
441
717
|
type ExtractRelations<TSchema extends Record<string, Table | unknown>> = {
|
|
@@ -550,7 +826,7 @@ type DeleteResolver<TTable extends Table, IsReturnless extends boolean> = (sourc
|
|
|
550
826
|
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
827
|
type QueriesCore<TSchemaTables extends Record<string, Table>, TSchemaRelations extends Record<string, Relations>, TInputs extends Record<string, GraphQLInputObjectType>, TOutputs extends Record<string, GraphQLObjectType>> = {
|
|
552
828
|
[TName in keyof TSchemaTables as TName extends string ? `${Uncapitalize<TName>}` : never]: TName extends string ? {
|
|
553
|
-
type: GraphQLNonNull<GraphQLList<GraphQLNonNull<TOutputs[
|
|
829
|
+
type: GraphQLNonNull<GraphQLList<GraphQLNonNull<TOutputs[Capitalize<TName>]>>>;
|
|
554
830
|
args: {
|
|
555
831
|
offset: {
|
|
556
832
|
type: GraphQLScalarType<number, number>;
|
|
@@ -572,7 +848,7 @@ type QueriesCore<TSchemaTables extends Record<string, Table>, TSchemaRelations e
|
|
|
572
848
|
} : never;
|
|
573
849
|
} & {
|
|
574
850
|
[TName in keyof TSchemaTables as TName extends string ? `${Uncapitalize<TName>}Single` : never]: TName extends string ? {
|
|
575
|
-
type: TOutputs[
|
|
851
|
+
type: TOutputs[Capitalize<TName>];
|
|
576
852
|
args: {
|
|
577
853
|
offset: {
|
|
578
854
|
type: GraphQLScalarType<number, number>;
|
|
@@ -599,30 +875,30 @@ type QueriesCore<TSchemaTables extends Record<string, Table>, TSchemaRelations e
|
|
|
599
875
|
};
|
|
600
876
|
type MutationsCore<TSchemaTables extends Record<string, Table>, TInputs extends Record<string, GraphQLInputObjectType>, TOutputs extends Record<string, GraphQLObjectType>, IsReturnless extends boolean> = {
|
|
601
877
|
[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[
|
|
878
|
+
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : GraphQLNonNull<GraphQLList<GraphQLNonNull<TOutputs[Capitalize<TName>]>>>;
|
|
603
879
|
args: {
|
|
604
880
|
values: {
|
|
605
|
-
type: GraphQLNonNull<GraphQLList<GraphQLNonNull<TInputs[
|
|
881
|
+
type: GraphQLNonNull<GraphQLList<GraphQLNonNull<TInputs[`Create${Capitalize<TName>}Input`]>>>;
|
|
606
882
|
};
|
|
607
883
|
};
|
|
608
884
|
resolve: InsertArrResolver<TSchemaTables[TName], IsReturnless>;
|
|
609
885
|
} : never;
|
|
610
886
|
} & {
|
|
611
887
|
[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[
|
|
888
|
+
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : TOutputs[Capitalize<TName>];
|
|
613
889
|
args: {
|
|
614
890
|
values: {
|
|
615
|
-
type: GraphQLNonNull<TInputs[
|
|
891
|
+
type: GraphQLNonNull<TInputs[`Create${Capitalize<TName>}Input`]>;
|
|
616
892
|
};
|
|
617
893
|
};
|
|
618
894
|
resolve: InsertResolver<TSchemaTables[TName], IsReturnless>;
|
|
619
895
|
} : never;
|
|
620
896
|
} & {
|
|
621
897
|
[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[
|
|
898
|
+
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : GraphQLNonNull<GraphQLList<GraphQLNonNull<TOutputs[Capitalize<TName>]>>>;
|
|
623
899
|
args: {
|
|
624
900
|
values: {
|
|
625
|
-
type: GraphQLNonNull<GraphQLList<GraphQLNonNull<TInputs[
|
|
901
|
+
type: GraphQLNonNull<GraphQLList<GraphQLNonNull<TInputs[`Create${Capitalize<TName>}Input`]>>>;
|
|
626
902
|
};
|
|
627
903
|
onConflict: {
|
|
628
904
|
type: GraphQLInputObjectType;
|
|
@@ -632,10 +908,10 @@ type MutationsCore<TSchemaTables extends Record<string, Table>, TInputs extends
|
|
|
632
908
|
} : never;
|
|
633
909
|
} & {
|
|
634
910
|
[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[
|
|
911
|
+
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : TOutputs[Capitalize<TName>];
|
|
636
912
|
args: {
|
|
637
913
|
values: {
|
|
638
|
-
type: GraphQLNonNull<TInputs[
|
|
914
|
+
type: GraphQLNonNull<TInputs[`Create${Capitalize<TName>}Input`]>;
|
|
639
915
|
};
|
|
640
916
|
onConflict: {
|
|
641
917
|
type: GraphQLInputObjectType;
|
|
@@ -645,10 +921,10 @@ type MutationsCore<TSchemaTables extends Record<string, Table>, TInputs extends
|
|
|
645
921
|
} : never;
|
|
646
922
|
} & {
|
|
647
923
|
[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[
|
|
924
|
+
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : GraphQLNonNull<GraphQLList<GraphQLNonNull<TOutputs[Capitalize<TName>]>>>;
|
|
649
925
|
args: {
|
|
650
926
|
set: {
|
|
651
|
-
type: GraphQLNonNull<TInputs[
|
|
927
|
+
type: GraphQLNonNull<TInputs[`Update${Capitalize<TName>}Input`]>;
|
|
652
928
|
};
|
|
653
929
|
where: {
|
|
654
930
|
type: TInputs[`${Capitalize<TName>}Filters`] extends GraphQLInputObjectType ? TInputs[`${Capitalize<TName>}Filters`] : never;
|
|
@@ -658,20 +934,20 @@ type MutationsCore<TSchemaTables extends Record<string, Table>, TInputs extends
|
|
|
658
934
|
} : never;
|
|
659
935
|
} & {
|
|
660
936
|
[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[
|
|
937
|
+
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : GraphQLNonNull<GraphQLList<TOutputs[Capitalize<TName>]>>;
|
|
662
938
|
args: {
|
|
663
939
|
updates: {
|
|
664
|
-
type: GraphQLNonNull<GraphQLList<GraphQLNonNull<TInputs[
|
|
940
|
+
type: GraphQLNonNull<GraphQLList<GraphQLNonNull<TInputs[`Update${Capitalize<TName>}ManyInput`]>>>;
|
|
665
941
|
};
|
|
666
942
|
};
|
|
667
943
|
resolve: UpdateManyResolver<TSchemaTables[TName], IsReturnless>;
|
|
668
944
|
} : never;
|
|
669
945
|
} & {
|
|
670
946
|
[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[
|
|
947
|
+
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : TOutputs[Capitalize<TName>];
|
|
672
948
|
args: {
|
|
673
949
|
set: {
|
|
674
|
-
type: GraphQLNonNull<TInputs[
|
|
950
|
+
type: GraphQLNonNull<TInputs[`Update${Capitalize<TName>}Input`]>;
|
|
675
951
|
};
|
|
676
952
|
where: {
|
|
677
953
|
type: GraphQLNonNull<TInputs[`${Capitalize<TName>}Filters`] extends GraphQLInputObjectType ? TInputs[`${Capitalize<TName>}Filters`] : never>;
|
|
@@ -681,7 +957,7 @@ type MutationsCore<TSchemaTables extends Record<string, Table>, TInputs extends
|
|
|
681
957
|
} : never;
|
|
682
958
|
} & {
|
|
683
959
|
[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[
|
|
960
|
+
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : GraphQLNonNull<GraphQLList<GraphQLNonNull<TOutputs[Capitalize<TName>]>>>;
|
|
685
961
|
args: {
|
|
686
962
|
where: {
|
|
687
963
|
type: TInputs[`${Capitalize<TName>}Filters`] extends GraphQLInputObjectType ? TInputs[`${Capitalize<TName>}Filters`] : never;
|
|
@@ -691,7 +967,7 @@ type MutationsCore<TSchemaTables extends Record<string, Table>, TInputs extends
|
|
|
691
967
|
} : never;
|
|
692
968
|
} & {
|
|
693
969
|
[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[
|
|
970
|
+
type: IsReturnless extends true ? TOutputs['MutationReturn'] extends GraphQLObjectType ? TOutputs['MutationReturn'] : never : TOutputs[Capitalize<TName>];
|
|
695
971
|
args: {
|
|
696
972
|
where: {
|
|
697
973
|
type: GraphQLNonNull<TInputs[`${Capitalize<TName>}Filters`] extends GraphQLInputObjectType ? TInputs[`${Capitalize<TName>}Filters`] : never>;
|
|
@@ -700,25 +976,42 @@ type MutationsCore<TSchemaTables extends Record<string, Table>, TInputs extends
|
|
|
700
976
|
resolve: DeleteSingleResolver<TSchemaTables[TName], IsReturnless>;
|
|
701
977
|
} : never;
|
|
702
978
|
};
|
|
979
|
+
/**
|
|
980
|
+
* Keys of `entities.inputs`, which is keyed by generated GraphQL input type name.
|
|
981
|
+
*
|
|
982
|
+
* The write inputs are named from the configured `prefixes`, so these keys describe a build
|
|
983
|
+
* that uses the defaults (`insert: 'create'`, `update: 'update'`); a build that overrides a
|
|
984
|
+
* prefix produces correspondingly different keys. Inputs that only exist when a feature is
|
|
985
|
+
* enabled — `${Table}OnConflict` for upsert, `${Table}Having` for group-by — are not listed,
|
|
986
|
+
* since whether they were generated is a runtime decision.
|
|
987
|
+
*/
|
|
703
988
|
type GeneratedInputs<TSchema extends Record<string, Table>> = {
|
|
704
|
-
[TName in keyof TSchema as TName extends string ?
|
|
989
|
+
[TName in keyof TSchema as TName extends string ? `Create${Capitalize<TName>}Input` : never]: GraphQLInputObjectType;
|
|
705
990
|
} & {
|
|
706
|
-
[TName in keyof TSchema as TName extends string ?
|
|
991
|
+
[TName in keyof TSchema as TName extends string ? `Update${Capitalize<TName>}Input` : never]: GraphQLInputObjectType;
|
|
707
992
|
} & {
|
|
708
|
-
[TName in keyof TSchema as TName extends string ?
|
|
993
|
+
[TName in keyof TSchema as TName extends string ? `Update${Capitalize<TName>}ManyInput` : never]: GraphQLInputObjectType;
|
|
709
994
|
} & {
|
|
710
995
|
[TName in keyof TSchema as TName extends string ? `${Capitalize<TName>}OrderBy` : never]: GraphQLInputObjectType;
|
|
711
996
|
} & {
|
|
712
997
|
[TName in keyof TSchema as TName extends string ? `${Capitalize<TName>}Filters` : never]: GraphQLInputObjectType;
|
|
713
998
|
};
|
|
999
|
+
/**
|
|
1000
|
+
* Keys of `entities.types`, which is keyed by generated GraphQL type name.
|
|
1001
|
+
*
|
|
1002
|
+
* This build emits ONE object type per table (`Users`) used for both selects and mutation
|
|
1003
|
+
* returns — upstream drizzle-graphql emitted two (`UsersSelectItem` / `UsersItem`), and this
|
|
1004
|
+
* type kept those names long after the generator stopped producing them. MySQL still has a
|
|
1005
|
+
* shared `MutationReturn` instead of per-table return types, because its writes return no rows.
|
|
1006
|
+
*/
|
|
714
1007
|
type GeneratedOutputs<TSchema extends Record<string, Table>, IsReturnless extends boolean> = {
|
|
715
|
-
[TName in keyof TSchema as TName extends string ?
|
|
1008
|
+
[TName in keyof TSchema as TName extends string ? Capitalize<TName> : never]: GraphQLObjectType;
|
|
716
1009
|
} & {
|
|
717
1010
|
[TName in keyof TSchema as TName extends string ? `${Capitalize<TName>}Aggregate` : never]: GraphQLObjectType;
|
|
718
1011
|
} & (IsReturnless extends true ? {
|
|
719
1012
|
MutationReturn: GraphQLObjectType;
|
|
720
1013
|
} : {
|
|
721
|
-
[TName in keyof TSchema as TName extends string ?
|
|
1014
|
+
[TName in keyof TSchema as TName extends string ? Capitalize<TName> : never]: GraphQLObjectType;
|
|
722
1015
|
});
|
|
723
1016
|
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
1017
|
queries: QueriesCore<TSchemaTables, TSchemaRelations, TInputs, TOutputs>;
|
|
@@ -750,7 +1043,8 @@ type GeneratedData<TDatabase extends AnyDrizzleDB<any>> = {
|
|
|
750
1043
|
type FeatureSwitch = boolean | ((tableName: string) => boolean);
|
|
751
1044
|
/**
|
|
752
1045
|
* Per-feature switches for what `buildSchema` generates. Every flag defaults to `true` except
|
|
753
|
-
* `upsert`, `nestedWrites`, `fieldUpdateOperations`, `countMutations` and
|
|
1046
|
+
* `upsert`, `nestedWrites`, `fieldUpdateOperations`, `countMutations`, `requireWhere` and
|
|
1047
|
+
* `uniqueKeyFilters`.
|
|
754
1048
|
* Each one takes a boolean or a per-table predicate, apart from `nestedWrites`, which is
|
|
755
1049
|
* build-wide.
|
|
756
1050
|
* See {@link BuildSchemaConfig.features}.
|
|
@@ -885,6 +1179,29 @@ type SchemaFeatures = {
|
|
|
885
1179
|
* @default false
|
|
886
1180
|
*/
|
|
887
1181
|
requireWhere?: FeatureSwitch;
|
|
1182
|
+
/**
|
|
1183
|
+
* One `where` field per compound unique constraint, so a lookup by a natural key names the
|
|
1184
|
+
* key instead of restating its columns:
|
|
1185
|
+
*
|
|
1186
|
+
* ```graphql
|
|
1187
|
+
* stockSingle(where: { itemId_locationId: { itemId: "i1", locationId: "l1" } }) { quantity }
|
|
1188
|
+
* ```
|
|
1189
|
+
*
|
|
1190
|
+
* The field is named after its member columns and every member is non-null, so a half-
|
|
1191
|
+
* supplied key fails query validation rather than becoming a broader filter that returns
|
|
1192
|
+
* whichever row happens to come first. It compiles to the same equalities the columns would
|
|
1193
|
+
* have — the guarantee is in the input type.
|
|
1194
|
+
*
|
|
1195
|
+
* Single-column constraints get no field (`eq` on the column already says it), and a
|
|
1196
|
+
* constraint whose field name is taken by a column or a relation is skipped. The fields live
|
|
1197
|
+
* on `<Type>Filters`, so they are accepted wherever a filter is: the `Single` reads and
|
|
1198
|
+
* writes they are meant for, but also list queries, relation filters and `onConflict.where`.
|
|
1199
|
+
*
|
|
1200
|
+
* Off unless asked for: it adds an input type per compound constraint.
|
|
1201
|
+
*
|
|
1202
|
+
* @default false
|
|
1203
|
+
*/
|
|
1204
|
+
uniqueKeyFilters?: FeatureSwitch;
|
|
888
1205
|
};
|
|
889
1206
|
/**
|
|
890
1207
|
* Per-field cost hints for `graphql-query-complexity` (or any estimator that reads
|
|
@@ -995,6 +1312,33 @@ type SoftDeleteColumn = string | {
|
|
|
995
1312
|
* for a NOT NULL boolean; required for any other NOT NULL column.
|
|
996
1313
|
*/
|
|
997
1314
|
restoredValue?: any;
|
|
1315
|
+
/**
|
|
1316
|
+
* Which generated reads hide marked rows by default.
|
|
1317
|
+
*
|
|
1318
|
+
* - `'all'` (the default) — the table's own query fields and every relation field that
|
|
1319
|
+
* points at it. A *required* to-one relation is the one exception: hiding the row
|
|
1320
|
+
* there can only produce "Cannot return null for non-nullable field", never a usable
|
|
1321
|
+
* result, so it reads `INCLUDE` unless the request says otherwise.
|
|
1322
|
+
* - `'root'` — only the table's own query fields. Relation fields read marked rows,
|
|
1323
|
+
* which is what "retired, not erased" usually means: keep the row off the pickers and
|
|
1324
|
+
* the lists, keep rendering it on the historical rows that reference it.
|
|
1325
|
+
*
|
|
1326
|
+
* The `deleted` argument is generated either way, so either default can be overridden
|
|
1327
|
+
* per request.
|
|
1328
|
+
*/
|
|
1329
|
+
scope?: 'root' | 'all';
|
|
1330
|
+
/**
|
|
1331
|
+
* Whether the table's delete mutations accept `hard: Boolean = false`, which issues a
|
|
1332
|
+
* real `DELETE` instead of writing the marker — emptying the trash, reclaiming a unique
|
|
1333
|
+
* key, clearing a table. Opt-in per table, and the argument is only generated when it is
|
|
1334
|
+
* on, so the schema itself says which tables can be purged.
|
|
1335
|
+
*
|
|
1336
|
+
* A hard delete reads at `INCLUDE`: it reaches already-marked rows, which is the case it
|
|
1337
|
+
* mostly exists for. A `scope` still confines it, exactly as it confines every other write.
|
|
1338
|
+
*
|
|
1339
|
+
* @default false
|
|
1340
|
+
*/
|
|
1341
|
+
hardDelete?: boolean;
|
|
998
1342
|
};
|
|
999
1343
|
|
|
1000
1344
|
/**
|
|
@@ -1466,6 +1810,58 @@ type BuildSchemaConfig = {
|
|
|
1466
1810
|
singular: string;
|
|
1467
1811
|
plural: string;
|
|
1468
1812
|
} | undefined);
|
|
1813
|
+
/**
|
|
1814
|
+
* Renames the types generated *around* a table — the filter, the write inputs, the
|
|
1815
|
+
* order-by, the aggregate family, the group-by types, the conflict input, the shared scalar
|
|
1816
|
+
* filters. `typeNameMapper` names a table's object type and its root fields; those derived
|
|
1817
|
+
* names follow from it by a fixed rule, and this is the hook that overrides the rule.
|
|
1818
|
+
*
|
|
1819
|
+
* Asked once per generated type, with the kind, the name the library would use, and the
|
|
1820
|
+
* table it belongs to where it belongs to one. Return `undefined` — or the same name — to
|
|
1821
|
+
* keep the default, so a mapper that answers for one kind leaves everything else alone:
|
|
1822
|
+
*
|
|
1823
|
+
* ```ts
|
|
1824
|
+
* buildSchema(db, {
|
|
1825
|
+
* derivedTypeNameMapper: ({ kind, table, operation, defaultName }) =>
|
|
1826
|
+
* kind === 'aggregate' && operation ? `${table}Aggregate${operation}` : undefined,
|
|
1827
|
+
* });
|
|
1828
|
+
* ```
|
|
1829
|
+
*
|
|
1830
|
+
* A returned name is used verbatim — {@link BuildSchemaConfig.typeNamePrefix} and
|
|
1831
|
+
* {@link BuildSchemaConfig.typeNameSuffix} do not wrap it, since the more specific of the
|
|
1832
|
+
* two knobs wins.
|
|
1833
|
+
*
|
|
1834
|
+
* The point of it is stitching: a schema merged with a second generator over the same
|
|
1835
|
+
* tables collides on the derived names constantly, because both derive them from the model
|
|
1836
|
+
* name by the same obvious rule. Renaming them here means the collision never exists, rather
|
|
1837
|
+
* than being papered over by a `RenameTypes` transform on the way out.
|
|
1838
|
+
*/
|
|
1839
|
+
derivedTypeNameMapper?: DerivedTypeNameMapper;
|
|
1840
|
+
/**
|
|
1841
|
+
* Prepended to every generated type name — object types, filters, write inputs, the
|
|
1842
|
+
* aggregate family, the shared scalar filters, everything — that
|
|
1843
|
+
* {@link BuildSchemaConfig.derivedTypeNameMapper} did not answer for. The one-line way to
|
|
1844
|
+
* make a whole subschema collision-free before stitching it:
|
|
1845
|
+
*
|
|
1846
|
+
* ```ts
|
|
1847
|
+
* buildSchema(db, { typeNamePrefix: 'Db' });
|
|
1848
|
+
* // type DbUsers, input DbUsersFilters, input DbStringFilter, enum DbOrderNulls, …
|
|
1849
|
+
* ```
|
|
1850
|
+
*
|
|
1851
|
+
* Custom scalars, database enum types and `PgGeometryObject` keep their own names: their
|
|
1852
|
+
* definition does not vary between builds, so a gateway merges them rather than colliding
|
|
1853
|
+
* on them. Field and argument names are untouched too — only type names move, so a client's
|
|
1854
|
+
* queries are unaffected apart from the names it spells in variable declarations.
|
|
1855
|
+
*
|
|
1856
|
+
* Must be a valid GraphQL name start (`/^[_A-Za-z][_0-9A-Za-z]*$/`); anything else throws.
|
|
1857
|
+
*/
|
|
1858
|
+
typeNamePrefix?: string;
|
|
1859
|
+
/**
|
|
1860
|
+
* Appended to every generated type name that {@link BuildSchemaConfig.derivedTypeNameMapper}
|
|
1861
|
+
* did not answer for. The counterpart of {@link BuildSchemaConfig.typeNamePrefix}; both may
|
|
1862
|
+
* be given at once.
|
|
1863
|
+
*/
|
|
1864
|
+
typeNameSuffix?: string;
|
|
1469
1865
|
/**
|
|
1470
1866
|
* Controls whether a relation is eagerly pre-fetched via Drizzle's `with:` clause
|
|
1471
1867
|
* when its parent is loaded through a generated query or mutation.
|
|
@@ -1682,110 +2078,6 @@ declare const singularizeMapper: (tableName: string) => {
|
|
|
1682
2078
|
plural: string;
|
|
1683
2079
|
};
|
|
1684
2080
|
|
|
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
2081
|
/**
|
|
1790
2082
|
* A 64-bit integer. Always transported as a decimal string, in both directions, so no value
|
|
1791
2083
|
* is ever silently rounded by JSON's double-precision numbers. `graphql-scalars`' own
|
|
@@ -1813,6 +2105,14 @@ type SelectionOptions = {
|
|
|
1813
2105
|
* pass the same mapper here or nothing will match.
|
|
1814
2106
|
*/
|
|
1815
2107
|
typeNameMapper?: TypeNameMapper;
|
|
2108
|
+
/**
|
|
2109
|
+
* The `derivedTypeNameMapper` / `typeNamePrefix` / `typeNameSuffix` the schema was built
|
|
2110
|
+
* with, when any were configured. Same reason as `typeNameMapper`: the translation matches
|
|
2111
|
+
* selections against the names the build actually published.
|
|
2112
|
+
*/
|
|
2113
|
+
derivedTypeNameMapper?: DerivedTypeNameMapper;
|
|
2114
|
+
typeNamePrefix?: string;
|
|
2115
|
+
typeNameSuffix?: string;
|
|
1816
2116
|
};
|
|
1817
2117
|
/**
|
|
1818
2118
|
* Translates a GraphQL selection set into the relational query builder's `with` tree — the
|
|
@@ -1872,4 +2172,4 @@ declare const resolveSelection: (info: GraphQLResolveInfo | ResolveTree, options
|
|
|
1872
2172
|
|
|
1873
2173
|
declare const buildSchema: <TDbClient extends AnyDrizzleDB<any>>(db: TDbClient, config?: BuildSchemaConfig) => GeneratedData<TDbClient>;
|
|
1874
2174
|
|
|
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 };
|
|
2175
|
+
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 };
|