pothos-drizzle-generator 0.0.1

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.
@@ -0,0 +1,395 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { BasePlugin } from "@pothos/core";
3
+ import { sql } from "drizzle-orm";
4
+ import { PothosDrizzleGenerator } from "./generator.js";
5
+ import { createWhereQuery, getQueryDepth } from "./libs/utils.js";
6
+ export class PothosDrizzleGeneratorPlugin extends BasePlugin {
7
+ generator;
8
+ constructor(buildCache, name) {
9
+ super(buildCache, name);
10
+ this.generator = new PothosDrizzleGenerator(this.builder);
11
+ }
12
+ beforeBuild() {
13
+ const generator = this.generator;
14
+ const builder = this.builder;
15
+ const depthLimit = generator.getDepthLimit();
16
+ const tables = generator.getTables();
17
+ for (const [modelName, { table, tableInfo, relations, columns, operations, executable, limit, where, orderBy, inputData, },] of Object.entries(tables)) {
18
+ const objectRef = builder.objectRef(modelName);
19
+ objectRef.implement({
20
+ fields: (t) => Object.fromEntries(columns.map((c) => {
21
+ return [
22
+ c.name,
23
+ t.expose(c.name, {
24
+ type: generator.getDataType(c),
25
+ nullable: !c.notNull,
26
+ }),
27
+ ];
28
+ })),
29
+ });
30
+ const filterRelations = Object.entries(relations).filter(([, relay]) => tables[relay.targetTableName]);
31
+ builder.drizzleObject(modelName, {
32
+ name: tableInfo.name,
33
+ fields: (t) => {
34
+ const relayList = filterRelations.map(([relayName, relay]) => {
35
+ const modelName = relay.targetTableName;
36
+ const { executable, where, orderBy, limit, operations } = tables[modelName];
37
+ const operation = relay.relationType === "one" ? "findFirst" : "findMany";
38
+ if (!operations.includes(operation))
39
+ return [];
40
+ const inputWhere = generator.getInputWhere(modelName);
41
+ const inputOrderBy = generator.getInputOrderBy(modelName);
42
+ return [
43
+ relayName,
44
+ t.relation(relayName, {
45
+ columns: { id: true },
46
+ args: {
47
+ offset: t.arg({ type: "Int" }),
48
+ limit: t.arg({ type: "Int" }),
49
+ where: t.arg({ type: inputWhere }),
50
+ orderBy: t.arg({ type: inputOrderBy }),
51
+ },
52
+ query: (args, ctx) => {
53
+ if (executable?.({
54
+ modelName,
55
+ ctx,
56
+ operation,
57
+ }) === false) {
58
+ throw new Error("No permission");
59
+ }
60
+ const p = {
61
+ limit: limit?.({ modelName, ctx, operation }),
62
+ where: where?.({ modelName, ctx, operation }),
63
+ orderBy: orderBy?.({ modelName, ctx, operation }),
64
+ };
65
+ return {
66
+ ...args,
67
+ limit: p.limit && args.limit
68
+ ? Math.min(p.limit, args.limit)
69
+ : p.limit ?? args.limit,
70
+ where: { AND: [args.where, p.where].filter((v) => v) },
71
+ orderBy: args.orderBy && Object.keys(args.orderBy).length
72
+ ? args.orderBy
73
+ : p.orderBy,
74
+ };
75
+ },
76
+ }),
77
+ ];
78
+ });
79
+ const relayCount = filterRelations.map(([relayName, relay]) => {
80
+ const modelName = relay.targetTableName;
81
+ const operation = "count";
82
+ const { executable, where, operations } = tables[modelName];
83
+ if (!operations.includes(operation))
84
+ return [];
85
+ const inputWhere = generator.getInputWhere(modelName);
86
+ return [
87
+ `${relayName}Count`,
88
+ t.relatedCount(relayName, {
89
+ args: { where: t.arg({ type: inputWhere }) },
90
+ where: (args, ctx) => {
91
+ if (executable?.({
92
+ modelName,
93
+ ctx,
94
+ operation,
95
+ }) === false) {
96
+ throw new Error("No permission");
97
+ }
98
+ const p = {
99
+ where: where?.({ modelName, ctx, operation }),
100
+ };
101
+ return createWhereQuery(relay.targetTable, {
102
+ AND: [args.where, p.where].filter((v) => v),
103
+ });
104
+ },
105
+ }),
106
+ ];
107
+ });
108
+ return Object.fromEntries([
109
+ ...relayCount,
110
+ ...relayList,
111
+ ...columns.map((c) => {
112
+ return [
113
+ c.name,
114
+ t.expose(c.name, {
115
+ type: generator.getDataType(c),
116
+ nullable: !c.notNull,
117
+ }),
118
+ ];
119
+ }),
120
+ ]);
121
+ },
122
+ });
123
+ const inputWhere = generator.getInputWhere(modelName);
124
+ const inputOrderBy = generator.getInputOrderBy(modelName);
125
+ const inputCreate = generator.getInputCreate(modelName);
126
+ const inputUpdate = generator.getInputUpdate(modelName);
127
+ if (operations.includes("findMany")) {
128
+ builder.queryType({
129
+ fields: (t) => ({
130
+ [`findMany${tableInfo.name}`]: t.drizzleField({
131
+ type: [modelName],
132
+ nullable: false,
133
+ args: {
134
+ offset: t.arg({ type: "Int" }),
135
+ limit: t.arg({ type: "Int" }),
136
+ where: t.arg({ type: inputWhere }),
137
+ orderBy: t.arg({ type: inputOrderBy }),
138
+ },
139
+ resolve: async (query, _parent, args, ctx, info) => {
140
+ const operation = "findMany";
141
+ if (executable?.({
142
+ modelName,
143
+ ctx,
144
+ operation,
145
+ }) === false) {
146
+ throw new Error("No permission");
147
+ }
148
+ const p = {
149
+ depthLimit: depthLimit?.({ modelName, ctx, operation }),
150
+ limit: limit?.({ modelName, ctx, operation }),
151
+ where: where?.({ modelName, ctx, operation }),
152
+ orderBy: orderBy?.({ modelName, ctx, operation }),
153
+ };
154
+ if (p.depthLimit !== undefined &&
155
+ getQueryDepth(info) > p.depthLimit)
156
+ throw new Error("Depth limit exceeded");
157
+ return generator.getClient(ctx).query[modelName].findMany(query({
158
+ ...args,
159
+ limit: p.limit && args.limit
160
+ ? Math.min(p.limit, args.limit)
161
+ : p.limit ?? args.limit,
162
+ where: { AND: [args.where, p.where].filter((v) => v) },
163
+ orderBy: args.orderBy && Object.keys(args.orderBy).length
164
+ ? args.orderBy
165
+ : p.orderBy,
166
+ }));
167
+ },
168
+ }),
169
+ }),
170
+ });
171
+ }
172
+ if (operations.includes("findFirst")) {
173
+ builder.queryType({
174
+ fields: (t) => ({
175
+ [`findFirst${tableInfo.name}`]: t.drizzleField({
176
+ type: modelName,
177
+ args: {
178
+ offset: t.arg({ type: "Int" }),
179
+ where: t.arg({ type: inputWhere }),
180
+ orderBy: t.arg({ type: inputOrderBy }),
181
+ },
182
+ resolve: async (query, _parent, args, ctx, info) => {
183
+ const operation = "findFirst";
184
+ if (executable?.({
185
+ modelName,
186
+ ctx,
187
+ operation,
188
+ }) === false) {
189
+ throw new Error("No permission");
190
+ }
191
+ const p = {
192
+ depthLimit: depthLimit?.({ modelName, ctx, operation }),
193
+ where: where?.({ modelName, ctx, operation }),
194
+ orderBy: orderBy?.({ modelName, ctx, operation }),
195
+ };
196
+ if (p.depthLimit !== undefined &&
197
+ getQueryDepth(info) > p.depthLimit)
198
+ throw new Error("Depth limit exceeded");
199
+ return generator.getClient(ctx).query[modelName].findFirst(query({
200
+ ...args,
201
+ where: { AND: [args.where, p.where].filter((v) => v) },
202
+ orderBy: args.orderBy && Object.keys(args.orderBy).length
203
+ ? args.orderBy
204
+ : p.orderBy,
205
+ }));
206
+ },
207
+ }),
208
+ }),
209
+ });
210
+ }
211
+ if (operations.includes("count")) {
212
+ builder.queryType({
213
+ fields: (t) => ({
214
+ [`count${tableInfo.name}`]: t.field({
215
+ type: "Int",
216
+ nullable: false,
217
+ args: {
218
+ limit: t.arg({ type: "Int" }),
219
+ where: t.arg({ type: inputWhere }),
220
+ },
221
+ resolve: async (_query, _parent, args, ctx, info) => {
222
+ const operation = "count";
223
+ if (executable?.({
224
+ modelName,
225
+ ctx,
226
+ operation,
227
+ }) === false) {
228
+ throw new Error("No permission");
229
+ }
230
+ const p = {
231
+ depthLimit: depthLimit?.({ modelName, ctx, operation }),
232
+ limit: limit?.({ modelName, ctx, operation }),
233
+ where: where?.({ modelName, ctx, operation }),
234
+ };
235
+ if (p.depthLimit !== undefined &&
236
+ getQueryDepth(info) > p.depthLimit)
237
+ throw new Error("Depth limit exceeded");
238
+ return generator.getClient(ctx).query[modelName]
239
+ .findFirst({
240
+ columns: {},
241
+ extras: { _count: () => sql `count(*)` },
242
+ ...args,
243
+ limit: p.limit && args.limit
244
+ ? Math.min(p.limit, args.limit)
245
+ : p.limit ?? args.limit,
246
+ where: { AND: [args.where, p.where].filter((v) => v) },
247
+ })
248
+ .then((v) => v._count);
249
+ },
250
+ }),
251
+ }),
252
+ });
253
+ }
254
+ if (operations.includes("createOne")) {
255
+ builder.mutationType({
256
+ fields: (t) => ({
257
+ [`createOne${tableInfo.name}`]: t.drizzleField({
258
+ type: modelName,
259
+ nullable: false,
260
+ args: { input: t.arg({ type: inputCreate, required: true }) },
261
+ resolve: async (_query, _parent, args, ctx, info) => {
262
+ const operation = "createOne";
263
+ if (executable?.({
264
+ modelName,
265
+ ctx,
266
+ operation,
267
+ }) === false) {
268
+ throw new Error("No permission");
269
+ }
270
+ const p = {
271
+ depthLimit: depthLimit?.({ modelName, ctx, operation }),
272
+ input: inputData?.({ modelName, ctx, operation }),
273
+ };
274
+ if (p.depthLimit !== undefined &&
275
+ getQueryDepth(info) > p.depthLimit)
276
+ throw new Error("Depth limit exceeded");
277
+ return generator.getClient(ctx)
278
+ .insert(table)
279
+ .values({ ...args.input, ...p.input })
280
+ .returning()
281
+ .then((v) => v[0]);
282
+ },
283
+ }),
284
+ }),
285
+ });
286
+ }
287
+ if (operations.includes("createMany")) {
288
+ builder.mutationType({
289
+ fields: (t) => ({
290
+ [`createMany${tableInfo.name}`]: t.drizzleField({
291
+ type: [modelName],
292
+ nullable: false,
293
+ args: { input: t.arg({ type: [inputCreate], required: true }) },
294
+ resolve: async (_query, _parent, args, ctx, info) => {
295
+ const operation = "createMany";
296
+ if (executable?.({
297
+ modelName,
298
+ ctx,
299
+ operation,
300
+ }) === false) {
301
+ throw new Error("No permission");
302
+ }
303
+ const p = {
304
+ depthLimit: depthLimit?.({ modelName, ctx, operation }),
305
+ args: inputData?.({ modelName, ctx, operation }),
306
+ };
307
+ if (p.depthLimit !== undefined &&
308
+ getQueryDepth(info) > p.depthLimit)
309
+ throw new Error("Depth limit exceeded");
310
+ return generator.getClient(ctx)
311
+ .insert(table)
312
+ .values(args.input.map((v) => ({ ...v, ...p.args })))
313
+ .returning();
314
+ },
315
+ }),
316
+ }),
317
+ });
318
+ }
319
+ if (operations.includes("update")) {
320
+ builder.mutationType({
321
+ fields: (t) => ({
322
+ [`update${tableInfo.name}`]: t.drizzleField({
323
+ type: [modelName],
324
+ nullable: false,
325
+ args: {
326
+ input: t.arg({ type: inputUpdate, required: true }),
327
+ where: t.arg({ type: inputWhere }),
328
+ },
329
+ resolve: async (_query, _parent, args, ctx, info) => {
330
+ const operation = "update";
331
+ if (executable?.({
332
+ modelName,
333
+ ctx,
334
+ operation,
335
+ }) === false) {
336
+ throw new Error("No permission");
337
+ }
338
+ const p = {
339
+ depthLimit: depthLimit?.({ modelName, ctx, operation }),
340
+ where: where?.({ modelName, ctx, operation }),
341
+ };
342
+ if (p.depthLimit !== undefined &&
343
+ getQueryDepth(info) > p.depthLimit)
344
+ throw new Error("Depth limit exceeded");
345
+ return generator.getClient(ctx)
346
+ .update(table)
347
+ .set(args.input)
348
+ .where(createWhereQuery(table, {
349
+ AND: [args.where, p.where].filter((v) => v),
350
+ }))
351
+ .returning();
352
+ },
353
+ }),
354
+ }),
355
+ });
356
+ }
357
+ if (operations.includes("delete")) {
358
+ builder.mutationType({
359
+ fields: (t) => ({
360
+ [`delete${tableInfo.name}`]: t.field({
361
+ type: [modelName],
362
+ nullable: false,
363
+ args: {
364
+ where: t.arg({ type: inputWhere }),
365
+ },
366
+ resolve: async (_parent, args, ctx, info) => {
367
+ const operation = "delete";
368
+ if (executable?.({
369
+ modelName,
370
+ ctx,
371
+ operation,
372
+ }) === false) {
373
+ throw new Error("No permission");
374
+ }
375
+ const p = {
376
+ depthLimit: depthLimit?.({ modelName, ctx, operation }),
377
+ where: where?.({ modelName, ctx, operation }),
378
+ };
379
+ if (p.depthLimit !== undefined &&
380
+ getQueryDepth(info) > p.depthLimit)
381
+ throw new Error("Depth limit exceeded");
382
+ return generator.getClient(ctx)
383
+ .delete(table)
384
+ .where(createWhereQuery(table, {
385
+ AND: [args.where, p.where].filter((v) => v),
386
+ }))
387
+ .returning();
388
+ },
389
+ }),
390
+ }),
391
+ });
392
+ }
393
+ }
394
+ }
395
+ }
@@ -0,0 +1,63 @@
1
+ import { type AnyRelations, type RelationsRecord, type SchemaEntry } from "drizzle-orm";
2
+ import { OperationBasic } from "./libs/operations.js";
3
+ import type { DrizzleClient } from "@pothos/plugin-drizzle";
4
+ import type { PgColumn, getTableConfig } from "drizzle-orm/pg-core";
5
+ type ModelData = {
6
+ table: SchemaEntry;
7
+ operations: (typeof OperationBasic)[number][];
8
+ columns: PgColumn<any, object>[];
9
+ inputColumns: PgColumn<any, object>[];
10
+ tableInfo: ReturnType<typeof getTableConfig>;
11
+ relations: RelationsRecord;
12
+ executable?: (params: {
13
+ ctx: any;
14
+ modelName: string;
15
+ operation: (typeof OperationBasic)[number];
16
+ }) => boolean | undefined;
17
+ limit?: (params: {
18
+ ctx: any;
19
+ modelName: string;
20
+ operation: (typeof OperationBasic)[number];
21
+ }) => number | undefined;
22
+ orderBy?: (params: {
23
+ ctx: any;
24
+ modelName: string;
25
+ operation: (typeof OperationBasic)[number];
26
+ }) => object | undefined;
27
+ where?: (params: {
28
+ ctx: any;
29
+ modelName: string;
30
+ operation: (typeof OperationBasic)[number];
31
+ }) => object | undefined;
32
+ inputData?: (params: {
33
+ ctx: any;
34
+ modelName: string;
35
+ operation: (typeof OperationBasic)[number];
36
+ }) => object | undefined;
37
+ };
38
+ export declare class PothosDrizzleGenerator {
39
+ enums: Record<string, PothosSchemaTypes.EnumRef<any, any>>;
40
+ inputOperators: Record<string, PothosSchemaTypes.InputObjectRef<any, any>>;
41
+ inputType: Record<string, Record<string, PothosSchemaTypes.InputObjectRef<any, any>>>;
42
+ tables?: Record<string, ModelData>;
43
+ builder: PothosSchemaTypes.SchemaBuilder<any>;
44
+ constructor(builder: PothosSchemaTypes.SchemaBuilder<any>);
45
+ createTableInfo(): Record<string, ModelData>;
46
+ getClient(ctx: any): DrizzleClient;
47
+ getRelations(): AnyRelations;
48
+ getTables(): Record<string, ModelData>;
49
+ getDepthLimit(): ((params: {
50
+ ctx: any;
51
+ modelName: string | number | symbol;
52
+ operation: (typeof OperationBasic)[number];
53
+ }) => number | undefined) | undefined;
54
+ getInputType(modelName: string, type: string, options: PothosSchemaTypes.InputObjectTypeOptions<any, any>): PothosSchemaTypes.InputObjectRef<any, any>;
55
+ getInputCreate(modelName: string): PothosSchemaTypes.InputObjectRef<any, any>;
56
+ getInputUpdate(modelName: string): PothosSchemaTypes.InputObjectRef<any, any>;
57
+ getInputWhere(modelName: string): PothosSchemaTypes.InputObjectRef<any, any>;
58
+ getInputOrderBy(modelName: string): PothosSchemaTypes.InputObjectRef<any, any>;
59
+ getInputOperator(type: string | [string]): PothosSchemaTypes.InputObjectRef<any, any>;
60
+ createInputType(): void;
61
+ getDataType(column: PgColumn): string | [string];
62
+ }
63
+ export {};
@@ -0,0 +1,227 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { isTable, } from "drizzle-orm";
3
+ import { BigIntResolver, ByteResolver, DateResolver, DateTimeResolver, HexadecimalResolver, JSONResolver, } from "graphql-scalars";
4
+ import { expandOperations, OperationBasic } from "./libs/operations.js";
5
+ import { createInputOperator } from "./libs/utils.js";
6
+ export class PothosDrizzleGenerator {
7
+ enums = {};
8
+ inputOperators = {};
9
+ inputType = {};
10
+ tables;
11
+ builder;
12
+ constructor(builder) {
13
+ this.builder = builder;
14
+ this.createInputType();
15
+ }
16
+ createTableInfo() {
17
+ const options = this.builder.options.pothosDrizzleGenerator;
18
+ const drizzleOption = this.builder.options.drizzle;
19
+ const getConfig = drizzleOption.getTableConfig;
20
+ const relations = this.getRelations();
21
+ const tables = Object.values(relations)
22
+ .filter((t) => isTable(t.table))
23
+ .map(({ name, table, relations }) => {
24
+ const tableInfo = getConfig(table);
25
+ const modelOptions = options?.models?.[name];
26
+ const columns = tableInfo.columns;
27
+ //Operations
28
+ const operationIncludes = expandOperations(modelOptions?.operations?.include ?? OperationBasic);
29
+ const operationExcludes = expandOperations(modelOptions?.operations?.exclude ?? []);
30
+ const operations = operationIncludes.filter((v) => !operationExcludes.includes(v));
31
+ // Columns filter
32
+ const include = options?.models?.[name]?.fields?.include ??
33
+ columns.map((c) => c.name);
34
+ const exclude = options?.models?.[name]?.fields?.exclude ?? [];
35
+ const filterColumns = include.filter((name) => !exclude.includes(name));
36
+ // Input columns filter
37
+ const includeInput = options?.models?.[name]?.inputFields?.include ??
38
+ columns.map((c) => c.name);
39
+ const excludeInput = options?.models?.[name]?.inputFields?.exclude ?? [];
40
+ const filterInputColumns = includeInput.filter((name) => !excludeInput.includes(name));
41
+ return [
42
+ name,
43
+ {
44
+ table,
45
+ columns: columns.filter((c) => filterColumns.includes(c.name)),
46
+ operations,
47
+ inputColumns: columns.filter((c) => filterInputColumns.includes(c.name)),
48
+ tableInfo,
49
+ relations,
50
+ executable: modelOptions?.executable,
51
+ limit: modelOptions?.limit,
52
+ orderBy: modelOptions?.orderBy,
53
+ where: modelOptions?.where,
54
+ inputData: modelOptions?.inputData,
55
+ },
56
+ ];
57
+ });
58
+ const modelNames = tables.map(([name]) => name);
59
+ // Model filter
60
+ const include = options?.use?.include ?? modelNames;
61
+ const exclude = options?.use?.exclude ?? [];
62
+ const filterTables = include.filter((name) => !exclude.includes(name));
63
+ return Object.fromEntries(tables.filter(([name]) => filterTables.includes(name)));
64
+ }
65
+ getClient(ctx) {
66
+ const options = this.builder.options;
67
+ const drizzleOption = options.drizzle;
68
+ const client = drizzleOption.client instanceof Function
69
+ ? drizzleOption.client(ctx)
70
+ : drizzleOption.client;
71
+ return client;
72
+ }
73
+ getRelations() {
74
+ const drizzleOption = this.builder.options.drizzle;
75
+ const client = drizzleOption.client;
76
+ return drizzleOption.relations ?? client._.relations;
77
+ }
78
+ getTables() {
79
+ if (this.tables)
80
+ return this.tables;
81
+ const tables = this.createTableInfo();
82
+ this.tables = tables;
83
+ return tables;
84
+ }
85
+ getDepthLimit() {
86
+ const options = this.builder.options.pothosDrizzleGenerator;
87
+ return options?.depthLimit;
88
+ }
89
+ getInputType(modelName, type, options) {
90
+ if (!this.inputType[modelName])
91
+ this.inputType[modelName] = {};
92
+ if (this.inputType[modelName][type])
93
+ return this.inputType[modelName][type];
94
+ const { tableInfo } = this.getTables()[modelName];
95
+ const input = this.builder.inputType(`${tableInfo.name}${type}`, options);
96
+ this.inputType[modelName][type] = input;
97
+ return input;
98
+ }
99
+ getInputCreate(modelName) {
100
+ const { inputColumns } = this.getTables()[modelName];
101
+ return this.getInputType(modelName, "Create", {
102
+ fields: (t) => Object.fromEntries(inputColumns.map((c) => [
103
+ c.name,
104
+ t.field({
105
+ type: this.getDataType(c),
106
+ required: c.notNull && !c.default,
107
+ }),
108
+ ])),
109
+ });
110
+ }
111
+ getInputUpdate(modelName) {
112
+ const { inputColumns } = this.getTables()[modelName];
113
+ return this.getInputType(modelName, "Input", {
114
+ fields: (t) => {
115
+ return Object.fromEntries(inputColumns.map((c) => [
116
+ c.name,
117
+ t.field({
118
+ type: this.getDataType(c),
119
+ }),
120
+ ]));
121
+ },
122
+ });
123
+ }
124
+ getInputWhere(modelName) {
125
+ const { tableInfo } = this.getTables()[modelName];
126
+ const inputWhere = this.getInputType(modelName, "Where", {
127
+ fields: (t) => {
128
+ return Object.fromEntries([
129
+ ["AND", t.field({ type: [inputWhere] })],
130
+ ["OR", t.field({ type: [inputWhere] })],
131
+ ["NOT", t.field({ type: inputWhere })],
132
+ ...tableInfo.columns.map((c) => {
133
+ return [
134
+ c.name,
135
+ t.field({
136
+ type: this.getInputOperator(this.getDataType(c)),
137
+ }),
138
+ ];
139
+ }),
140
+ ]);
141
+ },
142
+ });
143
+ return inputWhere;
144
+ }
145
+ getInputOrderBy(modelName) {
146
+ const { tableInfo } = this.getTables()[modelName];
147
+ const inputWhere = this.getInputType(modelName, "OrderBy", {
148
+ fields: (t) => {
149
+ return Object.fromEntries(tableInfo.columns.map((c) => {
150
+ return [
151
+ c.name,
152
+ t.field({
153
+ type: this.enums["OrderBy"],
154
+ }),
155
+ ];
156
+ }));
157
+ },
158
+ });
159
+ return inputWhere;
160
+ }
161
+ getInputOperator(type) {
162
+ const typeName = Array.isArray(type) ? `Array${type[0]}` : type;
163
+ const input = this.inputOperators[typeName] ?? createInputOperator(this.builder, type);
164
+ this.inputOperators[typeName] = input;
165
+ return input;
166
+ }
167
+ createInputType() {
168
+ const builder = this.builder;
169
+ const scalars = [
170
+ ["BigInt", BigIntResolver],
171
+ ["Date", DateResolver],
172
+ ["Bytes", ByteResolver],
173
+ ["DateTime", DateTimeResolver],
174
+ ["Json", JSONResolver],
175
+ ["Decimal", HexadecimalResolver],
176
+ ];
177
+ for (const [scalarName, scalarResolver] of scalars) {
178
+ if (!builder.configStore.hasConfig(scalarName)) {
179
+ builder.addScalarType(scalarName, scalarResolver, {});
180
+ }
181
+ }
182
+ this.enums["OrderBy"] = builder.enumType("OrderBy", {
183
+ values: {
184
+ Asc: { value: "asc" },
185
+ Desc: { value: "desc" },
186
+ },
187
+ });
188
+ }
189
+ getDataType(column) {
190
+ const isArray = column.dataType.split(" ")[0] === "array";
191
+ const c = isArray ? column.baseColumn : column;
192
+ const types = c.dataType.split(" ");
193
+ switch (types[1] ?? types[0]) {
194
+ case "enum": {
195
+ const sqlType = c.getSQLType();
196
+ const e = this.enums[sqlType];
197
+ if (!e) {
198
+ this.enums[sqlType] = this.builder.enumType(sqlType, {
199
+ values: c.enumValues ?? [],
200
+ });
201
+ }
202
+ return isArray ? [sqlType] : sqlType;
203
+ }
204
+ case "json":
205
+ return isArray ? ["Json"] : "Json";
206
+ case "date":
207
+ return isArray ? ["DateTime"] : "DateTime";
208
+ case "datetime":
209
+ return isArray ? ["DateTime"] : "DateTime";
210
+ case "boolean":
211
+ return isArray ? ["Boolean"] : "Boolean";
212
+ case "double":
213
+ case "float":
214
+ case "udouble":
215
+ case "ufloat":
216
+ return isArray ? ["Float"] : "Float";
217
+ }
218
+ const type = isArray ? types[1] : types[0];
219
+ const scalerMap = {
220
+ bigint: "BigInt",
221
+ number: "Float",
222
+ string: "String",
223
+ };
224
+ const result = scalerMap[type] ?? "String";
225
+ return isArray ? [result] : result;
226
+ }
227
+ }