@constructive-io/graphql-query 2.4.3
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 +201 -0
- package/ast.d.ts +38 -0
- package/ast.js +631 -0
- package/custom-ast.d.ts +4 -0
- package/custom-ast.js +89 -0
- package/esm/ast.js +585 -0
- package/esm/custom-ast.js +50 -0
- package/esm/index.js +342 -0
- package/esm/meta-object/convert.js +52 -0
- package/esm/meta-object/format.json +83 -0
- package/esm/meta-object/index.js +2 -0
- package/esm/meta-object/validate.js +12 -0
- package/index.d.ts +22 -0
- package/index.js +382 -0
- package/meta-object/convert.d.ts +3 -0
- package/meta-object/convert.js +55 -0
- package/meta-object/format.json +83 -0
- package/meta-object/index.d.ts +2 -0
- package/meta-object/index.js +18 -0
- package/meta-object/validate.d.ts +4 -0
- package/meta-object/validate.js +18 -0
- package/package.json +49 -0
package/custom-ast.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.getCustomAst = getCustomAst;
|
|
38
|
+
exports.geometryAst = geometryAst;
|
|
39
|
+
exports.intervalAst = intervalAst;
|
|
40
|
+
exports.isIntervalType = isIntervalType;
|
|
41
|
+
const t = __importStar(require("gql-ast"));
|
|
42
|
+
function getCustomAst(fieldDefn) {
|
|
43
|
+
const { pgType } = fieldDefn.type;
|
|
44
|
+
if (pgType === 'geometry') {
|
|
45
|
+
return geometryAst(fieldDefn.name);
|
|
46
|
+
}
|
|
47
|
+
if (pgType === 'interval') {
|
|
48
|
+
return intervalAst(fieldDefn.name);
|
|
49
|
+
}
|
|
50
|
+
return t.field({
|
|
51
|
+
name: fieldDefn.name
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
function geometryAst(name) {
|
|
55
|
+
return t.field({
|
|
56
|
+
name,
|
|
57
|
+
selectionSet: t.selectionSet({
|
|
58
|
+
selections: toFieldArray(['geojson'])
|
|
59
|
+
})
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
function intervalAst(name) {
|
|
63
|
+
return t.field({
|
|
64
|
+
name,
|
|
65
|
+
selectionSet: t.selectionSet({
|
|
66
|
+
selections: toFieldArray([
|
|
67
|
+
'days',
|
|
68
|
+
'hours',
|
|
69
|
+
'minutes',
|
|
70
|
+
'months',
|
|
71
|
+
'seconds',
|
|
72
|
+
'years'
|
|
73
|
+
])
|
|
74
|
+
})
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
function toFieldArray(strArr) {
|
|
78
|
+
return strArr.map((fieldName) => t.field({ name: fieldName }));
|
|
79
|
+
}
|
|
80
|
+
function isIntervalType(obj) {
|
|
81
|
+
return [
|
|
82
|
+
'days',
|
|
83
|
+
'hours',
|
|
84
|
+
'minutes',
|
|
85
|
+
'months',
|
|
86
|
+
'seconds',
|
|
87
|
+
'years'
|
|
88
|
+
].every((key) => obj.hasOwnProperty(key));
|
|
89
|
+
}
|
package/esm/ast.js
ADDED
|
@@ -0,0 +1,585 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import * as t from 'gql-ast';
|
|
3
|
+
import inflection from 'inflection';
|
|
4
|
+
import plz from 'pluralize';
|
|
5
|
+
import { getCustomAst, isIntervalType } from './custom-ast';
|
|
6
|
+
const isObject = val => val !== null && typeof val === 'object';
|
|
7
|
+
const NON_MUTABLE_PROPS = ['createdAt', 'createdBy', 'updatedAt', 'updatedBy'];
|
|
8
|
+
const objectToArray = (obj) => Object.keys(obj).map((k) => ({ name: k, ...obj[k] }));
|
|
9
|
+
const createGqlMutation = ({ operationName, mutationName, selectArgs, selections, variableDefinitions, modelName, useModel = true }) => {
|
|
10
|
+
const opSel = !modelName
|
|
11
|
+
? [
|
|
12
|
+
t.field({
|
|
13
|
+
name: operationName,
|
|
14
|
+
args: selectArgs,
|
|
15
|
+
selectionSet: t.selectionSet({ selections })
|
|
16
|
+
})
|
|
17
|
+
]
|
|
18
|
+
: [
|
|
19
|
+
t.field({
|
|
20
|
+
name: operationName,
|
|
21
|
+
args: selectArgs,
|
|
22
|
+
selectionSet: t.selectionSet({
|
|
23
|
+
selections: useModel
|
|
24
|
+
? [
|
|
25
|
+
t.field({
|
|
26
|
+
name: modelName,
|
|
27
|
+
selectionSet: t.selectionSet({ selections })
|
|
28
|
+
})
|
|
29
|
+
]
|
|
30
|
+
: selections
|
|
31
|
+
})
|
|
32
|
+
})
|
|
33
|
+
];
|
|
34
|
+
return t.document({
|
|
35
|
+
definitions: [
|
|
36
|
+
t.operationDefinition({
|
|
37
|
+
operation: 'mutation',
|
|
38
|
+
name: mutationName,
|
|
39
|
+
variableDefinitions,
|
|
40
|
+
selectionSet: t.selectionSet({ selections: opSel })
|
|
41
|
+
})
|
|
42
|
+
]
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
export const getAll = ({ queryName, operationName, query, selection }) => {
|
|
46
|
+
const selections = getSelections(selection);
|
|
47
|
+
const opSel = [
|
|
48
|
+
t.field({
|
|
49
|
+
name: operationName,
|
|
50
|
+
selectionSet: t.objectValue({
|
|
51
|
+
fields: [
|
|
52
|
+
t.field({
|
|
53
|
+
name: 'totalCount'
|
|
54
|
+
}),
|
|
55
|
+
t.field({
|
|
56
|
+
name: 'nodes',
|
|
57
|
+
selectionSet: t.selectionSet({ selections })
|
|
58
|
+
})
|
|
59
|
+
]
|
|
60
|
+
})
|
|
61
|
+
})
|
|
62
|
+
];
|
|
63
|
+
const ast = t.document({
|
|
64
|
+
definitions: [
|
|
65
|
+
t.operationDefinition({
|
|
66
|
+
operation: 'query',
|
|
67
|
+
name: queryName,
|
|
68
|
+
selectionSet: t.selectionSet({ selections: opSel })
|
|
69
|
+
})
|
|
70
|
+
]
|
|
71
|
+
});
|
|
72
|
+
return ast;
|
|
73
|
+
};
|
|
74
|
+
export const getMany = ({ builder, // we can use props here to enable pagination, etc
|
|
75
|
+
queryName, operationName, query, selection }) => {
|
|
76
|
+
const Singular = query.model;
|
|
77
|
+
const Plural = operationName.charAt(0).toUpperCase() + operationName.slice(1);
|
|
78
|
+
const Condition = `${Singular}Condition`;
|
|
79
|
+
const Filter = `${Singular}Filter`;
|
|
80
|
+
const OrderBy = `${Plural}OrderBy`;
|
|
81
|
+
const selections = getSelections(selection);
|
|
82
|
+
const ast = t.document({
|
|
83
|
+
definitions: [
|
|
84
|
+
t.operationDefinition({
|
|
85
|
+
operation: 'query',
|
|
86
|
+
name: queryName,
|
|
87
|
+
variableDefinitions: [
|
|
88
|
+
t.variableDefinition({
|
|
89
|
+
variable: t.variable({
|
|
90
|
+
name: 'first'
|
|
91
|
+
}),
|
|
92
|
+
type: t.namedType({
|
|
93
|
+
type: 'Int'
|
|
94
|
+
})
|
|
95
|
+
}),
|
|
96
|
+
t.variableDefinition({
|
|
97
|
+
variable: t.variable({
|
|
98
|
+
name: 'last'
|
|
99
|
+
}),
|
|
100
|
+
type: t.namedType({
|
|
101
|
+
type: 'Int'
|
|
102
|
+
})
|
|
103
|
+
}),
|
|
104
|
+
t.variableDefinition({
|
|
105
|
+
variable: t.variable({
|
|
106
|
+
name: 'after'
|
|
107
|
+
}),
|
|
108
|
+
type: t.namedType({
|
|
109
|
+
type: 'Cursor'
|
|
110
|
+
})
|
|
111
|
+
}),
|
|
112
|
+
t.variableDefinition({
|
|
113
|
+
variable: t.variable({
|
|
114
|
+
name: 'before'
|
|
115
|
+
}),
|
|
116
|
+
type: t.namedType({
|
|
117
|
+
type: 'Cursor'
|
|
118
|
+
})
|
|
119
|
+
}),
|
|
120
|
+
t.variableDefinition({
|
|
121
|
+
variable: t.variable({
|
|
122
|
+
name: 'offset'
|
|
123
|
+
}),
|
|
124
|
+
type: t.namedType({
|
|
125
|
+
type: 'Int'
|
|
126
|
+
})
|
|
127
|
+
}),
|
|
128
|
+
t.variableDefinition({
|
|
129
|
+
variable: t.variable({
|
|
130
|
+
name: 'condition'
|
|
131
|
+
}),
|
|
132
|
+
type: t.namedType({
|
|
133
|
+
type: Condition
|
|
134
|
+
})
|
|
135
|
+
}),
|
|
136
|
+
t.variableDefinition({
|
|
137
|
+
variable: t.variable({
|
|
138
|
+
name: 'filter'
|
|
139
|
+
}),
|
|
140
|
+
type: t.namedType({
|
|
141
|
+
type: Filter
|
|
142
|
+
})
|
|
143
|
+
}),
|
|
144
|
+
t.variableDefinition({
|
|
145
|
+
variable: t.variable({
|
|
146
|
+
name: 'orderBy'
|
|
147
|
+
}),
|
|
148
|
+
type: t.listType({
|
|
149
|
+
type: t.nonNullType({ type: t.namedType({ type: OrderBy }) })
|
|
150
|
+
})
|
|
151
|
+
})
|
|
152
|
+
],
|
|
153
|
+
selectionSet: t.selectionSet({
|
|
154
|
+
selections: [
|
|
155
|
+
t.field({
|
|
156
|
+
name: operationName,
|
|
157
|
+
args: [
|
|
158
|
+
t.argument({
|
|
159
|
+
name: 'first',
|
|
160
|
+
value: t.variable({
|
|
161
|
+
name: 'first'
|
|
162
|
+
})
|
|
163
|
+
}),
|
|
164
|
+
t.argument({
|
|
165
|
+
name: 'last',
|
|
166
|
+
value: t.variable({
|
|
167
|
+
name: 'last'
|
|
168
|
+
})
|
|
169
|
+
}),
|
|
170
|
+
t.argument({
|
|
171
|
+
name: 'offset',
|
|
172
|
+
value: t.variable({
|
|
173
|
+
name: 'offset'
|
|
174
|
+
})
|
|
175
|
+
}),
|
|
176
|
+
t.argument({
|
|
177
|
+
name: 'after',
|
|
178
|
+
value: t.variable({
|
|
179
|
+
name: 'after'
|
|
180
|
+
})
|
|
181
|
+
}),
|
|
182
|
+
t.argument({
|
|
183
|
+
name: 'before',
|
|
184
|
+
value: t.variable({
|
|
185
|
+
name: 'before'
|
|
186
|
+
})
|
|
187
|
+
}),
|
|
188
|
+
t.argument({
|
|
189
|
+
name: 'condition',
|
|
190
|
+
value: t.variable({
|
|
191
|
+
name: 'condition'
|
|
192
|
+
})
|
|
193
|
+
}),
|
|
194
|
+
t.argument({
|
|
195
|
+
name: 'filter',
|
|
196
|
+
value: t.variable({
|
|
197
|
+
name: 'filter'
|
|
198
|
+
})
|
|
199
|
+
}),
|
|
200
|
+
t.argument({
|
|
201
|
+
name: 'orderBy',
|
|
202
|
+
value: t.variable({
|
|
203
|
+
name: 'orderBy'
|
|
204
|
+
})
|
|
205
|
+
})
|
|
206
|
+
],
|
|
207
|
+
selectionSet: t.objectValue({
|
|
208
|
+
fields: [
|
|
209
|
+
t.field({
|
|
210
|
+
name: 'totalCount'
|
|
211
|
+
}),
|
|
212
|
+
t.field({
|
|
213
|
+
name: 'pageInfo',
|
|
214
|
+
selectionSet: t.selectionSet({
|
|
215
|
+
selections: [
|
|
216
|
+
t.field({ name: 'hasNextPage' }),
|
|
217
|
+
t.field({ name: 'hasPreviousPage' }),
|
|
218
|
+
t.field({ name: 'endCursor' }),
|
|
219
|
+
t.field({ name: 'startCursor' })
|
|
220
|
+
]
|
|
221
|
+
})
|
|
222
|
+
}),
|
|
223
|
+
builder._edges
|
|
224
|
+
? t.field({
|
|
225
|
+
name: 'edges',
|
|
226
|
+
selectionSet: t.selectionSet({
|
|
227
|
+
selections: [
|
|
228
|
+
t.field({ name: 'cursor' }),
|
|
229
|
+
t.field({
|
|
230
|
+
name: 'node',
|
|
231
|
+
selectionSet: t.selectionSet({ selections })
|
|
232
|
+
})
|
|
233
|
+
]
|
|
234
|
+
})
|
|
235
|
+
})
|
|
236
|
+
: t.field({
|
|
237
|
+
name: 'nodes',
|
|
238
|
+
selectionSet: t.selectionSet({
|
|
239
|
+
selections
|
|
240
|
+
})
|
|
241
|
+
})
|
|
242
|
+
]
|
|
243
|
+
})
|
|
244
|
+
})
|
|
245
|
+
]
|
|
246
|
+
})
|
|
247
|
+
})
|
|
248
|
+
]
|
|
249
|
+
});
|
|
250
|
+
return ast;
|
|
251
|
+
};
|
|
252
|
+
export const getOne = ({ builder, // we can use props here to enable pagination, etc
|
|
253
|
+
queryName, operationName, query, selection }) => {
|
|
254
|
+
const variableDefinitions = Object.keys(query.properties)
|
|
255
|
+
.map((key) => ({ name: key, ...query.properties[key] }))
|
|
256
|
+
.filter((field) => field.isNotNull)
|
|
257
|
+
.map((field) => {
|
|
258
|
+
const { name: fieldName, type: fieldType, isNotNull, isArray, isArrayNotNull } = field;
|
|
259
|
+
let type = t.namedType({ type: fieldType });
|
|
260
|
+
if (isNotNull)
|
|
261
|
+
type = t.nonNullType({ type });
|
|
262
|
+
if (isArray) {
|
|
263
|
+
type = t.listType({ type });
|
|
264
|
+
if (isArrayNotNull)
|
|
265
|
+
type = t.nonNullType({ type });
|
|
266
|
+
}
|
|
267
|
+
return t.variableDefinition({
|
|
268
|
+
variable: t.variable({ name: fieldName }),
|
|
269
|
+
type
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
const props = objectToArray(query.properties);
|
|
273
|
+
const selectArgs = props
|
|
274
|
+
.filter((field) => field.isNotNull)
|
|
275
|
+
.map((field) => {
|
|
276
|
+
return t.argument({
|
|
277
|
+
name: field.name,
|
|
278
|
+
value: t.variable({ name: field.name })
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
const selections = getSelections(selection);
|
|
282
|
+
const opSel = [
|
|
283
|
+
t.field({
|
|
284
|
+
name: operationName,
|
|
285
|
+
args: selectArgs,
|
|
286
|
+
selectionSet: t.selectionSet({ selections })
|
|
287
|
+
})
|
|
288
|
+
];
|
|
289
|
+
const ast = t.document({
|
|
290
|
+
definitions: [
|
|
291
|
+
t.operationDefinition({
|
|
292
|
+
operation: 'query',
|
|
293
|
+
name: queryName,
|
|
294
|
+
variableDefinitions,
|
|
295
|
+
selectionSet: t.selectionSet({ selections: opSel })
|
|
296
|
+
})
|
|
297
|
+
]
|
|
298
|
+
});
|
|
299
|
+
return ast;
|
|
300
|
+
};
|
|
301
|
+
export const createOne = ({ mutationName, operationName, mutation, selection }) => {
|
|
302
|
+
if (!mutation.properties?.input?.properties) {
|
|
303
|
+
console.log('no input field for mutation for' + mutationName);
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
const modelName = inflection.camelize([plz.singular(mutation.model)].join('_'), true);
|
|
307
|
+
const allAttrs = objectToArray(mutation.properties.input.properties[modelName].properties);
|
|
308
|
+
const attrs = allAttrs.filter((field) => !NON_MUTABLE_PROPS.includes(field.name));
|
|
309
|
+
const variableDefinitions = getCreateVariablesAst(attrs);
|
|
310
|
+
const selectArgs = [
|
|
311
|
+
t.argument({
|
|
312
|
+
name: 'input',
|
|
313
|
+
value: t.objectValue({
|
|
314
|
+
fields: [
|
|
315
|
+
t.objectField({
|
|
316
|
+
name: modelName,
|
|
317
|
+
value: t.objectValue({
|
|
318
|
+
fields: attrs.map((field) => t.objectField({
|
|
319
|
+
name: field.name,
|
|
320
|
+
value: t.variable({
|
|
321
|
+
name: field.name
|
|
322
|
+
})
|
|
323
|
+
}))
|
|
324
|
+
})
|
|
325
|
+
})
|
|
326
|
+
]
|
|
327
|
+
})
|
|
328
|
+
})
|
|
329
|
+
];
|
|
330
|
+
const selections = selection
|
|
331
|
+
? getSelections(selection)
|
|
332
|
+
: allAttrs.map((field) => t.field({ name: field.name }));
|
|
333
|
+
const ast = createGqlMutation({
|
|
334
|
+
operationName,
|
|
335
|
+
mutationName,
|
|
336
|
+
selectArgs,
|
|
337
|
+
selections,
|
|
338
|
+
variableDefinitions,
|
|
339
|
+
modelName
|
|
340
|
+
});
|
|
341
|
+
return ast;
|
|
342
|
+
};
|
|
343
|
+
export const patchOne = ({ mutationName, operationName, mutation, selection }) => {
|
|
344
|
+
if (!mutation.properties?.input?.properties) {
|
|
345
|
+
console.log('no input field for mutation for' + mutationName);
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
const modelName = inflection.camelize([plz.singular(mutation.model)].join('_'), true);
|
|
349
|
+
const allAttrs = objectToArray(mutation.properties.input.properties['patch']?.properties || {});
|
|
350
|
+
const patchAttrs = allAttrs.filter((prop) => !NON_MUTABLE_PROPS.includes(prop.name));
|
|
351
|
+
const patchByAttrs = objectToArray(mutation.properties.input.properties).filter((n) => n.name !== 'patch');
|
|
352
|
+
const patchers = patchByAttrs.map((p) => p.name);
|
|
353
|
+
const variableDefinitions = getUpdateVariablesAst(patchAttrs, patchers);
|
|
354
|
+
const selectArgs = [
|
|
355
|
+
t.argument({
|
|
356
|
+
name: 'input',
|
|
357
|
+
value: t.objectValue({
|
|
358
|
+
fields: [
|
|
359
|
+
...patchByAttrs.map((field) => t.objectField({
|
|
360
|
+
name: field.name,
|
|
361
|
+
value: t.variable({ name: field.name })
|
|
362
|
+
})),
|
|
363
|
+
t.objectField({
|
|
364
|
+
name: 'patch',
|
|
365
|
+
value: t.objectValue({
|
|
366
|
+
fields: patchAttrs
|
|
367
|
+
.filter((field) => !patchers.includes(field.name))
|
|
368
|
+
.map((field) => t.objectField({
|
|
369
|
+
name: field.name,
|
|
370
|
+
value: t.variable({
|
|
371
|
+
name: field.name
|
|
372
|
+
})
|
|
373
|
+
}))
|
|
374
|
+
})
|
|
375
|
+
})
|
|
376
|
+
]
|
|
377
|
+
})
|
|
378
|
+
})
|
|
379
|
+
];
|
|
380
|
+
const selections = selection
|
|
381
|
+
? getSelections(selection)
|
|
382
|
+
: allAttrs.map((field) => t.field({ name: field.name }));
|
|
383
|
+
const ast = createGqlMutation({
|
|
384
|
+
operationName,
|
|
385
|
+
mutationName,
|
|
386
|
+
selectArgs,
|
|
387
|
+
selections,
|
|
388
|
+
variableDefinitions,
|
|
389
|
+
modelName
|
|
390
|
+
});
|
|
391
|
+
return ast;
|
|
392
|
+
};
|
|
393
|
+
export const deleteOne = ({ mutationName, operationName, mutation }) => {
|
|
394
|
+
if (!mutation.properties?.input?.properties) {
|
|
395
|
+
console.log('no input field for mutation for' + mutationName);
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
const modelName = inflection.camelize([plz.singular(mutation.model)].join('_'), true);
|
|
399
|
+
const deleteAttrs = objectToArray(mutation.properties.input.properties);
|
|
400
|
+
const variableDefinitions = deleteAttrs.map((field) => {
|
|
401
|
+
const { name: fieldName, type: fieldType, isNotNull, isArray, isArrayNotNull } = field;
|
|
402
|
+
let type = t.namedType({ type: fieldType });
|
|
403
|
+
if (isNotNull)
|
|
404
|
+
type = t.nonNullType({ type });
|
|
405
|
+
if (isArray) {
|
|
406
|
+
type = t.listType({ type });
|
|
407
|
+
// no need to check isArrayNotNull since we need this field for deletion
|
|
408
|
+
type = t.nonNullType({ type });
|
|
409
|
+
}
|
|
410
|
+
return t.variableDefinition({
|
|
411
|
+
variable: t.variable({ name: fieldName }),
|
|
412
|
+
type
|
|
413
|
+
});
|
|
414
|
+
});
|
|
415
|
+
const selectArgs = [
|
|
416
|
+
t.argument({
|
|
417
|
+
name: 'input',
|
|
418
|
+
value: t.objectValue({
|
|
419
|
+
fields: deleteAttrs.map((f) => t.objectField({
|
|
420
|
+
name: f.name,
|
|
421
|
+
value: t.variable({ name: f.name })
|
|
422
|
+
}))
|
|
423
|
+
})
|
|
424
|
+
})
|
|
425
|
+
];
|
|
426
|
+
// so we can support column select grants plugin
|
|
427
|
+
const selections = [t.field({ name: 'clientMutationId' })];
|
|
428
|
+
const ast = createGqlMutation({
|
|
429
|
+
operationName,
|
|
430
|
+
mutationName,
|
|
431
|
+
selectArgs,
|
|
432
|
+
selections,
|
|
433
|
+
useModel: false,
|
|
434
|
+
variableDefinitions,
|
|
435
|
+
modelName
|
|
436
|
+
});
|
|
437
|
+
return ast;
|
|
438
|
+
};
|
|
439
|
+
export function getSelections(selection = []) {
|
|
440
|
+
const selectionAst = (field) => {
|
|
441
|
+
return typeof field === 'string'
|
|
442
|
+
? t.field({
|
|
443
|
+
name: field
|
|
444
|
+
})
|
|
445
|
+
: getCustomAst(field.fieldDefn);
|
|
446
|
+
};
|
|
447
|
+
return selection
|
|
448
|
+
.map((selectionDefn) => {
|
|
449
|
+
if (selectionDefn.isObject) {
|
|
450
|
+
const { name, selection, variables = {}, isBelongTo } = selectionDefn;
|
|
451
|
+
return t.field({
|
|
452
|
+
name,
|
|
453
|
+
args: Object.entries(variables).reduce((args, variable) => {
|
|
454
|
+
const [argName, argValue] = variable;
|
|
455
|
+
const argAst = t.argument({
|
|
456
|
+
name: argName,
|
|
457
|
+
value: getValueAst(argValue)
|
|
458
|
+
});
|
|
459
|
+
args = argAst ? [...args, argAst] : args;
|
|
460
|
+
return args;
|
|
461
|
+
}, []),
|
|
462
|
+
selectionSet: isBelongTo
|
|
463
|
+
? t.selectionSet({
|
|
464
|
+
selections: selection.map((field) => selectionAst(field))
|
|
465
|
+
})
|
|
466
|
+
: t.objectValue({
|
|
467
|
+
fields: [
|
|
468
|
+
t.field({
|
|
469
|
+
name: 'totalCount'
|
|
470
|
+
}),
|
|
471
|
+
t.field({
|
|
472
|
+
name: 'nodes',
|
|
473
|
+
selectionSet: t.selectionSet({
|
|
474
|
+
selections: selection.map((field) => selectionAst(field))
|
|
475
|
+
})
|
|
476
|
+
})
|
|
477
|
+
]
|
|
478
|
+
})
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
else {
|
|
482
|
+
const { fieldDefn } = selectionDefn;
|
|
483
|
+
// Field is not found in model meta, do nothing
|
|
484
|
+
if (!fieldDefn)
|
|
485
|
+
return null;
|
|
486
|
+
return getCustomAst(fieldDefn);
|
|
487
|
+
}
|
|
488
|
+
})
|
|
489
|
+
.filter(Boolean);
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* Get argument AST from a value
|
|
493
|
+
* @param {*} value
|
|
494
|
+
* @returns {Object} AST for the argument
|
|
495
|
+
*/
|
|
496
|
+
function getValueAst(value) {
|
|
497
|
+
if (value == null) {
|
|
498
|
+
return t.nullValue();
|
|
499
|
+
}
|
|
500
|
+
if (typeof value === 'number') {
|
|
501
|
+
return t.intValue({ value });
|
|
502
|
+
}
|
|
503
|
+
if (typeof value === 'string') {
|
|
504
|
+
return t.stringValue({ value });
|
|
505
|
+
}
|
|
506
|
+
if (typeof value === 'boolean') {
|
|
507
|
+
return t.booleanValue({ value });
|
|
508
|
+
}
|
|
509
|
+
if (Array.isArray(value)) {
|
|
510
|
+
return t.listValue({ values: value.map((v) => getValueAst(v)) });
|
|
511
|
+
}
|
|
512
|
+
if (isObject(value)) {
|
|
513
|
+
return t.objectValue({
|
|
514
|
+
fields: Object.entries(value).reduce((fields, entry) => {
|
|
515
|
+
const [objKey, objValue] = entry;
|
|
516
|
+
fields = [
|
|
517
|
+
...fields,
|
|
518
|
+
t.objectField({
|
|
519
|
+
name: objKey,
|
|
520
|
+
value: getValueAst(objValue)
|
|
521
|
+
})
|
|
522
|
+
];
|
|
523
|
+
return fields;
|
|
524
|
+
}, [])
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
const CustomInputTypes = {
|
|
529
|
+
interval: 'IntervalInput'
|
|
530
|
+
};
|
|
531
|
+
/**
|
|
532
|
+
* Get mutation variables AST from attributes array
|
|
533
|
+
* @param {Array} attrs
|
|
534
|
+
* @returns {Object} AST for the variables
|
|
535
|
+
*/
|
|
536
|
+
function getCreateVariablesAst(attrs) {
|
|
537
|
+
return attrs.map((field) => {
|
|
538
|
+
const { name: fieldName, type: fieldType, isNotNull, isArray, isArrayNotNull, properties } = field;
|
|
539
|
+
let type;
|
|
540
|
+
if (properties == null) {
|
|
541
|
+
type = t.namedType({ type: fieldType });
|
|
542
|
+
}
|
|
543
|
+
else if (isIntervalType(properties)) {
|
|
544
|
+
type = t.namedType({ type: CustomInputTypes.interval });
|
|
545
|
+
}
|
|
546
|
+
if (isNotNull)
|
|
547
|
+
type = t.nonNullType({ type });
|
|
548
|
+
if (isArray) {
|
|
549
|
+
type = t.listType({ type });
|
|
550
|
+
if (isArrayNotNull)
|
|
551
|
+
type = t.nonNullType({ type });
|
|
552
|
+
}
|
|
553
|
+
return t.variableDefinition({
|
|
554
|
+
variable: t.variable({ name: fieldName }),
|
|
555
|
+
type
|
|
556
|
+
});
|
|
557
|
+
});
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* Get mutation variables AST from attributes array
|
|
561
|
+
* @param {Array} attrs
|
|
562
|
+
* @returns {Object} AST for the variables
|
|
563
|
+
*/
|
|
564
|
+
function getUpdateVariablesAst(attrs, patchers) {
|
|
565
|
+
return attrs.map((field) => {
|
|
566
|
+
const { name: fieldName, type: fieldType, isNotNull, isArray, properties } = field;
|
|
567
|
+
let type;
|
|
568
|
+
if (properties == null) {
|
|
569
|
+
type = t.namedType({ type: fieldType });
|
|
570
|
+
}
|
|
571
|
+
else if (isIntervalType(properties)) {
|
|
572
|
+
type = t.namedType({ type: CustomInputTypes.interval });
|
|
573
|
+
}
|
|
574
|
+
if (isNotNull)
|
|
575
|
+
type = t.nonNullType({ type });
|
|
576
|
+
if (isArray)
|
|
577
|
+
type = t.listType({ type });
|
|
578
|
+
if (patchers.includes(field.name))
|
|
579
|
+
type = t.nonNullType({ type });
|
|
580
|
+
return t.variableDefinition({
|
|
581
|
+
variable: t.variable({ name: fieldName }),
|
|
582
|
+
type
|
|
583
|
+
});
|
|
584
|
+
});
|
|
585
|
+
}
|