@pgpmjs/migrate-client 0.1.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/LICENSE +23 -0
- package/README.md +112 -0
- package/esm/index.d.ts +1 -0
- package/esm/index.js +1 -0
- package/esm/migrate/index.d.ts +5 -0
- package/esm/migrate/index.js +5 -0
- package/esm/migrate/orm/client.d.ts +55 -0
- package/esm/migrate/orm/client.js +99 -0
- package/esm/migrate/orm/index.d.ts +48 -0
- package/esm/migrate/orm/index.js +45 -0
- package/esm/migrate/orm/input-types.d.ts +513 -0
- package/esm/migrate/orm/input-types.js +2 -0
- package/esm/migrate/orm/models/index.d.ts +7 -0
- package/esm/migrate/orm/models/index.js +7 -0
- package/esm/migrate/orm/models/migrateFile.d.ts +56 -0
- package/esm/migrate/orm/models/migrateFile.js +94 -0
- package/esm/migrate/orm/models/sqlAction.d.ts +56 -0
- package/esm/migrate/orm/models/sqlAction.js +94 -0
- package/esm/migrate/orm/mutation/index.d.ts +27 -0
- package/esm/migrate/orm/mutation/index.js +30 -0
- package/esm/migrate/orm/query-builder.d.ts +91 -0
- package/esm/migrate/orm/query-builder.js +572 -0
- package/esm/migrate/orm/select-types.d.ts +103 -0
- package/esm/migrate/orm/select-types.js +1 -0
- package/esm/migrate/orm/types.d.ts +6 -0
- package/esm/migrate/orm/types.js +7 -0
- package/index.d.ts +1 -0
- package/index.js +17 -0
- package/migrate/index.d.ts +5 -0
- package/migrate/index.js +21 -0
- package/migrate/orm/client.d.ts +55 -0
- package/migrate/orm/client.js +105 -0
- package/migrate/orm/index.d.ts +48 -0
- package/migrate/orm/index.js +66 -0
- package/migrate/orm/input-types.d.ts +513 -0
- package/migrate/orm/input-types.js +5 -0
- package/migrate/orm/models/index.d.ts +7 -0
- package/migrate/orm/models/index.js +12 -0
- package/migrate/orm/models/migrateFile.d.ts +56 -0
- package/migrate/orm/models/migrateFile.js +98 -0
- package/migrate/orm/models/sqlAction.d.ts +56 -0
- package/migrate/orm/models/sqlAction.js +98 -0
- package/migrate/orm/mutation/index.d.ts +27 -0
- package/migrate/orm/mutation/index.js +33 -0
- package/migrate/orm/query-builder.d.ts +91 -0
- package/migrate/orm/query-builder.js +619 -0
- package/migrate/orm/select-types.d.ts +103 -0
- package/migrate/orm/select-types.js +2 -0
- package/migrate/orm/types.d.ts +6 -0
- package/migrate/orm/types.js +23 -0
- package/package.json +53 -0
|
@@ -0,0 +1,572 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Query Builder - Builds and executes GraphQL operations
|
|
3
|
+
* @generated by @constructive-io/graphql-codegen
|
|
4
|
+
* DO NOT EDIT - changes will be overwritten
|
|
5
|
+
*/
|
|
6
|
+
import { parseType, print } from '@0no-co/graphql.web';
|
|
7
|
+
import * as t from 'gql-ast';
|
|
8
|
+
import { GraphQLRequestError } from './client';
|
|
9
|
+
export class QueryBuilder {
|
|
10
|
+
config;
|
|
11
|
+
constructor(config) {
|
|
12
|
+
this.config = config;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Execute the query and return a discriminated union result
|
|
16
|
+
* Use result.ok to check success, or .unwrap() to throw on error
|
|
17
|
+
*/
|
|
18
|
+
async execute() {
|
|
19
|
+
const rawResult = await this.config.client.execute(this.config.document, this.config.variables);
|
|
20
|
+
if (!rawResult.ok) {
|
|
21
|
+
return rawResult;
|
|
22
|
+
}
|
|
23
|
+
if (!this.config.transform) {
|
|
24
|
+
return rawResult;
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
ok: true,
|
|
28
|
+
data: this.config.transform(rawResult.data),
|
|
29
|
+
errors: undefined,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Execute and unwrap the result, throwing GraphQLRequestError on failure
|
|
34
|
+
* @throws {GraphQLRequestError} If the query returns errors
|
|
35
|
+
*/
|
|
36
|
+
async unwrap() {
|
|
37
|
+
const result = await this.execute();
|
|
38
|
+
if (!result.ok) {
|
|
39
|
+
throw new GraphQLRequestError(result.errors, result.data);
|
|
40
|
+
}
|
|
41
|
+
return result.data;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Execute and unwrap, returning defaultValue on error instead of throwing
|
|
45
|
+
*/
|
|
46
|
+
async unwrapOr(defaultValue) {
|
|
47
|
+
const result = await this.execute();
|
|
48
|
+
if (!result.ok) {
|
|
49
|
+
return defaultValue;
|
|
50
|
+
}
|
|
51
|
+
return result.data;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Execute and unwrap, calling onError callback on failure
|
|
55
|
+
*/
|
|
56
|
+
async unwrapOrElse(onError) {
|
|
57
|
+
const result = await this.execute();
|
|
58
|
+
if (!result.ok) {
|
|
59
|
+
return onError(result.errors);
|
|
60
|
+
}
|
|
61
|
+
return result.data;
|
|
62
|
+
}
|
|
63
|
+
toGraphQL() {
|
|
64
|
+
return this.config.document;
|
|
65
|
+
}
|
|
66
|
+
getVariables() {
|
|
67
|
+
return this.config.variables;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const OP_QUERY = 'query';
|
|
71
|
+
const OP_MUTATION = 'mutation';
|
|
72
|
+
const ENUM_VALUE_KIND = 'EnumValue';
|
|
73
|
+
// ============================================================================
|
|
74
|
+
// Selection Builders
|
|
75
|
+
// ============================================================================
|
|
76
|
+
export function buildSelections(select, connectionFieldsMap, entityType) {
|
|
77
|
+
if (!select) {
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
const fields = [];
|
|
81
|
+
const entityConnections = entityType ? connectionFieldsMap?.[entityType] : undefined;
|
|
82
|
+
for (const [key, value] of Object.entries(select)) {
|
|
83
|
+
if (value === false || value === undefined) {
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
if (value === true) {
|
|
87
|
+
fields.push(t.field({ name: key }));
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (typeof value === 'object' && value !== null) {
|
|
91
|
+
const nested = value;
|
|
92
|
+
if (!nested.select || typeof nested.select !== 'object') {
|
|
93
|
+
throw new Error(`Invalid selection for field "${key}": nested selections must include a "select" object.`);
|
|
94
|
+
}
|
|
95
|
+
const relatedEntityType = entityConnections?.[key];
|
|
96
|
+
const nestedSelections = buildSelections(nested.select, connectionFieldsMap, relatedEntityType);
|
|
97
|
+
const isConnection = nested.connection === true ||
|
|
98
|
+
nested.first !== undefined ||
|
|
99
|
+
nested.filter !== undefined ||
|
|
100
|
+
relatedEntityType !== undefined;
|
|
101
|
+
const args = buildArgs([
|
|
102
|
+
buildOptionalArg('first', nested.first),
|
|
103
|
+
nested.filter
|
|
104
|
+
? t.argument({
|
|
105
|
+
name: 'filter',
|
|
106
|
+
value: buildValueAst(nested.filter),
|
|
107
|
+
})
|
|
108
|
+
: null,
|
|
109
|
+
buildEnumListArg('orderBy', nested.orderBy),
|
|
110
|
+
]);
|
|
111
|
+
if (isConnection) {
|
|
112
|
+
fields.push(t.field({
|
|
113
|
+
name: key,
|
|
114
|
+
args,
|
|
115
|
+
selectionSet: t.selectionSet({
|
|
116
|
+
selections: buildConnectionSelections(nestedSelections),
|
|
117
|
+
}),
|
|
118
|
+
}));
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
fields.push(t.field({
|
|
122
|
+
name: key,
|
|
123
|
+
args,
|
|
124
|
+
selectionSet: t.selectionSet({ selections: nestedSelections }),
|
|
125
|
+
}));
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return fields;
|
|
130
|
+
}
|
|
131
|
+
// ============================================================================
|
|
132
|
+
// Document Builders
|
|
133
|
+
// ============================================================================
|
|
134
|
+
export function buildFindManyDocument(operationName, queryField, select, args, filterTypeName, orderByTypeName, connectionFieldsMap, conditionTypeName) {
|
|
135
|
+
const selections = select
|
|
136
|
+
? buildSelections(select, connectionFieldsMap, operationName)
|
|
137
|
+
: [t.field({ name: 'id' })];
|
|
138
|
+
const variableDefinitions = [];
|
|
139
|
+
const queryArgs = [];
|
|
140
|
+
const variables = {};
|
|
141
|
+
addVariable({
|
|
142
|
+
varName: 'condition',
|
|
143
|
+
typeName: conditionTypeName,
|
|
144
|
+
value: args.condition,
|
|
145
|
+
}, variableDefinitions, queryArgs, variables);
|
|
146
|
+
addVariable({
|
|
147
|
+
varName: 'where',
|
|
148
|
+
typeName: filterTypeName,
|
|
149
|
+
value: args.where,
|
|
150
|
+
}, variableDefinitions, queryArgs, variables);
|
|
151
|
+
addVariable({
|
|
152
|
+
varName: 'orderBy',
|
|
153
|
+
typeName: '[' + orderByTypeName + '!]',
|
|
154
|
+
value: args.orderBy?.length ? args.orderBy : undefined,
|
|
155
|
+
}, variableDefinitions, queryArgs, variables);
|
|
156
|
+
addVariable({ varName: 'first', typeName: 'Int', value: args.first }, variableDefinitions, queryArgs, variables);
|
|
157
|
+
addVariable({ varName: 'last', typeName: 'Int', value: args.last }, variableDefinitions, queryArgs, variables);
|
|
158
|
+
addVariable({ varName: 'after', typeName: 'Cursor', value: args.after }, variableDefinitions, queryArgs, variables);
|
|
159
|
+
addVariable({ varName: 'before', typeName: 'Cursor', value: args.before }, variableDefinitions, queryArgs, variables);
|
|
160
|
+
addVariable({ varName: 'offset', typeName: 'Int', value: args.offset }, variableDefinitions, queryArgs, variables);
|
|
161
|
+
const document = t.document({
|
|
162
|
+
definitions: [
|
|
163
|
+
t.operationDefinition({
|
|
164
|
+
operation: OP_QUERY,
|
|
165
|
+
name: operationName + 'Query',
|
|
166
|
+
variableDefinitions: variableDefinitions.length ? variableDefinitions : undefined,
|
|
167
|
+
selectionSet: t.selectionSet({
|
|
168
|
+
selections: [
|
|
169
|
+
t.field({
|
|
170
|
+
name: queryField,
|
|
171
|
+
args: queryArgs.length ? queryArgs : undefined,
|
|
172
|
+
selectionSet: t.selectionSet({
|
|
173
|
+
selections: buildConnectionSelections(selections),
|
|
174
|
+
}),
|
|
175
|
+
}),
|
|
176
|
+
],
|
|
177
|
+
}),
|
|
178
|
+
}),
|
|
179
|
+
],
|
|
180
|
+
});
|
|
181
|
+
return { document: print(document), variables };
|
|
182
|
+
}
|
|
183
|
+
export function buildFindFirstDocument(operationName, queryField, select, args, filterTypeName, connectionFieldsMap, conditionTypeName) {
|
|
184
|
+
const selections = select
|
|
185
|
+
? buildSelections(select, connectionFieldsMap, operationName)
|
|
186
|
+
: [t.field({ name: 'id' })];
|
|
187
|
+
const variableDefinitions = [];
|
|
188
|
+
const queryArgs = [];
|
|
189
|
+
const variables = {};
|
|
190
|
+
// Always add first: 1 for findFirst
|
|
191
|
+
addVariable({ varName: 'first', typeName: 'Int', value: 1 }, variableDefinitions, queryArgs, variables);
|
|
192
|
+
addVariable({
|
|
193
|
+
varName: 'condition',
|
|
194
|
+
typeName: conditionTypeName,
|
|
195
|
+
value: args.condition,
|
|
196
|
+
}, variableDefinitions, queryArgs, variables);
|
|
197
|
+
addVariable({
|
|
198
|
+
varName: 'where',
|
|
199
|
+
typeName: filterTypeName,
|
|
200
|
+
value: args.where,
|
|
201
|
+
}, variableDefinitions, queryArgs, variables);
|
|
202
|
+
const document = t.document({
|
|
203
|
+
definitions: [
|
|
204
|
+
t.operationDefinition({
|
|
205
|
+
operation: OP_QUERY,
|
|
206
|
+
name: operationName + 'Query',
|
|
207
|
+
variableDefinitions,
|
|
208
|
+
selectionSet: t.selectionSet({
|
|
209
|
+
selections: [
|
|
210
|
+
t.field({
|
|
211
|
+
name: queryField,
|
|
212
|
+
args: queryArgs,
|
|
213
|
+
selectionSet: t.selectionSet({
|
|
214
|
+
selections: [
|
|
215
|
+
t.field({
|
|
216
|
+
name: 'nodes',
|
|
217
|
+
selectionSet: t.selectionSet({ selections }),
|
|
218
|
+
}),
|
|
219
|
+
],
|
|
220
|
+
}),
|
|
221
|
+
}),
|
|
222
|
+
],
|
|
223
|
+
}),
|
|
224
|
+
}),
|
|
225
|
+
],
|
|
226
|
+
});
|
|
227
|
+
return { document: print(document), variables };
|
|
228
|
+
}
|
|
229
|
+
export function buildCreateDocument(operationName, mutationField, entityField, select, data, inputTypeName, connectionFieldsMap) {
|
|
230
|
+
const selections = select
|
|
231
|
+
? buildSelections(select, connectionFieldsMap, operationName)
|
|
232
|
+
: [t.field({ name: 'id' })];
|
|
233
|
+
return {
|
|
234
|
+
document: buildInputMutationDocument({
|
|
235
|
+
operationName,
|
|
236
|
+
mutationField,
|
|
237
|
+
inputTypeName,
|
|
238
|
+
resultSelections: [
|
|
239
|
+
t.field({
|
|
240
|
+
name: entityField,
|
|
241
|
+
selectionSet: t.selectionSet({ selections }),
|
|
242
|
+
}),
|
|
243
|
+
],
|
|
244
|
+
}),
|
|
245
|
+
variables: {
|
|
246
|
+
input: {
|
|
247
|
+
[entityField]: data,
|
|
248
|
+
},
|
|
249
|
+
},
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
export function buildUpdateDocument(operationName, mutationField, entityField, select, where, data, inputTypeName, patchFieldName, connectionFieldsMap) {
|
|
253
|
+
const selections = select
|
|
254
|
+
? buildSelections(select, connectionFieldsMap, operationName)
|
|
255
|
+
: [t.field({ name: 'id' })];
|
|
256
|
+
return {
|
|
257
|
+
document: buildInputMutationDocument({
|
|
258
|
+
operationName,
|
|
259
|
+
mutationField,
|
|
260
|
+
inputTypeName,
|
|
261
|
+
resultSelections: [
|
|
262
|
+
t.field({
|
|
263
|
+
name: entityField,
|
|
264
|
+
selectionSet: t.selectionSet({ selections }),
|
|
265
|
+
}),
|
|
266
|
+
],
|
|
267
|
+
}),
|
|
268
|
+
variables: {
|
|
269
|
+
input: {
|
|
270
|
+
id: where.id,
|
|
271
|
+
[patchFieldName]: data,
|
|
272
|
+
},
|
|
273
|
+
},
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
export function buildUpdateByPkDocument(operationName, mutationField, entityField, select, id, data, inputTypeName, idFieldName, patchFieldName, connectionFieldsMap) {
|
|
277
|
+
const selections = select
|
|
278
|
+
? buildSelections(select, connectionFieldsMap, operationName)
|
|
279
|
+
: [t.field({ name: 'id' })];
|
|
280
|
+
return {
|
|
281
|
+
document: buildInputMutationDocument({
|
|
282
|
+
operationName,
|
|
283
|
+
mutationField,
|
|
284
|
+
inputTypeName,
|
|
285
|
+
resultSelections: [
|
|
286
|
+
t.field({
|
|
287
|
+
name: entityField,
|
|
288
|
+
selectionSet: t.selectionSet({ selections }),
|
|
289
|
+
}),
|
|
290
|
+
],
|
|
291
|
+
}),
|
|
292
|
+
variables: {
|
|
293
|
+
input: {
|
|
294
|
+
[idFieldName]: id,
|
|
295
|
+
[patchFieldName]: data,
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
export function buildFindOneDocument(operationName, queryField, id, select, idArgName, idTypeName, connectionFieldsMap) {
|
|
301
|
+
const selections = select
|
|
302
|
+
? buildSelections(select, connectionFieldsMap, operationName)
|
|
303
|
+
: [t.field({ name: 'id' })];
|
|
304
|
+
const variableDefinitions = [
|
|
305
|
+
t.variableDefinition({
|
|
306
|
+
variable: t.variable({ name: idArgName }),
|
|
307
|
+
type: parseType(idTypeName),
|
|
308
|
+
}),
|
|
309
|
+
];
|
|
310
|
+
const queryArgs = [
|
|
311
|
+
t.argument({
|
|
312
|
+
name: idArgName,
|
|
313
|
+
value: t.variable({ name: idArgName }),
|
|
314
|
+
}),
|
|
315
|
+
];
|
|
316
|
+
const document = t.document({
|
|
317
|
+
definitions: [
|
|
318
|
+
t.operationDefinition({
|
|
319
|
+
operation: OP_QUERY,
|
|
320
|
+
name: operationName + 'Query',
|
|
321
|
+
variableDefinitions,
|
|
322
|
+
selectionSet: t.selectionSet({
|
|
323
|
+
selections: [
|
|
324
|
+
t.field({
|
|
325
|
+
name: queryField,
|
|
326
|
+
args: queryArgs,
|
|
327
|
+
selectionSet: t.selectionSet({ selections }),
|
|
328
|
+
}),
|
|
329
|
+
],
|
|
330
|
+
}),
|
|
331
|
+
}),
|
|
332
|
+
],
|
|
333
|
+
});
|
|
334
|
+
return {
|
|
335
|
+
document: print(document),
|
|
336
|
+
variables: { [idArgName]: id },
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
export function buildDeleteDocument(operationName, mutationField, entityField, where, inputTypeName, select, connectionFieldsMap) {
|
|
340
|
+
const entitySelections = select
|
|
341
|
+
? buildSelections(select, connectionFieldsMap, operationName)
|
|
342
|
+
: [t.field({ name: 'id' })];
|
|
343
|
+
return {
|
|
344
|
+
document: buildInputMutationDocument({
|
|
345
|
+
operationName,
|
|
346
|
+
mutationField,
|
|
347
|
+
inputTypeName,
|
|
348
|
+
resultSelections: [
|
|
349
|
+
t.field({
|
|
350
|
+
name: entityField,
|
|
351
|
+
selectionSet: t.selectionSet({
|
|
352
|
+
selections: entitySelections,
|
|
353
|
+
}),
|
|
354
|
+
}),
|
|
355
|
+
],
|
|
356
|
+
}),
|
|
357
|
+
variables: {
|
|
358
|
+
input: {
|
|
359
|
+
id: where.id,
|
|
360
|
+
},
|
|
361
|
+
},
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
export function buildDeleteByPkDocument(operationName, mutationField, entityField, id, inputTypeName, idFieldName, select, connectionFieldsMap) {
|
|
365
|
+
const entitySelections = select
|
|
366
|
+
? buildSelections(select, connectionFieldsMap, operationName)
|
|
367
|
+
: [t.field({ name: 'id' })];
|
|
368
|
+
return {
|
|
369
|
+
document: buildInputMutationDocument({
|
|
370
|
+
operationName,
|
|
371
|
+
mutationField,
|
|
372
|
+
inputTypeName,
|
|
373
|
+
resultSelections: [
|
|
374
|
+
t.field({
|
|
375
|
+
name: entityField,
|
|
376
|
+
selectionSet: t.selectionSet({ selections: entitySelections }),
|
|
377
|
+
}),
|
|
378
|
+
],
|
|
379
|
+
}),
|
|
380
|
+
variables: {
|
|
381
|
+
input: {
|
|
382
|
+
[idFieldName]: id,
|
|
383
|
+
},
|
|
384
|
+
},
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
export function buildCustomDocument(operationType, operationName, fieldName, select, args, variableDefinitions, connectionFieldsMap, entityType) {
|
|
388
|
+
let actualSelect = select;
|
|
389
|
+
let isConnection = false;
|
|
390
|
+
if (isCustomSelectionWrapper(select)) {
|
|
391
|
+
actualSelect = select.select;
|
|
392
|
+
isConnection = select.connection === true;
|
|
393
|
+
}
|
|
394
|
+
const selections = actualSelect
|
|
395
|
+
? buildSelections(actualSelect, connectionFieldsMap, entityType)
|
|
396
|
+
: [];
|
|
397
|
+
const variableDefs = variableDefinitions.map((definition) => t.variableDefinition({
|
|
398
|
+
variable: t.variable({ name: definition.name }),
|
|
399
|
+
type: parseType(definition.type),
|
|
400
|
+
}));
|
|
401
|
+
const fieldArgs = variableDefinitions.map((definition) => t.argument({
|
|
402
|
+
name: definition.name,
|
|
403
|
+
value: t.variable({ name: definition.name }),
|
|
404
|
+
}));
|
|
405
|
+
const fieldSelections = isConnection ? buildConnectionSelections(selections) : selections;
|
|
406
|
+
const document = t.document({
|
|
407
|
+
definitions: [
|
|
408
|
+
t.operationDefinition({
|
|
409
|
+
operation: operationType === 'mutation' ? OP_MUTATION : OP_QUERY,
|
|
410
|
+
name: operationName,
|
|
411
|
+
variableDefinitions: variableDefs.length ? variableDefs : undefined,
|
|
412
|
+
selectionSet: t.selectionSet({
|
|
413
|
+
selections: [
|
|
414
|
+
t.field({
|
|
415
|
+
name: fieldName,
|
|
416
|
+
args: fieldArgs.length ? fieldArgs : undefined,
|
|
417
|
+
selectionSet: fieldSelections.length
|
|
418
|
+
? t.selectionSet({ selections: fieldSelections })
|
|
419
|
+
: undefined,
|
|
420
|
+
}),
|
|
421
|
+
],
|
|
422
|
+
}),
|
|
423
|
+
}),
|
|
424
|
+
],
|
|
425
|
+
});
|
|
426
|
+
return {
|
|
427
|
+
document: print(document),
|
|
428
|
+
variables: (args ?? {}),
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
function isCustomSelectionWrapper(value) {
|
|
432
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
433
|
+
return false;
|
|
434
|
+
}
|
|
435
|
+
const record = value;
|
|
436
|
+
const keys = Object.keys(record);
|
|
437
|
+
if (!keys.includes('select') || !keys.includes('connection')) {
|
|
438
|
+
return false;
|
|
439
|
+
}
|
|
440
|
+
if (keys.some((key) => key !== 'select' && key !== 'connection')) {
|
|
441
|
+
return false;
|
|
442
|
+
}
|
|
443
|
+
return !!record.select && typeof record.select === 'object' && !Array.isArray(record.select);
|
|
444
|
+
}
|
|
445
|
+
// ============================================================================
|
|
446
|
+
// Helper Functions
|
|
447
|
+
// ============================================================================
|
|
448
|
+
function buildArgs(args) {
|
|
449
|
+
return args.filter((arg) => arg !== null);
|
|
450
|
+
}
|
|
451
|
+
function buildOptionalArg(name, value) {
|
|
452
|
+
if (value === undefined) {
|
|
453
|
+
return null;
|
|
454
|
+
}
|
|
455
|
+
const valueNode = typeof value === 'number' ? t.intValue({ value: value.toString() }) : t.stringValue({ value });
|
|
456
|
+
return t.argument({ name, value: valueNode });
|
|
457
|
+
}
|
|
458
|
+
function buildEnumListArg(name, values) {
|
|
459
|
+
if (!values || values.length === 0) {
|
|
460
|
+
return null;
|
|
461
|
+
}
|
|
462
|
+
return t.argument({
|
|
463
|
+
name,
|
|
464
|
+
value: t.listValue({
|
|
465
|
+
values: values.map((value) => buildEnumValue(value)),
|
|
466
|
+
}),
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
function buildEnumValue(value) {
|
|
470
|
+
return {
|
|
471
|
+
kind: ENUM_VALUE_KIND,
|
|
472
|
+
value,
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
function buildPageInfoSelections() {
|
|
476
|
+
return [
|
|
477
|
+
t.field({ name: 'hasNextPage' }),
|
|
478
|
+
t.field({ name: 'hasPreviousPage' }),
|
|
479
|
+
t.field({ name: 'startCursor' }),
|
|
480
|
+
t.field({ name: 'endCursor' }),
|
|
481
|
+
];
|
|
482
|
+
}
|
|
483
|
+
function buildConnectionSelections(nodeSelections) {
|
|
484
|
+
return [
|
|
485
|
+
t.field({
|
|
486
|
+
name: 'nodes',
|
|
487
|
+
selectionSet: t.selectionSet({ selections: nodeSelections }),
|
|
488
|
+
}),
|
|
489
|
+
t.field({ name: 'totalCount' }),
|
|
490
|
+
t.field({
|
|
491
|
+
name: 'pageInfo',
|
|
492
|
+
selectionSet: t.selectionSet({ selections: buildPageInfoSelections() }),
|
|
493
|
+
}),
|
|
494
|
+
];
|
|
495
|
+
}
|
|
496
|
+
function buildInputMutationDocument(config) {
|
|
497
|
+
const document = t.document({
|
|
498
|
+
definitions: [
|
|
499
|
+
t.operationDefinition({
|
|
500
|
+
operation: OP_MUTATION,
|
|
501
|
+
name: config.operationName + 'Mutation',
|
|
502
|
+
variableDefinitions: [
|
|
503
|
+
t.variableDefinition({
|
|
504
|
+
variable: t.variable({ name: 'input' }),
|
|
505
|
+
type: parseType(config.inputTypeName + '!'),
|
|
506
|
+
}),
|
|
507
|
+
],
|
|
508
|
+
selectionSet: t.selectionSet({
|
|
509
|
+
selections: [
|
|
510
|
+
t.field({
|
|
511
|
+
name: config.mutationField,
|
|
512
|
+
args: [
|
|
513
|
+
t.argument({
|
|
514
|
+
name: 'input',
|
|
515
|
+
value: t.variable({ name: 'input' }),
|
|
516
|
+
}),
|
|
517
|
+
],
|
|
518
|
+
selectionSet: t.selectionSet({
|
|
519
|
+
selections: config.resultSelections,
|
|
520
|
+
}),
|
|
521
|
+
}),
|
|
522
|
+
],
|
|
523
|
+
}),
|
|
524
|
+
}),
|
|
525
|
+
],
|
|
526
|
+
});
|
|
527
|
+
return print(document);
|
|
528
|
+
}
|
|
529
|
+
function addVariable(spec, definitions, args, variables) {
|
|
530
|
+
if (spec.value === undefined || !spec.typeName)
|
|
531
|
+
return;
|
|
532
|
+
definitions.push(t.variableDefinition({
|
|
533
|
+
variable: t.variable({ name: spec.varName }),
|
|
534
|
+
type: parseType(spec.typeName),
|
|
535
|
+
}));
|
|
536
|
+
args.push(t.argument({
|
|
537
|
+
name: spec.argName ?? spec.varName,
|
|
538
|
+
value: t.variable({ name: spec.varName }),
|
|
539
|
+
}));
|
|
540
|
+
variables[spec.varName] = spec.value;
|
|
541
|
+
}
|
|
542
|
+
function buildValueAst(value) {
|
|
543
|
+
if (value === null) {
|
|
544
|
+
return t.nullValue();
|
|
545
|
+
}
|
|
546
|
+
if (typeof value === 'boolean') {
|
|
547
|
+
return t.booleanValue({ value });
|
|
548
|
+
}
|
|
549
|
+
if (typeof value === 'number') {
|
|
550
|
+
return Number.isInteger(value)
|
|
551
|
+
? t.intValue({ value: value.toString() })
|
|
552
|
+
: t.floatValue({ value: value.toString() });
|
|
553
|
+
}
|
|
554
|
+
if (typeof value === 'string') {
|
|
555
|
+
return t.stringValue({ value });
|
|
556
|
+
}
|
|
557
|
+
if (Array.isArray(value)) {
|
|
558
|
+
return t.listValue({
|
|
559
|
+
values: value.map((item) => buildValueAst(item)),
|
|
560
|
+
});
|
|
561
|
+
}
|
|
562
|
+
if (typeof value === 'object' && value !== null) {
|
|
563
|
+
const obj = value;
|
|
564
|
+
return t.objectValue({
|
|
565
|
+
fields: Object.entries(obj).map(([key, val]) => t.objectField({
|
|
566
|
+
name: key,
|
|
567
|
+
value: buildValueAst(val),
|
|
568
|
+
})),
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
throw new Error('Unsupported value type: ' + typeof value);
|
|
572
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type utilities for select inference
|
|
3
|
+
* @generated by @constructive-io/graphql-codegen
|
|
4
|
+
* DO NOT EDIT - changes will be overwritten
|
|
5
|
+
*/
|
|
6
|
+
export interface ConnectionResult<T> {
|
|
7
|
+
nodes: T[];
|
|
8
|
+
totalCount: number;
|
|
9
|
+
pageInfo: PageInfo;
|
|
10
|
+
}
|
|
11
|
+
export interface PageInfo {
|
|
12
|
+
hasNextPage: boolean;
|
|
13
|
+
hasPreviousPage: boolean;
|
|
14
|
+
startCursor?: string | null;
|
|
15
|
+
endCursor?: string | null;
|
|
16
|
+
}
|
|
17
|
+
export interface FindManyArgs<TSelect, TWhere, TCondition = never, TOrderBy = never> {
|
|
18
|
+
select?: TSelect;
|
|
19
|
+
where?: TWhere;
|
|
20
|
+
condition?: TCondition;
|
|
21
|
+
orderBy?: TOrderBy[];
|
|
22
|
+
first?: number;
|
|
23
|
+
last?: number;
|
|
24
|
+
after?: string;
|
|
25
|
+
before?: string;
|
|
26
|
+
offset?: number;
|
|
27
|
+
}
|
|
28
|
+
export interface FindFirstArgs<TSelect, TWhere, TCondition = never> {
|
|
29
|
+
select?: TSelect;
|
|
30
|
+
where?: TWhere;
|
|
31
|
+
condition?: TCondition;
|
|
32
|
+
}
|
|
33
|
+
export interface CreateArgs<TSelect, TData> {
|
|
34
|
+
data: TData;
|
|
35
|
+
select?: TSelect;
|
|
36
|
+
}
|
|
37
|
+
export interface UpdateArgs<TSelect, TWhere, TData> {
|
|
38
|
+
where: TWhere;
|
|
39
|
+
data: TData;
|
|
40
|
+
select?: TSelect;
|
|
41
|
+
}
|
|
42
|
+
export type FindOneArgs<TSelect, TIdName extends string = 'id', TId = string> = {
|
|
43
|
+
select?: TSelect;
|
|
44
|
+
} & Record<TIdName, TId>;
|
|
45
|
+
export interface DeleteArgs<TWhere, TSelect = undefined> {
|
|
46
|
+
where: TWhere;
|
|
47
|
+
select?: TSelect;
|
|
48
|
+
}
|
|
49
|
+
type DepthLevel = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;
|
|
50
|
+
type DecrementDepth = {
|
|
51
|
+
0: 0;
|
|
52
|
+
1: 0;
|
|
53
|
+
2: 1;
|
|
54
|
+
3: 2;
|
|
55
|
+
4: 3;
|
|
56
|
+
5: 4;
|
|
57
|
+
6: 5;
|
|
58
|
+
7: 6;
|
|
59
|
+
8: 7;
|
|
60
|
+
9: 8;
|
|
61
|
+
10: 9;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Recursively validates select objects, rejecting unknown keys.
|
|
65
|
+
*
|
|
66
|
+
* NOTE: Depth is intentionally capped to avoid circular-instantiation issues
|
|
67
|
+
* in very large cyclic schemas.
|
|
68
|
+
*/
|
|
69
|
+
export type DeepExact<T, Shape, Depth extends DepthLevel = 10> = Depth extends 0 ? T extends Shape ? T : never : T extends Shape ? Exclude<keyof T, keyof Shape> extends never ? {
|
|
70
|
+
[K in keyof T]: K extends keyof Shape ? T[K] extends {
|
|
71
|
+
select: infer NS;
|
|
72
|
+
} ? Extract<Shape[K], {
|
|
73
|
+
select?: unknown;
|
|
74
|
+
}> extends {
|
|
75
|
+
select?: infer ShapeNS;
|
|
76
|
+
} ? DeepExact<Omit<T[K], 'select'> & {
|
|
77
|
+
select: DeepExact<NS, NonNullable<ShapeNS>, DecrementDepth[Depth]>;
|
|
78
|
+
}, Extract<Shape[K], {
|
|
79
|
+
select?: unknown;
|
|
80
|
+
}>, DecrementDepth[Depth]> : never : T[K] : never;
|
|
81
|
+
} : never : never;
|
|
82
|
+
/**
|
|
83
|
+
* Enforces exact select shape while keeping contextual typing on `S extends XxxSelect`.
|
|
84
|
+
* Use this as an intersection in overloads:
|
|
85
|
+
* `{ select: S } & StrictSelect<S, XxxSelect>`.
|
|
86
|
+
*/
|
|
87
|
+
export type StrictSelect<S, Shape> = S extends DeepExact<S, Shape> ? {} : never;
|
|
88
|
+
/**
|
|
89
|
+
* Hook-optimized strict select variant.
|
|
90
|
+
*
|
|
91
|
+
* Uses a shallower recursion depth to keep editor autocomplete responsive
|
|
92
|
+
* in large schemas while still validating common nested-select mistakes.
|
|
93
|
+
*/
|
|
94
|
+
export type HookStrictSelect<S, Shape> = S extends DeepExact<S, Shape, 5> ? {} : never;
|
|
95
|
+
/**
|
|
96
|
+
* Infer result type from select configuration
|
|
97
|
+
*/
|
|
98
|
+
export type InferSelectResult<TEntity, TSelect> = TSelect extends undefined ? TEntity : {
|
|
99
|
+
[K in keyof TSelect as TSelect[K] extends false | undefined ? never : K]: TSelect[K] extends true ? K extends keyof TEntity ? TEntity[K] : never : TSelect[K] extends {
|
|
100
|
+
select: infer NestedSelect;
|
|
101
|
+
} ? K extends keyof TEntity ? NonNullable<TEntity[K]> extends ConnectionResult<infer NodeType> ? ConnectionResult<InferSelectResult<NodeType, NestedSelect>> : InferSelectResult<NonNullable<TEntity[K]>, NestedSelect> | (null extends TEntity[K] ? null : never) : never : K extends keyof TEntity ? TEntity[K] : never;
|
|
102
|
+
};
|
|
103
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './migrate/orm';
|