@vantreeseba/drizzle-graphql 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,2329 @@
1
+ // src/index.ts
2
+ import { is as is6 } from "drizzle-orm";
3
+ import { MySqlDatabase } from "drizzle-orm/mysql-core";
4
+ import { PgAsyncDatabase } from "drizzle-orm/pg-core";
5
+ import { BaseSQLiteDatabase } from "drizzle-orm/sqlite-core";
6
+ import {
7
+ GraphQLObjectType as GraphQLObjectType4,
8
+ GraphQLSchema
9
+ } from "graphql";
10
+
11
+ // src/util/builders/mysql.ts
12
+ import { is as is3 } from "drizzle-orm";
13
+ import { MySqlTable } from "drizzle-orm/mysql-core";
14
+ import {
15
+ GraphQLBoolean as GraphQLBoolean3,
16
+ GraphQLError as GraphQLError3,
17
+ GraphQLInt as GraphQLInt3,
18
+ GraphQLList as GraphQLList3,
19
+ GraphQLNonNull as GraphQLNonNull3,
20
+ GraphQLObjectType as GraphQLObjectType3
21
+ } from "graphql";
22
+ import { parseResolveInfo } from "graphql-parse-resolve-info";
23
+
24
+ // src/util/builders/common.ts
25
+ import {
26
+ and,
27
+ asc,
28
+ desc,
29
+ eq,
30
+ getColumns as getColumns2,
31
+ gt,
32
+ gte,
33
+ ilike,
34
+ inArray,
35
+ is as is2,
36
+ isNotNull,
37
+ isNull,
38
+ like,
39
+ lt,
40
+ lte,
41
+ ne,
42
+ notIlike,
43
+ notInArray,
44
+ notLike,
45
+ One,
46
+ or
47
+ } from "drizzle-orm";
48
+ import {
49
+ GraphQLBoolean as GraphQLBoolean2,
50
+ GraphQLEnumType as GraphQLEnumType2,
51
+ GraphQLError as GraphQLError2,
52
+ GraphQLInputObjectType as GraphQLInputObjectType2,
53
+ GraphQLInt as GraphQLInt2,
54
+ GraphQLList as GraphQLList2,
55
+ GraphQLNonNull as GraphQLNonNull2,
56
+ GraphQLObjectType as GraphQLObjectType2,
57
+ GraphQLString as GraphQLString2
58
+ } from "graphql";
59
+
60
+ // src/util/case-ops/index.ts
61
+ import pluralize from "pluralize";
62
+ var uncapitalize = (input) => input?.length ? `${input[0].toLocaleLowerCase()}${input.length > 1 ? input.slice(1, input.length) : ""}` : input;
63
+ var capitalize = (input) => input?.length ? `${input[0].toLocaleUpperCase()}${input.length > 1 ? input.slice(1, input.length) : ""}` : input;
64
+ var singularize = (input) => pluralize.singular(input);
65
+
66
+ // src/util/data-mappers/index.ts
67
+ import { getTableColumns } from "drizzle-orm";
68
+ import { GraphQLError } from "graphql";
69
+ var remapToGraphQLCore = (key, value, tableName, column, relationMap) => {
70
+ if (Array.isArray(value)) {
71
+ const relations = relationMap?.[tableName];
72
+ if (relations?.[key]) {
73
+ const rel = relations[key];
74
+ return remapToGraphQLArrayOutput(
75
+ value,
76
+ rel.targetTableName,
77
+ rel.relation?.targetTable ?? rel.relation?.referencedTable,
78
+ relationMap
79
+ );
80
+ }
81
+ }
82
+ if (typeof value === "object" && value !== null) {
83
+ const relations = relationMap?.[tableName];
84
+ if (relations?.[key]) {
85
+ const rel = relations[key];
86
+ const remapped = remapToGraphQLSingleOutput(
87
+ value,
88
+ rel.targetTableName,
89
+ rel.relation?.targetTable ?? rel.relation?.referencedTable,
90
+ relationMap
91
+ );
92
+ return remapped;
93
+ }
94
+ }
95
+ if (!column) {
96
+ return value;
97
+ }
98
+ if (value instanceof Date) {
99
+ return value.toISOString();
100
+ }
101
+ if (value instanceof Buffer) {
102
+ return Array.from(value);
103
+ }
104
+ if (typeof value === "bigint") {
105
+ return value.toString();
106
+ }
107
+ if (Array.isArray(value)) {
108
+ if (column.columnType === "PgGeometry" || column.columnType === "PgVector") {
109
+ return value;
110
+ }
111
+ return value.map((arrVal) => remapToGraphQLCore(key, arrVal, tableName, column, relationMap));
112
+ }
113
+ if (typeof value === "object" && value !== null) {
114
+ if (column.columnType === "PgGeometryObject") {
115
+ return value;
116
+ }
117
+ return JSON.stringify(value);
118
+ }
119
+ return value;
120
+ };
121
+ var remapToGraphQLSingleOutput = (queryOutput, tableName, table, relationMap) => {
122
+ for (const [key, value] of Object.entries(queryOutput)) {
123
+ if (value === void 0 || value === null) {
124
+ delete queryOutput[key];
125
+ continue;
126
+ }
127
+ const column = table[key];
128
+ if (value === 0n && column && column.columnType === "SQLiteBigInt" && !column.notNull) {
129
+ delete queryOutput[key];
130
+ continue;
131
+ }
132
+ queryOutput[key] = remapToGraphQLCore(key, value, tableName, column, relationMap);
133
+ }
134
+ return queryOutput;
135
+ };
136
+ var remapToGraphQLArrayOutput = (queryOutput, tableName, table, relationMap) => {
137
+ for (const entry of queryOutput) {
138
+ remapToGraphQLSingleOutput(entry, tableName, table, relationMap);
139
+ }
140
+ return queryOutput;
141
+ };
142
+ var remapFromGraphQLCore = (value, column, columnName) => {
143
+ const dataType = column.dataType ?? "";
144
+ const columnType = column.columnType ?? "";
145
+ const isTimestampColumn = columnType === "SQLiteTimestamp" || columnType === "SQLiteTimestampMs" || columnType === "MySqlTimestamp" || columnType === "MySqlDateTime" || columnType === "PgTimestamp" || columnType === "PgTimestampString";
146
+ if (isTimestampColumn) {
147
+ const formatted = new Date(value);
148
+ if (Number.isNaN(formatted.getTime())) {
149
+ throw new GraphQLError(`Field '${columnName}' is not a valid date!`);
150
+ }
151
+ return formatted;
152
+ }
153
+ const isDateOnlyColumn = columnType === "MySqlDate" || columnType === "PgDate";
154
+ if (isDateOnlyColumn && typeof value === "string") {
155
+ const dateOnly = value.includes("T") ? value.split("T")[0] : value;
156
+ const check = new Date(dateOnly);
157
+ if (Number.isNaN(check.getTime())) {
158
+ throw new GraphQLError(`Field '${columnName}' is not a valid date!`);
159
+ }
160
+ return dateOnly;
161
+ }
162
+ if (dataType.includes("bigint")) {
163
+ try {
164
+ return BigInt(value);
165
+ } catch {
166
+ throw new GraphQLError(`Field '${columnName}' is not a BigInt!`);
167
+ }
168
+ }
169
+ if (dataType.includes("json") && column.columnType !== "PgGeometryObject") {
170
+ if (typeof value !== "string") {
171
+ return value;
172
+ }
173
+ try {
174
+ return JSON.parse(value);
175
+ } catch (e) {
176
+ throw new GraphQLError(
177
+ `Invalid JSON in field '${columnName}':
178
+ ${e instanceof Error ? e.message : "Unknown error"}`
179
+ );
180
+ }
181
+ }
182
+ switch (dataType) {
183
+ case "date": {
184
+ const formatted = new Date(value);
185
+ if (Number.isNaN(formatted.getTime())) {
186
+ throw new GraphQLError(`Field '${columnName}' is not a valid date!`);
187
+ }
188
+ return formatted;
189
+ }
190
+ case "buffer": {
191
+ if (!Array.isArray(value)) {
192
+ throw new GraphQLError(`Field '${columnName}' is not an array!`);
193
+ }
194
+ return Buffer.from(value);
195
+ }
196
+ case "json": {
197
+ if (column.columnType === "PgGeometryObject") {
198
+ return value;
199
+ }
200
+ try {
201
+ return JSON.parse(value);
202
+ } catch (e) {
203
+ throw new GraphQLError(
204
+ `Invalid JSON in field '${columnName}':
205
+ ${e instanceof Error ? e.message : "Unknown error"}`
206
+ );
207
+ }
208
+ }
209
+ case "array": {
210
+ if (!Array.isArray(value)) {
211
+ throw new GraphQLError(`Field '${columnName}' is not an array!`);
212
+ }
213
+ if (column.columnType === "PgGeometry" && value.length !== 2) {
214
+ throw new GraphQLError(
215
+ `Invalid float tuple in field '${columnName}': expected array with length of 2, received ${value.length}`
216
+ );
217
+ }
218
+ return value;
219
+ }
220
+ case "bigint": {
221
+ try {
222
+ return BigInt(value);
223
+ } catch (_error) {
224
+ throw new GraphQLError(`Field '${columnName}' is not a BigInt!`);
225
+ }
226
+ }
227
+ default: {
228
+ if (typeof value === "object" && value !== null && Object.getPrototypeOf(value) === null) {
229
+ return Object.assign({}, value);
230
+ }
231
+ return value;
232
+ }
233
+ }
234
+ };
235
+ var remapFromGraphQLSingleInput = (queryInput, table) => {
236
+ for (const [key, value] of Object.entries(queryInput)) {
237
+ if (value === void 0) {
238
+ delete queryInput[key];
239
+ } else {
240
+ const column = getTableColumns(table)[key];
241
+ if (!column) {
242
+ throw new GraphQLError(`Unknown column: ${key}`);
243
+ }
244
+ if (value === null && column.notNull) {
245
+ delete queryInput[key];
246
+ continue;
247
+ }
248
+ queryInput[key] = remapFromGraphQLCore(value, column, key);
249
+ }
250
+ }
251
+ return queryInput;
252
+ };
253
+ var remapFromGraphQLArrayInput = (queryInput, table) => {
254
+ for (const entry of queryInput) {
255
+ remapFromGraphQLSingleInput(entry, table);
256
+ }
257
+ return queryInput;
258
+ };
259
+
260
+ // src/util/type-converter/index.ts
261
+ import { extractExtendedColumnType, getColumns, is } from "drizzle-orm";
262
+ import { MySqlInt, MySqlSerial } from "drizzle-orm/mysql-core";
263
+ import { PgDate, PgDateString, PgInteger, PgSerial, PgTimestamp, PgTimestampString } from "drizzle-orm/pg-core";
264
+ import { SQLiteInteger } from "drizzle-orm/sqlite-core";
265
+ import {
266
+ GraphQLBoolean,
267
+ GraphQLEnumType,
268
+ GraphQLFloat,
269
+ GraphQLInputObjectType,
270
+ GraphQLInt,
271
+ GraphQLList,
272
+ GraphQLNonNull,
273
+ GraphQLObjectType,
274
+ GraphQLString
275
+ } from "graphql";
276
+ import { GraphQLDate, GraphQLDateTime } from "graphql-scalars";
277
+ var allowedNameChars = /^[a-zA-Z0-9_]+$/;
278
+ var enumMap = /* @__PURE__ */ new WeakMap();
279
+ var generateEnumCached = (column, columnName, tableName) => {
280
+ if (enumMap.has(column)) {
281
+ return enumMap.get(column);
282
+ }
283
+ const gqlEnum = new GraphQLEnumType({
284
+ name: `${capitalize(tableName)}${capitalize(columnName)}Enum`,
285
+ values: Object.fromEntries(
286
+ column.enumValues.map((e, index) => [
287
+ allowedNameChars.test(e) ? e : `Option${index}`,
288
+ {
289
+ value: e,
290
+ description: `Value: ${e}`
291
+ }
292
+ ])
293
+ )
294
+ });
295
+ enumMap.set(column, gqlEnum);
296
+ return gqlEnum;
297
+ };
298
+ var geoXyType = new GraphQLObjectType({
299
+ name: "PgGeometryObject",
300
+ fields: {
301
+ x: { type: GraphQLFloat },
302
+ y: { type: GraphQLFloat }
303
+ }
304
+ });
305
+ var geoXyInputType = new GraphQLInputObjectType({
306
+ name: "PgGeometryObjectInput",
307
+ fields: {
308
+ x: { type: GraphQLFloat },
309
+ y: { type: GraphQLFloat }
310
+ }
311
+ });
312
+ var columnToGraphQLCore = (column, columnName, tableName, isInput) => {
313
+ const { type: baseType } = extractExtendedColumnType(column);
314
+ switch (baseType) {
315
+ case "boolean":
316
+ return { type: GraphQLBoolean, description: "Boolean" };
317
+ case "object":
318
+ if (column instanceof PgTimestamp || column instanceof PgDate) {
319
+ return { type: GraphQLDateTime, description: "DateTime" };
320
+ }
321
+ return column.columnType === "PgGeometryObject" ? {
322
+ type: isInput ? geoXyInputType : geoXyType,
323
+ description: "Geometry points XY"
324
+ } : column.columnType === "PgBytea" ? {
325
+ type: new GraphQLList(new GraphQLNonNull(GraphQLInt)),
326
+ description: "Buffer"
327
+ } : { type: GraphQLString, description: "JSON" };
328
+ case "string":
329
+ if (column.enumValues?.length) {
330
+ return { type: generateEnumCached(column, columnName, tableName) };
331
+ }
332
+ if (column instanceof PgTimestamp || column instanceof PgTimestampString) {
333
+ return { type: GraphQLDateTime, description: "DateTime" };
334
+ }
335
+ if (column instanceof PgDateString) {
336
+ return isInput ? { type: GraphQLString, description: "Date" } : { type: GraphQLDate, description: "Date" };
337
+ }
338
+ return { type: GraphQLString, description: "String" };
339
+ case "bigint":
340
+ return { type: GraphQLString, description: "BigInt" };
341
+ case "number": {
342
+ const dims = column.dimensions;
343
+ if (dims !== void 0 && dims > 0) {
344
+ const baseDesc = is(column, PgInteger) || is(column, PgSerial) ? "Integer" : "Float";
345
+ const baseType2 = baseDesc === "Integer" ? GraphQLInt : GraphQLFloat;
346
+ return {
347
+ type: new GraphQLList(new GraphQLNonNull(baseType2)),
348
+ description: `Array<${baseDesc}>`
349
+ };
350
+ }
351
+ return is(column, PgInteger) || is(column, PgSerial) || is(column, MySqlInt) || is(column, MySqlSerial) || is(column, SQLiteInteger) ? { type: GraphQLInt, description: "Integer" } : { type: GraphQLFloat, description: "Float" };
352
+ }
353
+ case "array": {
354
+ if (column.columnType === "PgVector") {
355
+ return {
356
+ type: new GraphQLList(new GraphQLNonNull(GraphQLFloat)),
357
+ description: "Array<Float>"
358
+ };
359
+ }
360
+ if (column.columnType === "PgGeometry") {
361
+ return {
362
+ type: new GraphQLList(new GraphQLNonNull(GraphQLFloat)),
363
+ description: "Tuple<[Float, Float]>"
364
+ };
365
+ }
366
+ const innerType = columnToGraphQLCore(
367
+ column.baseColumn,
368
+ columnName,
369
+ tableName,
370
+ isInput
371
+ );
372
+ return {
373
+ type: new GraphQLList(new GraphQLNonNull(innerType.type)),
374
+ description: `Array<${innerType.description}>`
375
+ };
376
+ }
377
+ default:
378
+ throw new Error(`Drizzle-GraphQL Error: Type ${column.dataType} is not implemented!`);
379
+ }
380
+ };
381
+ var drizzleRelationToGraphQLInsertType = (tables, relationMap) => {
382
+ if (!relationMap) {
383
+ return null;
384
+ }
385
+ for (const [tableName, _val] of Object.entries(relationMap)) {
386
+ const table = tables[tableName];
387
+ if (!table) {
388
+ continue;
389
+ }
390
+ const columns = getColumns(table);
391
+ const columnEntries = Object.entries(columns).filter(([_key, value]) => value.primary);
392
+ const _connectFields = Object.fromEntries(
393
+ columnEntries.map(([columnName, columnDescription]) => [
394
+ columnName,
395
+ drizzleColumnToGraphQLType(columnDescription, columnName, tableName, false, true, true)
396
+ ])
397
+ );
398
+ }
399
+ return null;
400
+ };
401
+ var drizzleColumnToGraphQLType = (column, columnName, tableName, forceNullable = false, defaultIsNullable = false, isInput = false) => {
402
+ const typeDesc = columnToGraphQLCore(column, columnName, tableName, isInput);
403
+ const noDesc = ["string", "boolean", "number"];
404
+ const { type: baseType } = extractExtendedColumnType(column);
405
+ if (noDesc.find((e) => e === baseType)) {
406
+ delete typeDesc.description;
407
+ }
408
+ if (forceNullable) {
409
+ return typeDesc;
410
+ }
411
+ if (column.notNull && !(defaultIsNullable && (column.hasDefault || column.defaultFn))) {
412
+ return {
413
+ type: new GraphQLNonNull(typeDesc.type),
414
+ description: typeDesc.description
415
+ };
416
+ }
417
+ return typeDesc;
418
+ };
419
+
420
+ // src/util/builders/common.ts
421
+ var rqbCrashTypes = ["SQLiteBigInt", "SQLiteBlobJson", "SQLiteBlobBuffer"];
422
+ var toTypeName = (name, singular) => singular ? capitalize(singularize(name)) : capitalize(name);
423
+ var buildNamedRelations = (relations, tableEntries) => {
424
+ const namedRelations = {};
425
+ for (const [relTableName, relConfig] of Object.entries(relations)) {
426
+ if (!relConfig?.relations) {
427
+ continue;
428
+ }
429
+ const namedConfig = {};
430
+ for (const [innerRelName, innerRelValue] of Object.entries(relConfig.relations)) {
431
+ const targetTable = innerRelValue.targetTable ?? innerRelValue.referencedTable;
432
+ const directTargetName = innerRelValue.targetTableName;
433
+ let targetTableName;
434
+ if (directTargetName) {
435
+ const targetEntry = tableEntries.find(([key]) => key === directTargetName);
436
+ targetTableName = targetEntry?.[0];
437
+ } else if (targetTable) {
438
+ const targetEntry = tableEntries.find(([, tableValue]) => tableValue === targetTable);
439
+ targetTableName = targetEntry?.[0];
440
+ }
441
+ if (!targetTableName) {
442
+ continue;
443
+ }
444
+ namedConfig[innerRelName] = {
445
+ relation: innerRelValue,
446
+ targetTableName
447
+ };
448
+ }
449
+ if (Object.keys(namedConfig).length > 0) {
450
+ namedRelations[relTableName] = namedConfig;
451
+ }
452
+ }
453
+ return namedRelations;
454
+ };
455
+ var extractSelectedColumnsFromTree = (tree, table) => {
456
+ const tableColumns = getColumns2(table);
457
+ const treeEntries = Object.entries(tree);
458
+ const selectedColumns = [];
459
+ for (const [_fieldName, fieldData] of treeEntries) {
460
+ if (!tableColumns[fieldData.name]) {
461
+ continue;
462
+ }
463
+ selectedColumns.push([fieldData.name, true]);
464
+ }
465
+ if (!selectedColumns.length) {
466
+ const columnKeys = Object.entries(tableColumns);
467
+ const columnName = columnKeys.find((e) => rqbCrashTypes.find((haram) => e[1].columnType !== haram))?.[0] ?? columnKeys[0][0];
468
+ selectedColumns.push([columnName, true]);
469
+ }
470
+ return Object.fromEntries(selectedColumns);
471
+ };
472
+ var extractSelectedColumnsFromTreeSQLFormat = (tree, table) => {
473
+ const tableColumns = getColumns2(table);
474
+ const treeEntries = Object.entries(tree);
475
+ const selectedColumns = [];
476
+ for (const [_fieldName, fieldData] of treeEntries) {
477
+ if (!tableColumns[fieldData.name]) {
478
+ continue;
479
+ }
480
+ selectedColumns.push([fieldData.name, tableColumns[fieldData.name]]);
481
+ }
482
+ if (!selectedColumns.length) {
483
+ const columnKeys = Object.entries(tableColumns);
484
+ const columnName = columnKeys.find((e) => rqbCrashTypes.find((haram) => e[1].columnType !== haram))?.[0] ?? columnKeys[0][0];
485
+ selectedColumns.push([columnName, tableColumns[columnName]]);
486
+ }
487
+ return Object.fromEntries(selectedColumns);
488
+ };
489
+ var innerOrder = new GraphQLInputObjectType2({
490
+ name: "InnerOrder",
491
+ fields: {
492
+ direction: {
493
+ type: new GraphQLNonNull2(
494
+ new GraphQLEnumType2({
495
+ name: "OrderDirection",
496
+ description: "Order by direction",
497
+ values: {
498
+ asc: {
499
+ value: "asc",
500
+ description: "Ascending order"
501
+ },
502
+ desc: {
503
+ value: "desc",
504
+ description: "Descending order"
505
+ }
506
+ }
507
+ })
508
+ )
509
+ },
510
+ priority: {
511
+ type: new GraphQLNonNull2(GraphQLInt2),
512
+ description: "Priority of current field"
513
+ }
514
+ }
515
+ });
516
+ var resolveGenericFilterName = (column, columnName, columnGraphQLType) => {
517
+ if (columnName === "id" || columnName.endsWith("Id")) {
518
+ return "Id";
519
+ }
520
+ if (columnGraphQLType.type === GraphQLBoolean2) {
521
+ return "Boolean";
522
+ }
523
+ if (columnGraphQLType.type instanceof GraphQLEnumType2) {
524
+ return columnGraphQLType.type.name;
525
+ }
526
+ if (columnGraphQLType.type instanceof GraphQLList2) {
527
+ const desc2 = columnGraphQLType.description ?? "";
528
+ return desc2.includes("Integer") ? "IntArray" : "FloatArray";
529
+ }
530
+ const ct = column.columnType ?? "";
531
+ if (ct === "PgTimestamp" || ct === "PgTimestampString" || ct === "PgDate") {
532
+ return "DateTime";
533
+ }
534
+ return "String";
535
+ };
536
+ var generateColumnFilterValues = (column, tableName, columnName, cacheCtx) => {
537
+ const columnGraphQLType = drizzleColumnToGraphQLType(column, columnName, tableName, true, false, true);
538
+ const genericName = resolveGenericFilterName(column, columnName, columnGraphQLType);
539
+ const cached = cacheCtx.genericFilterCache.get(genericName);
540
+ if (cached) {
541
+ return cached.main;
542
+ }
543
+ const colType = columnGraphQLType.type;
544
+ const colDesc = columnGraphQLType.description;
545
+ const colArr = new GraphQLList2(new GraphQLNonNull2(colType));
546
+ const isId = genericName === "Id";
547
+ const baseFields = {
548
+ eq: { type: colType, description: colDesc },
549
+ ne: { type: colType, description: colDesc },
550
+ lt: { type: colType, description: colDesc },
551
+ lte: { type: colType, description: colDesc },
552
+ gt: { type: colType, description: colDesc },
553
+ gte: { type: colType, description: colDesc },
554
+ ...isId ? {} : {
555
+ like: { type: GraphQLString2 },
556
+ notLike: { type: GraphQLString2 },
557
+ ilike: { type: GraphQLString2 },
558
+ notIlike: { type: GraphQLString2 }
559
+ },
560
+ inArray: { type: colArr, description: `Array<${colDesc}>` },
561
+ notInArray: { type: colArr, description: `Array<${colDesc}>` },
562
+ isNull: { type: GraphQLBoolean2 },
563
+ isNotNull: { type: GraphQLBoolean2 }
564
+ };
565
+ const orType = new GraphQLInputObjectType2({
566
+ name: `${genericName}FilterOr`,
567
+ fields: { ...baseFields }
568
+ });
569
+ const mainType = new GraphQLInputObjectType2({
570
+ name: `${genericName}Filter`,
571
+ fields: {
572
+ ...baseFields,
573
+ OR: {
574
+ type: new GraphQLList2(new GraphQLNonNull2(orType))
575
+ }
576
+ }
577
+ });
578
+ cacheCtx.genericFilterCache.set(genericName, { main: mainType, or: orType });
579
+ return mainType;
580
+ };
581
+ var orderMap = /* @__PURE__ */ new WeakMap();
582
+ var generateTableOrderCached = (table) => {
583
+ if (orderMap.has(table)) {
584
+ return orderMap.get(table);
585
+ }
586
+ let remapped = {};
587
+ try {
588
+ const columns = getColumns2(table);
589
+ const columnEntries = Object.entries(columns);
590
+ remapped = Object.fromEntries(
591
+ columnEntries.map(([columnName, _columnDescription]) => [columnName, { type: innerOrder }])
592
+ );
593
+ orderMap.set(table, remapped);
594
+ } catch (_err) {
595
+ }
596
+ return remapped;
597
+ };
598
+ var filterMap = /* @__PURE__ */ new WeakMap();
599
+ var generateTableFilterValuesCached = (table, tableName, cacheCtx) => {
600
+ if (filterMap.has(table)) {
601
+ return filterMap.get(table);
602
+ }
603
+ const columns = getColumns2(table);
604
+ const columnEntries = Object.entries(columns);
605
+ const remapped = Object.fromEntries(
606
+ columnEntries.map(([columnName, columnDescription]) => [
607
+ columnName,
608
+ {
609
+ type: generateColumnFilterValues(columnDescription, tableName, columnName, cacheCtx)
610
+ }
611
+ ])
612
+ );
613
+ filterMap.set(table, remapped);
614
+ return remapped;
615
+ };
616
+ var fieldMap = /* @__PURE__ */ new WeakMap();
617
+ var generateTableSelectTypeFieldsCached = (table, tableName) => {
618
+ if (fieldMap.has(table)) {
619
+ return fieldMap.get(table);
620
+ }
621
+ const columns = getColumns2(table);
622
+ const columnEntries = Object.entries(columns);
623
+ const remapped = Object.fromEntries(
624
+ columnEntries.map(([columnName, columnDescription]) => [
625
+ columnName,
626
+ drizzleColumnToGraphQLType(columnDescription, columnName, tableName)
627
+ ])
628
+ );
629
+ fieldMap.set(table, remapped);
630
+ return remapped;
631
+ };
632
+ var orderTypeMap = /* @__PURE__ */ new WeakMap();
633
+ var generateTableOrderTypeCached = (table, tableName, singularTypes) => {
634
+ if (orderTypeMap.has(table)) {
635
+ return orderTypeMap.get(table);
636
+ }
637
+ const orderColumns = generateTableOrderCached(table);
638
+ const order = new GraphQLInputObjectType2({
639
+ name: `${toTypeName(tableName, singularTypes)}OrderBy`,
640
+ fields: orderColumns
641
+ });
642
+ orderTypeMap.set(table, order);
643
+ return order;
644
+ };
645
+ var filterTypeMap = /* @__PURE__ */ new WeakMap();
646
+ var generateTableFilterTypeCached = (table, tableName, cacheCtx, singularTypes) => {
647
+ if (filterTypeMap.has(table)) {
648
+ return filterTypeMap.get(table);
649
+ }
650
+ const filterColumns = generateTableFilterValuesCached(table, tableName, cacheCtx);
651
+ const filters = new GraphQLInputObjectType2({
652
+ name: `${toTypeName(tableName, singularTypes)}Filters`,
653
+ fields: {
654
+ ...filterColumns,
655
+ OR: {
656
+ type: new GraphQLList2(
657
+ new GraphQLNonNull2(
658
+ new GraphQLInputObjectType2({
659
+ name: `${toTypeName(tableName, singularTypes)}FiltersOr`,
660
+ fields: filterColumns
661
+ })
662
+ )
663
+ )
664
+ }
665
+ }
666
+ });
667
+ filterTypeMap.set(table, filters);
668
+ return filters;
669
+ };
670
+ var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromRelationName, withOrder, _relationsDepthLimit, cacheCtx, singularTypes, usedTables = /* @__PURE__ */ new Set()) => {
671
+ const table = tables[tableName];
672
+ const order = withOrder ? generateTableOrderTypeCached(table, tableName, singularTypes) : void 0;
673
+ const filters = generateTableFilterTypeCached(table, tableName, cacheCtx, singularTypes);
674
+ const tableFields = generateTableSelectTypeFieldsCached(table, tableName);
675
+ const relationsForTable = relationMap[tableName];
676
+ const relationEntries = relationsForTable ? Object.entries(relationsForTable) : [];
677
+ if (usedTables.has(tableName)) {
678
+ return {
679
+ order,
680
+ filters,
681
+ tableFields,
682
+ relationFields: {}
683
+ };
684
+ }
685
+ const isRootCall = fromTableName === "" && fromRelationName === "";
686
+ if (isRootCall && cacheCtx.fullyBuiltTables.has(tableName)) {
687
+ return {
688
+ order,
689
+ filters,
690
+ tableFields,
691
+ relationFields: {}
692
+ };
693
+ }
694
+ let container = cacheCtx.relationFieldContainers.get(tableName);
695
+ if (!container) {
696
+ container = { fields: {} };
697
+ cacheCtx.relationFieldContainers.set(tableName, container);
698
+ }
699
+ if (isRootCall && !cacheCtx.objectTypeCache.has(tableName)) {
700
+ const typeName = toTypeName(tableName, singularTypes);
701
+ const shell = new GraphQLObjectType2({
702
+ name: typeName,
703
+ fields: () => ({ ...tableFields, ...container.fields })
704
+ });
705
+ cacheCtx.objectTypeCache.set(tableName, shell);
706
+ }
707
+ if (relationEntries.length > 0) {
708
+ const rawRelationFields = [];
709
+ const nextUsedTables = new Set(usedTables);
710
+ nextUsedTables.add(tableName);
711
+ for (const [relationName, relEntry] of relationEntries) {
712
+ const { targetTableName } = relEntry;
713
+ const relation = relEntry.relation ?? relEntry;
714
+ const isOne = is2(relation, One);
715
+ const relSelectData = generateSelectFields(
716
+ tables,
717
+ targetTableName,
718
+ relationMap,
719
+ tableName,
720
+ // fromTableName for the relation type
721
+ relationName,
722
+ // fromRelationName for the relation type
723
+ !isOne,
724
+ void 0,
725
+ cacheCtx,
726
+ singularTypes,
727
+ nextUsedTables
728
+ );
729
+ let relType = cacheCtx.objectTypeCache.get(targetTableName);
730
+ if (!relType) {
731
+ const targetTable = tables[targetTableName];
732
+ const targetTableFields = generateTableSelectTypeFieldsCached(targetTable, targetTableName);
733
+ let targetContainer = cacheCtx.relationFieldContainers.get(targetTableName);
734
+ if (!targetContainer) {
735
+ targetContainer = { fields: {} };
736
+ cacheCtx.relationFieldContainers.set(targetTableName, targetContainer);
737
+ }
738
+ const capturedTargetContainer = targetContainer;
739
+ relType = new GraphQLObjectType2({
740
+ name: toTypeName(targetTableName, singularTypes),
741
+ fields: () => ({ ...targetTableFields, ...capturedTargetContainer.fields })
742
+ });
743
+ cacheCtx.objectTypeCache.set(targetTableName, relType);
744
+ }
745
+ if (isOne) {
746
+ rawRelationFields.push([
747
+ relationName,
748
+ {
749
+ type: relType,
750
+ args: {
751
+ where: { type: relSelectData.filters }
752
+ }
753
+ }
754
+ ]);
755
+ continue;
756
+ }
757
+ rawRelationFields.push([
758
+ relationName,
759
+ {
760
+ type: new GraphQLNonNull2(new GraphQLList2(new GraphQLNonNull2(relType))),
761
+ args: {
762
+ where: { type: relSelectData.filters },
763
+ orderBy: { type: relSelectData.order },
764
+ offset: { type: GraphQLInt2 },
765
+ limit: { type: GraphQLInt2 }
766
+ }
767
+ }
768
+ ]);
769
+ }
770
+ const builtRelationFields = Object.fromEntries(rawRelationFields);
771
+ if (isRootCall) {
772
+ container.fields = builtRelationFields;
773
+ cacheCtx.fullyBuiltTables.add(tableName);
774
+ }
775
+ return {
776
+ order,
777
+ filters,
778
+ tableFields,
779
+ relationFields: builtRelationFields
780
+ };
781
+ }
782
+ if (isRootCall) {
783
+ cacheCtx.fullyBuiltTables.add(tableName);
784
+ }
785
+ return {
786
+ order,
787
+ filters,
788
+ tableFields,
789
+ relationFields: {}
790
+ };
791
+ };
792
+ var generateTableTypes = (tableName, tables, relationMap, withReturning, relationsDepthLimit, cacheCtx, singularTypes = false, insertPrefix = "insertInto", updatePrefix = "update") => {
793
+ const { tableFields, relationFields, filters, order } = generateSelectFields(
794
+ tables,
795
+ tableName,
796
+ relationMap,
797
+ "",
798
+ // root call: no fromTableName
799
+ "",
800
+ // root call: no fromRelationName
801
+ true,
802
+ relationsDepthLimit,
803
+ cacheCtx,
804
+ singularTypes
805
+ );
806
+ const table = tables[tableName];
807
+ const columns = getColumns2(table);
808
+ const columnEntries = Object.entries(columns);
809
+ const _insertNested = drizzleRelationToGraphQLInsertType(tables, relationMap[tableName] ?? {});
810
+ const insertFields = Object.fromEntries(
811
+ columnEntries.map(([columnName, columnDescription]) => [
812
+ columnName,
813
+ drizzleColumnToGraphQLType(columnDescription, columnName, tableName, false, true, true)
814
+ ])
815
+ );
816
+ const updateFields = Object.fromEntries(
817
+ columnEntries.map(([columnName, columnDescription]) => [
818
+ columnName,
819
+ drizzleColumnToGraphQLType(columnDescription, columnName, tableName, true, false, true)
820
+ ])
821
+ );
822
+ const insertInput = new GraphQLInputObjectType2({
823
+ name: `${capitalize(insertPrefix)}${toTypeName(tableName, singularTypes)}Input`,
824
+ fields: insertFields
825
+ });
826
+ const updateInput = new GraphQLInputObjectType2({
827
+ name: `${capitalize(updatePrefix)}${toTypeName(tableName, singularTypes)}Input`,
828
+ fields: updateFields
829
+ });
830
+ const selectSingleOutput = cacheCtx.objectTypeCache.get(tableName) ?? new GraphQLObjectType2({
831
+ name: toTypeName(tableName, singularTypes),
832
+ fields: { ...tableFields, ...relationFields }
833
+ });
834
+ const selectArrOutput = new GraphQLNonNull2(new GraphQLList2(new GraphQLNonNull2(selectSingleOutput)));
835
+ const arrTableItemOutput = withReturning ? (
836
+ // ? new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(singleTableItemOutput!)))
837
+ new GraphQLNonNull2(new GraphQLList2(new GraphQLNonNull2(selectSingleOutput)))
838
+ ) : void 0;
839
+ const inputs = {
840
+ insertInput,
841
+ updateInput,
842
+ tableOrder: order,
843
+ tableFilters: filters
844
+ };
845
+ const outputs = withReturning ? {
846
+ selectSingleOutput,
847
+ selectArrOutput,
848
+ singleTableItemOutput: selectSingleOutput,
849
+ // singleTableItemOutput: singleTableItemOutput!,
850
+ arrTableItemOutput
851
+ } : {
852
+ selectSingleOutput,
853
+ selectArrOutput
854
+ };
855
+ return {
856
+ inputs,
857
+ outputs
858
+ };
859
+ };
860
+ var extractOrderBy = (table, orderArgs) => {
861
+ const res = [];
862
+ for (const [column, config] of Object.entries(orderArgs).sort(
863
+ (a, b) => (b[1]?.priority ?? 0) - (a[1]?.priority ?? 0)
864
+ )) {
865
+ if (!config) {
866
+ continue;
867
+ }
868
+ const { direction } = config;
869
+ res.push(direction === "asc" ? asc(getColumns2(table)[column]) : desc(getColumns2(table)[column]));
870
+ }
871
+ return res;
872
+ };
873
+ var extractFiltersColumn = (column, columnName, operators) => {
874
+ if (!operators.OR?.length) {
875
+ delete operators.OR;
876
+ }
877
+ const entries = Object.entries(operators);
878
+ if (operators.OR) {
879
+ if (entries.length > 1) {
880
+ throw new GraphQLError2(`WHERE ${columnName}: Cannot specify both fields and 'OR' in column operators!`);
881
+ }
882
+ const variants2 = [];
883
+ for (const variant of operators.OR) {
884
+ const extracted = extractFiltersColumn(column, columnName, variant);
885
+ if (extracted) {
886
+ variants2.push(extracted);
887
+ }
888
+ }
889
+ return variants2.length ? variants2.length > 1 ? or(...variants2) : variants2[0] : void 0;
890
+ }
891
+ const variants = [];
892
+ for (const [operatorName, operatorValue] of entries) {
893
+ if (operatorValue === null || operatorValue === false) {
894
+ continue;
895
+ }
896
+ let operator;
897
+ switch (operatorName) {
898
+ case "eq":
899
+ operator = operator ?? eq;
900
+ case "ne":
901
+ operator = operator ?? ne;
902
+ case "gt":
903
+ operator = operator ?? gt;
904
+ case "gte":
905
+ operator = operator ?? gte;
906
+ case "lt":
907
+ operator = operator ?? lt;
908
+ case "lte": {
909
+ operator = operator ?? lte;
910
+ const singleValue = remapFromGraphQLCore(operatorValue, column, columnName);
911
+ variants.push(operator(column, singleValue));
912
+ break;
913
+ }
914
+ case "like":
915
+ operator = operator ?? like;
916
+ case "notLike":
917
+ operator = operator ?? notLike;
918
+ case "ilike":
919
+ operator = operator ?? ilike;
920
+ case "notIlike":
921
+ operator = operator ?? notIlike;
922
+ variants.push(operator(column, operatorValue));
923
+ break;
924
+ case "inArray":
925
+ operator = operator ?? inArray;
926
+ case "notInArray": {
927
+ operator = operator ?? notInArray;
928
+ if (!operatorValue.length) {
929
+ throw new GraphQLError2(`WHERE ${columnName}: Unable to use operator ${operatorName} with an empty array!`);
930
+ }
931
+ const arrayValue = operatorValue.map((val) => remapFromGraphQLCore(val, column, columnName));
932
+ variants.push(operator(column, arrayValue));
933
+ break;
934
+ }
935
+ case "isNull":
936
+ operator = operator ?? isNull;
937
+ case "isNotNull":
938
+ operator = operator ?? isNotNull;
939
+ variants.push(operator(column));
940
+ }
941
+ }
942
+ return variants.length ? variants.length > 1 ? and(...variants) : variants[0] : void 0;
943
+ };
944
+ var extractFilters = (table, tableName, filters) => {
945
+ if (!filters.OR?.length) {
946
+ delete filters.OR;
947
+ }
948
+ const entries = Object.entries(filters);
949
+ if (!entries.length) {
950
+ return;
951
+ }
952
+ if (filters.OR) {
953
+ if (entries.length > 1) {
954
+ throw new GraphQLError2(`WHERE ${tableName}: Cannot specify both fields and 'OR' in table filters!`);
955
+ }
956
+ const variants2 = [];
957
+ for (const variant of filters.OR) {
958
+ const extracted = extractFilters(table, tableName, variant);
959
+ if (extracted) {
960
+ variants2.push(extracted);
961
+ }
962
+ }
963
+ return variants2.length ? variants2.length > 1 ? or(...variants2) : variants2[0] : void 0;
964
+ }
965
+ const variants = [];
966
+ for (const [columnName, operators] of entries) {
967
+ if (operators === null) {
968
+ continue;
969
+ }
970
+ const column = getColumns2(table)[columnName];
971
+ variants.push(extractFiltersColumn(column, columnName, operators));
972
+ }
973
+ return variants.length ? variants.length > 1 ? and(...variants) : variants[0] : void 0;
974
+ };
975
+ var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, originField, singularTypes = false, _isInitial = false) => {
976
+ const relationsForTable = relationMap[tableName];
977
+ if (!relationsForTable) {
978
+ return void 0;
979
+ }
980
+ const baseField = Object.entries(originField.fieldsByTypeName).find(([key, _value]) => key === typeName)?.[1];
981
+ if (!baseField) {
982
+ return void 0;
983
+ }
984
+ const args = {};
985
+ for (const [relName, { targetTableName }] of Object.entries(relationsForTable)) {
986
+ const relTypeName = toTypeName(targetTableName, singularTypes);
987
+ const field = baseField[relName] ?? Object.values(baseField).find((f) => f.name === relName);
988
+ if (!field) {
989
+ continue;
990
+ }
991
+ const relField = field?.fieldsByTypeName;
992
+ const relFieldSelection = relField?.[relTypeName];
993
+ if (!relFieldSelection) {
994
+ continue;
995
+ }
996
+ const columns = extractSelectedColumnsFromTree(relFieldSelection, tables[targetTableName]);
997
+ const thisRecord = {};
998
+ thisRecord.columns = columns;
999
+ const relationField = Object.values(baseField).find((e) => e.name === relName);
1000
+ const relationArgs = relationField?.args;
1001
+ const offset = relationArgs?.offset ?? void 0;
1002
+ const limit = relationArgs?.limit ?? void 0;
1003
+ const relWhere = relationArgs?.where;
1004
+ thisRecord.where = relWhere ? { RAW: (aliasedTable) => extractFilters(aliasedTable, relName, relWhere) } : void 0;
1005
+ thisRecord.orderBy = relationArgs?.orderBy ? (aliasedTable) => extractOrderBy(aliasedTable, relationArgs.orderBy) : void 0;
1006
+ thisRecord.offset = offset;
1007
+ thisRecord.limit = limit;
1008
+ const relWith = relationField ? extractRelationsParamsInner(relationMap, tables, targetTableName, relTypeName, relationField, singularTypes) : void 0;
1009
+ thisRecord.with = relWith;
1010
+ args[relName] = thisRecord;
1011
+ }
1012
+ return args;
1013
+ };
1014
+ var extractRelationsParams = (relationMap, tables, tableName, info, typeName, singularTypes = false) => {
1015
+ if (!info) {
1016
+ return void 0;
1017
+ }
1018
+ return extractRelationsParamsInner(relationMap, tables, tableName, typeName, info, singularTypes, true);
1019
+ };
1020
+
1021
+ // src/util/builders/mysql.ts
1022
+ var toTypeName2 = (name, singular) => singular ? capitalize(singularize(name)) : capitalize(name);
1023
+ var generateSelectArray = (db, tableName, tables, relationMap, orderArgs, filterArgs, listSuffix, singularTypes) => {
1024
+ const queryName = `${uncapitalize(tableName)}${listSuffix}`;
1025
+ const queryBase = db.query[tableName];
1026
+ if (!queryBase) {
1027
+ throw new Error(
1028
+ `Drizzle-GraphQL Error: Table ${tableName} not found in drizzle instance. Did you forget to pass schema to drizzle constructor?`
1029
+ );
1030
+ }
1031
+ const queryArgs = {
1032
+ offset: {
1033
+ type: GraphQLInt3
1034
+ },
1035
+ limit: {
1036
+ type: GraphQLInt3
1037
+ },
1038
+ orderBy: {
1039
+ type: orderArgs
1040
+ },
1041
+ where: {
1042
+ type: filterArgs
1043
+ }
1044
+ };
1045
+ const typeName = toTypeName2(tableName, singularTypes);
1046
+ const table = tables[tableName];
1047
+ return {
1048
+ name: queryName,
1049
+ resolver: async (_source, args, _context, info) => {
1050
+ try {
1051
+ const { offset, limit, orderBy, where } = args;
1052
+ const parsedInfo = parseResolveInfo(info, {
1053
+ deep: true
1054
+ });
1055
+ const query = queryBase.findMany({
1056
+ columns: extractSelectedColumnsFromTree(parsedInfo.fieldsByTypeName[typeName], table),
1057
+ offset,
1058
+ limit,
1059
+ // drizzle-orm v1 RQB calls orderBy with the aliased table proxy —
1060
+ // use it directly so column refs match the CTE alias.
1061
+ orderBy: orderBy ? (aliasedTable) => extractOrderBy(aliasedTable, orderBy) : void 0,
1062
+ where: where ? { RAW: (aliased) => extractFilters(aliased, tableName, where) } : void 0,
1063
+ with: relationMap[tableName] ? extractRelationsParams(relationMap, tables, tableName, parsedInfo, typeName, singularTypes) : void 0
1064
+ });
1065
+ const result = await query;
1066
+ return remapToGraphQLArrayOutput(result, tableName, table, relationMap);
1067
+ } catch (e) {
1068
+ if (e instanceof Error) {
1069
+ throw new GraphQLError3(e.message);
1070
+ }
1071
+ throw e;
1072
+ }
1073
+ },
1074
+ args: queryArgs
1075
+ };
1076
+ };
1077
+ var generateSelectSingle = (db, tableName, tables, relationMap, orderArgs, filterArgs, singleSuffix, singularTypes) => {
1078
+ const queryName = `${uncapitalize(tableName)}${singleSuffix}`;
1079
+ const queryBase = db.query[tableName];
1080
+ if (!queryBase) {
1081
+ throw new Error(
1082
+ `Drizzle-GraphQL Error: Table ${tableName} not found in drizzle instance. Did you forget to pass schema to drizzle constructor?`
1083
+ );
1084
+ }
1085
+ const queryArgs = {
1086
+ offset: {
1087
+ type: GraphQLInt3
1088
+ },
1089
+ orderBy: {
1090
+ type: orderArgs
1091
+ },
1092
+ where: {
1093
+ type: filterArgs
1094
+ }
1095
+ };
1096
+ const typeName = toTypeName2(tableName, singularTypes);
1097
+ const table = tables[tableName];
1098
+ return {
1099
+ name: queryName,
1100
+ resolver: async (_source, args, _context, info) => {
1101
+ try {
1102
+ const { offset, orderBy, where } = args;
1103
+ const parsedInfo = parseResolveInfo(info, {
1104
+ deep: true
1105
+ });
1106
+ const query = queryBase.findFirst({
1107
+ columns: extractSelectedColumnsFromTree(parsedInfo.fieldsByTypeName[typeName], table),
1108
+ offset,
1109
+ // drizzle-orm v1 RQB calls orderBy with the aliased table proxy —
1110
+ // use it directly so column refs match the CTE alias.
1111
+ orderBy: orderBy ? (aliasedTable) => extractOrderBy(aliasedTable, orderBy) : void 0,
1112
+ where: where ? { RAW: (aliased) => extractFilters(aliased, tableName, where) } : void 0,
1113
+ with: relationMap[tableName] ? extractRelationsParams(relationMap, tables, tableName, parsedInfo, typeName, singularTypes) : void 0
1114
+ });
1115
+ const result = await query;
1116
+ if (!result) {
1117
+ return void 0;
1118
+ }
1119
+ return remapToGraphQLSingleOutput(result, tableName, table, relationMap);
1120
+ } catch (e) {
1121
+ if (e instanceof Error) {
1122
+ throw new GraphQLError3(e.message);
1123
+ }
1124
+ throw e;
1125
+ }
1126
+ },
1127
+ args: queryArgs
1128
+ };
1129
+ };
1130
+ var generateInsertArray = (db, tableName, table, baseType) => {
1131
+ const queryName = `insertInto${capitalize(tableName)}`;
1132
+ const queryArgs = {
1133
+ values: {
1134
+ type: new GraphQLNonNull3(new GraphQLList3(new GraphQLNonNull3(baseType)))
1135
+ }
1136
+ };
1137
+ return {
1138
+ name: queryName,
1139
+ resolver: async (_source, args, _context, _info) => {
1140
+ try {
1141
+ const input = remapFromGraphQLArrayInput(args.values, table);
1142
+ if (!input.length) {
1143
+ throw new GraphQLError3("No values were provided!");
1144
+ }
1145
+ await db.insert(table).values(input);
1146
+ return { isSuccess: true };
1147
+ } catch (e) {
1148
+ if (e instanceof Error) {
1149
+ throw new GraphQLError3(e.message);
1150
+ }
1151
+ throw e;
1152
+ }
1153
+ },
1154
+ args: queryArgs
1155
+ };
1156
+ };
1157
+ var generateInsertSingle = (db, tableName, table, baseType) => {
1158
+ const queryName = `insertInto${capitalize(tableName)}Single`;
1159
+ const queryArgs = {
1160
+ values: {
1161
+ type: new GraphQLNonNull3(baseType)
1162
+ }
1163
+ };
1164
+ return {
1165
+ name: queryName,
1166
+ resolver: async (_source, args, _context, _info) => {
1167
+ try {
1168
+ const input = remapFromGraphQLSingleInput(args.values, table);
1169
+ await db.insert(table).values(input);
1170
+ return { isSuccess: true };
1171
+ } catch (e) {
1172
+ if (e instanceof Error) {
1173
+ throw new GraphQLError3(e.message);
1174
+ }
1175
+ throw e;
1176
+ }
1177
+ },
1178
+ args: queryArgs
1179
+ };
1180
+ };
1181
+ var generateUpdate = (db, tableName, table, setArgs, filterArgs) => {
1182
+ const queryName = `update${capitalize(tableName)}`;
1183
+ const queryArgs = {
1184
+ set: {
1185
+ type: new GraphQLNonNull3(setArgs)
1186
+ },
1187
+ where: {
1188
+ type: filterArgs
1189
+ }
1190
+ };
1191
+ return {
1192
+ name: queryName,
1193
+ resolver: async (_source, args, _context, _info) => {
1194
+ try {
1195
+ const { where, set } = args;
1196
+ const input = remapFromGraphQLSingleInput(set, table);
1197
+ if (!Object.keys(input).length) {
1198
+ throw new GraphQLError3("Unable to update with no values specified!");
1199
+ }
1200
+ let query = db.update(table).set(input);
1201
+ if (where) {
1202
+ const filters = extractFilters(table, tableName, where);
1203
+ query = query.where(filters);
1204
+ }
1205
+ await query;
1206
+ return { isSuccess: true };
1207
+ } catch (e) {
1208
+ if (e instanceof Error) {
1209
+ throw new GraphQLError3(e.message);
1210
+ }
1211
+ throw e;
1212
+ }
1213
+ },
1214
+ args: queryArgs
1215
+ };
1216
+ };
1217
+ var generateDelete = (db, tableName, table, filterArgs) => {
1218
+ const queryName = `deleteFrom${capitalize(tableName)}`;
1219
+ const queryArgs = {
1220
+ where: {
1221
+ type: filterArgs
1222
+ }
1223
+ };
1224
+ return {
1225
+ name: queryName,
1226
+ resolver: async (_source, args, _context, _info) => {
1227
+ try {
1228
+ const { where } = args;
1229
+ let query = db.delete(table);
1230
+ if (where) {
1231
+ const filters = extractFilters(table, tableName, where);
1232
+ query = query.where(filters);
1233
+ }
1234
+ await query;
1235
+ return { isSuccess: true };
1236
+ } catch (e) {
1237
+ if (e instanceof Error) {
1238
+ throw new GraphQLError3(e.message);
1239
+ }
1240
+ throw e;
1241
+ }
1242
+ },
1243
+ args: queryArgs
1244
+ };
1245
+ };
1246
+ var buildNamedRelations2 = (relations, tableEntries) => {
1247
+ const namedRelations = {};
1248
+ for (const [relTableName, relConfig] of Object.entries(relations)) {
1249
+ if (!relConfig?.relations) {
1250
+ continue;
1251
+ }
1252
+ const namedConfig = {};
1253
+ for (const [innerRelName, innerRelValue] of Object.entries(relConfig.relations)) {
1254
+ const targetTable = innerRelValue.targetTable ?? innerRelValue.referencedTable;
1255
+ const directTargetName = innerRelValue.targetTableName;
1256
+ let targetTableName;
1257
+ if (directTargetName) {
1258
+ const targetEntry = tableEntries.find(([key]) => key === directTargetName);
1259
+ targetTableName = targetEntry?.[0];
1260
+ } else if (targetTable) {
1261
+ const targetEntry = tableEntries.find(([, tableValue]) => tableValue === targetTable);
1262
+ targetTableName = targetEntry?.[0];
1263
+ }
1264
+ if (!targetTableName) {
1265
+ continue;
1266
+ }
1267
+ namedConfig[innerRelName] = {
1268
+ relation: innerRelValue,
1269
+ targetTableName
1270
+ };
1271
+ }
1272
+ if (Object.keys(namedConfig).length > 0) {
1273
+ namedRelations[relTableName] = namedConfig;
1274
+ }
1275
+ }
1276
+ return namedRelations;
1277
+ };
1278
+ var generateSchemaData = (db, schema, relations, relationsDepthLimit, prefixes, suffixes, singularTypes = false) => {
1279
+ const rawSchema = schema;
1280
+ const schemaEntries = Object.entries(rawSchema);
1281
+ const tableEntries = schemaEntries.filter(([_key, value]) => is3(value, MySqlTable));
1282
+ const tables = Object.fromEntries(tableEntries);
1283
+ if (!tableEntries.length) {
1284
+ throw new Error(
1285
+ "Drizzle-GraphQL Error: No tables detected in Drizzle-ORM's database instance. Did you forget to pass schema to drizzle constructor?"
1286
+ );
1287
+ }
1288
+ const namedRelations = buildNamedRelations2(relations ?? {}, tableEntries);
1289
+ const cacheCtx = {
1290
+ genericFilterCache: /* @__PURE__ */ new Map(),
1291
+ objectTypeCache: /* @__PURE__ */ new Map(),
1292
+ relationFieldContainers: /* @__PURE__ */ new Map(),
1293
+ fullyBuiltTables: /* @__PURE__ */ new Set(),
1294
+ relationTypeCache: /* @__PURE__ */ new Map()
1295
+ };
1296
+ const queries = {};
1297
+ const mutations = {};
1298
+ const gqlSchemaTypes = Object.fromEntries(
1299
+ Object.entries(tables).map(([tableName, _table]) => [
1300
+ tableName,
1301
+ generateTableTypes(
1302
+ tableName,
1303
+ tables,
1304
+ namedRelations,
1305
+ false,
1306
+ relationsDepthLimit,
1307
+ cacheCtx,
1308
+ singularTypes,
1309
+ prefixes.insert,
1310
+ prefixes.update
1311
+ )
1312
+ ])
1313
+ );
1314
+ const mutationReturnType = new GraphQLObjectType3({
1315
+ name: "MutationReturn",
1316
+ fields: {
1317
+ isSuccess: {
1318
+ type: new GraphQLNonNull3(GraphQLBoolean3)
1319
+ }
1320
+ }
1321
+ });
1322
+ const inputs = {};
1323
+ const outputs = {
1324
+ MutationReturn: mutationReturnType
1325
+ };
1326
+ for (const [tableName, tableTypes] of Object.entries(gqlSchemaTypes)) {
1327
+ const { insertInput, updateInput, tableFilters, tableOrder } = tableTypes.inputs;
1328
+ const { selectSingleOutput, selectArrOutput } = tableTypes.outputs;
1329
+ const selectArrGenerated = generateSelectArray(
1330
+ db,
1331
+ tableName,
1332
+ tables,
1333
+ namedRelations,
1334
+ tableOrder,
1335
+ tableFilters,
1336
+ suffixes.list,
1337
+ singularTypes
1338
+ );
1339
+ const selectSingleGenerated = generateSelectSingle(
1340
+ db,
1341
+ tableName,
1342
+ tables,
1343
+ namedRelations,
1344
+ tableOrder,
1345
+ tableFilters,
1346
+ suffixes.single,
1347
+ singularTypes
1348
+ );
1349
+ const insertArrGenerated = generateInsertArray(db, tableName, schema[tableName], insertInput);
1350
+ const insertSingleGenerated = generateInsertSingle(db, tableName, schema[tableName], insertInput);
1351
+ const updateGenerated = generateUpdate(db, tableName, schema[tableName], updateInput, tableFilters);
1352
+ const deleteGenerated = generateDelete(db, tableName, schema[tableName], tableFilters);
1353
+ queries[selectArrGenerated.name] = {
1354
+ type: selectArrOutput,
1355
+ args: selectArrGenerated.args,
1356
+ resolve: selectArrGenerated.resolver
1357
+ };
1358
+ queries[selectSingleGenerated.name] = {
1359
+ type: selectSingleOutput,
1360
+ args: selectSingleGenerated.args,
1361
+ resolve: selectSingleGenerated.resolver
1362
+ };
1363
+ mutations[insertArrGenerated.name] = {
1364
+ type: mutationReturnType,
1365
+ args: insertArrGenerated.args,
1366
+ resolve: insertArrGenerated.resolver
1367
+ };
1368
+ mutations[insertSingleGenerated.name] = {
1369
+ type: mutationReturnType,
1370
+ args: insertSingleGenerated.args,
1371
+ resolve: insertSingleGenerated.resolver
1372
+ };
1373
+ mutations[updateGenerated.name] = {
1374
+ type: mutationReturnType,
1375
+ args: updateGenerated.args,
1376
+ resolve: updateGenerated.resolver
1377
+ };
1378
+ mutations[deleteGenerated.name] = {
1379
+ type: mutationReturnType,
1380
+ args: deleteGenerated.args,
1381
+ resolve: deleteGenerated.resolver
1382
+ };
1383
+ [insertInput, updateInput, tableFilters, tableOrder].forEach((e) => {
1384
+ inputs[e.name] = e;
1385
+ });
1386
+ outputs[selectSingleOutput.name] = selectSingleOutput;
1387
+ }
1388
+ return { queries, mutations, inputs, types: outputs };
1389
+ };
1390
+
1391
+ // src/util/builders/pg.ts
1392
+ import { is as is4 } from "drizzle-orm";
1393
+ import { PgTable } from "drizzle-orm/pg-core";
1394
+ import {
1395
+ GraphQLError as GraphQLError4,
1396
+ GraphQLInt as GraphQLInt4,
1397
+ GraphQLList as GraphQLList4,
1398
+ GraphQLNonNull as GraphQLNonNull4
1399
+ } from "graphql";
1400
+ import { parseResolveInfo as parseResolveInfo2 } from "graphql-parse-resolve-info";
1401
+ var toTypeName3 = (name, singular) => singular ? capitalize(singularize(name)) : capitalize(name);
1402
+ var generateSelectArray2 = (db, tableName, tables, relationMap, orderArgs, filterArgs, listSuffix, singularTypes) => {
1403
+ const queryEntityBase = singularTypes ? singularize(uncapitalize(tableName)) : uncapitalize(tableName);
1404
+ const queryName = `${queryEntityBase}${listSuffix}`;
1405
+ const queryBase = db.query[tableName];
1406
+ const queryArgs = {
1407
+ offset: {
1408
+ type: GraphQLInt4
1409
+ },
1410
+ limit: {
1411
+ type: GraphQLInt4
1412
+ },
1413
+ orderBy: {
1414
+ type: orderArgs
1415
+ },
1416
+ where: {
1417
+ type: filterArgs
1418
+ }
1419
+ };
1420
+ const typeName = toTypeName3(tableName, singularTypes);
1421
+ const table = tables[tableName];
1422
+ return {
1423
+ name: queryName,
1424
+ resolver: async (_source, args, _context, info) => {
1425
+ try {
1426
+ const { offset, limit, orderBy, where } = args;
1427
+ const parsedInfo = parseResolveInfo2(info, {
1428
+ deep: true
1429
+ });
1430
+ const selectedColumns = extractSelectedColumnsFromTree(parsedInfo.fieldsByTypeName[typeName], table);
1431
+ let result;
1432
+ if (queryBase) {
1433
+ const withParams = relationMap[tableName] ? extractRelationsParams(relationMap, tables, tableName, parsedInfo, typeName, singularTypes) : void 0;
1434
+ result = await queryBase.findMany({
1435
+ columns: selectedColumns,
1436
+ offset,
1437
+ limit,
1438
+ // drizzle-orm v1 RQB calls orderBy with the aliased table proxy (e.g.
1439
+ // d0, d1) — use it directly so column refs match the CTE alias.
1440
+ orderBy: orderBy ? (aliasedTable) => extractOrderBy(aliasedTable, orderBy) : void 0,
1441
+ where: where ? { RAW: (aliased) => extractFilters(aliased, tableName, where) } : void 0,
1442
+ with: withParams
1443
+ });
1444
+ } else {
1445
+ let q = db.select(selectedColumns).from(table);
1446
+ if (where) {
1447
+ q = q.where(extractFilters(table, tableName, where));
1448
+ }
1449
+ if (orderBy) {
1450
+ q = q.orderBy(...extractOrderBy(table, orderBy));
1451
+ }
1452
+ if (offset) {
1453
+ q = q.offset(offset);
1454
+ }
1455
+ if (limit) {
1456
+ q = q.limit(limit);
1457
+ }
1458
+ result = await q;
1459
+ }
1460
+ return remapToGraphQLArrayOutput(result, tableName, table, relationMap);
1461
+ } catch (e) {
1462
+ if (e instanceof Error) {
1463
+ throw new GraphQLError4(e.message);
1464
+ }
1465
+ throw e;
1466
+ }
1467
+ },
1468
+ args: queryArgs
1469
+ };
1470
+ };
1471
+ var generateSelectSingle2 = (db, tableName, tables, relationMap, orderArgs, filterArgs, singleSuffix, singularTypes) => {
1472
+ const queryEntityBase = singularTypes ? singularize(uncapitalize(tableName)) : uncapitalize(tableName);
1473
+ const queryName = `${queryEntityBase}${singleSuffix}`;
1474
+ const queryBase = db.query[tableName];
1475
+ const queryArgs = {
1476
+ offset: {
1477
+ type: GraphQLInt4
1478
+ },
1479
+ orderBy: {
1480
+ type: orderArgs
1481
+ },
1482
+ where: {
1483
+ type: filterArgs
1484
+ }
1485
+ };
1486
+ const typeName = toTypeName3(tableName, singularTypes);
1487
+ const table = tables[tableName];
1488
+ return {
1489
+ name: queryName,
1490
+ resolver: async (_source, args, _context, info) => {
1491
+ try {
1492
+ const { offset, orderBy, where } = args;
1493
+ const parsedInfo = parseResolveInfo2(info, {
1494
+ deep: true
1495
+ });
1496
+ const selectedColumns = extractSelectedColumnsFromTree(parsedInfo.fieldsByTypeName[typeName], table);
1497
+ let result;
1498
+ if (queryBase) {
1499
+ result = await queryBase.findFirst({
1500
+ columns: selectedColumns,
1501
+ offset,
1502
+ // drizzle-orm v1 RQB calls orderBy with the aliased table proxy (e.g.
1503
+ // d0, d1) — use it directly so column refs match the CTE alias.
1504
+ orderBy: orderBy ? (aliasedTable) => extractOrderBy(aliasedTable, orderBy) : void 0,
1505
+ where: where ? { RAW: (aliased) => extractFilters(aliased, tableName, where) } : void 0,
1506
+ with: relationMap[tableName] ? extractRelationsParams(relationMap, tables, tableName, parsedInfo, typeName, singularTypes) : void 0
1507
+ });
1508
+ } else {
1509
+ let q = db.select(selectedColumns).from(table);
1510
+ if (where) {
1511
+ q = q.where(extractFilters(table, tableName, where));
1512
+ }
1513
+ if (orderBy) {
1514
+ q = q.orderBy(...extractOrderBy(table, orderBy));
1515
+ }
1516
+ if (offset) {
1517
+ q = q.offset(offset);
1518
+ }
1519
+ const rows = await q.limit(1);
1520
+ result = rows[0];
1521
+ }
1522
+ if (!result) {
1523
+ return void 0;
1524
+ }
1525
+ return remapToGraphQLSingleOutput(result, tableName, table, relationMap);
1526
+ } catch (e) {
1527
+ if (e instanceof Error) {
1528
+ throw new GraphQLError4(e.message);
1529
+ }
1530
+ throw e;
1531
+ }
1532
+ },
1533
+ args: queryArgs
1534
+ };
1535
+ };
1536
+ var generateInsertArray2 = (db, tableName, table, baseType, prefix, conflictDoNothing = false, singularTypes = false) => {
1537
+ const queryName = `${prefix}${capitalize(tableName)}`;
1538
+ const typeName = toTypeName3(tableName, singularTypes);
1539
+ const queryArgs = {
1540
+ values: {
1541
+ type: new GraphQLNonNull4(new GraphQLList4(new GraphQLNonNull4(baseType)))
1542
+ }
1543
+ };
1544
+ return {
1545
+ name: queryName,
1546
+ resolver: async (_source, args, _context, info) => {
1547
+ try {
1548
+ const input = remapFromGraphQLArrayInput(args.values, table);
1549
+ if (!input.length) {
1550
+ throw new GraphQLError4("No values were provided!");
1551
+ }
1552
+ const parsedInfo = parseResolveInfo2(info, {
1553
+ deep: true
1554
+ });
1555
+ const columns = extractSelectedColumnsFromTreeSQLFormat(
1556
+ parsedInfo.fieldsByTypeName[typeName],
1557
+ table
1558
+ );
1559
+ let query = db.insert(table).values(input).returning(columns);
1560
+ if (conflictDoNothing) {
1561
+ query = query.onConflictDoNothing();
1562
+ }
1563
+ const result = await query;
1564
+ return remapToGraphQLArrayOutput(result, tableName, table);
1565
+ } catch (e) {
1566
+ if (e instanceof Error) {
1567
+ throw new GraphQLError4(e.message);
1568
+ }
1569
+ throw e;
1570
+ }
1571
+ },
1572
+ args: queryArgs
1573
+ };
1574
+ };
1575
+ var generateInsertSingle2 = (db, tableName, table, baseType, prefix, conflictDoNothing = false, singularTypes = false) => {
1576
+ const queryEntityBase = singularTypes ? singularize(capitalize(tableName)) : capitalize(tableName);
1577
+ const queryName = singularTypes ? `${prefix}${queryEntityBase}` : `${prefix}${queryEntityBase}Single`;
1578
+ const typeName = toTypeName3(tableName, singularTypes);
1579
+ const queryArgs = {
1580
+ values: {
1581
+ type: new GraphQLNonNull4(baseType)
1582
+ }
1583
+ };
1584
+ return {
1585
+ name: queryName,
1586
+ resolver: async (_source, args, _context, info) => {
1587
+ try {
1588
+ const input = remapFromGraphQLSingleInput(args.values, table);
1589
+ const parsedInfo = parseResolveInfo2(info, {
1590
+ deep: true
1591
+ });
1592
+ const columns = extractSelectedColumnsFromTreeSQLFormat(
1593
+ parsedInfo.fieldsByTypeName[typeName],
1594
+ table
1595
+ );
1596
+ let query = db.insert(table).values(input).returning(columns);
1597
+ if (conflictDoNothing) {
1598
+ query = query.onConflictDoNothing();
1599
+ }
1600
+ const result = await query;
1601
+ if (!result[0]) {
1602
+ return void 0;
1603
+ }
1604
+ return remapToGraphQLSingleOutput(result[0], tableName, table);
1605
+ } catch (e) {
1606
+ if (e instanceof Error) {
1607
+ throw new GraphQLError4(e.message);
1608
+ }
1609
+ throw e;
1610
+ }
1611
+ },
1612
+ args: queryArgs
1613
+ };
1614
+ };
1615
+ var generateUpdate2 = (db, tableName, table, setArgs, filterArgs, prefix, singularTypes = false) => {
1616
+ const queryName = `${prefix}${capitalize(tableName)}`;
1617
+ const typeName = toTypeName3(tableName, singularTypes);
1618
+ const queryArgs = {
1619
+ set: {
1620
+ type: new GraphQLNonNull4(setArgs)
1621
+ },
1622
+ where: {
1623
+ type: filterArgs
1624
+ }
1625
+ };
1626
+ return {
1627
+ name: queryName,
1628
+ resolver: async (_source, args, _context, info) => {
1629
+ try {
1630
+ const { where, set } = args;
1631
+ const parsedInfo = parseResolveInfo2(info, {
1632
+ deep: true
1633
+ });
1634
+ const columns = extractSelectedColumnsFromTreeSQLFormat(
1635
+ parsedInfo.fieldsByTypeName[typeName],
1636
+ table
1637
+ );
1638
+ const input = remapFromGraphQLSingleInput(set, table);
1639
+ if (!Object.keys(input).length) {
1640
+ throw new GraphQLError4("Unable to update with no values specified!");
1641
+ }
1642
+ let query = db.update(table).set(input);
1643
+ if (where) {
1644
+ const filters = extractFilters(table, tableName, where);
1645
+ query = query.where(filters);
1646
+ }
1647
+ query = query.returning(columns);
1648
+ const result = await query;
1649
+ return remapToGraphQLArrayOutput(result, tableName, table);
1650
+ } catch (e) {
1651
+ if (e instanceof Error) {
1652
+ throw new GraphQLError4(e.message);
1653
+ }
1654
+ throw e;
1655
+ }
1656
+ },
1657
+ args: queryArgs
1658
+ };
1659
+ };
1660
+ var generateDelete2 = (db, tableName, table, filterArgs, prefix, singularTypes = false) => {
1661
+ const queryName = `${prefix}${capitalize(tableName)}`;
1662
+ const typeName = toTypeName3(tableName, singularTypes);
1663
+ const queryArgs = {
1664
+ where: {
1665
+ type: filterArgs
1666
+ }
1667
+ };
1668
+ return {
1669
+ name: queryName,
1670
+ resolver: async (_source, args, _context, info) => {
1671
+ try {
1672
+ const { where } = args;
1673
+ const parsedInfo = parseResolveInfo2(info, {
1674
+ deep: true
1675
+ });
1676
+ const columns = extractSelectedColumnsFromTreeSQLFormat(
1677
+ parsedInfo.fieldsByTypeName[typeName],
1678
+ table
1679
+ );
1680
+ let query = db.delete(table);
1681
+ if (where) {
1682
+ const filters = extractFilters(table, tableName, where);
1683
+ query = query.where(filters);
1684
+ }
1685
+ query = query.returning(columns);
1686
+ const result = await query;
1687
+ return remapToGraphQLArrayOutput(result, tableName, table);
1688
+ } catch (e) {
1689
+ if (e instanceof Error) {
1690
+ throw new GraphQLError4(e.message);
1691
+ }
1692
+ throw e;
1693
+ }
1694
+ },
1695
+ args: queryArgs
1696
+ };
1697
+ };
1698
+ function generateSchemaData2(db, schema, relations, relationsDepthLimit, prefixes, suffixes, conflictDoNothing = false, singularTypes = false) {
1699
+ const schemaEntries = Object.entries(schema);
1700
+ const tableEntries = schemaEntries.filter(([_key, value]) => is4(value, PgTable));
1701
+ const tables = Object.fromEntries(tableEntries);
1702
+ if (!tableEntries.length) {
1703
+ throw new Error(
1704
+ "Drizzle-GraphQL Error: No tables detected in Drizzle-ORM's database instance. Did you forget to pass schema to drizzle constructor?"
1705
+ );
1706
+ }
1707
+ const namedRelations = buildNamedRelations(relations ?? {}, tableEntries);
1708
+ const cacheCtx = {
1709
+ genericFilterCache: /* @__PURE__ */ new Map(),
1710
+ objectTypeCache: /* @__PURE__ */ new Map(),
1711
+ relationFieldContainers: /* @__PURE__ */ new Map(),
1712
+ fullyBuiltTables: /* @__PURE__ */ new Set(),
1713
+ relationTypeCache: /* @__PURE__ */ new Map()
1714
+ };
1715
+ const queries = {};
1716
+ const mutations = {};
1717
+ const gqlSchemaTypes = Object.fromEntries(
1718
+ Object.entries(tables).map(([tableName, _table]) => [
1719
+ tableName,
1720
+ generateTableTypes(
1721
+ tableName,
1722
+ tables,
1723
+ namedRelations,
1724
+ true,
1725
+ relationsDepthLimit,
1726
+ cacheCtx,
1727
+ singularTypes,
1728
+ prefixes.insert,
1729
+ prefixes.update
1730
+ )
1731
+ ])
1732
+ );
1733
+ const inputs = {};
1734
+ const outputs = {};
1735
+ for (const [tableName, tableTypes] of Object.entries(gqlSchemaTypes)) {
1736
+ const { insertInput, updateInput, tableFilters, tableOrder } = tableTypes.inputs;
1737
+ const { selectSingleOutput, selectArrOutput, singleTableItemOutput, arrTableItemOutput } = tableTypes.outputs;
1738
+ const selectArrGenerated = generateSelectArray2(
1739
+ db,
1740
+ tableName,
1741
+ tables,
1742
+ namedRelations,
1743
+ tableOrder,
1744
+ tableFilters,
1745
+ suffixes.list,
1746
+ singularTypes
1747
+ );
1748
+ const selectSingleGenerated = generateSelectSingle2(
1749
+ db,
1750
+ tableName,
1751
+ tables,
1752
+ namedRelations,
1753
+ tableOrder,
1754
+ tableFilters,
1755
+ suffixes.single,
1756
+ singularTypes
1757
+ );
1758
+ const insertArrGenerated = generateInsertArray2(
1759
+ db,
1760
+ tableName,
1761
+ schema[tableName],
1762
+ insertInput,
1763
+ prefixes.insert,
1764
+ conflictDoNothing,
1765
+ singularTypes
1766
+ );
1767
+ const insertSingleGenerated = generateInsertSingle2(
1768
+ db,
1769
+ tableName,
1770
+ schema[tableName],
1771
+ insertInput,
1772
+ prefixes.insert,
1773
+ conflictDoNothing,
1774
+ singularTypes
1775
+ );
1776
+ const updateGenerated = generateUpdate2(
1777
+ db,
1778
+ tableName,
1779
+ schema[tableName],
1780
+ updateInput,
1781
+ tableFilters,
1782
+ prefixes.update,
1783
+ singularTypes
1784
+ );
1785
+ const deleteGenerated = generateDelete2(
1786
+ db,
1787
+ tableName,
1788
+ schema[tableName],
1789
+ tableFilters,
1790
+ prefixes.delete,
1791
+ singularTypes
1792
+ );
1793
+ queries[selectArrGenerated.name] = {
1794
+ type: selectArrOutput,
1795
+ args: selectArrGenerated.args,
1796
+ resolve: selectArrGenerated.resolver
1797
+ };
1798
+ queries[selectSingleGenerated.name] = {
1799
+ type: selectSingleOutput,
1800
+ args: selectSingleGenerated.args,
1801
+ resolve: selectSingleGenerated.resolver
1802
+ };
1803
+ mutations[insertArrGenerated.name] = {
1804
+ type: arrTableItemOutput,
1805
+ args: insertArrGenerated.args,
1806
+ resolve: insertArrGenerated.resolver
1807
+ };
1808
+ mutations[insertSingleGenerated.name] = {
1809
+ type: singleTableItemOutput,
1810
+ args: insertSingleGenerated.args,
1811
+ resolve: insertSingleGenerated.resolver
1812
+ };
1813
+ mutations[updateGenerated.name] = {
1814
+ type: arrTableItemOutput,
1815
+ args: updateGenerated.args,
1816
+ resolve: updateGenerated.resolver
1817
+ };
1818
+ mutations[deleteGenerated.name] = {
1819
+ type: arrTableItemOutput,
1820
+ args: deleteGenerated.args,
1821
+ resolve: deleteGenerated.resolver
1822
+ };
1823
+ [insertInput, updateInput, tableFilters, tableOrder].forEach((e) => {
1824
+ inputs[e.name] = e;
1825
+ });
1826
+ outputs[selectSingleOutput.name] = selectSingleOutput;
1827
+ outputs[singleTableItemOutput.name] = singleTableItemOutput;
1828
+ }
1829
+ return { queries, mutations, inputs, types: outputs };
1830
+ }
1831
+
1832
+ // src/util/builders/sqlite.ts
1833
+ import { is as is5 } from "drizzle-orm";
1834
+ import { SQLiteTable } from "drizzle-orm/sqlite-core";
1835
+ import {
1836
+ GraphQLError as GraphQLError5,
1837
+ GraphQLInt as GraphQLInt5,
1838
+ GraphQLList as GraphQLList5,
1839
+ GraphQLNonNull as GraphQLNonNull5
1840
+ } from "graphql";
1841
+ import { parseResolveInfo as parseResolveInfo3 } from "graphql-parse-resolve-info";
1842
+ var toTypeName4 = (name, singular) => singular ? capitalize(singularize(name)) : capitalize(name);
1843
+ var generateSelectArray3 = (db, tableName, tables, relationMap, orderArgs, filterArgs, listSuffix, singularTypes) => {
1844
+ const queryEntityBase = singularTypes ? singularize(uncapitalize(tableName)) : uncapitalize(tableName);
1845
+ const queryName = `${queryEntityBase}${listSuffix}`;
1846
+ const queryBase = db.query[tableName];
1847
+ if (!queryBase) {
1848
+ throw new Error(
1849
+ `Drizzle-GraphQL Error: Table ${tableName} not found in drizzle instance. Did you forget to pass schema to drizzle constructor?`
1850
+ );
1851
+ }
1852
+ const queryArgs = {
1853
+ offset: {
1854
+ type: GraphQLInt5
1855
+ },
1856
+ limit: {
1857
+ type: GraphQLInt5
1858
+ },
1859
+ orderBy: {
1860
+ type: orderArgs
1861
+ },
1862
+ where: {
1863
+ type: filterArgs
1864
+ }
1865
+ };
1866
+ const typeName = toTypeName4(tableName, singularTypes);
1867
+ const table = tables[tableName];
1868
+ return {
1869
+ name: queryName,
1870
+ resolver: async (_source, args, _context, info) => {
1871
+ try {
1872
+ const { offset, limit, orderBy, where } = args;
1873
+ const parsedInfo = parseResolveInfo3(info, {
1874
+ deep: true
1875
+ });
1876
+ const query = queryBase.findMany({
1877
+ columns: extractSelectedColumnsFromTree(parsedInfo.fieldsByTypeName[typeName], table),
1878
+ offset,
1879
+ limit,
1880
+ // drizzle-orm v1 RQB calls orderBy with the aliased table proxy —
1881
+ // use it directly so column refs match the CTE alias.
1882
+ orderBy: orderBy ? (aliasedTable) => extractOrderBy(aliasedTable, orderBy) : void 0,
1883
+ where: where ? { RAW: (aliased) => extractFilters(aliased, tableName, where) } : void 0,
1884
+ with: relationMap[tableName] ? extractRelationsParams(relationMap, tables, tableName, parsedInfo, typeName, singularTypes) : void 0
1885
+ });
1886
+ const result = await query;
1887
+ return remapToGraphQLArrayOutput(result, tableName, table, relationMap);
1888
+ } catch (e) {
1889
+ if (e instanceof Error) {
1890
+ throw new GraphQLError5(e.message);
1891
+ }
1892
+ throw e;
1893
+ }
1894
+ },
1895
+ args: queryArgs
1896
+ };
1897
+ };
1898
+ var generateSelectSingle3 = (db, tableName, tables, relationMap, orderArgs, filterArgs, singleSuffix, singularTypes) => {
1899
+ const queryEntityBase = singularTypes ? singularize(uncapitalize(tableName)) : uncapitalize(tableName);
1900
+ const queryName = `${queryEntityBase}${singleSuffix}`;
1901
+ const queryBase = db.query[tableName];
1902
+ if (!queryBase) {
1903
+ throw new Error(
1904
+ `Drizzle-GraphQL Error: Table ${tableName} not found in drizzle instance. Did you forget to pass schema to drizzle constructor?`
1905
+ );
1906
+ }
1907
+ const queryArgs = {
1908
+ offset: {
1909
+ type: GraphQLInt5
1910
+ },
1911
+ orderBy: {
1912
+ type: orderArgs
1913
+ },
1914
+ where: {
1915
+ type: filterArgs
1916
+ }
1917
+ };
1918
+ const typeName = toTypeName4(tableName, singularTypes);
1919
+ const table = tables[tableName];
1920
+ return {
1921
+ name: queryName,
1922
+ resolver: async (_source, args, _context, info) => {
1923
+ try {
1924
+ const { offset, orderBy, where } = args;
1925
+ const parsedInfo = parseResolveInfo3(info, {
1926
+ deep: true
1927
+ });
1928
+ const query = queryBase.findFirst({
1929
+ columns: extractSelectedColumnsFromTree(parsedInfo.fieldsByTypeName[typeName], table),
1930
+ offset,
1931
+ // drizzle-orm v1 RQB calls orderBy with the aliased table proxy —
1932
+ // use it directly so column refs match the CTE alias.
1933
+ orderBy: orderBy ? (aliasedTable) => extractOrderBy(aliasedTable, orderBy) : void 0,
1934
+ where: where ? { RAW: (aliased) => extractFilters(aliased, tableName, where) } : void 0,
1935
+ with: relationMap[tableName] ? extractRelationsParams(relationMap, tables, tableName, parsedInfo, typeName, singularTypes) : void 0
1936
+ });
1937
+ const result = await query;
1938
+ if (!result) {
1939
+ return void 0;
1940
+ }
1941
+ return remapToGraphQLSingleOutput(result, tableName, table, relationMap);
1942
+ } catch (e) {
1943
+ if (e instanceof Error) {
1944
+ throw new GraphQLError5(e.message);
1945
+ }
1946
+ throw e;
1947
+ }
1948
+ },
1949
+ args: queryArgs
1950
+ };
1951
+ };
1952
+ var generateInsertArray3 = (db, tableName, table, baseType, singularTypes = false) => {
1953
+ const queryName = `insertInto${capitalize(tableName)}`;
1954
+ const typeName = toTypeName4(tableName, singularTypes);
1955
+ const queryArgs = {
1956
+ values: {
1957
+ type: new GraphQLNonNull5(new GraphQLList5(new GraphQLNonNull5(baseType)))
1958
+ }
1959
+ };
1960
+ return {
1961
+ name: queryName,
1962
+ resolver: async (_source, args, _context, info) => {
1963
+ try {
1964
+ const input = remapFromGraphQLArrayInput(args.values, table);
1965
+ if (!input.length) {
1966
+ throw new GraphQLError5("No values were provided!");
1967
+ }
1968
+ const parsedInfo = parseResolveInfo3(info, {
1969
+ deep: true
1970
+ });
1971
+ const columns = extractSelectedColumnsFromTreeSQLFormat(
1972
+ parsedInfo.fieldsByTypeName[typeName],
1973
+ table
1974
+ );
1975
+ const result = await db.insert(table).values(input).returning(columns).onConflictDoNothing();
1976
+ return remapToGraphQLArrayOutput(result, tableName, table);
1977
+ } catch (e) {
1978
+ if (e instanceof Error) {
1979
+ throw new GraphQLError5(e.message);
1980
+ }
1981
+ throw e;
1982
+ }
1983
+ },
1984
+ args: queryArgs
1985
+ };
1986
+ };
1987
+ var generateInsertSingle3 = (db, tableName, table, baseType, singularTypes = false) => {
1988
+ const queryEntityBase = singularTypes ? singularize(capitalize(tableName)) : capitalize(tableName);
1989
+ const queryName = singularTypes ? `insertInto${queryEntityBase}` : `insertInto${queryEntityBase}Single`;
1990
+ const typeName = toTypeName4(tableName, singularTypes);
1991
+ const queryArgs = {
1992
+ values: {
1993
+ type: new GraphQLNonNull5(baseType)
1994
+ }
1995
+ };
1996
+ return {
1997
+ name: queryName,
1998
+ resolver: async (_source, args, _context, info) => {
1999
+ try {
2000
+ const input = remapFromGraphQLSingleInput(args.values, table);
2001
+ const parsedInfo = parseResolveInfo3(info, {
2002
+ deep: true
2003
+ });
2004
+ const columns = extractSelectedColumnsFromTreeSQLFormat(
2005
+ parsedInfo.fieldsByTypeName[typeName],
2006
+ table
2007
+ );
2008
+ const result = await db.insert(table).values(input).returning(columns).onConflictDoNothing();
2009
+ if (!result[0]) {
2010
+ return void 0;
2011
+ }
2012
+ return remapToGraphQLSingleOutput(result[0], tableName, table);
2013
+ } catch (e) {
2014
+ if (e instanceof Error) {
2015
+ throw new GraphQLError5(e.message);
2016
+ }
2017
+ throw e;
2018
+ }
2019
+ },
2020
+ args: queryArgs
2021
+ };
2022
+ };
2023
+ var generateUpdate3 = (db, tableName, table, setArgs, filterArgs, singularTypes = false) => {
2024
+ const queryName = `update${capitalize(tableName)}`;
2025
+ const typeName = toTypeName4(tableName, singularTypes);
2026
+ const queryArgs = {
2027
+ set: {
2028
+ type: new GraphQLNonNull5(setArgs)
2029
+ },
2030
+ where: {
2031
+ type: filterArgs
2032
+ }
2033
+ };
2034
+ return {
2035
+ name: queryName,
2036
+ resolver: async (_source, args, _context, info) => {
2037
+ try {
2038
+ const { where, set } = args;
2039
+ const parsedInfo = parseResolveInfo3(info, {
2040
+ deep: true
2041
+ });
2042
+ const columns = extractSelectedColumnsFromTreeSQLFormat(
2043
+ parsedInfo.fieldsByTypeName[typeName],
2044
+ table
2045
+ );
2046
+ const input = remapFromGraphQLSingleInput(set, table);
2047
+ if (!Object.keys(input).length) {
2048
+ throw new GraphQLError5("Unable to update with no values specified!");
2049
+ }
2050
+ let query = db.update(table).set(input);
2051
+ if (where) {
2052
+ const filters = extractFilters(table, tableName, where);
2053
+ query = query.where(filters);
2054
+ }
2055
+ query = query.returning(columns);
2056
+ const result = await query;
2057
+ return remapToGraphQLArrayOutput(result, tableName, table);
2058
+ } catch (e) {
2059
+ if (e instanceof Error) {
2060
+ throw new GraphQLError5(e.message);
2061
+ }
2062
+ throw e;
2063
+ }
2064
+ },
2065
+ args: queryArgs
2066
+ };
2067
+ };
2068
+ var generateDelete3 = (db, tableName, table, filterArgs, singularTypes = false) => {
2069
+ const queryName = `deleteFrom${capitalize(tableName)}`;
2070
+ const typeName = toTypeName4(tableName, singularTypes);
2071
+ const queryArgs = {
2072
+ where: {
2073
+ type: filterArgs
2074
+ }
2075
+ };
2076
+ return {
2077
+ name: queryName,
2078
+ resolver: async (_source, args, _context, info) => {
2079
+ try {
2080
+ const { where } = args;
2081
+ const parsedInfo = parseResolveInfo3(info, {
2082
+ deep: true
2083
+ });
2084
+ const columns = extractSelectedColumnsFromTreeSQLFormat(
2085
+ parsedInfo.fieldsByTypeName[typeName],
2086
+ table
2087
+ );
2088
+ let query = db.delete(table);
2089
+ if (where) {
2090
+ const filters = extractFilters(table, tableName, where);
2091
+ query = query.where(filters);
2092
+ }
2093
+ query = query.returning(columns);
2094
+ const result = await query;
2095
+ return remapToGraphQLArrayOutput(result, tableName, table);
2096
+ } catch (e) {
2097
+ if (e instanceof Error) {
2098
+ throw new GraphQLError5(e.message);
2099
+ }
2100
+ throw e;
2101
+ }
2102
+ },
2103
+ args: queryArgs
2104
+ };
2105
+ };
2106
+ var generateSchemaData3 = (db, schema, relations, relationsDepthLimit, prefixes, suffixes, singularTypes = false) => {
2107
+ const rawSchema = schema;
2108
+ const schemaEntries = Object.entries(rawSchema);
2109
+ const tableEntries = schemaEntries.filter(([_key, value]) => is5(value, SQLiteTable));
2110
+ const tables = Object.fromEntries(tableEntries);
2111
+ if (!tableEntries.length) {
2112
+ throw new Error(
2113
+ "Drizzle-GraphQL Error: No tables detected in Drizzle-ORM's database instance. Did you forget to pass schema to drizzle constructor?"
2114
+ );
2115
+ }
2116
+ const namedRelations = buildNamedRelations(relations ?? {}, tableEntries);
2117
+ const cacheCtx = {
2118
+ genericFilterCache: /* @__PURE__ */ new Map(),
2119
+ objectTypeCache: /* @__PURE__ */ new Map(),
2120
+ relationFieldContainers: /* @__PURE__ */ new Map(),
2121
+ fullyBuiltTables: /* @__PURE__ */ new Set(),
2122
+ relationTypeCache: /* @__PURE__ */ new Map()
2123
+ };
2124
+ const queries = {};
2125
+ const mutations = {};
2126
+ const gqlSchemaTypes = Object.fromEntries(
2127
+ Object.entries(tables).map(([tableName, _table]) => [
2128
+ tableName,
2129
+ generateTableTypes(
2130
+ tableName,
2131
+ tables,
2132
+ namedRelations,
2133
+ true,
2134
+ relationsDepthLimit,
2135
+ cacheCtx,
2136
+ singularTypes,
2137
+ prefixes.insert,
2138
+ prefixes.update
2139
+ )
2140
+ ])
2141
+ );
2142
+ const inputs = {};
2143
+ const outputs = {};
2144
+ for (const [tableName, tableTypes] of Object.entries(gqlSchemaTypes)) {
2145
+ const { insertInput, updateInput, tableFilters, tableOrder } = tableTypes.inputs;
2146
+ const { selectSingleOutput, selectArrOutput, singleTableItemOutput, arrTableItemOutput } = tableTypes.outputs;
2147
+ const selectArrGenerated = generateSelectArray3(
2148
+ db,
2149
+ tableName,
2150
+ tables,
2151
+ namedRelations,
2152
+ tableOrder,
2153
+ tableFilters,
2154
+ suffixes.list,
2155
+ singularTypes
2156
+ );
2157
+ const selectSingleGenerated = generateSelectSingle3(
2158
+ db,
2159
+ tableName,
2160
+ tables,
2161
+ namedRelations,
2162
+ tableOrder,
2163
+ tableFilters,
2164
+ suffixes.single,
2165
+ singularTypes
2166
+ );
2167
+ const insertArrGenerated = generateInsertArray3(
2168
+ db,
2169
+ tableName,
2170
+ schema[tableName],
2171
+ insertInput,
2172
+ singularTypes
2173
+ );
2174
+ const insertSingleGenerated = generateInsertSingle3(
2175
+ db,
2176
+ tableName,
2177
+ schema[tableName],
2178
+ insertInput,
2179
+ singularTypes
2180
+ );
2181
+ const updateGenerated = generateUpdate3(
2182
+ db,
2183
+ tableName,
2184
+ schema[tableName],
2185
+ updateInput,
2186
+ tableFilters,
2187
+ singularTypes
2188
+ );
2189
+ const deleteGenerated = generateDelete3(
2190
+ db,
2191
+ tableName,
2192
+ schema[tableName],
2193
+ tableFilters,
2194
+ singularTypes
2195
+ );
2196
+ queries[selectArrGenerated.name] = {
2197
+ type: selectArrOutput,
2198
+ args: selectArrGenerated.args,
2199
+ resolve: selectArrGenerated.resolver
2200
+ };
2201
+ queries[selectSingleGenerated.name] = {
2202
+ type: selectSingleOutput,
2203
+ args: selectSingleGenerated.args,
2204
+ resolve: selectSingleGenerated.resolver
2205
+ };
2206
+ mutations[insertArrGenerated.name] = {
2207
+ type: arrTableItemOutput,
2208
+ args: insertArrGenerated.args,
2209
+ resolve: insertArrGenerated.resolver
2210
+ };
2211
+ mutations[insertSingleGenerated.name] = {
2212
+ type: singleTableItemOutput,
2213
+ args: insertSingleGenerated.args,
2214
+ resolve: insertSingleGenerated.resolver
2215
+ };
2216
+ mutations[updateGenerated.name] = {
2217
+ type: arrTableItemOutput,
2218
+ args: updateGenerated.args,
2219
+ resolve: updateGenerated.resolver
2220
+ };
2221
+ mutations[deleteGenerated.name] = {
2222
+ type: arrTableItemOutput,
2223
+ args: deleteGenerated.args,
2224
+ resolve: deleteGenerated.resolver
2225
+ };
2226
+ [insertInput, updateInput, tableFilters, tableOrder].forEach((e) => {
2227
+ inputs[e.name] = e;
2228
+ });
2229
+ outputs[selectSingleOutput.name] = selectSingleOutput;
2230
+ outputs[singleTableItemOutput.name] = singleTableItemOutput;
2231
+ }
2232
+ return { queries, mutations, inputs, types: outputs };
2233
+ };
2234
+
2235
+ // src/index.ts
2236
+ var buildSchema = (db, config) => {
2237
+ const schema = db._.fullSchema;
2238
+ const relations = db._.relations;
2239
+ if (!schema) {
2240
+ throw new Error(
2241
+ "Drizzle-GraphQL Error: Schema not found in drizzle instance. Make sure you're using drizzle-orm v0.30.9 or above and schema is passed to drizzle constructor!"
2242
+ );
2243
+ }
2244
+ const prefixes = {
2245
+ insert: config?.prefixes?.insert ?? "insertInto",
2246
+ delete: config?.prefixes?.delete ?? "deleteFrom",
2247
+ update: config?.prefixes?.update ?? "update"
2248
+ };
2249
+ const suffixes = {
2250
+ list: config?.suffixes?.list ?? "",
2251
+ single: config?.suffixes?.single ?? "Single"
2252
+ };
2253
+ const singularTypes = config?.singularTypes ?? false;
2254
+ if (typeof config?.relationsDepthLimit === "number") {
2255
+ if (config.relationsDepthLimit < 0) {
2256
+ throw new Error(
2257
+ "Drizzle-GraphQL Error: config.relationsDepthLimit is supposed to be nonnegative integer or undefined!"
2258
+ );
2259
+ }
2260
+ if (config.relationsDepthLimit !== ~~config.relationsDepthLimit) {
2261
+ throw new Error(
2262
+ "Drizzle-GraphQL Error: config.relationsDepthLimit is supposed to be nonnegative integer or undefined!"
2263
+ );
2264
+ }
2265
+ if (suffixes.list === suffixes.single) {
2266
+ throw new Error(
2267
+ "Drizzle-GraphQL Error: List and single query suffixes cannot be the same. This would create conflicting GraphQL field names."
2268
+ );
2269
+ }
2270
+ }
2271
+ let generatorOutput;
2272
+ if (is6(db, MySqlDatabase)) {
2273
+ generatorOutput = generateSchemaData(
2274
+ db,
2275
+ schema,
2276
+ relations,
2277
+ config?.relationsDepthLimit,
2278
+ prefixes,
2279
+ suffixes,
2280
+ singularTypes
2281
+ );
2282
+ } else if (is6(db, PgAsyncDatabase)) {
2283
+ generatorOutput = generateSchemaData2(
2284
+ db,
2285
+ schema,
2286
+ relations,
2287
+ config?.relationsDepthLimit,
2288
+ prefixes,
2289
+ suffixes,
2290
+ config?.conflictDoNothing ?? false,
2291
+ singularTypes
2292
+ );
2293
+ } else if (is6(db, BaseSQLiteDatabase)) {
2294
+ generatorOutput = generateSchemaData3(
2295
+ db,
2296
+ schema,
2297
+ relations,
2298
+ config?.relationsDepthLimit,
2299
+ prefixes,
2300
+ suffixes,
2301
+ singularTypes
2302
+ );
2303
+ } else {
2304
+ throw new Error("Drizzle-GraphQL Error: Unknown database instance type");
2305
+ }
2306
+ const { queries, mutations, inputs, types } = generatorOutput;
2307
+ const graphQLSchemaConfig = {
2308
+ types: [...Object.values(inputs), ...Object.values(types)],
2309
+ query: new GraphQLObjectType4({
2310
+ name: "Query",
2311
+ fields: queries
2312
+ })
2313
+ };
2314
+ if (config?.mutations !== false) {
2315
+ const mutation = new GraphQLObjectType4({
2316
+ name: "Mutation",
2317
+ fields: mutations
2318
+ });
2319
+ graphQLSchemaConfig.mutation = mutation;
2320
+ }
2321
+ const outputSchema = new GraphQLSchema(graphQLSchemaConfig);
2322
+ return { schema: outputSchema, entities: generatorOutput };
2323
+ };
2324
+ export {
2325
+ buildSchema,
2326
+ extractFilters,
2327
+ extractOrderBy
2328
+ };
2329
+ //# sourceMappingURL=index.js.map