drizzle-graphql-plus 0.8.6 → 0.8.8

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.
@@ -1,524 +1,622 @@
1
- import { createTableRelationsHelpers, is, Relation, Relations, Table } from 'drizzle-orm';
2
- import { BaseSQLiteDatabase, SQLiteColumn, SQLiteTable } from 'drizzle-orm/sqlite-core';
3
1
  import {
4
- GraphQLError,
5
- GraphQLInputObjectType,
6
- GraphQLInt,
7
- GraphQLList,
8
- GraphQLNonNull,
9
- GraphQLObjectType,
10
- } from 'graphql';
2
+ createTableRelationsHelpers,
3
+ is,
4
+ Relation,
5
+ Relations,
6
+ Table,
7
+ } from "drizzle-orm";
8
+ import {
9
+ BaseSQLiteDatabase,
10
+ SQLiteColumn,
11
+ SQLiteTable,
12
+ } from "drizzle-orm/sqlite-core";
13
+ import {
14
+ GraphQLError,
15
+ GraphQLInputObjectType,
16
+ GraphQLInt,
17
+ GraphQLInterfaceType,
18
+ GraphQLList,
19
+ GraphQLNonNull,
20
+ GraphQLObjectType,
21
+ } from "graphql";
11
22
 
12
23
  import {
13
- extractFilters,
14
- extractOrderBy,
15
- extractRelationsParams,
16
- extractSelectedColumnsFromTree,
17
- extractSelectedColumnsFromTreeSQLFormat,
18
- generateTableTypes,
19
- } from '@/util/builders/common';
20
- import { capitalize, uncapitalize } from '@/util/case-ops';
24
+ extractFilters,
25
+ extractOrderBy,
26
+ extractRelationsParams,
27
+ extractSelectedColumnsFromTree,
28
+ extractSelectedColumnsFromTreeSQLFormat,
29
+ generateTableTypes,
30
+ } from "@/util/builders/common";
31
+ import { capitalize, uncapitalize } from "@/util/case-ops";
21
32
  import {
22
- remapFromGraphQLArrayInput,
23
- remapFromGraphQLSingleInput,
24
- remapToGraphQLArrayOutput,
25
- remapToGraphQLSingleOutput,
26
- } from '@/util/data-mappers';
27
- import { parseResolveInfo } from 'graphql-parse-resolve-info';
28
-
29
- import type { GeneratedEntities } from '@/types';
30
- import type { RelationalQueryBuilder } from 'drizzle-orm/mysql-core/query-builders/query';
31
- import type { GraphQLFieldConfig, GraphQLFieldConfigArgumentMap, ThunkObjMap } from 'graphql';
32
- import type { ResolveTree } from 'graphql-parse-resolve-info';
33
- import type { CreatedResolver, Filters, TableNamedRelations, TableSelectArgs } from './types';
33
+ remapFromGraphQLArrayInput,
34
+ remapFromGraphQLSingleInput,
35
+ remapToGraphQLArrayOutput,
36
+ remapToGraphQLSingleOutput,
37
+ } from "@/util/data-mappers";
38
+ import { parseResolveInfo } from "graphql-parse-resolve-info";
39
+
40
+ import type { GeneratedEntities } from "@/types";
41
+ import type { RelationalQueryBuilder } from "drizzle-orm/mysql-core/query-builders/query";
42
+ import type {
43
+ GraphQLFieldConfig,
44
+ GraphQLFieldConfigArgumentMap,
45
+ ThunkObjMap,
46
+ } from "graphql";
47
+ import type { ResolveTree } from "graphql-parse-resolve-info";
48
+ import type {
49
+ CreatedResolver,
50
+ Filters,
51
+ TableNamedRelations,
52
+ TableSelectArgs,
53
+ } from "./types";
34
54
 
35
55
  const generateSelectArray = (
36
- db: BaseSQLiteDatabase<any, any, any, any>,
37
- tableName: string,
38
- tables: Record<string, Table>,
39
- relationMap: Record<string, Record<string, TableNamedRelations>>,
40
- orderArgs: GraphQLInputObjectType,
41
- filterArgs: GraphQLInputObjectType,
56
+ db: BaseSQLiteDatabase<any, any, any, any>,
57
+ tableName: string,
58
+ tables: Record<string, Table>,
59
+ relationMap: Record<string, Record<string, TableNamedRelations>>,
60
+ orderArgs: GraphQLInputObjectType,
61
+ filterArgs: GraphQLInputObjectType
42
62
  ): CreatedResolver => {
43
- const queryName = `${uncapitalize(tableName)}`;
44
- const queryBase = db.query[tableName as keyof typeof db.query] as unknown as
45
- | RelationalQueryBuilder<any, any, any>
46
- | undefined;
47
- if (!queryBase) {
48
- throw new Error(
49
- `Drizzle-GraphQL Error: Table ${tableName} not found in drizzle instance. Did you forget to pass schema to drizzle constructor?`,
50
- );
51
- }
52
-
53
- const queryArgs = {
54
- offset: {
55
- type: GraphQLInt,
56
- },
57
- limit: {
58
- type: GraphQLInt,
59
- },
60
- orderBy: {
61
- type: orderArgs,
62
- },
63
- where: {
64
- type: filterArgs,
65
- },
66
- } as GraphQLFieldConfigArgumentMap;
67
-
68
- const typeName = `${capitalize(tableName)}SelectItem`;
69
- const table = tables[tableName]!;
70
-
71
- return {
72
- name: queryName,
73
- resolver: async (source, args: Partial<TableSelectArgs>, context, info) => {
74
- try {
75
- const { offset, limit, orderBy, where } = args;
76
-
77
- const parsedInfo = parseResolveInfo(info, {
78
- deep: true,
79
- }) as ResolveTree;
80
-
81
- const query = queryBase.findMany({
82
- columns: extractSelectedColumnsFromTree(
83
- parsedInfo.fieldsByTypeName[typeName]!,
84
- table,
85
- ),
86
- offset,
87
- limit,
88
- orderBy: orderBy ? extractOrderBy(table, orderBy) : undefined,
89
- where: where ? extractFilters(table, tableName, where) : undefined,
90
- with: relationMap[tableName]
91
- ? extractRelationsParams(relationMap, tables, tableName, parsedInfo, typeName)
92
- : undefined,
93
- });
94
-
95
- const result = await query;
96
-
97
- return remapToGraphQLArrayOutput(result, tableName, table, relationMap);
98
- } catch (e) {
99
- if (typeof e === 'object' && typeof (<any> e).message === 'string') {
100
- throw new GraphQLError((<any> e).message);
101
- }
102
-
103
- throw e;
104
- }
105
- },
106
- args: queryArgs,
107
- };
63
+ const queryName = `${uncapitalize(tableName)}`;
64
+ const queryBase = db.query[tableName as keyof typeof db.query] as unknown as
65
+ | RelationalQueryBuilder<any, any, any>
66
+ | undefined;
67
+ if (!queryBase) {
68
+ throw new Error(
69
+ `Drizzle-GraphQL Error: Table ${tableName} not found in drizzle instance. Did you forget to pass schema to drizzle constructor?`
70
+ );
71
+ }
72
+
73
+ const queryArgs = {
74
+ offset: {
75
+ type: GraphQLInt,
76
+ },
77
+ limit: {
78
+ type: GraphQLInt,
79
+ },
80
+ orderBy: {
81
+ type: orderArgs,
82
+ },
83
+ where: {
84
+ type: filterArgs,
85
+ },
86
+ } as GraphQLFieldConfigArgumentMap;
87
+
88
+ const typeName = `${capitalize(tableName)}SelectItem`;
89
+ const table = tables[tableName]!;
90
+
91
+ return {
92
+ name: queryName,
93
+ resolver: async (source, args: Partial<TableSelectArgs>, context, info) => {
94
+ try {
95
+ const { offset, limit, orderBy, where } = args;
96
+
97
+ const parsedInfo = parseResolveInfo(info, {
98
+ deep: true,
99
+ }) as ResolveTree;
100
+
101
+ const query = queryBase.findMany({
102
+ columns: extractSelectedColumnsFromTree(
103
+ parsedInfo.fieldsByTypeName[typeName]!,
104
+ table
105
+ ),
106
+ offset,
107
+ limit,
108
+ orderBy: orderBy ? extractOrderBy(table, orderBy) : undefined,
109
+ where: where ? extractFilters(table, tableName, where) : undefined,
110
+ with: relationMap[tableName]
111
+ ? extractRelationsParams(
112
+ relationMap,
113
+ tables,
114
+ tableName,
115
+ parsedInfo,
116
+ typeName
117
+ )
118
+ : undefined,
119
+ });
120
+
121
+ const result = await query;
122
+
123
+ return remapToGraphQLArrayOutput(result, tableName, table, relationMap);
124
+ } catch (e) {
125
+ if (typeof e === "object" && typeof (<any>e).message === "string") {
126
+ throw new GraphQLError((<any>e).message);
127
+ }
128
+
129
+ throw e;
130
+ }
131
+ },
132
+ args: queryArgs,
133
+ };
108
134
  };
109
135
 
110
136
  const generateSelectSingle = (
111
- db: BaseSQLiteDatabase<any, any, any, any>,
112
- tableName: string,
113
- tables: Record<string, Table>,
114
- relationMap: Record<string, Record<string, TableNamedRelations>>,
115
- orderArgs: GraphQLInputObjectType,
116
- filterArgs: GraphQLInputObjectType,
137
+ db: BaseSQLiteDatabase<any, any, any, any>,
138
+ tableName: string,
139
+ tables: Record<string, Table>,
140
+ relationMap: Record<string, Record<string, TableNamedRelations>>,
141
+ orderArgs: GraphQLInputObjectType,
142
+ filterArgs: GraphQLInputObjectType
117
143
  ): CreatedResolver => {
118
- const queryName = `${uncapitalize(tableName)}Single`;
119
- const queryBase = db.query[tableName as keyof typeof db.query] as unknown as
120
- | RelationalQueryBuilder<any, any, any>
121
- | undefined;
122
- if (!queryBase) {
123
- throw new Error(
124
- `Drizzle-GraphQL Error: Table ${tableName} not found in drizzle instance. Did you forget to pass schema to drizzle constructor?`,
125
- );
126
- }
127
-
128
- const queryArgs = {
129
- offset: {
130
- type: GraphQLInt,
131
- },
132
- orderBy: {
133
- type: orderArgs,
134
- },
135
- where: {
136
- type: filterArgs,
137
- },
138
- } as GraphQLFieldConfigArgumentMap;
139
-
140
- const typeName = `${capitalize(tableName)}SelectItem`;
141
- const table = tables[tableName]!;
142
-
143
- return {
144
- name: queryName,
145
- resolver: async (source, args: Partial<TableSelectArgs>, context, info) => {
146
- try {
147
- const { offset, orderBy, where } = args;
148
-
149
- const parsedInfo = parseResolveInfo(info, {
150
- deep: true,
151
- }) as ResolveTree;
152
-
153
- const query = queryBase.findFirst({
154
- columns: extractSelectedColumnsFromTree(
155
- parsedInfo.fieldsByTypeName[typeName]!,
156
- table,
157
- ),
158
- offset,
159
- orderBy: orderBy ? extractOrderBy(table, orderBy) : undefined,
160
- where: where ? extractFilters(table, tableName, where) : undefined,
161
- with: relationMap[tableName]
162
- ? extractRelationsParams(relationMap, tables, tableName, parsedInfo, typeName)
163
- : undefined,
164
- });
165
-
166
- const result = await query;
167
- if (!result) return undefined;
168
-
169
- return remapToGraphQLSingleOutput(result, tableName, table, relationMap);
170
- } catch (e) {
171
- if (typeof e === 'object' && typeof (<any> e).message === 'string') {
172
- throw new GraphQLError((<any> e).message);
173
- }
174
-
175
- throw e;
176
- }
177
- },
178
- args: queryArgs,
179
- };
144
+ const queryName = `${uncapitalize(tableName)}Single`;
145
+ const queryBase = db.query[tableName as keyof typeof db.query] as unknown as
146
+ | RelationalQueryBuilder<any, any, any>
147
+ | undefined;
148
+ if (!queryBase) {
149
+ throw new Error(
150
+ `Drizzle-GraphQL Error: Table ${tableName} not found in drizzle instance. Did you forget to pass schema to drizzle constructor?`
151
+ );
152
+ }
153
+
154
+ const queryArgs = {
155
+ offset: {
156
+ type: GraphQLInt,
157
+ },
158
+ orderBy: {
159
+ type: orderArgs,
160
+ },
161
+ where: {
162
+ type: filterArgs,
163
+ },
164
+ } as GraphQLFieldConfigArgumentMap;
165
+
166
+ const typeName = `${capitalize(tableName)}SelectItem`;
167
+ const table = tables[tableName]!;
168
+
169
+ return {
170
+ name: queryName,
171
+ resolver: async (source, args: Partial<TableSelectArgs>, context, info) => {
172
+ try {
173
+ const { offset, orderBy, where } = args;
174
+
175
+ const parsedInfo = parseResolveInfo(info, {
176
+ deep: true,
177
+ }) as ResolveTree;
178
+
179
+ const query = queryBase.findFirst({
180
+ columns: extractSelectedColumnsFromTree(
181
+ parsedInfo.fieldsByTypeName[typeName]!,
182
+ table
183
+ ),
184
+ offset,
185
+ orderBy: orderBy ? extractOrderBy(table, orderBy) : undefined,
186
+ where: where ? extractFilters(table, tableName, where) : undefined,
187
+ with: relationMap[tableName]
188
+ ? extractRelationsParams(
189
+ relationMap,
190
+ tables,
191
+ tableName,
192
+ parsedInfo,
193
+ typeName
194
+ )
195
+ : undefined,
196
+ });
197
+
198
+ const result = await query;
199
+ if (!result) return undefined;
200
+
201
+ return remapToGraphQLSingleOutput(
202
+ result,
203
+ tableName,
204
+ table,
205
+ relationMap
206
+ );
207
+ } catch (e) {
208
+ if (typeof e === "object" && typeof (<any>e).message === "string") {
209
+ throw new GraphQLError((<any>e).message);
210
+ }
211
+
212
+ throw e;
213
+ }
214
+ },
215
+ args: queryArgs,
216
+ };
180
217
  };
181
218
 
182
219
  const generateInsertArray = (
183
- db: BaseSQLiteDatabase<any, any, any, any>,
184
- tableName: string,
185
- table: SQLiteTable,
186
- baseType: GraphQLInputObjectType,
220
+ db: BaseSQLiteDatabase<any, any, any, any>,
221
+ tableName: string,
222
+ table: SQLiteTable,
223
+ baseType: GraphQLInputObjectType
187
224
  ): CreatedResolver => {
188
- const queryName = `insertInto${capitalize(tableName)}`;
189
- const typeName = `${capitalize(tableName)}Item`;
190
-
191
- const queryArgs: GraphQLFieldConfigArgumentMap = {
192
- values: {
193
- type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(baseType))),
194
- },
195
- };
196
-
197
- return {
198
- name: queryName,
199
- resolver: async (source, args: { values: Record<string, any>[] }, context, info) => {
200
- try {
201
- const input = remapFromGraphQLArrayInput(args.values, table);
202
- if (!input.length) throw new GraphQLError('No values were provided!');
203
-
204
- const parsedInfo = parseResolveInfo(info, {
205
- deep: true,
206
- }) as ResolveTree;
207
-
208
- const columns = extractSelectedColumnsFromTreeSQLFormat<SQLiteColumn>(
209
- parsedInfo.fieldsByTypeName[typeName]!,
210
- table,
211
- );
212
-
213
- const result = await db
214
- .insert(table)
215
- .values(input)
216
- .returning(columns)
217
- .onConflictDoNothing();
218
-
219
- return remapToGraphQLArrayOutput(result, tableName, table);
220
- } catch (e) {
221
- if (typeof e === 'object' && typeof (<any> e).message === 'string') {
222
- throw new GraphQLError((<any> e).message);
223
- }
224
-
225
- throw e;
226
- }
227
- },
228
- args: queryArgs,
229
- };
225
+ const queryName = `insertInto${capitalize(tableName)}`;
226
+ const typeName = `${capitalize(tableName)}Item`;
227
+
228
+ const queryArgs: GraphQLFieldConfigArgumentMap = {
229
+ values: {
230
+ type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(baseType))),
231
+ },
232
+ };
233
+
234
+ return {
235
+ name: queryName,
236
+ resolver: async (
237
+ source,
238
+ args: { values: Record<string, any>[] },
239
+ context,
240
+ info
241
+ ) => {
242
+ try {
243
+ const input = remapFromGraphQLArrayInput(args.values, table);
244
+ if (!input.length) throw new GraphQLError("No values were provided!");
245
+
246
+ const parsedInfo = parseResolveInfo(info, {
247
+ deep: true,
248
+ }) as ResolveTree;
249
+
250
+ const columns = extractSelectedColumnsFromTreeSQLFormat<SQLiteColumn>(
251
+ parsedInfo.fieldsByTypeName[typeName]!,
252
+ table
253
+ );
254
+
255
+ const result = await db
256
+ .insert(table)
257
+ .values(input)
258
+ .returning(columns)
259
+ .onConflictDoNothing();
260
+
261
+ return remapToGraphQLArrayOutput(result, tableName, table);
262
+ } catch (e) {
263
+ if (typeof e === "object" && typeof (<any>e).message === "string") {
264
+ throw new GraphQLError((<any>e).message);
265
+ }
266
+
267
+ throw e;
268
+ }
269
+ },
270
+ args: queryArgs,
271
+ };
230
272
  };
231
273
 
232
274
  const generateInsertSingle = (
233
- db: BaseSQLiteDatabase<any, any, any, any>,
234
- tableName: string,
235
- table: SQLiteTable,
236
- baseType: GraphQLInputObjectType,
275
+ db: BaseSQLiteDatabase<any, any, any, any>,
276
+ tableName: string,
277
+ table: SQLiteTable,
278
+ baseType: GraphQLInputObjectType
237
279
  ): CreatedResolver => {
238
- const queryName = `insertInto${capitalize(tableName)}Single`;
239
- const typeName = `${capitalize(tableName)}Item`;
240
-
241
- const queryArgs: GraphQLFieldConfigArgumentMap = {
242
- values: {
243
- type: new GraphQLNonNull(baseType),
244
- },
245
- };
246
-
247
- return {
248
- name: queryName,
249
- resolver: async (source, args: { values: Record<string, any> }, context, info) => {
250
- try {
251
- const input = remapFromGraphQLSingleInput(args.values, table);
252
-
253
- const parsedInfo = parseResolveInfo(info, {
254
- deep: true,
255
- }) as ResolveTree;
256
-
257
- const columns = extractSelectedColumnsFromTreeSQLFormat<SQLiteColumn>(
258
- parsedInfo.fieldsByTypeName[typeName]!,
259
- table,
260
- );
261
- const result = await db.insert(table).values(input).returning(columns).onConflictDoNothing();
262
-
263
- if (!result[0]) return undefined;
264
-
265
- return remapToGraphQLSingleOutput(result[0], tableName, table);
266
- } catch (e) {
267
- if (typeof e === 'object' && typeof (<any> e).message === 'string') {
268
- throw new GraphQLError((<any> e).message);
269
- }
270
-
271
- throw e;
272
- }
273
- },
274
- args: queryArgs,
275
- };
280
+ const queryName = `insertInto${capitalize(tableName)}Single`;
281
+ const typeName = `${capitalize(tableName)}Item`;
282
+
283
+ const queryArgs: GraphQLFieldConfigArgumentMap = {
284
+ values: {
285
+ type: new GraphQLNonNull(baseType),
286
+ },
287
+ };
288
+
289
+ return {
290
+ name: queryName,
291
+ resolver: async (
292
+ source,
293
+ args: { values: Record<string, any> },
294
+ context,
295
+ info
296
+ ) => {
297
+ try {
298
+ const input = remapFromGraphQLSingleInput(args.values, table);
299
+
300
+ const parsedInfo = parseResolveInfo(info, {
301
+ deep: true,
302
+ }) as ResolveTree;
303
+
304
+ const columns = extractSelectedColumnsFromTreeSQLFormat<SQLiteColumn>(
305
+ parsedInfo.fieldsByTypeName[typeName]!,
306
+ table
307
+ );
308
+ const result = await db
309
+ .insert(table)
310
+ .values(input)
311
+ .returning(columns)
312
+ .onConflictDoNothing();
313
+
314
+ if (!result[0]) return undefined;
315
+
316
+ return remapToGraphQLSingleOutput(result[0], tableName, table);
317
+ } catch (e) {
318
+ if (typeof e === "object" && typeof (<any>e).message === "string") {
319
+ throw new GraphQLError((<any>e).message);
320
+ }
321
+
322
+ throw e;
323
+ }
324
+ },
325
+ args: queryArgs,
326
+ };
276
327
  };
277
328
 
278
329
  const generateUpdate = (
279
- db: BaseSQLiteDatabase<any, any, any, any>,
280
- tableName: string,
281
- table: SQLiteTable,
282
- setArgs: GraphQLInputObjectType,
283
- filterArgs: GraphQLInputObjectType,
330
+ db: BaseSQLiteDatabase<any, any, any, any>,
331
+ tableName: string,
332
+ table: SQLiteTable,
333
+ setArgs: GraphQLInputObjectType,
334
+ filterArgs: GraphQLInputObjectType
284
335
  ): CreatedResolver => {
285
- const queryName = `update${capitalize(tableName)}`;
286
- const typeName = `${capitalize(tableName)}Item`;
287
-
288
- const queryArgs = {
289
- set: {
290
- type: new GraphQLNonNull(setArgs),
291
- },
292
- where: {
293
- type: filterArgs,
294
- },
295
- } as const satisfies GraphQLFieldConfigArgumentMap;
296
-
297
- return {
298
- name: queryName,
299
- resolver: async (source, args: { where?: Filters<Table>; set: Record<string, any> }, context, info) => {
300
- try {
301
- const { where, set } = args;
302
-
303
- const parsedInfo = parseResolveInfo(info, {
304
- deep: true,
305
- }) as ResolveTree;
306
-
307
- const columns = extractSelectedColumnsFromTreeSQLFormat<SQLiteColumn>(
308
- parsedInfo.fieldsByTypeName[typeName]!,
309
- table,
310
- );
311
-
312
- const input = remapFromGraphQLSingleInput(set, table);
313
- if (!Object.keys(input).length) throw new GraphQLError('Unable to update with no values specified!');
314
-
315
- let query = db.update(table).set(input);
316
- if (where) {
317
- const filters = extractFilters(table, tableName, where);
318
- query = query.where(filters) as any;
319
- }
320
-
321
- query = query.returning(columns) as any;
322
-
323
- const result = await query;
324
-
325
- return remapToGraphQLArrayOutput(result, tableName, table);
326
- } catch (e) {
327
- if (typeof e === 'object' && typeof (<any> e).message === 'string') {
328
- throw new GraphQLError((<any> e).message);
329
- }
330
-
331
- throw e;
332
- }
333
- },
334
- args: queryArgs,
335
- };
336
+ const queryName = `update${capitalize(tableName)}`;
337
+ const typeName = `${capitalize(tableName)}Item`;
338
+
339
+ const queryArgs = {
340
+ set: {
341
+ type: new GraphQLNonNull(setArgs),
342
+ },
343
+ where: {
344
+ type: filterArgs,
345
+ },
346
+ } as const satisfies GraphQLFieldConfigArgumentMap;
347
+
348
+ return {
349
+ name: queryName,
350
+ resolver: async (
351
+ source,
352
+ args: { where?: Filters<Table>; set: Record<string, any> },
353
+ context,
354
+ info
355
+ ) => {
356
+ try {
357
+ const { where, set } = args;
358
+
359
+ const parsedInfo = parseResolveInfo(info, {
360
+ deep: true,
361
+ }) as ResolveTree;
362
+
363
+ const columns = extractSelectedColumnsFromTreeSQLFormat<SQLiteColumn>(
364
+ parsedInfo.fieldsByTypeName[typeName]!,
365
+ table
366
+ );
367
+
368
+ const input = remapFromGraphQLSingleInput(set, table);
369
+ if (!Object.keys(input).length)
370
+ throw new GraphQLError("Unable to update with no values specified!");
371
+
372
+ let query = db.update(table).set(input);
373
+ if (where) {
374
+ const filters = extractFilters(table, tableName, where);
375
+ query = query.where(filters) as any;
376
+ }
377
+
378
+ query = query.returning(columns) as any;
379
+
380
+ const result = await query;
381
+
382
+ return remapToGraphQLArrayOutput(result, tableName, table);
383
+ } catch (e) {
384
+ if (typeof e === "object" && typeof (<any>e).message === "string") {
385
+ throw new GraphQLError((<any>e).message);
386
+ }
387
+
388
+ throw e;
389
+ }
390
+ },
391
+ args: queryArgs,
392
+ };
336
393
  };
337
394
 
338
395
  const generateDelete = (
339
- db: BaseSQLiteDatabase<any, any, any, any>,
340
- tableName: string,
341
- table: SQLiteTable,
342
- filterArgs: GraphQLInputObjectType,
396
+ db: BaseSQLiteDatabase<any, any, any, any>,
397
+ tableName: string,
398
+ table: SQLiteTable,
399
+ filterArgs: GraphQLInputObjectType
343
400
  ): CreatedResolver => {
344
- const queryName = `deleteFrom${capitalize(tableName)}`;
345
- const typeName = `${capitalize(tableName)}Item`;
346
-
347
- const queryArgs = {
348
- where: {
349
- type: filterArgs,
350
- },
351
- } as const satisfies GraphQLFieldConfigArgumentMap;
352
-
353
- return {
354
- name: queryName,
355
- resolver: async (source, args: { where?: Filters<Table> }, context, info) => {
356
- try {
357
- const { where } = args;
358
-
359
- const parsedInfo = parseResolveInfo(info, {
360
- deep: true,
361
- }) as ResolveTree;
362
-
363
- const columns = extractSelectedColumnsFromTreeSQLFormat<SQLiteColumn>(
364
- parsedInfo.fieldsByTypeName[typeName]!,
365
- table,
366
- );
367
-
368
- let query = db.delete(table);
369
- if (where) {
370
- const filters = extractFilters(table, tableName, where);
371
- query = query.where(filters) as any;
372
- }
373
-
374
- query = query.returning(columns) as any;
375
-
376
- const result = await query;
377
-
378
- return remapToGraphQLArrayOutput(result, tableName, table);
379
- } catch (e) {
380
- if (typeof e === 'object' && typeof (<any> e).message === 'string') {
381
- throw new GraphQLError((<any> e).message);
382
- }
383
-
384
- throw e;
385
- }
386
- },
387
- args: queryArgs,
388
- };
401
+ const queryName = `deleteFrom${capitalize(tableName)}`;
402
+ const typeName = `${capitalize(tableName)}Item`;
403
+
404
+ const queryArgs = {
405
+ where: {
406
+ type: filterArgs,
407
+ },
408
+ } as const satisfies GraphQLFieldConfigArgumentMap;
409
+
410
+ return {
411
+ name: queryName,
412
+ resolver: async (
413
+ source,
414
+ args: { where?: Filters<Table> },
415
+ context,
416
+ info
417
+ ) => {
418
+ try {
419
+ const { where } = args;
420
+
421
+ const parsedInfo = parseResolveInfo(info, {
422
+ deep: true,
423
+ }) as ResolveTree;
424
+
425
+ const columns = extractSelectedColumnsFromTreeSQLFormat<SQLiteColumn>(
426
+ parsedInfo.fieldsByTypeName[typeName]!,
427
+ table
428
+ );
429
+
430
+ let query = db.delete(table);
431
+ if (where) {
432
+ const filters = extractFilters(table, tableName, where);
433
+ query = query.where(filters) as any;
434
+ }
435
+
436
+ query = query.returning(columns) as any;
437
+
438
+ const result = await query;
439
+
440
+ return remapToGraphQLArrayOutput(result, tableName, table);
441
+ } catch (e) {
442
+ if (typeof e === "object" && typeof (<any>e).message === "string") {
443
+ throw new GraphQLError((<any>e).message);
444
+ }
445
+
446
+ throw e;
447
+ }
448
+ },
449
+ args: queryArgs,
450
+ };
389
451
  };
390
452
 
391
453
  export const generateSchemaData = <
392
- TDrizzleInstance extends BaseSQLiteDatabase<any, any, any, any>,
393
- TSchema extends Record<string, Table | unknown>,
454
+ TDrizzleInstance extends BaseSQLiteDatabase<any, any, any, any>,
455
+ TSchema extends Record<string, Table | unknown>
394
456
  >(
395
- db: TDrizzleInstance,
396
- schema: TSchema,
397
- relationsDepthLimit: number | undefined,
457
+ db: TDrizzleInstance,
458
+ schema: TSchema,
459
+ relationsDepthLimit: number | undefined
398
460
  ): GeneratedEntities<TDrizzleInstance, TSchema> => {
399
- const rawSchema = schema;
400
- const schemaEntries = Object.entries(rawSchema);
401
-
402
- const tableEntries = schemaEntries.filter(([key, value]) => is(value, SQLiteTable)) as [string, SQLiteTable][];
403
- const tables = Object.fromEntries(tableEntries) as Record<
404
- string,
405
- SQLiteTable
406
- >;
407
-
408
- if (!tableEntries.length) {
409
- throw new Error(
410
- "Drizzle-GraphQL Error: No tables detected in Drizzle-ORM's database instance. Did you forget to pass schema to drizzle constructor?",
411
- );
412
- }
413
-
414
- const rawRelations = schemaEntries
415
- .filter(([key, value]) => is(value, Relations))
416
- .map<[string, Relations]>(([key, value]) => [
417
- tableEntries.find(
418
- ([tableName, tableValue]) => tableValue === (value as Relations).table,
419
- )![0] as string,
420
- value as Relations,
421
- ]).map<[string, Record<string, Relation>]>(([tableName, relValue]) => [
422
- tableName,
423
- relValue.config(createTableRelationsHelpers(tables[tableName]!)),
424
- ]);
425
-
426
- const namedRelations = Object.fromEntries(
427
- rawRelations
428
- .map(([relName, config]) => {
429
- const namedConfig: Record<string, TableNamedRelations> = Object.fromEntries(
430
- Object.entries(config).map(([innerRelName, innerRelValue]) => [innerRelName, {
431
- relation: innerRelValue,
432
- targetTableName: tableEntries.find(([tableName, tableValue]) =>
433
- tableValue === innerRelValue.referencedTable
434
- )![0],
435
- }]),
436
- );
437
-
438
- return [
439
- relName,
440
- namedConfig,
441
- ];
442
- }),
443
- );
444
-
445
- const queries: ThunkObjMap<GraphQLFieldConfig<any, any>> = {};
446
- const mutations: ThunkObjMap<GraphQLFieldConfig<any, any>> = {};
447
- const gqlSchemaTypes = Object.fromEntries(
448
- Object.entries(tables).map(([tableName, table]) => [
449
- tableName,
450
- generateTableTypes(tableName, tables, namedRelations, true, relationsDepthLimit),
451
- ]),
452
- );
453
-
454
- const inputs: Record<string, GraphQLInputObjectType> = {};
455
- const outputs: Record<string, GraphQLObjectType> = {};
456
-
457
- for (const [tableName, tableTypes] of Object.entries(gqlSchemaTypes)) {
458
- const { insertInput, updateInput, tableFilters, tableOrder } = tableTypes.inputs;
459
- const { selectSingleOutput, selectArrOutput, singleTableItemOutput, arrTableItemOutput } = tableTypes.outputs;
460
-
461
- const selectArrGenerated = generateSelectArray(
462
- db,
463
- tableName,
464
- tables,
465
- namedRelations,
466
- tableOrder,
467
- tableFilters,
468
- );
469
- const selectSingleGenerated = generateSelectSingle(
470
- db,
471
- tableName,
472
- tables,
473
- namedRelations,
474
- tableOrder,
475
- tableFilters,
476
- );
477
- const insertArrGenerated = generateInsertArray(db, tableName, schema[tableName] as SQLiteTable, insertInput);
478
- const insertSingleGenerated = generateInsertSingle(db, tableName, schema[tableName] as SQLiteTable, insertInput);
479
- const updateGenerated = generateUpdate(
480
- db,
481
- tableName,
482
- schema[tableName] as SQLiteTable,
483
- updateInput,
484
- tableFilters,
485
- );
486
- const deleteGenerated = generateDelete(db, tableName, schema[tableName] as SQLiteTable, tableFilters);
487
-
488
- queries[selectArrGenerated.name] = {
489
- type: selectArrOutput,
490
- args: selectArrGenerated.args,
491
- resolve: selectArrGenerated.resolver,
492
- };
493
- queries[selectSingleGenerated.name] = {
494
- type: selectSingleOutput,
495
- args: selectSingleGenerated.args,
496
- resolve: selectSingleGenerated.resolver,
497
- };
498
- mutations[insertArrGenerated.name] = {
499
- type: arrTableItemOutput,
500
- args: insertArrGenerated.args,
501
- resolve: insertArrGenerated.resolver,
502
- };
503
- mutations[insertSingleGenerated.name] = {
504
- type: singleTableItemOutput,
505
- args: insertSingleGenerated.args,
506
- resolve: insertSingleGenerated.resolver,
507
- };
508
- mutations[updateGenerated.name] = {
509
- type: arrTableItemOutput,
510
- args: updateGenerated.args,
511
- resolve: updateGenerated.resolver,
512
- };
513
- mutations[deleteGenerated.name] = {
514
- type: arrTableItemOutput,
515
- args: deleteGenerated.args,
516
- resolve: deleteGenerated.resolver,
517
- };
518
- [insertInput, updateInput, tableFilters, tableOrder].forEach((e) => (inputs[e.name] = e));
519
- outputs[selectSingleOutput.name] = selectSingleOutput;
520
- outputs[singleTableItemOutput.name] = singleTableItemOutput;
521
- }
522
-
523
- return { queries, mutations, inputs, types: outputs } as any;
461
+ const rawSchema = schema;
462
+ const schemaEntries = Object.entries(rawSchema);
463
+
464
+ const tableEntries = schemaEntries.filter(([key, value]) =>
465
+ is(value, SQLiteTable)
466
+ ) as [string, SQLiteTable][];
467
+ const tables = Object.fromEntries(tableEntries) as Record<
468
+ string,
469
+ SQLiteTable
470
+ >;
471
+
472
+ if (!tableEntries.length) {
473
+ throw new Error(
474
+ "Drizzle-GraphQL Error: No tables detected in Drizzle-ORM's database instance. Did you forget to pass schema to drizzle constructor?"
475
+ );
476
+ }
477
+
478
+ const rawRelations = schemaEntries
479
+ .filter(([key, value]) => is(value, Relations))
480
+ .map<[string, Relations]>(([key, value]) => [
481
+ tableEntries.find(
482
+ ([tableName, tableValue]) => tableValue === (value as Relations).table
483
+ )![0] as string,
484
+ value as Relations,
485
+ ])
486
+ .map<[string, Record<string, Relation>]>(([tableName, relValue]) => [
487
+ tableName,
488
+ relValue.config(createTableRelationsHelpers(tables[tableName]!)),
489
+ ]);
490
+
491
+ const namedRelations = Object.fromEntries(
492
+ rawRelations.map(([relName, config]) => {
493
+ const namedConfig: Record<string, TableNamedRelations> =
494
+ Object.fromEntries(
495
+ Object.entries(config).map(([innerRelName, innerRelValue]) => [
496
+ innerRelName,
497
+ {
498
+ relation: innerRelValue,
499
+ targetTableName: tableEntries.find(
500
+ ([tableName, tableValue]) =>
501
+ tableValue === innerRelValue.referencedTable
502
+ )![0],
503
+ },
504
+ ])
505
+ );
506
+
507
+ return [relName, namedConfig];
508
+ })
509
+ );
510
+
511
+ const queries: ThunkObjMap<GraphQLFieldConfig<any, any>> = {};
512
+ const mutations: ThunkObjMap<GraphQLFieldConfig<any, any>> = {};
513
+ const gqlSchemaTypes = Object.fromEntries(
514
+ Object.entries(tables).map(([tableName, table]) => [
515
+ tableName,
516
+ generateTableTypes(
517
+ tableName,
518
+ tables,
519
+ namedRelations,
520
+ true,
521
+ relationsDepthLimit
522
+ ),
523
+ ])
524
+ );
525
+
526
+ const inputs: Record<string, GraphQLInputObjectType> = {};
527
+ const interfaces: Record<string, GraphQLInterfaceType> = {};
528
+ const outputs: Record<string, GraphQLObjectType> = {};
529
+
530
+ for (const [tableName, tableTypes] of Object.entries(gqlSchemaTypes)) {
531
+ const { insertInput, updateInput, tableFilters, tableOrder } =
532
+ tableTypes.inputs;
533
+ const {
534
+ selectSingleOutput,
535
+ selectArrOutput,
536
+ singleTableItemOutput,
537
+ arrTableItemOutput,
538
+ tableFieldsInterface,
539
+ } = tableTypes.outputs;
540
+
541
+ const selectArrGenerated = generateSelectArray(
542
+ db,
543
+ tableName,
544
+ tables,
545
+ namedRelations,
546
+ tableOrder,
547
+ tableFilters
548
+ );
549
+ const selectSingleGenerated = generateSelectSingle(
550
+ db,
551
+ tableName,
552
+ tables,
553
+ namedRelations,
554
+ tableOrder,
555
+ tableFilters
556
+ );
557
+ const insertArrGenerated = generateInsertArray(
558
+ db,
559
+ tableName,
560
+ schema[tableName] as SQLiteTable,
561
+ insertInput
562
+ );
563
+ const insertSingleGenerated = generateInsertSingle(
564
+ db,
565
+ tableName,
566
+ schema[tableName] as SQLiteTable,
567
+ insertInput
568
+ );
569
+ const updateGenerated = generateUpdate(
570
+ db,
571
+ tableName,
572
+ schema[tableName] as SQLiteTable,
573
+ updateInput,
574
+ tableFilters
575
+ );
576
+ const deleteGenerated = generateDelete(
577
+ db,
578
+ tableName,
579
+ schema[tableName] as SQLiteTable,
580
+ tableFilters
581
+ );
582
+
583
+ queries[selectArrGenerated.name] = {
584
+ type: selectArrOutput,
585
+ args: selectArrGenerated.args,
586
+ resolve: selectArrGenerated.resolver,
587
+ };
588
+ queries[selectSingleGenerated.name] = {
589
+ type: selectSingleOutput,
590
+ args: selectSingleGenerated.args,
591
+ resolve: selectSingleGenerated.resolver,
592
+ };
593
+ mutations[insertArrGenerated.name] = {
594
+ type: arrTableItemOutput,
595
+ args: insertArrGenerated.args,
596
+ resolve: insertArrGenerated.resolver,
597
+ };
598
+ mutations[insertSingleGenerated.name] = {
599
+ type: singleTableItemOutput,
600
+ args: insertSingleGenerated.args,
601
+ resolve: insertSingleGenerated.resolver,
602
+ };
603
+ mutations[updateGenerated.name] = {
604
+ type: arrTableItemOutput,
605
+ args: updateGenerated.args,
606
+ resolve: updateGenerated.resolver,
607
+ };
608
+ mutations[deleteGenerated.name] = {
609
+ type: arrTableItemOutput,
610
+ args: deleteGenerated.args,
611
+ resolve: deleteGenerated.resolver,
612
+ };
613
+ [insertInput, updateInput, tableFilters, tableOrder].forEach(
614
+ (e) => (inputs[e.name] = e)
615
+ );
616
+ outputs[selectSingleOutput.name] = selectSingleOutput;
617
+ outputs[singleTableItemOutput.name] = singleTableItemOutput;
618
+ interfaces[tableFieldsInterface.name] = tableFieldsInterface;
619
+ }
620
+
621
+ return { queries, mutations, inputs, interfaces, types: outputs } as any;
524
622
  };