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