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