drizzle-graphql-plus 0.8.6 → 0.8.7
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/index.cjs +1974 -0
- package/index.cjs.map +1 -0
- package/index.d.cts +247 -0
- package/index.d.ts +247 -0
- package/index.js +2012 -0
- package/index.js.map +1 -0
- package/package.json +16 -15
- package/.github/workflows/release.yaml +0 -74
- package/LICENSE +0 -201
- package/dprint.json +0 -31
- package/drizzle.test-config.ts +0 -29
- package/scripts/build.ts +0 -28
- package/src/index.ts +0 -74
- package/src/types.ts +0 -417
- package/src/util/builders/common.ts +0 -840
- package/src/util/builders/index.ts +0 -5
- package/src/util/builders/mysql.ts +0 -482
- package/src/util/builders/pg.ts +0 -517
- package/src/util/builders/sqlite.ts +0 -524
- package/src/util/builders/types.ts +0 -231
- package/src/util/case-ops/index.ts +0 -9
- package/src/util/data-mappers/index.ts +0 -162
- package/src/util/type-converter/index.ts +0 -148
- package/src/util/type-converter/types.ts +0 -54
- package/tests/mysql-custom.test.ts +0 -2009
- package/tests/mysql.test.ts +0 -4600
- package/tests/pg-custom.test.ts +0 -2054
- package/tests/pg.test.ts +0 -4285
- package/tests/schema/mysql.ts +0 -72
- package/tests/schema/pg.ts +0 -83
- package/tests/schema/sqlite.ts +0 -64
- package/tests/sqlite-custom.test.ts +0 -1956
- package/tests/sqlite.test.ts +0 -3749
- package/tests/tsconfig.json +0 -11
- package/tests/util/query/index.ts +0 -30
- package/tsconfig.build.json +0 -4
- package/tsconfig.dts.json +0 -13
- package/tsconfig.json +0 -48
- package/vitest.config.ts +0 -17
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
import type { Column, Relation, SQL, Table } from 'drizzle-orm';
|
|
2
|
-
import type { PgArray } from 'drizzle-orm/pg-core';
|
|
3
|
-
import type {
|
|
4
|
-
GraphQLFieldConfigArgumentMap,
|
|
5
|
-
GraphQLFieldResolver,
|
|
6
|
-
GraphQLInputObjectType,
|
|
7
|
-
GraphQLList,
|
|
8
|
-
GraphQLNonNull,
|
|
9
|
-
GraphQLObjectType,
|
|
10
|
-
GraphQLScalarType,
|
|
11
|
-
} from 'graphql';
|
|
12
|
-
import type { ConvertedColumn, ConvertedRelationColumnWithArgs } from '../type-converter';
|
|
13
|
-
|
|
14
|
-
export type TableNamedRelations = {
|
|
15
|
-
relation: Relation;
|
|
16
|
-
targetTableName: string;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export type TableSelectArgs = {
|
|
20
|
-
offset: number;
|
|
21
|
-
limit: number;
|
|
22
|
-
where: Filters<Table>;
|
|
23
|
-
orderBy: OrderByArgs<Table>;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export type ProcessedTableSelectArgs = {
|
|
27
|
-
columns: Record<string, true>;
|
|
28
|
-
offset: number;
|
|
29
|
-
limit: number;
|
|
30
|
-
where: SQL;
|
|
31
|
-
orderBy: SQL[];
|
|
32
|
-
with?: Record<string, Partial<ProcessedTableSelectArgs>>;
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
export type SelectedColumnsRaw = [string, true][];
|
|
36
|
-
|
|
37
|
-
export type SelectedSQLColumns = [string, Column][];
|
|
38
|
-
|
|
39
|
-
export type SelectedColumns = {
|
|
40
|
-
[columnName in keyof Table['_']['columns']]: true;
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
export type CreatedResolver = {
|
|
44
|
-
name: string;
|
|
45
|
-
resolver: GraphQLFieldResolver<any, any>;
|
|
46
|
-
args: GraphQLFieldConfigArgumentMap;
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
export type ArgMapToArgsType<TArgMap extends GraphQLFieldConfigArgumentMap> = {
|
|
50
|
-
[Key in keyof TArgMap]?: TArgMap[Key] extends { type: GraphQLScalarType<infer R, any> } ? R : never;
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
export type ColTypeIsNull<TColumn extends Column, TColType> = TColumn['_']['notNull'] extends true ? TColType
|
|
54
|
-
: TColType | null;
|
|
55
|
-
|
|
56
|
-
export type ColTypeIsNullOrUndefined<TColumn extends Column, TColType> = TColumn['_']['notNull'] extends true ? TColType
|
|
57
|
-
: TColType | null | undefined;
|
|
58
|
-
|
|
59
|
-
export type ColTypeIsNullOrUndefinedWithDefault<TColumn extends Column, TColType> = TColumn['_']['notNull'] extends true
|
|
60
|
-
? TColumn['_']['hasDefault'] extends true ? TColType | null | undefined
|
|
61
|
-
: TColumn['defaultFn'] extends undefined ? TColType
|
|
62
|
-
: TColType | null | undefined
|
|
63
|
-
: TColType | null | undefined;
|
|
64
|
-
|
|
65
|
-
export type GetColumnGqlDataType<TColumn extends Column> = TColumn['dataType'] extends 'boolean'
|
|
66
|
-
? ColTypeIsNull<TColumn, boolean>
|
|
67
|
-
: TColumn['dataType'] extends 'json'
|
|
68
|
-
? TColumn['_']['columnType'] extends 'PgGeometryObject' ? ColTypeIsNull<TColumn, {
|
|
69
|
-
x: number;
|
|
70
|
-
y: number;
|
|
71
|
-
}>
|
|
72
|
-
: ColTypeIsNull<TColumn, string>
|
|
73
|
-
: TColumn['dataType'] extends 'date' | 'string' | 'bigint'
|
|
74
|
-
? TColumn['enumValues'] extends [string, ...string[]] ? ColTypeIsNull<TColumn, TColumn['enumValues'][number]>
|
|
75
|
-
: ColTypeIsNull<TColumn, string>
|
|
76
|
-
: TColumn['dataType'] extends 'number' ? ColTypeIsNull<TColumn, number>
|
|
77
|
-
: TColumn['dataType'] extends 'buffer' ? ColTypeIsNull<TColumn, number[]>
|
|
78
|
-
: TColumn['dataType'] extends 'array' ? TColumn['columnType'] extends 'PgVector' ? ColTypeIsNull<TColumn, number[]>
|
|
79
|
-
: TColumn['columnType'] extends 'PgGeometry' ? ColTypeIsNullOrUndefinedWithDefault<TColumn, [number, number]>
|
|
80
|
-
: ColTypeIsNull<
|
|
81
|
-
TColumn,
|
|
82
|
-
Array<
|
|
83
|
-
GetColumnGqlDataType<TColumn extends { baseColumn: Column } ? TColumn['baseColumn'] : never> extends
|
|
84
|
-
infer InnerColType ? InnerColType extends null | undefined ? never
|
|
85
|
-
: InnerColType
|
|
86
|
-
: never
|
|
87
|
-
>
|
|
88
|
-
>
|
|
89
|
-
: never;
|
|
90
|
-
|
|
91
|
-
export type GetColumnGqlInsertDataType<TColumn extends Column> = TColumn['dataType'] extends 'boolean'
|
|
92
|
-
? ColTypeIsNullOrUndefinedWithDefault<TColumn, boolean>
|
|
93
|
-
: TColumn['dataType'] extends 'json'
|
|
94
|
-
? TColumn['_']['columnType'] extends 'PgGeometryObject' ? ColTypeIsNullOrUndefinedWithDefault<TColumn, {
|
|
95
|
-
x: number;
|
|
96
|
-
y: number;
|
|
97
|
-
}>
|
|
98
|
-
: ColTypeIsNullOrUndefinedWithDefault<TColumn, string>
|
|
99
|
-
: TColumn['dataType'] extends 'date' | 'string' | 'bigint'
|
|
100
|
-
? TColumn['enumValues'] extends [string, ...string[]]
|
|
101
|
-
? ColTypeIsNullOrUndefinedWithDefault<TColumn, TColumn['enumValues'][number]>
|
|
102
|
-
: ColTypeIsNullOrUndefinedWithDefault<TColumn, string>
|
|
103
|
-
: TColumn['dataType'] extends 'number' ? ColTypeIsNullOrUndefinedWithDefault<TColumn, number>
|
|
104
|
-
: TColumn['dataType'] extends 'buffer' ? ColTypeIsNullOrUndefinedWithDefault<TColumn, number[]>
|
|
105
|
-
: TColumn['dataType'] extends 'array'
|
|
106
|
-
? TColumn['columnType'] extends 'PgVector' ? ColTypeIsNullOrUndefinedWithDefault<TColumn, number[]>
|
|
107
|
-
: TColumn['columnType'] extends 'PgGeometry' ? ColTypeIsNullOrUndefinedWithDefault<TColumn, [number, number]>
|
|
108
|
-
: ColTypeIsNullOrUndefinedWithDefault<
|
|
109
|
-
TColumn,
|
|
110
|
-
Array<
|
|
111
|
-
GetColumnGqlDataType<TColumn extends { baseColumn: Column } ? TColumn['baseColumn'] : never> extends
|
|
112
|
-
infer InnerColType ? InnerColType extends null | undefined ? never
|
|
113
|
-
: InnerColType
|
|
114
|
-
: never
|
|
115
|
-
>
|
|
116
|
-
>
|
|
117
|
-
: never;
|
|
118
|
-
|
|
119
|
-
export type GetColumnGqlUpdateDataType<TColumn extends Column> = TColumn['dataType'] extends 'boolean'
|
|
120
|
-
? boolean | null | undefined
|
|
121
|
-
: TColumn['dataType'] extends 'json' ? TColumn['_']['columnType'] extends 'PgGeometryObject' ?
|
|
122
|
-
| {
|
|
123
|
-
x: number;
|
|
124
|
-
y: number;
|
|
125
|
-
}
|
|
126
|
-
| null
|
|
127
|
-
| undefined
|
|
128
|
-
: string | null | undefined
|
|
129
|
-
: TColumn['dataType'] extends 'date' | 'string' | 'bigint'
|
|
130
|
-
? TColumn['enumValues'] extends [string, ...string[]] ? TColumn['enumValues'][number] | null | undefined
|
|
131
|
-
: string | null | undefined
|
|
132
|
-
: TColumn['dataType'] extends 'number' ? number | null | undefined
|
|
133
|
-
: TColumn['dataType'] extends 'buffer' ? number[] | null | undefined
|
|
134
|
-
: TColumn['dataType'] extends 'array' ? TColumn['columnType'] extends 'PgVector' ? number[] | null | undefined
|
|
135
|
-
: TColumn['columnType'] extends 'PgGeometry' ? [number, number] | null | undefined
|
|
136
|
-
:
|
|
137
|
-
| Array<
|
|
138
|
-
GetColumnGqlDataType<TColumn extends { baseColumn: Column } ? TColumn['baseColumn'] : never> extends
|
|
139
|
-
infer InnerColType ? InnerColType extends null | undefined ? never
|
|
140
|
-
: InnerColType
|
|
141
|
-
: never
|
|
142
|
-
>
|
|
143
|
-
| null
|
|
144
|
-
| undefined
|
|
145
|
-
: never;
|
|
146
|
-
|
|
147
|
-
export type GetRemappedTableDataType<
|
|
148
|
-
TTable extends Table,
|
|
149
|
-
TColumns extends TTable['_']['columns'] = TTable['_']['columns'],
|
|
150
|
-
> = {
|
|
151
|
-
[K in keyof TColumns]: GetColumnGqlDataType<TColumns[K]>;
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
export type GetRemappedTableInsertDataType<TTable extends Table> = {
|
|
155
|
-
[K in keyof TTable['_']['columns']]: GetColumnGqlInsertDataType<TTable['_']['columns'][K]>;
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
export type GetRemappedTableUpdateDataType<TTable extends Table> = {
|
|
159
|
-
[K in keyof TTable['_']['columns']]: GetColumnGqlUpdateDataType<TTable['_']['columns'][K]>;
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
export type FilterColumnOperatorsCore<TColumn extends Column, TColType = GetColumnGqlDataType<TColumn>> = Partial<{
|
|
163
|
-
eq: TColType;
|
|
164
|
-
ne: TColType;
|
|
165
|
-
lt: TColType;
|
|
166
|
-
lte: TColType;
|
|
167
|
-
gt: TColType;
|
|
168
|
-
gte: TColType;
|
|
169
|
-
like: string;
|
|
170
|
-
notLike: string;
|
|
171
|
-
ilike: string;
|
|
172
|
-
notIlike: string;
|
|
173
|
-
inArray: Array<TColType>;
|
|
174
|
-
notInArray: Array<TColType>;
|
|
175
|
-
isNull: boolean;
|
|
176
|
-
isNotNull: boolean;
|
|
177
|
-
}>;
|
|
178
|
-
|
|
179
|
-
export type FilterColumnOperators<
|
|
180
|
-
TColumn extends Column,
|
|
181
|
-
TOperators extends FilterColumnOperatorsCore<TColumn> = FilterColumnOperatorsCore<TColumn>,
|
|
182
|
-
> = TOperators & {
|
|
183
|
-
OR?: TOperators[];
|
|
184
|
-
};
|
|
185
|
-
|
|
186
|
-
export type FiltersCore<TTable extends Table> = Partial<
|
|
187
|
-
{
|
|
188
|
-
[Column in keyof TTable['_']['columns']]: FilterColumnOperatorsCore<TTable['_']['columns'][Column]>;
|
|
189
|
-
}
|
|
190
|
-
>;
|
|
191
|
-
|
|
192
|
-
export type Filters<TTable extends Table, TFilterType = FiltersCore<TTable>> = TFilterType & {
|
|
193
|
-
OR?: TFilterType[];
|
|
194
|
-
};
|
|
195
|
-
|
|
196
|
-
export type OrderByArgs<TTable extends Table> = {
|
|
197
|
-
[Key in keyof TTable['_']['columns']]?: {
|
|
198
|
-
direction: 'asc' | 'desc';
|
|
199
|
-
priority: number;
|
|
200
|
-
};
|
|
201
|
-
};
|
|
202
|
-
|
|
203
|
-
export type GeneratedTableTypesInputs = {
|
|
204
|
-
insertInput: GraphQLInputObjectType;
|
|
205
|
-
updateInput: GraphQLInputObjectType;
|
|
206
|
-
tableOrder: GraphQLInputObjectType;
|
|
207
|
-
tableFilters: GraphQLInputObjectType;
|
|
208
|
-
};
|
|
209
|
-
|
|
210
|
-
export type GeneratedTableTypesOutputs<WithReturning extends boolean> = WithReturning extends true ? {
|
|
211
|
-
selectSingleOutput: GraphQLObjectType;
|
|
212
|
-
selectArrOutput: GraphQLNonNull<GraphQLList<GraphQLNonNull<GraphQLObjectType>>>;
|
|
213
|
-
singleTableItemOutput: GraphQLObjectType;
|
|
214
|
-
arrTableItemOutput: GraphQLNonNull<GraphQLList<GraphQLNonNull<GraphQLObjectType>>>;
|
|
215
|
-
}
|
|
216
|
-
: {
|
|
217
|
-
selectSingleOutput: GraphQLObjectType;
|
|
218
|
-
selectArrOutput: GraphQLNonNull<GraphQLList<GraphQLNonNull<GraphQLObjectType>>>;
|
|
219
|
-
};
|
|
220
|
-
|
|
221
|
-
export type GeneratedTableTypes<WithReturning extends boolean> = {
|
|
222
|
-
inputs: GeneratedTableTypesInputs;
|
|
223
|
-
outputs: GeneratedTableTypesOutputs<WithReturning>;
|
|
224
|
-
};
|
|
225
|
-
|
|
226
|
-
export type SelectData<TWithOrder extends boolean> = {
|
|
227
|
-
filters: GraphQLInputObjectType;
|
|
228
|
-
tableFields: Record<string, ConvertedColumn>;
|
|
229
|
-
relationFields: Record<string, ConvertedRelationColumnWithArgs>;
|
|
230
|
-
order: TWithOrder extends true ? GraphQLInputObjectType : undefined;
|
|
231
|
-
};
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export const uncapitalize = <T extends string>(input: T) =>
|
|
2
|
-
(input.length
|
|
3
|
-
? `${input[0]!.toLocaleLowerCase()}${input.length > 1 ? input.slice(1, input.length) : ''}`
|
|
4
|
-
: input) as Uncapitalize<T>;
|
|
5
|
-
|
|
6
|
-
export const capitalize = <T extends string>(input: T) =>
|
|
7
|
-
(input.length
|
|
8
|
-
? `${input[0]!.toLocaleUpperCase()}${input.length > 1 ? input.slice(1, input.length) : ''}`
|
|
9
|
-
: input) as Capitalize<T>;
|
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
import { type Column, getTableColumns, type Table } from 'drizzle-orm';
|
|
2
|
-
import { GraphQLError } from 'graphql';
|
|
3
|
-
import { TableNamedRelations } from '../builders';
|
|
4
|
-
|
|
5
|
-
export const remapToGraphQLCore = (
|
|
6
|
-
key: string,
|
|
7
|
-
value: any,
|
|
8
|
-
tableName: string,
|
|
9
|
-
column: Column,
|
|
10
|
-
relationMap?: Record<string, Record<string, TableNamedRelations>>,
|
|
11
|
-
): any => {
|
|
12
|
-
if (value instanceof Date) return value.toISOString();
|
|
13
|
-
|
|
14
|
-
if (value instanceof Buffer) return Array.from(value);
|
|
15
|
-
|
|
16
|
-
if (typeof value === 'bigint') return value.toString();
|
|
17
|
-
|
|
18
|
-
if (Array.isArray(value)) {
|
|
19
|
-
const relations = relationMap?.[tableName];
|
|
20
|
-
if (relations?.[key]) {
|
|
21
|
-
return remapToGraphQLArrayOutput(
|
|
22
|
-
value,
|
|
23
|
-
relations[key]!.targetTableName,
|
|
24
|
-
relations[key]!.relation.referencedTable,
|
|
25
|
-
relationMap,
|
|
26
|
-
);
|
|
27
|
-
}
|
|
28
|
-
if (column.columnType === 'PgGeometry' || column.columnType === 'PgVector') return value;
|
|
29
|
-
|
|
30
|
-
return value.map((arrVal) => remapToGraphQLCore(key, arrVal, tableName, column, relationMap));
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (typeof value === 'object') {
|
|
34
|
-
const relations = relationMap?.[tableName];
|
|
35
|
-
if (relations?.[key]) {
|
|
36
|
-
return remapToGraphQLSingleOutput(
|
|
37
|
-
value,
|
|
38
|
-
relations[key]!.targetTableName,
|
|
39
|
-
relations[key]!.relation.referencedTable,
|
|
40
|
-
relationMap,
|
|
41
|
-
);
|
|
42
|
-
}
|
|
43
|
-
if (column.columnType === 'PgGeometryObject') return value;
|
|
44
|
-
|
|
45
|
-
return JSON.stringify(value);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return value;
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
export const remapToGraphQLSingleOutput = (
|
|
52
|
-
queryOutput: Record<string, any>,
|
|
53
|
-
tableName: string,
|
|
54
|
-
table: Table,
|
|
55
|
-
relationMap?: Record<string, Record<string, TableNamedRelations>>,
|
|
56
|
-
) => {
|
|
57
|
-
for (const [key, value] of Object.entries(queryOutput)) {
|
|
58
|
-
if (value === undefined || value === null) {
|
|
59
|
-
delete queryOutput[key];
|
|
60
|
-
} else {
|
|
61
|
-
queryOutput[key] = remapToGraphQLCore(key, value, tableName, table[key as keyof Table]! as Column, relationMap);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return queryOutput;
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
export const remapToGraphQLArrayOutput = (
|
|
69
|
-
queryOutput: Record<string, any>[],
|
|
70
|
-
tableName: string,
|
|
71
|
-
table: Table,
|
|
72
|
-
relationMap?: Record<string, Record<string, TableNamedRelations>>,
|
|
73
|
-
) => {
|
|
74
|
-
for (const entry of queryOutput) {
|
|
75
|
-
remapToGraphQLSingleOutput(entry, tableName, table, relationMap);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return queryOutput;
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
export const remapFromGraphQLCore = (value: any, column: Column, columnName: string) => {
|
|
82
|
-
switch (column.dataType) {
|
|
83
|
-
case 'date': {
|
|
84
|
-
const formatted = new Date(value);
|
|
85
|
-
if (Number.isNaN(formatted.getTime())) throw new GraphQLError(`Field '${columnName}' is not a valid date!`);
|
|
86
|
-
|
|
87
|
-
return formatted;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
case 'buffer': {
|
|
91
|
-
if (!Array.isArray(value)) {
|
|
92
|
-
throw new GraphQLError(`Field '${columnName}' is not an array!`);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
return Buffer.from(value);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
case 'json': {
|
|
99
|
-
if (column.columnType === 'PgGeometryObject') return value;
|
|
100
|
-
|
|
101
|
-
try {
|
|
102
|
-
return JSON.parse(value);
|
|
103
|
-
} catch (e) {
|
|
104
|
-
throw new GraphQLError(
|
|
105
|
-
`Invalid JSON in field '${columnName}':\n${e instanceof Error ? e.message : 'Unknown error'}`,
|
|
106
|
-
);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
case 'array': {
|
|
111
|
-
if (!Array.isArray(value)) {
|
|
112
|
-
throw new GraphQLError(`Field '${columnName}' is not an array!`);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
if (column.columnType === 'PgGeometry' && value.length !== 2) {
|
|
116
|
-
throw new GraphQLError(
|
|
117
|
-
`Invalid float tuple in field '${columnName}': expected array with length of 2, received ${value.length}`,
|
|
118
|
-
);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
return value;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
case 'bigint': {
|
|
125
|
-
try {
|
|
126
|
-
return BigInt(value);
|
|
127
|
-
} catch (error) {
|
|
128
|
-
throw new GraphQLError(`Field '${columnName}' is not a BigInt!`);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
default: {
|
|
133
|
-
return value;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
export const remapFromGraphQLSingleInput = (queryInput: Record<string, any>, table: Table) => {
|
|
139
|
-
for (const [key, value] of Object.entries(queryInput)) {
|
|
140
|
-
if (value === undefined) {
|
|
141
|
-
delete queryInput[key];
|
|
142
|
-
} else {
|
|
143
|
-
const column = getTableColumns(table)[key];
|
|
144
|
-
if (!column) throw new GraphQLError(`Unknown column: ${key}`);
|
|
145
|
-
|
|
146
|
-
if (value === null && column.notNull) {
|
|
147
|
-
delete queryInput[key];
|
|
148
|
-
continue;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
queryInput[key] = remapFromGraphQLCore(value, column, key);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
return queryInput;
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
export const remapFromGraphQLArrayInput = (queryInput: Record<string, any>[], table: Table) => {
|
|
159
|
-
for (const entry of queryInput) remapFromGraphQLSingleInput(entry, table);
|
|
160
|
-
|
|
161
|
-
return queryInput;
|
|
162
|
-
};
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
import { is } from 'drizzle-orm';
|
|
2
|
-
import { MySqlInt, MySqlSerial } from 'drizzle-orm/mysql-core';
|
|
3
|
-
import { PgInteger, PgSerial } from 'drizzle-orm/pg-core';
|
|
4
|
-
import { SQLiteInteger } from 'drizzle-orm/sqlite-core';
|
|
5
|
-
import {
|
|
6
|
-
GraphQLBoolean,
|
|
7
|
-
GraphQLEnumType,
|
|
8
|
-
GraphQLFloat,
|
|
9
|
-
GraphQLInputObjectType,
|
|
10
|
-
GraphQLInt,
|
|
11
|
-
GraphQLList,
|
|
12
|
-
GraphQLNonNull,
|
|
13
|
-
GraphQLObjectType,
|
|
14
|
-
GraphQLScalarType,
|
|
15
|
-
GraphQLString,
|
|
16
|
-
} from 'graphql';
|
|
17
|
-
|
|
18
|
-
import type { Column } from 'drizzle-orm';
|
|
19
|
-
import type { PgArray } from 'drizzle-orm/pg-core';
|
|
20
|
-
import { capitalize } from '../case-ops';
|
|
21
|
-
import type { ConvertedColumn } from './types';
|
|
22
|
-
|
|
23
|
-
const allowedNameChars = /^[a-zA-Z0-9_]+$/;
|
|
24
|
-
|
|
25
|
-
const enumMap = new WeakMap<Object, GraphQLEnumType>();
|
|
26
|
-
const generateEnumCached = (column: Column, columnName: string, tableName: string): GraphQLEnumType => {
|
|
27
|
-
if (enumMap.has(column)) return enumMap.get(column)!;
|
|
28
|
-
|
|
29
|
-
const gqlEnum = new GraphQLEnumType({
|
|
30
|
-
name: `${capitalize(tableName)}${capitalize(columnName)}Enum`,
|
|
31
|
-
values: Object.fromEntries(column.enumValues!.map((e, index) => [allowedNameChars.test(e) ? e : `Option${index}`, {
|
|
32
|
-
value: e,
|
|
33
|
-
description: `Value: ${e}`,
|
|
34
|
-
}])),
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
enumMap.set(column, gqlEnum);
|
|
38
|
-
|
|
39
|
-
return gqlEnum;
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
const geoXyType = new GraphQLObjectType({
|
|
43
|
-
name: 'PgGeometryObject',
|
|
44
|
-
fields: {
|
|
45
|
-
x: { type: GraphQLFloat },
|
|
46
|
-
y: { type: GraphQLFloat },
|
|
47
|
-
},
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
const geoXyInputType = new GraphQLInputObjectType({
|
|
51
|
-
name: 'PgGeometryObjectInput',
|
|
52
|
-
fields: {
|
|
53
|
-
x: { type: GraphQLFloat },
|
|
54
|
-
y: { type: GraphQLFloat },
|
|
55
|
-
},
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
const columnToGraphQLCore = (
|
|
59
|
-
column: Column,
|
|
60
|
-
columnName: string,
|
|
61
|
-
tableName: string,
|
|
62
|
-
isInput: boolean,
|
|
63
|
-
): ConvertedColumn<boolean> => {
|
|
64
|
-
switch (column.dataType) {
|
|
65
|
-
case 'boolean':
|
|
66
|
-
return { type: GraphQLBoolean, description: 'Boolean' };
|
|
67
|
-
case 'json':
|
|
68
|
-
return column.columnType === 'PgGeometryObject'
|
|
69
|
-
? {
|
|
70
|
-
type: isInput ? geoXyInputType : geoXyType,
|
|
71
|
-
description: 'Geometry points XY',
|
|
72
|
-
}
|
|
73
|
-
: { type: GraphQLString, description: 'JSON' };
|
|
74
|
-
case 'date':
|
|
75
|
-
return { type: GraphQLString, description: 'Date' };
|
|
76
|
-
case 'string':
|
|
77
|
-
if (column.enumValues?.length) return { type: generateEnumCached(column, columnName, tableName) };
|
|
78
|
-
|
|
79
|
-
return { type: GraphQLString, description: 'String' };
|
|
80
|
-
case 'bigint':
|
|
81
|
-
return { type: GraphQLString, description: 'BigInt' };
|
|
82
|
-
case 'number':
|
|
83
|
-
return is(column, PgInteger)
|
|
84
|
-
|| is(column, PgSerial)
|
|
85
|
-
|| is(column, MySqlInt)
|
|
86
|
-
|| is(column, MySqlSerial)
|
|
87
|
-
|| is(column, SQLiteInteger)
|
|
88
|
-
? { type: GraphQLInt, description: 'Integer' }
|
|
89
|
-
: { type: GraphQLFloat, description: 'Float' };
|
|
90
|
-
case 'buffer':
|
|
91
|
-
return { type: new GraphQLList(new GraphQLNonNull(GraphQLInt)), description: 'Buffer' };
|
|
92
|
-
case 'array': {
|
|
93
|
-
if (column.columnType === 'PgVector') {
|
|
94
|
-
return {
|
|
95
|
-
type: new GraphQLList(new GraphQLNonNull(GraphQLFloat)),
|
|
96
|
-
description: 'Array<Float>',
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if (column.columnType === 'PgGeometry') {
|
|
101
|
-
return {
|
|
102
|
-
type: new GraphQLList(new GraphQLNonNull(GraphQLFloat)),
|
|
103
|
-
description: 'Tuple<[Float, Float]>',
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
const innerType = columnToGraphQLCore(
|
|
108
|
-
(column as Column as PgArray<any, any>).baseColumn,
|
|
109
|
-
columnName,
|
|
110
|
-
tableName,
|
|
111
|
-
isInput,
|
|
112
|
-
);
|
|
113
|
-
|
|
114
|
-
return {
|
|
115
|
-
type: new GraphQLList(new GraphQLNonNull(innerType.type as GraphQLScalarType)),
|
|
116
|
-
description: `Array<${innerType.description}>`,
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
case 'custom':
|
|
120
|
-
default:
|
|
121
|
-
throw new Error(`Drizzle-GraphQL Error: Type ${column.dataType} is not implemented!`);
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
export const drizzleColumnToGraphQLType = <TColumn extends Column, TIsInput extends boolean>(
|
|
126
|
-
column: TColumn,
|
|
127
|
-
columnName: string,
|
|
128
|
-
tableName: string,
|
|
129
|
-
forceNullable = false,
|
|
130
|
-
defaultIsNullable = false,
|
|
131
|
-
isInput: TIsInput = false as TIsInput,
|
|
132
|
-
): ConvertedColumn<TIsInput> => {
|
|
133
|
-
const typeDesc = columnToGraphQLCore(column, columnName, tableName, isInput);
|
|
134
|
-
const noDesc = ['string', 'boolean', 'number'];
|
|
135
|
-
if (noDesc.find((e) => e === column.dataType)) delete typeDesc.description;
|
|
136
|
-
|
|
137
|
-
if (forceNullable) return typeDesc as ConvertedColumn<TIsInput>;
|
|
138
|
-
if (column.notNull && !(defaultIsNullable && (column.hasDefault || column.defaultFn))) {
|
|
139
|
-
return {
|
|
140
|
-
type: new GraphQLNonNull(typeDesc.type),
|
|
141
|
-
description: typeDesc.description,
|
|
142
|
-
} as ConvertedColumn<TIsInput>;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
return typeDesc as ConvertedColumn<TIsInput>;
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
export * from './types';
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
GraphQLEnumType,
|
|
3
|
-
GraphQLFieldConfig,
|
|
4
|
-
GraphQLInputObjectType,
|
|
5
|
-
GraphQLList,
|
|
6
|
-
GraphQLNonNull,
|
|
7
|
-
GraphQLObjectType,
|
|
8
|
-
GraphQLScalarType,
|
|
9
|
-
} from 'graphql';
|
|
10
|
-
|
|
11
|
-
export type ConvertedColumn<TIsInput extends boolean = false> = {
|
|
12
|
-
type:
|
|
13
|
-
| GraphQLScalarType
|
|
14
|
-
| GraphQLEnumType
|
|
15
|
-
| GraphQLNonNull<GraphQLScalarType>
|
|
16
|
-
| GraphQLNonNull<GraphQLEnumType>
|
|
17
|
-
| GraphQLList<GraphQLScalarType>
|
|
18
|
-
| GraphQLList<GraphQLNonNull<GraphQLScalarType>>
|
|
19
|
-
| GraphQLNonNull<GraphQLList<GraphQLScalarType>>
|
|
20
|
-
| GraphQLNonNull<GraphQLList<GraphQLNonNull<GraphQLScalarType>>>
|
|
21
|
-
| (TIsInput extends true ?
|
|
22
|
-
| GraphQLInputObjectType
|
|
23
|
-
| GraphQLNonNull<GraphQLInputObjectType>
|
|
24
|
-
| GraphQLList<GraphQLInputObjectType>
|
|
25
|
-
| GraphQLNonNull<GraphQLList<GraphQLInputObjectType>>
|
|
26
|
-
| GraphQLNonNull<GraphQLList<GraphQLNonNull<GraphQLInputObjectType>>>
|
|
27
|
-
:
|
|
28
|
-
| GraphQLObjectType
|
|
29
|
-
| GraphQLNonNull<GraphQLObjectType>
|
|
30
|
-
| GraphQLList<GraphQLObjectType>
|
|
31
|
-
| GraphQLNonNull<GraphQLList<GraphQLObjectType>>
|
|
32
|
-
| GraphQLNonNull<GraphQLList<GraphQLNonNull<GraphQLObjectType>>>);
|
|
33
|
-
description?: string;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export type ConvertedColumnWithArgs = ConvertedColumn & {
|
|
37
|
-
args?: GraphQLFieldConfig<any, any>['args'];
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
export type ConvertedInputColumn = {
|
|
41
|
-
type: GraphQLInputObjectType;
|
|
42
|
-
description?: string;
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
export type ConvertedRelationColumn = {
|
|
46
|
-
type:
|
|
47
|
-
| GraphQLObjectType
|
|
48
|
-
| GraphQLNonNull<GraphQLObjectType>
|
|
49
|
-
| GraphQLNonNull<GraphQLList<GraphQLNonNull<GraphQLObjectType>>>;
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
export type ConvertedRelationColumnWithArgs = ConvertedRelationColumn & {
|
|
53
|
-
args?: GraphQLFieldConfig<any, any>['args'];
|
|
54
|
-
};
|