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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 SoraKumo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,127 @@
1
+ # pothos-drizzle-generator
2
+
3
+ A Pothos plugin that automatically generates GraphQL schemas based on Drizzle schema information.
4
+
5
+ ![](./documents/image.png)
6
+
7
+ # usage
8
+
9
+ To use this service, you must have version `drizzle-orm@1.0.0-beta.2` or later.
10
+
11
+ ```ts
12
+ import "dotenv/config";
13
+ import SchemaBuilder from "@pothos/core";
14
+ import DrizzlePlugin from "@pothos/plugin-drizzle";
15
+ import { drizzle } from "drizzle-orm/node-postgres";
16
+ import { getTableConfig } from "drizzle-orm/pg-core";
17
+ import { relations } from "./db/relations";
18
+ import PothosDrizzleGeneratorPlugin from "pothos-drizzle-generator";
19
+
20
+ const db = drizzle({
21
+ connection: process.env.DATABASE_URL!,
22
+ relations,
23
+ logger: true,
24
+ });
25
+
26
+ export interface PothosTypes {
27
+ DrizzleRelations: typeof relations;
28
+ Context: { userId?: string };
29
+ }
30
+
31
+ const builder = new SchemaBuilder<PothosTypes>({
32
+ plugins: [
33
+ DrizzlePlugin,
34
+ PothosDrizzleGeneratorPlugin, // Set plugin
35
+ ],
36
+ drizzle: {
37
+ client: () => db,
38
+ relations,
39
+ getTableConfig,
40
+ },
41
+ });
42
+
43
+ const schema = builder.toSchema();
44
+ ```
45
+
46
+ # Options
47
+
48
+ ```ts
49
+ const builder = new SchemaBuilder<PothosTypes>({
50
+ plugins: [
51
+ DrizzlePlugin,
52
+ PothosDrizzleGeneratorPlugin, // Set plugin
53
+ ],
54
+ drizzle: {
55
+ client: () => db,
56
+ relations,
57
+ getTableConfig,
58
+ },
59
+ pothosDrizzleGenerator: {
60
+ // Specifying the Maximum Query Depth
61
+ depthLimit: ({ ctx, modelName, operation }) => $limit$,
62
+ // Specifying the model to use
63
+ use: { include: [...$modelNames$], exclude: [...$modelNames$] },
64
+ models: {
65
+ [$modelName$]: {
66
+ // Specifying fields to use in queries
67
+ fields: { include: [...$fields$], exclude: [...$fields$] },
68
+ // Specifying the method of operation for the model
69
+ operations: { include: [...$operation$], exclude: [...$operation$] },
70
+ // Runtime Permission Check
71
+ executable: ({ ctx, modelName, operation }) => $permission$,
72
+ // Specify the maximum value for the query's limit
73
+ limit: ({ ctx, modelName, operation }) => $limit$,
74
+ // Override the query's orderBy
75
+ orderBy: ({ ctx, modelName, operation }) => $orderBy$,
76
+ // Add query conditions
77
+ where: ({ ctx, modelName, operation }) => $where$,
78
+ // Specifying input fields
79
+ inputFields: { include: [$fields$], exclude: [$fields$] },
80
+ // Overwriting input data
81
+ inputData: ({ ctx, modelName, operation }) => $inputData$,
82
+ },
83
+ },
84
+ },
85
+ });
86
+ ```
87
+
88
+ # Current implementation status
89
+
90
+ ## Operations
91
+
92
+ - findMany
93
+ - findFirst
94
+ - count
95
+ - create
96
+ - update
97
+ - delete
98
+
99
+ ## Parameters
100
+
101
+ - where
102
+ - orderBy
103
+ - offset
104
+ - limit
105
+
106
+ ## operators
107
+
108
+ - AND
109
+ - OR
110
+ - NOT
111
+ - eq
112
+ - ne
113
+ - gt
114
+ - gte
115
+ - lt
116
+ - lte
117
+ - like
118
+ - notLike
119
+ - ilike
120
+ - notIlike
121
+ - isNull
122
+ - isNotNull,
123
+ - in,
124
+ - notIn
125
+ - arrayContained
126
+ - arrayOverlaps
127
+ - arrayContains
@@ -0,0 +1,7 @@
1
+ import { BasePlugin, type BuildCache, type SchemaTypes } from "@pothos/core";
2
+ import { PothosDrizzleGenerator } from "./generator.js";
3
+ export declare class PothosDrizzleGeneratorPlugin<Types extends SchemaTypes, T extends object = object> extends BasePlugin<Types, T> {
4
+ generator: PothosDrizzleGenerator;
5
+ constructor(buildCache: BuildCache<Types>, name: keyof PothosSchemaTypes.Plugins<Types>);
6
+ beforeBuild(): void;
7
+ }
@@ -0,0 +1,399 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PothosDrizzleGeneratorPlugin = void 0;
4
+ /* eslint-disable @typescript-eslint/no-explicit-any */
5
+ const core_1 = require("@pothos/core");
6
+ const drizzle_orm_1 = require("drizzle-orm");
7
+ const generator_js_1 = require("./generator.js");
8
+ const utils_js_1 = require("./libs/utils.js");
9
+ class PothosDrizzleGeneratorPlugin extends core_1.BasePlugin {
10
+ generator;
11
+ constructor(buildCache, name) {
12
+ super(buildCache, name);
13
+ this.generator = new generator_js_1.PothosDrizzleGenerator(this.builder);
14
+ }
15
+ beforeBuild() {
16
+ const generator = this.generator;
17
+ const builder = this.builder;
18
+ const depthLimit = generator.getDepthLimit();
19
+ const tables = generator.getTables();
20
+ for (const [modelName, { table, tableInfo, relations, columns, operations, executable, limit, where, orderBy, inputData, },] of Object.entries(tables)) {
21
+ const objectRef = builder.objectRef(modelName);
22
+ objectRef.implement({
23
+ fields: (t) => Object.fromEntries(columns.map((c) => {
24
+ return [
25
+ c.name,
26
+ t.expose(c.name, {
27
+ type: generator.getDataType(c),
28
+ nullable: !c.notNull,
29
+ }),
30
+ ];
31
+ })),
32
+ });
33
+ const filterRelations = Object.entries(relations).filter(([, relay]) => tables[relay.targetTableName]);
34
+ builder.drizzleObject(modelName, {
35
+ name: tableInfo.name,
36
+ fields: (t) => {
37
+ const relayList = filterRelations.map(([relayName, relay]) => {
38
+ const modelName = relay.targetTableName;
39
+ const { executable, where, orderBy, limit, operations } = tables[modelName];
40
+ const operation = relay.relationType === "one" ? "findFirst" : "findMany";
41
+ if (!operations.includes(operation))
42
+ return [];
43
+ const inputWhere = generator.getInputWhere(modelName);
44
+ const inputOrderBy = generator.getInputOrderBy(modelName);
45
+ return [
46
+ relayName,
47
+ t.relation(relayName, {
48
+ columns: { id: true },
49
+ args: {
50
+ offset: t.arg({ type: "Int" }),
51
+ limit: t.arg({ type: "Int" }),
52
+ where: t.arg({ type: inputWhere }),
53
+ orderBy: t.arg({ type: inputOrderBy }),
54
+ },
55
+ query: (args, ctx) => {
56
+ if (executable?.({
57
+ modelName,
58
+ ctx,
59
+ operation,
60
+ }) === false) {
61
+ throw new Error("No permission");
62
+ }
63
+ const p = {
64
+ limit: limit?.({ modelName, ctx, operation }),
65
+ where: where?.({ modelName, ctx, operation }),
66
+ orderBy: orderBy?.({ modelName, ctx, operation }),
67
+ };
68
+ return {
69
+ ...args,
70
+ limit: p.limit && args.limit
71
+ ? Math.min(p.limit, args.limit)
72
+ : p.limit ?? args.limit,
73
+ where: { AND: [args.where, p.where].filter((v) => v) },
74
+ orderBy: args.orderBy && Object.keys(args.orderBy).length
75
+ ? args.orderBy
76
+ : p.orderBy,
77
+ };
78
+ },
79
+ }),
80
+ ];
81
+ });
82
+ const relayCount = filterRelations.map(([relayName, relay]) => {
83
+ const modelName = relay.targetTableName;
84
+ const operation = "count";
85
+ const { executable, where, operations } = tables[modelName];
86
+ if (!operations.includes(operation))
87
+ return [];
88
+ const inputWhere = generator.getInputWhere(modelName);
89
+ return [
90
+ `${relayName}Count`,
91
+ t.relatedCount(relayName, {
92
+ args: { where: t.arg({ type: inputWhere }) },
93
+ where: (args, ctx) => {
94
+ if (executable?.({
95
+ modelName,
96
+ ctx,
97
+ operation,
98
+ }) === false) {
99
+ throw new Error("No permission");
100
+ }
101
+ const p = {
102
+ where: where?.({ modelName, ctx, operation }),
103
+ };
104
+ return (0, utils_js_1.createWhereQuery)(relay.targetTable, {
105
+ AND: [args.where, p.where].filter((v) => v),
106
+ });
107
+ },
108
+ }),
109
+ ];
110
+ });
111
+ return Object.fromEntries([
112
+ ...relayCount,
113
+ ...relayList,
114
+ ...columns.map((c) => {
115
+ return [
116
+ c.name,
117
+ t.expose(c.name, {
118
+ type: generator.getDataType(c),
119
+ nullable: !c.notNull,
120
+ }),
121
+ ];
122
+ }),
123
+ ]);
124
+ },
125
+ });
126
+ const inputWhere = generator.getInputWhere(modelName);
127
+ const inputOrderBy = generator.getInputOrderBy(modelName);
128
+ const inputCreate = generator.getInputCreate(modelName);
129
+ const inputUpdate = generator.getInputUpdate(modelName);
130
+ if (operations.includes("findMany")) {
131
+ builder.queryType({
132
+ fields: (t) => ({
133
+ [`findMany${tableInfo.name}`]: t.drizzleField({
134
+ type: [modelName],
135
+ nullable: false,
136
+ args: {
137
+ offset: t.arg({ type: "Int" }),
138
+ limit: t.arg({ type: "Int" }),
139
+ where: t.arg({ type: inputWhere }),
140
+ orderBy: t.arg({ type: inputOrderBy }),
141
+ },
142
+ resolve: async (query, _parent, args, ctx, info) => {
143
+ const operation = "findMany";
144
+ if (executable?.({
145
+ modelName,
146
+ ctx,
147
+ operation,
148
+ }) === false) {
149
+ throw new Error("No permission");
150
+ }
151
+ const p = {
152
+ depthLimit: depthLimit?.({ modelName, ctx, operation }),
153
+ limit: limit?.({ modelName, ctx, operation }),
154
+ where: where?.({ modelName, ctx, operation }),
155
+ orderBy: orderBy?.({ modelName, ctx, operation }),
156
+ };
157
+ if (p.depthLimit !== undefined &&
158
+ (0, utils_js_1.getQueryDepth)(info) > p.depthLimit)
159
+ throw new Error("Depth limit exceeded");
160
+ return generator.getClient(ctx).query[modelName].findMany(query({
161
+ ...args,
162
+ limit: p.limit && args.limit
163
+ ? Math.min(p.limit, args.limit)
164
+ : p.limit ?? args.limit,
165
+ where: { AND: [args.where, p.where].filter((v) => v) },
166
+ orderBy: args.orderBy && Object.keys(args.orderBy).length
167
+ ? args.orderBy
168
+ : p.orderBy,
169
+ }));
170
+ },
171
+ }),
172
+ }),
173
+ });
174
+ }
175
+ if (operations.includes("findFirst")) {
176
+ builder.queryType({
177
+ fields: (t) => ({
178
+ [`findFirst${tableInfo.name}`]: t.drizzleField({
179
+ type: modelName,
180
+ args: {
181
+ offset: t.arg({ type: "Int" }),
182
+ where: t.arg({ type: inputWhere }),
183
+ orderBy: t.arg({ type: inputOrderBy }),
184
+ },
185
+ resolve: async (query, _parent, args, ctx, info) => {
186
+ const operation = "findFirst";
187
+ if (executable?.({
188
+ modelName,
189
+ ctx,
190
+ operation,
191
+ }) === false) {
192
+ throw new Error("No permission");
193
+ }
194
+ const p = {
195
+ depthLimit: depthLimit?.({ modelName, ctx, operation }),
196
+ where: where?.({ modelName, ctx, operation }),
197
+ orderBy: orderBy?.({ modelName, ctx, operation }),
198
+ };
199
+ if (p.depthLimit !== undefined &&
200
+ (0, utils_js_1.getQueryDepth)(info) > p.depthLimit)
201
+ throw new Error("Depth limit exceeded");
202
+ return generator.getClient(ctx).query[modelName].findFirst(query({
203
+ ...args,
204
+ where: { AND: [args.where, p.where].filter((v) => v) },
205
+ orderBy: args.orderBy && Object.keys(args.orderBy).length
206
+ ? args.orderBy
207
+ : p.orderBy,
208
+ }));
209
+ },
210
+ }),
211
+ }),
212
+ });
213
+ }
214
+ if (operations.includes("count")) {
215
+ builder.queryType({
216
+ fields: (t) => ({
217
+ [`count${tableInfo.name}`]: t.field({
218
+ type: "Int",
219
+ nullable: false,
220
+ args: {
221
+ limit: t.arg({ type: "Int" }),
222
+ where: t.arg({ type: inputWhere }),
223
+ },
224
+ resolve: async (_query, _parent, args, ctx, info) => {
225
+ const operation = "count";
226
+ if (executable?.({
227
+ modelName,
228
+ ctx,
229
+ operation,
230
+ }) === false) {
231
+ throw new Error("No permission");
232
+ }
233
+ const p = {
234
+ depthLimit: depthLimit?.({ modelName, ctx, operation }),
235
+ limit: limit?.({ modelName, ctx, operation }),
236
+ where: where?.({ modelName, ctx, operation }),
237
+ };
238
+ if (p.depthLimit !== undefined &&
239
+ (0, utils_js_1.getQueryDepth)(info) > p.depthLimit)
240
+ throw new Error("Depth limit exceeded");
241
+ return generator.getClient(ctx).query[modelName]
242
+ .findFirst({
243
+ columns: {},
244
+ extras: { _count: () => (0, drizzle_orm_1.sql) `count(*)` },
245
+ ...args,
246
+ limit: p.limit && args.limit
247
+ ? Math.min(p.limit, args.limit)
248
+ : p.limit ?? args.limit,
249
+ where: { AND: [args.where, p.where].filter((v) => v) },
250
+ })
251
+ .then((v) => v._count);
252
+ },
253
+ }),
254
+ }),
255
+ });
256
+ }
257
+ if (operations.includes("createOne")) {
258
+ builder.mutationType({
259
+ fields: (t) => ({
260
+ [`createOne${tableInfo.name}`]: t.drizzleField({
261
+ type: modelName,
262
+ nullable: false,
263
+ args: { input: t.arg({ type: inputCreate, required: true }) },
264
+ resolve: async (_query, _parent, args, ctx, info) => {
265
+ const operation = "createOne";
266
+ if (executable?.({
267
+ modelName,
268
+ ctx,
269
+ operation,
270
+ }) === false) {
271
+ throw new Error("No permission");
272
+ }
273
+ const p = {
274
+ depthLimit: depthLimit?.({ modelName, ctx, operation }),
275
+ input: inputData?.({ modelName, ctx, operation }),
276
+ };
277
+ if (p.depthLimit !== undefined &&
278
+ (0, utils_js_1.getQueryDepth)(info) > p.depthLimit)
279
+ throw new Error("Depth limit exceeded");
280
+ return generator.getClient(ctx)
281
+ .insert(table)
282
+ .values({ ...args.input, ...p.input })
283
+ .returning()
284
+ .then((v) => v[0]);
285
+ },
286
+ }),
287
+ }),
288
+ });
289
+ }
290
+ if (operations.includes("createMany")) {
291
+ builder.mutationType({
292
+ fields: (t) => ({
293
+ [`createMany${tableInfo.name}`]: t.drizzleField({
294
+ type: [modelName],
295
+ nullable: false,
296
+ args: { input: t.arg({ type: [inputCreate], required: true }) },
297
+ resolve: async (_query, _parent, args, ctx, info) => {
298
+ const operation = "createMany";
299
+ if (executable?.({
300
+ modelName,
301
+ ctx,
302
+ operation,
303
+ }) === false) {
304
+ throw new Error("No permission");
305
+ }
306
+ const p = {
307
+ depthLimit: depthLimit?.({ modelName, ctx, operation }),
308
+ args: inputData?.({ modelName, ctx, operation }),
309
+ };
310
+ if (p.depthLimit !== undefined &&
311
+ (0, utils_js_1.getQueryDepth)(info) > p.depthLimit)
312
+ throw new Error("Depth limit exceeded");
313
+ return generator.getClient(ctx)
314
+ .insert(table)
315
+ .values(args.input.map((v) => ({ ...v, ...p.args })))
316
+ .returning();
317
+ },
318
+ }),
319
+ }),
320
+ });
321
+ }
322
+ if (operations.includes("update")) {
323
+ builder.mutationType({
324
+ fields: (t) => ({
325
+ [`update${tableInfo.name}`]: t.drizzleField({
326
+ type: [modelName],
327
+ nullable: false,
328
+ args: {
329
+ input: t.arg({ type: inputUpdate, required: true }),
330
+ where: t.arg({ type: inputWhere }),
331
+ },
332
+ resolve: async (_query, _parent, args, ctx, info) => {
333
+ const operation = "update";
334
+ if (executable?.({
335
+ modelName,
336
+ ctx,
337
+ operation,
338
+ }) === false) {
339
+ throw new Error("No permission");
340
+ }
341
+ const p = {
342
+ depthLimit: depthLimit?.({ modelName, ctx, operation }),
343
+ where: where?.({ modelName, ctx, operation }),
344
+ };
345
+ if (p.depthLimit !== undefined &&
346
+ (0, utils_js_1.getQueryDepth)(info) > p.depthLimit)
347
+ throw new Error("Depth limit exceeded");
348
+ return generator.getClient(ctx)
349
+ .update(table)
350
+ .set(args.input)
351
+ .where((0, utils_js_1.createWhereQuery)(table, {
352
+ AND: [args.where, p.where].filter((v) => v),
353
+ }))
354
+ .returning();
355
+ },
356
+ }),
357
+ }),
358
+ });
359
+ }
360
+ if (operations.includes("delete")) {
361
+ builder.mutationType({
362
+ fields: (t) => ({
363
+ [`delete${tableInfo.name}`]: t.field({
364
+ type: [modelName],
365
+ nullable: false,
366
+ args: {
367
+ where: t.arg({ type: inputWhere }),
368
+ },
369
+ resolve: async (_parent, args, ctx, info) => {
370
+ const operation = "delete";
371
+ if (executable?.({
372
+ modelName,
373
+ ctx,
374
+ operation,
375
+ }) === false) {
376
+ throw new Error("No permission");
377
+ }
378
+ const p = {
379
+ depthLimit: depthLimit?.({ modelName, ctx, operation }),
380
+ where: where?.({ modelName, ctx, operation }),
381
+ };
382
+ if (p.depthLimit !== undefined &&
383
+ (0, utils_js_1.getQueryDepth)(info) > p.depthLimit)
384
+ throw new Error("Depth limit exceeded");
385
+ return generator.getClient(ctx)
386
+ .delete(table)
387
+ .where((0, utils_js_1.createWhereQuery)(table, {
388
+ AND: [args.where, p.where].filter((v) => v),
389
+ }))
390
+ .returning();
391
+ },
392
+ }),
393
+ }),
394
+ });
395
+ }
396
+ }
397
+ }
398
+ }
399
+ exports.PothosDrizzleGeneratorPlugin = PothosDrizzleGeneratorPlugin;
@@ -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 {};