@conduit-client/graphql-normalization 5.67.0-dev1

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.
Files changed (36) hide show
  1. package/dist/main/index.js +6 -0
  2. package/dist/main/index.js.map +1 -0
  3. package/dist/types/index.d.ts +0 -0
  4. package/dist/types/v1/__tests__/aura-normalized-cache-control-base.spec.d.ts +1 -0
  5. package/dist/types/v1/__tests__/aura-normalized-cache-control-connection.spec.d.ts +1 -0
  6. package/dist/types/v1/__tests__/aura-normalized-cache-control-directives.spec.d.ts +1 -0
  7. package/dist/types/v1/__tests__/aura-normalized-cache-control-fragments.spec.d.ts +1 -0
  8. package/dist/types/v1/__tests__/aura-normalized-cache-control-unidentifiable.spec.d.ts +1 -0
  9. package/dist/types/v1/__tests__/aura-normalized-cache-control-union.spec.d.ts +1 -0
  10. package/dist/types/v1/__tests__/connection-query-params.spec.d.ts +1 -0
  11. package/dist/types/v1/__tests__/directives.spec.d.ts +1 -0
  12. package/dist/types/v1/__tests__/identifiable-repository-cache-key-alias.spec.d.ts +1 -0
  13. package/dist/types/v1/__tests__/identifiable-repository-normalize-no-mutate.spec.d.ts +1 -0
  14. package/dist/types/v1/__tests__/query-augmentation.spec.d.ts +1 -0
  15. package/dist/types/v1/__tests__/selection-equality.spec.d.ts +1 -0
  16. package/dist/types/v1/__tests__/test-utils.d.ts +721 -0
  17. package/dist/types/v1/__tests__/utils.spec.d.ts +1 -0
  18. package/dist/types/v1/__tests__/value-extraction.spec.d.ts +1 -0
  19. package/dist/types/v1/base-object-repository.d.ts +29 -0
  20. package/dist/types/v1/cursor-connection-graphql-type-repository.d.ts +51 -0
  21. package/dist/types/v1/directives.d.ts +5 -0
  22. package/dist/types/v1/errors.d.ts +7 -0
  23. package/dist/types/v1/field-defs.d.ts +40 -0
  24. package/dist/types/v1/identifiable-object-repository.d.ts +34 -0
  25. package/dist/types/v1/index.d.ts +11 -0
  26. package/dist/types/v1/json-schema.d.ts +2 -0
  27. package/dist/types/v1/repository.d.ts +8 -0
  28. package/dist/types/v1/type-registry.d.ts +2 -0
  29. package/dist/types/v1/types.d.ts +52 -0
  30. package/dist/types/v1/unidentifiable-object-repository.d.ts +11 -0
  31. package/dist/types/v1/union-interface-repositories.d.ts +38 -0
  32. package/dist/types/v1/utils.d.ts +21 -0
  33. package/dist/types/v1/value-extraction.d.ts +61 -0
  34. package/dist/v1/index.js +1638 -0
  35. package/dist/v1/index.js.map +1 -0
  36. package/package.json +56 -0
@@ -0,0 +1,1638 @@
1
+ /*!
2
+ * Copyright (c) 2022, Salesforce, Inc.,
3
+ * All rights reserved.
4
+ * For full license text, see the LICENSE.txt file
5
+ */
6
+ import { buildReadWriteResult, extractReadWriteData, IdentifiableTypeRepository } from "@conduit-client/type-normalization/v1";
7
+ import { err, ok, stableJSONStringify, ObjectPrototypeHasOwnProperty, deepEquals } from "@conduit-client/utils";
8
+ import { Kind, visit } from "@conduit-client/onestore-graphql-parser/v1";
9
+ function extractValue(valueNode, variableDefinitions, expectedType) {
10
+ if (valueNode.kind === Kind.VARIABLE) {
11
+ const variableResult = extractVariableValue(valueNode.name.value, variableDefinitions);
12
+ if (variableResult.isErr()) {
13
+ return variableResult;
14
+ }
15
+ return validateExpectedType(variableResult.value, expectedType);
16
+ } else if (valueNode.kind === Kind.NULL) {
17
+ return validateExpectedType(null, expectedType);
18
+ } else if (valueNode.kind === Kind.LIST) {
19
+ const values = [];
20
+ for (const val of valueNode.values) {
21
+ const extractedResult = extractValue(val, variableDefinitions);
22
+ if (extractedResult.isErr()) {
23
+ return extractedResult;
24
+ }
25
+ values.push(extractedResult.value);
26
+ }
27
+ return validateExpectedType(values, expectedType);
28
+ } else if (valueNode.kind === Kind.OBJECT) {
29
+ const value = {};
30
+ for (const field of valueNode.fields) {
31
+ const extractedResult = extractValue(field.value, variableDefinitions);
32
+ if (extractedResult.isErr()) {
33
+ return extractedResult;
34
+ }
35
+ value[field.name.value] = extractedResult.value;
36
+ }
37
+ return validateExpectedType(value, expectedType);
38
+ } else if (valueNode.kind === Kind.INT) {
39
+ const value = parseInt(valueNode.value, 10);
40
+ return validateExpectedType(value, expectedType);
41
+ } else if (valueNode.kind === Kind.FLOAT) {
42
+ const value = parseFloat(valueNode.value);
43
+ return validateExpectedType(value, expectedType);
44
+ } else {
45
+ const value = valueNode.value;
46
+ return validateExpectedType(value, expectedType);
47
+ }
48
+ }
49
+ function extractVariableValue(variableName, variableDefinitions) {
50
+ const variable = variableDefinitions[variableName];
51
+ if (!variable) {
52
+ return err(
53
+ new Error(`Variable '${variableName}' was used in the query but was not defined`)
54
+ );
55
+ }
56
+ if (variable.value !== void 0) {
57
+ return ok(variable.value);
58
+ }
59
+ if (variable.definition.defaultValue) {
60
+ return extractValue(variable.definition.defaultValue, variableDefinitions);
61
+ }
62
+ return ok(void 0);
63
+ }
64
+ function validateExpectedType(value, expectedType) {
65
+ if (!expectedType) {
66
+ return ok(value);
67
+ }
68
+ if (value === null) {
69
+ if (expectedType.nullable) {
70
+ return ok(value);
71
+ } else {
72
+ return err(new Error(`Expected ${expectedType.type}, but got null`));
73
+ }
74
+ }
75
+ const actualType = typeof value;
76
+ if (actualType === expectedType.type) {
77
+ return ok(value);
78
+ }
79
+ const expectedTypeString = expectedType.nullable ? `${expectedType.type} | null` : expectedType.type;
80
+ return err(
81
+ new Error(`Expected ${expectedTypeString}, but got ${actualType}: ${JSON.stringify(value)}`)
82
+ );
83
+ }
84
+ function deepMerge(target, ...sources) {
85
+ for (const source of sources) {
86
+ for (const key in source) {
87
+ if (ObjectPrototypeHasOwnProperty.call(source, key)) {
88
+ const targetValue = target[key];
89
+ const sourceValue = source[key];
90
+ if (Array.isArray(targetValue) && Array.isArray(sourceValue)) {
91
+ const length = sourceValue.length;
92
+ target[key] = Array.from({ length }, (_, index) => {
93
+ const targetItem = targetValue[index];
94
+ const sourceItem = sourceValue[index];
95
+ if (targetItem === void 0) {
96
+ return sourceItem;
97
+ } else if (sourceItem === void 0) {
98
+ return targetItem;
99
+ } else if (targetItem instanceof Object && !Array.isArray(targetItem) && sourceItem instanceof Object && !Array.isArray(sourceItem)) {
100
+ return deepMerge({}, targetItem, sourceItem);
101
+ } else {
102
+ return sourceItem;
103
+ }
104
+ });
105
+ } else if (targetValue instanceof Object && !Array.isArray(targetValue) && sourceValue instanceof Object && !Array.isArray(sourceValue)) {
106
+ deepMerge(
107
+ targetValue,
108
+ sourceValue
109
+ );
110
+ } else {
111
+ target[key] = sourceValue;
112
+ }
113
+ }
114
+ }
115
+ }
116
+ return target;
117
+ }
118
+ function findExecutableOperation(input) {
119
+ const operations = input.query.definitions.filter(
120
+ (def) => def.kind === Kind.OPERATION_DEFINITION
121
+ );
122
+ if (operations.length === 0) {
123
+ return err(new Error("No operations found in query"));
124
+ }
125
+ if (operations.length === 1 && !input.operationName) {
126
+ return ok(operations[0]);
127
+ }
128
+ if (input.operationName) {
129
+ const specifiedOperation = operations.find((op) => {
130
+ var _a;
131
+ return ((_a = op.name) == null ? void 0 : _a.value) === input.operationName;
132
+ });
133
+ if (specifiedOperation) {
134
+ return ok(specifiedOperation);
135
+ }
136
+ return err(new Error(`Operation "${input.operationName}" not found in query`));
137
+ }
138
+ return err(new Error("Multiple operations found in query, and no operation name provided"));
139
+ }
140
+ function buildGraphQLInputExtension(input) {
141
+ const operationResult = findExecutableOperation(input);
142
+ if (operationResult.isErr()) {
143
+ return err(operationResult.error);
144
+ }
145
+ const operation = operationResult.value;
146
+ const selections = operation.selectionSet.selections;
147
+ const variableDefinitions = operation.variableDefinitions;
148
+ const variables = (variableDefinitions == null ? void 0 : variableDefinitions.reduce((prev, def) => {
149
+ var _a;
150
+ prev[def.variable.name.value] = {
151
+ definition: def,
152
+ value: (_a = input.variables) == null ? void 0 : _a[def.variable.name.value]
153
+ };
154
+ return prev;
155
+ }, {})) || {};
156
+ const fragments = input.query.definitions.filter(isFragmentDefinition).reduce((prev, fragment) => {
157
+ prev[fragment.name.value] = fragment;
158
+ return prev;
159
+ }, {});
160
+ return ok({
161
+ selections,
162
+ request: { definitions: { variables, fragments } },
163
+ parentFieldSelection: void 0
164
+ });
165
+ }
166
+ function buildAugmentedFieldSelection(newSelection, selections, fragments) {
167
+ var _a;
168
+ if (selectionExists(newSelection, selections)) {
169
+ return void 0;
170
+ }
171
+ const baseAlias = ((_a = newSelection.alias) == null ? void 0 : _a.value) || newSelection.name.value;
172
+ const baseInjectedAlias = `framework_augmented_${baseAlias}`;
173
+ const baseAliasedSelection = {
174
+ ...newSelection,
175
+ alias: {
176
+ kind: Kind.NAME,
177
+ value: baseInjectedAlias
178
+ }
179
+ };
180
+ if (selectionExists(baseAliasedSelection, selections)) {
181
+ return void 0;
182
+ }
183
+ const fieldName = getUniqueSelectionName(baseInjectedAlias, selections, fragments);
184
+ return {
185
+ ...newSelection,
186
+ alias: {
187
+ kind: Kind.NAME,
188
+ value: fieldName
189
+ }
190
+ };
191
+ }
192
+ function selectionExists(selection, selections) {
193
+ return selections.some((s) => selectionEquals(selection, s));
194
+ }
195
+ function selectionEquals(a, b) {
196
+ var _a, _b, _c, _d, _e, _f;
197
+ if (a.kind !== b.kind) {
198
+ return false;
199
+ }
200
+ if (a.kind === Kind.FIELD) {
201
+ const bField = b;
202
+ return !!(a.name.value === bField.name.value) && !!(((_a = a.alias) == null ? void 0 : _a.value) === ((_b = bField.alias) == null ? void 0 : _b.value)) && argumentsEqual(a.arguments, bField.arguments) && selectionSetsEqual((_c = a.selectionSet) == null ? void 0 : _c.selections, (_d = bField.selectionSet) == null ? void 0 : _d.selections) && directivesEqual(a.directives, bField.directives);
203
+ }
204
+ if (a.kind === Kind.FRAGMENT_SPREAD) {
205
+ const bFragmentSpread = b;
206
+ return a.name.value === bFragmentSpread.name.value && directivesEqual(a.directives, bFragmentSpread.directives);
207
+ }
208
+ const bInlineFragment = b;
209
+ return a.typeCondition === bInlineFragment.typeCondition && directivesEqual(a.directives, bInlineFragment.directives) && selectionSetsEqual((_e = a.selectionSet) == null ? void 0 : _e.selections, (_f = bInlineFragment.selectionSet) == null ? void 0 : _f.selections);
210
+ }
211
+ function argumentValueEquals(a, b) {
212
+ if (a.kind !== b.kind) {
213
+ return false;
214
+ }
215
+ switch (a.kind) {
216
+ case Kind.STRING:
217
+ case Kind.INT:
218
+ case Kind.FLOAT:
219
+ case Kind.BOOLEAN:
220
+ case Kind.ENUM:
221
+ return a.value === b.value;
222
+ case Kind.NULL:
223
+ return true;
224
+ case Kind.VARIABLE:
225
+ return a.name.value === b.name.value;
226
+ case Kind.LIST:
227
+ const bList = b;
228
+ if (a.values.length !== bList.values.length) {
229
+ return false;
230
+ }
231
+ return a.values.every((val, index) => argumentValueEquals(val, bList.values[index]));
232
+ case Kind.OBJECT:
233
+ const bObject = b;
234
+ if (a.fields.length !== bObject.fields.length) {
235
+ return false;
236
+ }
237
+ return a.fields.every((field, index) => {
238
+ const bField = bObject.fields[index];
239
+ return field.name.value === bField.name.value && argumentValueEquals(field.value, bField.value);
240
+ });
241
+ default:
242
+ return false;
243
+ }
244
+ }
245
+ function directivesEqual(a, b) {
246
+ if (a === void 0 && b === void 0) {
247
+ return true;
248
+ }
249
+ if (a === void 0 || b === void 0) {
250
+ return ((a == null ? void 0 : a.length) || 0) === ((b == null ? void 0 : b.length) || 0);
251
+ }
252
+ if (a.length !== b.length) {
253
+ return false;
254
+ }
255
+ return a.every((directive, index) => {
256
+ const bDirective = b[index];
257
+ return directive.name.value === bDirective.name.value && argumentsEqual(directive.arguments, bDirective.arguments);
258
+ });
259
+ }
260
+ function argumentsEqual(a, b) {
261
+ if (a === void 0 && b === void 0) {
262
+ return true;
263
+ }
264
+ if (a === void 0 || b === void 0) {
265
+ return ((a == null ? void 0 : a.length) || 0) === ((b == null ? void 0 : b.length) || 0);
266
+ }
267
+ if (a.length !== b.length) {
268
+ return false;
269
+ }
270
+ return a.every((arg, index) => {
271
+ const bArg = b[index];
272
+ return arg.name.value === bArg.name.value && argumentValueEquals(arg.value, bArg.value);
273
+ });
274
+ }
275
+ function selectionSetsEqual(a, b) {
276
+ return a === void 0 || b === void 0 || !!(a.length === b.length) && !!a.every((selection, index) => {
277
+ return selectionEquals(selection, b[index]);
278
+ });
279
+ }
280
+ function getUniqueSelectionName(fieldName, selections, fragments) {
281
+ const fieldNames = collectFieldNames(selections, fragments);
282
+ if (!fieldNames.includes(fieldName)) {
283
+ return fieldName;
284
+ }
285
+ let i = 1;
286
+ while (fieldNames.includes(`${fieldName}_${i}`)) {
287
+ i++;
288
+ }
289
+ return `${fieldName}_${i}`;
290
+ }
291
+ function collectFieldNames(selections, fragments) {
292
+ var _a;
293
+ const fieldNames = /* @__PURE__ */ new Set();
294
+ for (const selection of selections) {
295
+ if (isField(selection)) {
296
+ fieldNames.add(((_a = selection.alias) == null ? void 0 : _a.value) || selection.name.value);
297
+ } else if (isInlineFragment(selection)) {
298
+ collectFieldNames(
299
+ selection.selectionSet.selections,
300
+ fragments
301
+ ).forEach((name) => fieldNames.add(name));
302
+ } else if (isFragmentSpread(selection)) {
303
+ const fragment = fragments[selection.name.value];
304
+ if (fragment) {
305
+ collectFieldNames(
306
+ fragment.selectionSet.selections,
307
+ fragments
308
+ ).forEach((name) => fieldNames.add(name));
309
+ }
310
+ }
311
+ }
312
+ return Array.from(fieldNames);
313
+ }
314
+ function buildFieldKey(canonicalFieldName, fieldArguments, variables) {
315
+ if (fieldArguments === void 0 || fieldArguments.length === 0) {
316
+ return ok(canonicalFieldName);
317
+ }
318
+ const formattedArguments = {};
319
+ for (const arg of fieldArguments) {
320
+ const result = extractValue(arg.value, variables);
321
+ if (result.isErr()) {
322
+ return err(
323
+ new Error(
324
+ `Failed to extract argument '${arg.name.value}' for field '${canonicalFieldName}': ${result.error.message}`
325
+ )
326
+ );
327
+ }
328
+ formattedArguments[arg.name.value] = result.value;
329
+ }
330
+ return ok(`${canonicalFieldName}::${stableJSONStringify({ args: formattedArguments })}`);
331
+ }
332
+ const TYPENAME_FIELD = {
333
+ kind: Kind.FIELD,
334
+ name: {
335
+ kind: Kind.NAME,
336
+ value: "__typename"
337
+ }
338
+ };
339
+ function addTypenameToDocument(doc) {
340
+ return visit(doc, {
341
+ SelectionSet: {
342
+ enter(node, _key, parent) {
343
+ if (isOperationDefinition(parent)) {
344
+ return;
345
+ }
346
+ const { selections } = node;
347
+ if (!selections || selections.length === 0) {
348
+ return;
349
+ }
350
+ const skip = selections.some((selection) => {
351
+ return isField(selection) && (selection.name.value === "__typename" || selection.name.value.lastIndexOf("__", 0) === 0);
352
+ });
353
+ if (skip) {
354
+ return;
355
+ }
356
+ return {
357
+ ...node,
358
+ selections: [...selections, TYPENAME_FIELD]
359
+ };
360
+ }
361
+ }
362
+ });
363
+ }
364
+ function isOperationDefinition(parent) {
365
+ return !!parent && !Array.isArray(parent) && parent.kind === Kind.OPERATION_DEFINITION;
366
+ }
367
+ function isField(node) {
368
+ return node.kind === Kind.FIELD;
369
+ }
370
+ function isFragmentSpread(node) {
371
+ return node.kind === Kind.FRAGMENT_SPREAD;
372
+ }
373
+ function isInlineFragment(node) {
374
+ return node.kind === Kind.INLINE_FRAGMENT;
375
+ }
376
+ function isFragmentDefinition(node) {
377
+ return node.kind === Kind.FRAGMENT_DEFINITION;
378
+ }
379
+ function extractIfArgument(directive, variables, directiveName) {
380
+ var _a;
381
+ const ifArg = (_a = directive.arguments) == null ? void 0 : _a.find((arg) => arg.name.value === "if");
382
+ if (!ifArg) {
383
+ return err(new Error(`@${directiveName} directive requires an 'if' argument`));
384
+ }
385
+ const result = extractValue(ifArg.value, variables, { type: "boolean", nullable: false });
386
+ if (result.isErr()) {
387
+ return err(result.error);
388
+ }
389
+ return ok(result.value);
390
+ }
391
+ function shouldSkip(selection, variables) {
392
+ if (!selection.directives || selection.directives.length === 0) {
393
+ return ok(false);
394
+ }
395
+ for (const directive of selection.directives) {
396
+ if (directive.name.value === "skip") {
397
+ const ifResult = extractIfArgument(directive, variables, "skip");
398
+ if (ifResult.isErr()) {
399
+ return ifResult;
400
+ }
401
+ if (ifResult.value === true) {
402
+ return ok(true);
403
+ }
404
+ }
405
+ if (directive.name.value === "include") {
406
+ const ifResult = extractIfArgument(directive, variables, "include");
407
+ if (ifResult.isErr()) {
408
+ return ifResult;
409
+ }
410
+ if (ifResult.value === false) {
411
+ return ok(true);
412
+ }
413
+ }
414
+ }
415
+ return ok(false);
416
+ }
417
+ class BaseScalarFieldDef {
418
+ constructor(nullable) {
419
+ this.nullable = nullable;
420
+ }
421
+ write(_cache, input) {
422
+ if (input.data === void 0) {
423
+ return ok({ type: "missing" });
424
+ }
425
+ if (input.data === null) {
426
+ if (!this.nullable) {
427
+ return err([
428
+ {
429
+ type: "unknown",
430
+ error: new Error(
431
+ `Got a null value for non-nullable field "${input.selection.name.value}"`
432
+ )
433
+ }
434
+ ]);
435
+ }
436
+ }
437
+ return ok({ type: "data", data: input.data });
438
+ }
439
+ read(_cache, input) {
440
+ const normalizedData = input.normalizedData;
441
+ if (normalizedData.type === "missing") {
442
+ return ok(void 0);
443
+ }
444
+ return ok(normalizedData.data);
445
+ }
446
+ augmentSelections(input) {
447
+ return input;
448
+ }
449
+ buildFieldKey(selection, variables) {
450
+ return buildFieldKey(selection.name.value, selection.arguments, variables);
451
+ }
452
+ }
453
+ class BaseArrayFieldDef {
454
+ constructor(items, nullable) {
455
+ this.items = items;
456
+ this.nullable = nullable;
457
+ }
458
+ augmentSelections(input) {
459
+ return this.items.augmentSelections(input);
460
+ }
461
+ buildFieldKey(selection, variables) {
462
+ return this.items.buildFieldKey(selection, variables);
463
+ }
464
+ write(cache, input) {
465
+ if (input.data === void 0) {
466
+ return ok({ type: "missing" });
467
+ }
468
+ if (input.data === null) {
469
+ if (!this.nullable) {
470
+ return err([
471
+ {
472
+ type: "unknown",
473
+ error: new Error(
474
+ `Got a null value for non-nullable field "${input.selection.name.value}"`
475
+ )
476
+ }
477
+ ]);
478
+ }
479
+ return ok({ type: "data", data: input.data });
480
+ }
481
+ if (!Array.isArray(input.data)) {
482
+ return err([
483
+ {
484
+ type: "unknown",
485
+ error: new Error(
486
+ `Got a non array value for array field "${input.selection.name.value}"`
487
+ )
488
+ }
489
+ ]);
490
+ }
491
+ const arrayNormalizationErrors = [];
492
+ const normalizedArray = [];
493
+ input.data.forEach((item, index) => {
494
+ var _a;
495
+ const existingItemData = (_a = input.existingNormalizedData) == null ? void 0 : _a[index];
496
+ const normalizedItemResult = this.items.write(cache, {
497
+ ...input,
498
+ data: item,
499
+ existingNormalizedData: existingItemData,
500
+ request: input.request,
501
+ selection: input.selection
502
+ });
503
+ if (normalizedItemResult.isOk()) {
504
+ normalizedArray.push(normalizedItemResult.value);
505
+ } else {
506
+ arrayNormalizationErrors.push(...normalizedItemResult.error);
507
+ }
508
+ });
509
+ if (arrayNormalizationErrors.length > 0) {
510
+ return err(arrayNormalizationErrors);
511
+ }
512
+ return ok({ type: "data", data: normalizedArray });
513
+ }
514
+ read(cache, input) {
515
+ const normalizedData = input.normalizedData;
516
+ if (normalizedData.type === "missing") {
517
+ return ok(void 0);
518
+ }
519
+ if (normalizedData.data === null) {
520
+ if (!this.nullable) {
521
+ return err([
522
+ {
523
+ type: "unknown",
524
+ error: new Error(
525
+ `Got a null value for non-nullable field "${input.selection.name.value}"`
526
+ )
527
+ }
528
+ ]);
529
+ }
530
+ return ok({ type: "data", data: null });
531
+ }
532
+ if (!Array.isArray(normalizedData.data)) {
533
+ return err([
534
+ {
535
+ type: "unknown",
536
+ error: new Error(
537
+ `Got a non array value for array field "${input.selection.name.value}"`
538
+ )
539
+ }
540
+ ]);
541
+ }
542
+ const arrayDenormalizationErrors = [];
543
+ const denormalizedArray = [];
544
+ normalizedData.data.forEach((item) => {
545
+ const denormalizedItemResult = this.items.read(cache, {
546
+ ...input,
547
+ normalizedData: item,
548
+ request: input.request,
549
+ selection: input.selection
550
+ });
551
+ if (denormalizedItemResult.isOk()) {
552
+ denormalizedArray.push(denormalizedItemResult.value);
553
+ } else {
554
+ arrayDenormalizationErrors.push(...denormalizedItemResult.error);
555
+ }
556
+ });
557
+ if (arrayDenormalizationErrors.length > 0) {
558
+ return err(arrayDenormalizationErrors);
559
+ }
560
+ return ok(denormalizedArray);
561
+ }
562
+ }
563
+ class BaseObjectFieldDef {
564
+ constructor(repository, nullable) {
565
+ this.repository = repository;
566
+ this.nullable = nullable;
567
+ }
568
+ augmentSelections(input) {
569
+ return this.repository.augmentSelections(input);
570
+ }
571
+ buildFieldKey(selection, variables) {
572
+ return this.repository.buildFieldKey(selection, variables);
573
+ }
574
+ write(cache, input) {
575
+ var _a;
576
+ if (!input.selection.selectionSet) {
577
+ return err([
578
+ {
579
+ type: "unknown",
580
+ error: new Error(
581
+ `Selection set required for object type found on field "${input.selection.name.value}" in type ${this.repository.typeName}`
582
+ )
583
+ }
584
+ ]);
585
+ }
586
+ if (input.data === void 0) {
587
+ return ok({ type: "missing" });
588
+ }
589
+ if (input.data === null) {
590
+ if (!this.nullable) {
591
+ return err([
592
+ {
593
+ type: "unknown",
594
+ error: new Error(
595
+ `Got a null value for non-nullable field "${input.selection.name.value}"`
596
+ )
597
+ }
598
+ ]);
599
+ }
600
+ return ok({ type: "data", data: null });
601
+ }
602
+ const writeResult = this.repository.write(cache, {
603
+ ...input,
604
+ data: input.data,
605
+ existingNormalizedData: (_a = input.existingNormalizedData) == null ? void 0 : _a.data,
606
+ request: input.request,
607
+ selections: input.selection.selectionSet.selections,
608
+ parentFieldSelection: input.selection
609
+ });
610
+ if (writeResult.isErr()) {
611
+ return writeResult;
612
+ }
613
+ return ok({ type: "data", data: writeResult.value });
614
+ }
615
+ read(cache, input) {
616
+ var _a;
617
+ if (!input.selection.selectionSet) {
618
+ return err([
619
+ {
620
+ type: "unknown",
621
+ error: new Error(
622
+ `Selection set required for object type found on field "${input.selection.name.value}" in type ${this.repository.typeName}`
623
+ )
624
+ }
625
+ ]);
626
+ }
627
+ const normalizedData = input.normalizedData;
628
+ if (normalizedData.type === "missing") {
629
+ return ok(void 0);
630
+ }
631
+ if (normalizedData.data === null) {
632
+ if (!this.nullable) {
633
+ return err([
634
+ {
635
+ type: "unknown",
636
+ error: new Error(
637
+ `Got a null value for non-nullable field "${input.selection.name.value}"`
638
+ )
639
+ }
640
+ ]);
641
+ }
642
+ return ok(null);
643
+ }
644
+ return this.repository.read(cache, {
645
+ ...input,
646
+ normalizedData: normalizedData.data,
647
+ request: input.request,
648
+ selections: (_a = input.selection.selectionSet) == null ? void 0 : _a.selections,
649
+ parentFieldSelection: input.selection
650
+ });
651
+ }
652
+ }
653
+ const missingFieldDef = new BaseScalarFieldDef(false);
654
+ class BaseGraphQLTypeRepository {
655
+ equals(x, y) {
656
+ return deepEquals(x, y);
657
+ }
658
+ augmentSelections(input) {
659
+ const augmentedSelections = [];
660
+ let augmentedFragments = { ...input.fragments };
661
+ for (const selection of input.selections) {
662
+ if (isField(selection)) {
663
+ const result = this.augmentFieldSelection(selection, augmentedFragments);
664
+ augmentedSelections.push(...result.selections);
665
+ augmentedFragments = result.fragments;
666
+ } else if (isInlineFragment(selection)) {
667
+ const augmentedFragmentSelections = this.augmentInlineFragmentSelection(
668
+ selection,
669
+ augmentedFragments
670
+ );
671
+ augmentedSelections.push(...augmentedFragmentSelections.selections);
672
+ augmentedFragments = augmentedFragmentSelections.fragments;
673
+ } else {
674
+ const augmentedFragmentSelections = this.augmentFragmentSpreadSelection(
675
+ selection,
676
+ augmentedFragments
677
+ );
678
+ augmentedSelections.push(...augmentedFragmentSelections.selections);
679
+ augmentedFragments = augmentedFragmentSelections.fragments;
680
+ }
681
+ }
682
+ const newTypenameSelection = buildAugmentedFieldSelection(
683
+ {
684
+ kind: Kind.FIELD,
685
+ name: {
686
+ kind: Kind.NAME,
687
+ value: "__typename"
688
+ }
689
+ },
690
+ [...augmentedSelections, ...input.selections],
691
+ augmentedFragments
692
+ );
693
+ if (newTypenameSelection) {
694
+ augmentedSelections.push(newTypenameSelection);
695
+ }
696
+ return { selections: augmentedSelections, fragments: augmentedFragments };
697
+ }
698
+ augmentFieldSelection(selection, fragments) {
699
+ var _a;
700
+ const field = this.getFieldDef(void 0, selection);
701
+ if (field === void 0) {
702
+ return { selections: [selection], fragments };
703
+ }
704
+ const result = field.augmentSelections({
705
+ selections: ((_a = selection.selectionSet) == null ? void 0 : _a.selections) || [],
706
+ fragments
707
+ });
708
+ return {
709
+ selections: [
710
+ {
711
+ ...selection,
712
+ selectionSet: {
713
+ kind: Kind.SELECTION_SET,
714
+ selections: result.selections
715
+ }
716
+ }
717
+ ],
718
+ fragments: result.fragments
719
+ };
720
+ }
721
+ augmentInlineFragmentSelection(fragment, fragments) {
722
+ var _a;
723
+ const satisfiedFragmentTypeConditionResult = this.satisfiesFragmentTypeCondition(
724
+ void 0,
725
+ fragment
726
+ );
727
+ if (satisfiedFragmentTypeConditionResult.isErr() || !satisfiedFragmentTypeConditionResult.value) {
728
+ return { selections: [], fragments };
729
+ }
730
+ const augmentedFragmentSelections = this.augmentSelections({
731
+ selections: ((_a = fragment.selectionSet) == null ? void 0 : _a.selections) || [],
732
+ fragments
733
+ });
734
+ return {
735
+ selections: [
736
+ {
737
+ ...fragment,
738
+ selectionSet: {
739
+ kind: Kind.SELECTION_SET,
740
+ selections: augmentedFragmentSelections.selections
741
+ }
742
+ }
743
+ ],
744
+ fragments: augmentedFragmentSelections.fragments
745
+ };
746
+ }
747
+ augmentFragmentSpreadSelection(selection, fragments) {
748
+ var _a;
749
+ const fragment = fragments[selection.name.value];
750
+ if (fragment === void 0) {
751
+ return { selections: [selection], fragments };
752
+ }
753
+ const satisfiedFragmentTypeConditionResult = this.satisfiesFragmentTypeCondition(
754
+ void 0,
755
+ fragment
756
+ );
757
+ if (satisfiedFragmentTypeConditionResult.isErr() || !satisfiedFragmentTypeConditionResult.value) {
758
+ return { selections: [selection], fragments };
759
+ }
760
+ const augmentedFragment = this.augmentSelections({
761
+ selections: ((_a = fragment.selectionSet) == null ? void 0 : _a.selections) || [],
762
+ fragments
763
+ });
764
+ return {
765
+ selections: [selection],
766
+ fragments: {
767
+ ...augmentedFragment.fragments,
768
+ [fragment.name.value]: {
769
+ ...fragment,
770
+ selectionSet: {
771
+ kind: Kind.SELECTION_SET,
772
+ selections: augmentedFragment.selections
773
+ }
774
+ }
775
+ }
776
+ };
777
+ }
778
+ normalizeSelections(cache, input) {
779
+ const normalized = {};
780
+ const errors = [];
781
+ for (const selection of input.selections) {
782
+ if (isField(selection)) {
783
+ deepMerge(
784
+ normalized,
785
+ this.normalizeFieldSelection(cache, input, selection, errors)
786
+ );
787
+ } else {
788
+ let fragment;
789
+ if (isInlineFragment(selection)) {
790
+ fragment = selection;
791
+ } else {
792
+ const fragmentDefinition = input.request.definitions.fragments[selection.name.value];
793
+ if (fragmentDefinition === void 0) {
794
+ continue;
795
+ }
796
+ fragment = {
797
+ ...fragmentDefinition,
798
+ directives: [
799
+ ...selection.directives || [],
800
+ ...fragmentDefinition.directives || []
801
+ ]
802
+ };
803
+ }
804
+ deepMerge(normalized, this.normalizeFragment(cache, input, fragment, errors));
805
+ }
806
+ }
807
+ return buildReadWriteResult(normalized, errors);
808
+ }
809
+ normalizeFieldSelection(cache, input, selection, errorCollector) {
810
+ var _a;
811
+ const canonicalFieldName = selection.name.value;
812
+ const dataInstanceFieldName = ((_a = selection.alias) == null ? void 0 : _a.value) ?? selection.name.value;
813
+ const value = input.data[dataInstanceFieldName];
814
+ const fieldDef = this.getFieldDef(input, selection);
815
+ if (!fieldDef) {
816
+ errorCollector.push({
817
+ type: "unknown",
818
+ error: new Error(
819
+ `GraphQL query requests unknown field "${canonicalFieldName}" on type "${this.typeName}". Expected one of fields ${Object.keys(this.fields)}.`
820
+ )
821
+ });
822
+ return {};
823
+ }
824
+ const shouldSkipResult = shouldSkip(selection, input.request.definitions.variables);
825
+ if (shouldSkipResult.isErr()) {
826
+ errorCollector.push({
827
+ type: "unknown",
828
+ error: shouldSkipResult.error
829
+ });
830
+ return {};
831
+ }
832
+ if (shouldSkipResult.value) {
833
+ return {};
834
+ }
835
+ const existingFieldDataResult = this.getNormalizedFieldData(selection, input);
836
+ if (existingFieldDataResult.isErr()) {
837
+ errorCollector.push({
838
+ type: "unknown",
839
+ error: existingFieldDataResult.error
840
+ });
841
+ return {};
842
+ }
843
+ const existingFieldData = existingFieldDataResult.value;
844
+ const cacheFieldKeyResult = fieldDef.buildFieldKey(
845
+ selection,
846
+ input.request.definitions.variables
847
+ );
848
+ if (cacheFieldKeyResult.isErr()) {
849
+ errorCollector.push({
850
+ type: "unknown",
851
+ error: cacheFieldKeyResult.error
852
+ });
853
+ return {};
854
+ }
855
+ const cacheFieldKey = cacheFieldKeyResult.value;
856
+ return {
857
+ [cacheFieldKey]: extractReadWriteData(
858
+ fieldDef.write(cache, {
859
+ ...input,
860
+ data: value,
861
+ existingNormalizedData: existingFieldData,
862
+ request: input.request,
863
+ selection
864
+ }),
865
+ errorCollector
866
+ )
867
+ };
868
+ }
869
+ normalizeFragment(cache, input, fragment, errorCollector) {
870
+ const shouldProcessResult = this.shouldProcessFragment(input, fragment);
871
+ if (shouldProcessResult.isErr()) {
872
+ errorCollector.push({
873
+ type: "unknown",
874
+ error: shouldProcessResult.error
875
+ });
876
+ return {};
877
+ }
878
+ if (shouldProcessResult.value) {
879
+ return extractReadWriteData(
880
+ this.normalizeSelections(cache, {
881
+ ...input,
882
+ selections: fragment.selectionSet.selections
883
+ // readonly casting, todo
884
+ }),
885
+ errorCollector
886
+ ) || {};
887
+ }
888
+ return {};
889
+ }
890
+ denormalizeSelections(cache, input) {
891
+ const errors = [];
892
+ const denormalized = {};
893
+ for (const selection of input.selections) {
894
+ if (isField(selection)) {
895
+ deepMerge(
896
+ denormalized,
897
+ this.denormalizeFieldSelection(cache, input, selection, errors)
898
+ );
899
+ } else {
900
+ let fragment;
901
+ if (isInlineFragment(selection)) {
902
+ fragment = selection;
903
+ } else {
904
+ const fragmentDefinition = input.request.definitions.fragments[selection.name.value];
905
+ if (fragmentDefinition === void 0) {
906
+ continue;
907
+ }
908
+ fragment = {
909
+ ...fragmentDefinition,
910
+ directives: [
911
+ ...selection.directives || [],
912
+ ...fragmentDefinition.directives || []
913
+ ]
914
+ };
915
+ }
916
+ deepMerge(denormalized, this.denormalizeFragment(cache, input, fragment, errors));
917
+ }
918
+ }
919
+ return buildReadWriteResult(denormalized, errors);
920
+ }
921
+ getNormalizedFieldData(selection, input) {
922
+ var _a;
923
+ const fieldDef = this.getFieldDef(input, selection);
924
+ if (!fieldDef) {
925
+ return err(
926
+ new Error(
927
+ `Unknown field "${selection.name.value}" on type "${this.typeName}". Expected one of fields ${Object.keys(this.fields)}.`
928
+ )
929
+ );
930
+ }
931
+ const cacheFieldKeyResult = fieldDef.buildFieldKey(
932
+ selection,
933
+ input.request.definitions.variables
934
+ );
935
+ if (cacheFieldKeyResult.isErr()) {
936
+ return err(cacheFieldKeyResult.error);
937
+ }
938
+ const cacheFieldKey = cacheFieldKeyResult.value;
939
+ return ok((_a = input.existingNormalizedData || input.normalizedData) == null ? void 0 : _a[cacheFieldKey]);
940
+ }
941
+ denormalizeFieldSelection(cache, input, selection, errorCollector) {
942
+ var _a;
943
+ const canonicalFieldName = selection.name.value;
944
+ const fieldDef = this.getFieldDef(input, selection);
945
+ if (!fieldDef) {
946
+ errorCollector.push({
947
+ type: "unknown",
948
+ error: new Error(
949
+ `GraphQL query requests unknown field "${canonicalFieldName}" on type "${this.typeName}". Expected one of fields ${Object.keys(this.fields)}.`
950
+ )
951
+ });
952
+ return {};
953
+ }
954
+ const dataInstanceFieldName = ((_a = selection.alias) == null ? void 0 : _a.value) ?? selection.name.value;
955
+ const normalizedFieldDataResult = this.getNormalizedFieldData(selection, input);
956
+ if (normalizedFieldDataResult.isErr()) {
957
+ errorCollector.push({
958
+ type: "unknown",
959
+ error: normalizedFieldDataResult.error
960
+ });
961
+ return {};
962
+ }
963
+ const shouldSkipResult = shouldSkip(selection, input.request.definitions.variables);
964
+ if (shouldSkipResult.isErr()) {
965
+ errorCollector.push({
966
+ type: "unknown",
967
+ error: shouldSkipResult.error
968
+ });
969
+ return {};
970
+ }
971
+ if (shouldSkipResult.value) {
972
+ return {};
973
+ }
974
+ const normalizedFieldValue = normalizedFieldDataResult.value;
975
+ if (normalizedFieldValue === void 0) {
976
+ errorCollector.push({
977
+ type: "missingData",
978
+ namespace: this.namespace,
979
+ typeName: this.typeName,
980
+ data: canonicalFieldName
981
+ });
982
+ return {};
983
+ }
984
+ const fieldData = extractReadWriteData(
985
+ fieldDef.read(cache, {
986
+ ...input,
987
+ normalizedData: normalizedFieldValue,
988
+ request: input.request,
989
+ selection
990
+ }),
991
+ errorCollector
992
+ );
993
+ if (fieldData === void 0) {
994
+ return {};
995
+ }
996
+ return {
997
+ [dataInstanceFieldName]: fieldData
998
+ };
999
+ }
1000
+ denormalizeFragment(cache, input, fragment, errorCollector) {
1001
+ const shouldProcessResult = this.shouldProcessFragment(input, fragment);
1002
+ if (shouldProcessResult.isErr()) {
1003
+ errorCollector.push({
1004
+ type: "unknown",
1005
+ error: shouldProcessResult.error
1006
+ });
1007
+ return {};
1008
+ }
1009
+ if (shouldProcessResult.value) {
1010
+ return extractReadWriteData(
1011
+ this.denormalizeSelections(cache, {
1012
+ ...input,
1013
+ selections: fragment.selectionSet.selections
1014
+ // readonly casting, todo
1015
+ }),
1016
+ errorCollector
1017
+ ) || {};
1018
+ }
1019
+ return {};
1020
+ }
1021
+ getFieldDef(input, selection) {
1022
+ var _a, _b, _c;
1023
+ const canonicalFieldName = selection.name.value;
1024
+ const fieldDef = this.fields[canonicalFieldName];
1025
+ if (fieldDef) {
1026
+ return fieldDef;
1027
+ }
1028
+ const dataInstanceFieldName = ((_a = selection.alias) == null ? void 0 : _a.value) ?? selection.name.value;
1029
+ if (input === void 0) {
1030
+ return void 0;
1031
+ }
1032
+ if ("data" in input && input.data[dataInstanceFieldName] === void 0) {
1033
+ return missingFieldDef;
1034
+ } else if ("normalizedData" in input && ((_c = (_b = input.normalizedData) == null ? void 0 : _b[dataInstanceFieldName]) == null ? void 0 : _c.type) === "missing") {
1035
+ return missingFieldDef;
1036
+ }
1037
+ return void 0;
1038
+ }
1039
+ shouldProcessFragment(input, fragment) {
1040
+ const shouldSkipResult = shouldSkip(fragment, input.request.definitions.variables);
1041
+ if (shouldSkipResult.isErr()) {
1042
+ return shouldSkipResult;
1043
+ }
1044
+ if (shouldSkipResult.value) {
1045
+ return ok(false);
1046
+ }
1047
+ return this.satisfiesFragmentTypeCondition(input, fragment);
1048
+ }
1049
+ satisfiesFragmentTypeCondition(_input, fragment) {
1050
+ if (!fragment.typeCondition) {
1051
+ return ok(true);
1052
+ }
1053
+ const conditionalTypeName = fragment.typeCondition.name.value;
1054
+ if (conditionalTypeName === this.typeName) {
1055
+ return ok(true);
1056
+ }
1057
+ if (this.implementedInterfaces.includes(conditionalTypeName)) {
1058
+ return ok(true);
1059
+ }
1060
+ return ok(false);
1061
+ }
1062
+ getCacheKeyFieldArguments(selection) {
1063
+ return selection.arguments;
1064
+ }
1065
+ buildFieldKey(selection, variables) {
1066
+ return buildFieldKey(
1067
+ selection.name.value,
1068
+ this.getCacheKeyFieldArguments(selection),
1069
+ variables
1070
+ );
1071
+ }
1072
+ }
1073
+ class IdentifiableGraphQLTypeRepository extends IdentifiableTypeRepository {
1074
+ constructor() {
1075
+ super(...arguments);
1076
+ this.idField = "id";
1077
+ this._graphqlRepository = void 0;
1078
+ this.LocalGraphQLRepository = class extends BaseGraphQLTypeRepository {
1079
+ constructor(namespace, typeName, implementedInterfaces, fields, idField) {
1080
+ super();
1081
+ this.namespace = namespace;
1082
+ this.typeName = typeName;
1083
+ this.implementedInterfaces = implementedInterfaces;
1084
+ this.fields = fields;
1085
+ this.idField = idField;
1086
+ }
1087
+ augmentSelections(input) {
1088
+ const result = super.augmentSelections(input);
1089
+ const augmentedSelections = result.selections;
1090
+ let augmentedFragments = result.fragments;
1091
+ const newSelection = buildAugmentedFieldSelection(
1092
+ {
1093
+ kind: Kind.FIELD,
1094
+ name: {
1095
+ kind: Kind.NAME,
1096
+ value: this.idField
1097
+ }
1098
+ },
1099
+ [...augmentedSelections, ...input.selections],
1100
+ augmentedFragments
1101
+ );
1102
+ if (newSelection) {
1103
+ augmentedSelections.push(newSelection);
1104
+ }
1105
+ return { selections: augmentedSelections, fragments: augmentedFragments };
1106
+ }
1107
+ };
1108
+ }
1109
+ get graphqlRepository() {
1110
+ if (this._graphqlRepository === void 0) {
1111
+ this._graphqlRepository = new this.LocalGraphQLRepository(this.namespace, this.typeName, this.implementedInterfaces, this.fields, this.idField);
1112
+ }
1113
+ return this._graphqlRepository;
1114
+ }
1115
+ write(cache, input) {
1116
+ const key = this.buildKey(this.buildKeyParams(input));
1117
+ const normalized = this.normalizeData(cache, input);
1118
+ if (normalized.isErr()) {
1119
+ return err(normalized.error);
1120
+ }
1121
+ const existing = cache.get(key);
1122
+ if (!deepEquals(existing == null ? void 0 : existing.value, normalized.value)) {
1123
+ cache.set(key, {
1124
+ value: normalized.value,
1125
+ metadata: this.cacheMetadata
1126
+ });
1127
+ }
1128
+ return ok({
1129
+ type: "link",
1130
+ linkedKey: key
1131
+ });
1132
+ }
1133
+ normalizeData(cache, input) {
1134
+ const key = this.buildKey(this.buildKeyParams(input));
1135
+ const existingNormalizedData = cache.get(key, { copy: true });
1136
+ const normalizeDataResult = this.graphqlRepository.normalizeSelections(cache, {
1137
+ ...input,
1138
+ existingNormalizedData: existingNormalizedData == null ? void 0 : existingNormalizedData.value
1139
+ });
1140
+ if (normalizeDataResult.isErr()) {
1141
+ return normalizeDataResult;
1142
+ }
1143
+ return ok(
1144
+ deepMerge(
1145
+ {},
1146
+ (existingNormalizedData == null ? void 0 : existingNormalizedData.value) || {},
1147
+ normalizeDataResult.value
1148
+ )
1149
+ );
1150
+ }
1151
+ denormalizeData(cache, input) {
1152
+ return this.graphqlRepository.denormalizeSelections(cache, input);
1153
+ }
1154
+ augmentSelections(input) {
1155
+ return this.graphqlRepository.augmentSelections(input);
1156
+ }
1157
+ buildFieldKey(selection, variables) {
1158
+ return this.graphqlRepository.buildFieldKey(selection, variables);
1159
+ }
1160
+ buildKeyParams(input) {
1161
+ var _a;
1162
+ const idField = input.selections.find(
1163
+ (selection) => selection.kind === Kind.FIELD && selection.name.value === this.idField
1164
+ );
1165
+ if (!idField) {
1166
+ throw new Error(`Id field ${this.idField} not found in selections`);
1167
+ }
1168
+ const idFieldDataProperty = ((_a = idField.alias) == null ? void 0 : _a.value) || idField.name.value;
1169
+ return {
1170
+ [this.idField]: input.data[idFieldDataProperty]
1171
+ };
1172
+ }
1173
+ }
1174
+ class GraphQLDocumentRootTypeRepository extends IdentifiableGraphQLTypeRepository {
1175
+ constructor() {
1176
+ super(...arguments);
1177
+ this.implementedInterfaces = [];
1178
+ this._rootGraphqlRepository = void 0;
1179
+ this.LocalRootGraphQLRepository = class extends BaseGraphQLTypeRepository {
1180
+ constructor(namespace, typeName, implementedInterfaces, fields, idField) {
1181
+ super();
1182
+ this.namespace = namespace;
1183
+ this.typeName = typeName;
1184
+ this.implementedInterfaces = implementedInterfaces;
1185
+ this.fields = fields;
1186
+ this.idField = idField;
1187
+ }
1188
+ };
1189
+ }
1190
+ get graphqlRepository() {
1191
+ if (this._rootGraphqlRepository === void 0) {
1192
+ this._rootGraphqlRepository = new this.LocalRootGraphQLRepository(
1193
+ this.namespace,
1194
+ this.typeName,
1195
+ this.implementedInterfaces,
1196
+ this.fields,
1197
+ this.idField
1198
+ );
1199
+ }
1200
+ return this._rootGraphqlRepository;
1201
+ }
1202
+ augmentSelections(input) {
1203
+ return this.graphqlRepository.augmentSelections(input);
1204
+ }
1205
+ buildKeyParams(_input) {
1206
+ return null;
1207
+ }
1208
+ denormalizeData(cache, input) {
1209
+ const result = super.denormalizeData(cache, input);
1210
+ if (result.isErr()) {
1211
+ return result;
1212
+ }
1213
+ return ok({
1214
+ data: result.value
1215
+ });
1216
+ }
1217
+ buildAugmentedQuery(input) {
1218
+ var _a;
1219
+ const operationResult = findExecutableOperation(input);
1220
+ if (operationResult.isErr()) {
1221
+ return err(operationResult.error);
1222
+ }
1223
+ const operation = operationResult.value;
1224
+ const fragmentDefinitions = input.query.definitions.filter(
1225
+ (def) => def.kind === Kind.FRAGMENT_DEFINITION
1226
+ );
1227
+ const fragments = fragmentDefinitions.reduce(
1228
+ (acc, def) => {
1229
+ acc[def.name.value] = def;
1230
+ return acc;
1231
+ },
1232
+ {}
1233
+ );
1234
+ const result = this.augmentSelections({
1235
+ selections: ((_a = operationResult.value.selectionSet) == null ? void 0 : _a.selections) || [],
1236
+ fragments
1237
+ });
1238
+ const augmentedOperationSelections = result.selections;
1239
+ let augmentedFragments = result.fragments;
1240
+ const augmentedOperation = {
1241
+ ...operation,
1242
+ selectionSet: { kind: Kind.SELECTION_SET, selections: augmentedOperationSelections }
1243
+ };
1244
+ return ok({
1245
+ ...input.query,
1246
+ definitions: [
1247
+ ...input.query.definitions.filter((def) => def.kind !== Kind.FRAGMENT_DEFINITION).map((def) => {
1248
+ if (def.kind !== Kind.OPERATION_DEFINITION || def !== operation) {
1249
+ return def;
1250
+ }
1251
+ return augmentedOperation;
1252
+ }),
1253
+ ...Object.values(augmentedFragments)
1254
+ ]
1255
+ });
1256
+ }
1257
+ }
1258
+ class UnidentifiableGraphQLTypeRepository extends BaseGraphQLTypeRepository {
1259
+ constructor(services) {
1260
+ super();
1261
+ this.services = services;
1262
+ }
1263
+ write(cache, input) {
1264
+ return this.normalizeSelections(cache, input);
1265
+ }
1266
+ read(cache, input) {
1267
+ return this.denormalizeSelections(cache, input);
1268
+ }
1269
+ }
1270
+ class BaseInterfaceRepository {
1271
+ constructor(services) {
1272
+ this.services = services;
1273
+ }
1274
+ equals(x, y) {
1275
+ return deepEquals(x, y);
1276
+ }
1277
+ write(cache, input) {
1278
+ if (typeof input.data !== "object") {
1279
+ return err([
1280
+ {
1281
+ type: "unknown",
1282
+ error: new Error(`Got a non-object value for ${this.typeName} field"`)
1283
+ }
1284
+ ]);
1285
+ }
1286
+ const discriminator = this.getTypeDiscriminator(input.data, input.selections);
1287
+ const concreteTypeRepository = this.possibleTypes[discriminator];
1288
+ if (!concreteTypeRepository) {
1289
+ return err([
1290
+ {
1291
+ type: "unknown",
1292
+ error: new Error(
1293
+ `Unknown discriminator "${discriminator}" for ${this.typeName} field, expected one of ${Object.keys(this.possibleTypes)}`
1294
+ )
1295
+ }
1296
+ ]);
1297
+ }
1298
+ const selectionErr = this.verifyInterfaceFields(input.selections);
1299
+ if (selectionErr) {
1300
+ return err(selectionErr);
1301
+ }
1302
+ const normalizeInput = {
1303
+ ...input,
1304
+ data: input.data,
1305
+ existingNormalizedData: input.existingNormalizedData,
1306
+ selections: input.selections,
1307
+ request: input.request,
1308
+ parentFieldSelection: input.parentFieldSelection
1309
+ };
1310
+ const result = concreteTypeRepository.write(cache, normalizeInput);
1311
+ if (result.isOk()) {
1312
+ return ok({ discriminator, data: result.value });
1313
+ }
1314
+ return result;
1315
+ }
1316
+ read(cache, input) {
1317
+ const unionRep = input.normalizedData;
1318
+ if (typeof unionRep.data !== "object" || unionRep.data === null) {
1319
+ return err([
1320
+ {
1321
+ type: "unknown",
1322
+ error: new Error(`Got a non-object value for ${this.typeName} field.`)
1323
+ }
1324
+ ]);
1325
+ }
1326
+ const discriminator = unionRep.discriminator;
1327
+ const concreteRepository = this.possibleTypes[discriminator];
1328
+ if (!concreteRepository) {
1329
+ return err([
1330
+ {
1331
+ type: "unknown",
1332
+ error: new Error(
1333
+ `Unknown discriminator "${discriminator}" for ${this.typeName} field, expected one of ${Object.keys(this.possibleTypes)}`
1334
+ )
1335
+ }
1336
+ ]);
1337
+ }
1338
+ const selectionErr = this.verifyInterfaceFields(input.selections);
1339
+ if (selectionErr) {
1340
+ return err(selectionErr);
1341
+ }
1342
+ const denormalizeInput = {
1343
+ ...input,
1344
+ normalizedData: unionRep.data,
1345
+ selections: input.selections,
1346
+ request: input.request,
1347
+ parentFieldSelection: input.parentFieldSelection
1348
+ };
1349
+ const result = concreteRepository.read(cache, denormalizeInput);
1350
+ return result;
1351
+ }
1352
+ augmentSelections(input) {
1353
+ const augmentedSelections = [];
1354
+ let augmentedFragments = { ...input.fragments };
1355
+ input.selections.forEach((selection) => {
1356
+ var _a;
1357
+ if (selection.kind === Kind.FIELD) {
1358
+ if (Object.keys(this.fields).includes(selection.name.value)) {
1359
+ const field = this.fields[selection.name.value];
1360
+ const result2 = field.augmentSelections({
1361
+ selections: ((_a = selection.selectionSet) == null ? void 0 : _a.selections) || [],
1362
+ fragments: input.fragments
1363
+ });
1364
+ augmentedSelections.push({
1365
+ ...selection,
1366
+ selectionSet: { kind: Kind.SELECTION_SET, selections: result2.selections }
1367
+ });
1368
+ augmentedFragments = result2.fragments;
1369
+ } else {
1370
+ augmentedSelections.push(selection);
1371
+ }
1372
+ }
1373
+ });
1374
+ const result = augmentUnionLikeSelections(
1375
+ {
1376
+ selections: [...input.selections, ...augmentedSelections],
1377
+ fragments: augmentedFragments
1378
+ },
1379
+ this.possibleTypes
1380
+ );
1381
+ augmentedSelections.push(...result.selections);
1382
+ augmentedFragments = result.fragments;
1383
+ const newSelection = buildAugmentedFieldSelection(
1384
+ { kind: Kind.FIELD, name: { kind: Kind.NAME, value: "__typename" } },
1385
+ augmentedSelections,
1386
+ input.fragments
1387
+ );
1388
+ if (newSelection) {
1389
+ augmentedSelections.push(newSelection);
1390
+ }
1391
+ return { selections: augmentedSelections, fragments: augmentedFragments };
1392
+ }
1393
+ getTypeDiscriminator(data, selections) {
1394
+ var _a;
1395
+ const typenameSelection = selections.find(
1396
+ (selection) => selection.kind === Kind.FIELD && selection.name.value === "__typename"
1397
+ );
1398
+ if (typenameSelection) {
1399
+ return data[((_a = typenameSelection.alias) == null ? void 0 : _a.value) || typenameSelection.name.value];
1400
+ } else {
1401
+ return data.__typename;
1402
+ }
1403
+ }
1404
+ verifyInterfaceFields(selections) {
1405
+ let selectionErr;
1406
+ selections.forEach((selection) => {
1407
+ if (selection.kind === Kind.FIELD) {
1408
+ const fieldName = selection.name.value;
1409
+ const selectionAllowed = fieldName === "__typename" || Object.keys(this.fields).includes(fieldName);
1410
+ if (!selectionAllowed) {
1411
+ selectionErr = [
1412
+ {
1413
+ type: "unknown",
1414
+ error: new Error(
1415
+ `Dissallowed selection "${fieldName}" used outside of an inline fragment for interface type ${this.typeName}"`
1416
+ )
1417
+ }
1418
+ ];
1419
+ return;
1420
+ }
1421
+ }
1422
+ });
1423
+ return selectionErr;
1424
+ }
1425
+ buildFieldKey(selection, variables) {
1426
+ return buildFieldKey(
1427
+ selection.name.value,
1428
+ this.getCacheKeyFieldArguments(selection),
1429
+ variables
1430
+ );
1431
+ }
1432
+ getCacheKeyFieldArguments(selection) {
1433
+ return selection.arguments;
1434
+ }
1435
+ }
1436
+ class BaseUnionRepository {
1437
+ constructor(services) {
1438
+ this.services = services;
1439
+ }
1440
+ equals(x, y) {
1441
+ return deepEquals(x, y);
1442
+ }
1443
+ write(cache, input) {
1444
+ if (typeof input.data !== "object") {
1445
+ return err([
1446
+ {
1447
+ type: "unknown",
1448
+ error: new Error(`Got a non-object value for ${this.typeName} field"`)
1449
+ }
1450
+ ]);
1451
+ }
1452
+ const discriminator = this.getTypeDiscriminator(input.data, input.selections);
1453
+ const concreteTypeRepository = this.possibleTypes[discriminator];
1454
+ if (!concreteTypeRepository) {
1455
+ return err([
1456
+ {
1457
+ type: "unknown",
1458
+ error: new Error(
1459
+ `Unknown discriminator "${discriminator}" for ${this.typeName} field, expected one of ${Object.keys(this.possibleTypes)}`
1460
+ )
1461
+ }
1462
+ ]);
1463
+ }
1464
+ const selectionErr = this.verifyUnionFields(input.selections);
1465
+ if (selectionErr) {
1466
+ return err(selectionErr);
1467
+ }
1468
+ const normalizeInput = {
1469
+ ...input,
1470
+ data: input.data,
1471
+ existingNormalizedData: input.existingNormalizedData,
1472
+ selections: input.selections,
1473
+ request: input.request,
1474
+ parentFieldSelection: input.parentFieldSelection
1475
+ };
1476
+ const result = concreteTypeRepository.write(cache, normalizeInput);
1477
+ if (result.isOk()) {
1478
+ return ok({ discriminator, data: result.value });
1479
+ }
1480
+ return result;
1481
+ }
1482
+ read(cache, input) {
1483
+ const unionRep = input.normalizedData;
1484
+ if (typeof unionRep.data !== "object" || unionRep.data === null) {
1485
+ return err([
1486
+ {
1487
+ type: "unknown",
1488
+ error: new Error(`Got a non-object value for ${this.typeName} field.`)
1489
+ }
1490
+ ]);
1491
+ }
1492
+ const discriminator = unionRep.discriminator;
1493
+ const concreteRepository = this.possibleTypes[discriminator];
1494
+ if (!concreteRepository) {
1495
+ return err([
1496
+ {
1497
+ type: "unknown",
1498
+ error: new Error(
1499
+ `Unknown discriminator "${discriminator}" for ${this.typeName} field, expected one of ${Object.keys(this.possibleTypes)}`
1500
+ )
1501
+ }
1502
+ ]);
1503
+ }
1504
+ const selectionErr = this.verifyUnionFields(input.selections);
1505
+ if (selectionErr) {
1506
+ return err(selectionErr);
1507
+ }
1508
+ const denormalizeInput = {
1509
+ ...input,
1510
+ normalizedData: unionRep.data,
1511
+ selections: input.selections,
1512
+ request: input.request,
1513
+ parentFieldSelection: input.parentFieldSelection
1514
+ };
1515
+ const result = concreteRepository.read(cache, denormalizeInput);
1516
+ return result;
1517
+ }
1518
+ augmentSelections(input) {
1519
+ const augmentedSelections = [];
1520
+ let augmentedFragments = { ...input.fragments };
1521
+ const result = augmentUnionLikeSelections(
1522
+ {
1523
+ selections: [...input.selections, ...augmentedSelections],
1524
+ fragments: augmentedFragments
1525
+ },
1526
+ this.possibleTypes
1527
+ );
1528
+ augmentedSelections.push(...result.selections);
1529
+ augmentedFragments = result.fragments;
1530
+ const newSelection = buildAugmentedFieldSelection(
1531
+ { kind: Kind.FIELD, name: { kind: Kind.NAME, value: "__typename" } },
1532
+ augmentedSelections,
1533
+ input.fragments
1534
+ );
1535
+ if (newSelection) {
1536
+ augmentedSelections.push(newSelection);
1537
+ }
1538
+ return { selections: augmentedSelections, fragments: augmentedFragments };
1539
+ }
1540
+ getTypeDiscriminator(data, selections) {
1541
+ var _a;
1542
+ const typenameSelection = selections.find(
1543
+ (selection) => selection.kind === Kind.FIELD && selection.name.value === "__typename"
1544
+ );
1545
+ if (typenameSelection) {
1546
+ return data[((_a = typenameSelection.alias) == null ? void 0 : _a.value) || typenameSelection.name.value];
1547
+ } else {
1548
+ return data.__typename;
1549
+ }
1550
+ }
1551
+ verifyUnionFields(selections) {
1552
+ let selectionErr;
1553
+ selections.forEach((selection) => {
1554
+ if (selection.kind === Kind.FIELD) {
1555
+ const fieldName = selection.name.value;
1556
+ const selectionAllowed = fieldName === "__typename";
1557
+ if (!selectionAllowed) {
1558
+ selectionErr = [
1559
+ {
1560
+ type: "unknown",
1561
+ error: new Error(
1562
+ `Dissallowed selection "${fieldName}" used outside of an inline fragment for union type ${this.typeName}"`
1563
+ )
1564
+ }
1565
+ ];
1566
+ return;
1567
+ }
1568
+ }
1569
+ });
1570
+ return selectionErr;
1571
+ }
1572
+ buildFieldKey(selection, variables) {
1573
+ return buildFieldKey(
1574
+ selection.name.value,
1575
+ this.getCacheKeyFieldArguments(selection),
1576
+ variables
1577
+ );
1578
+ }
1579
+ getCacheKeyFieldArguments(selection) {
1580
+ return selection.arguments;
1581
+ }
1582
+ }
1583
+ function augmentUnionLikeSelections(input, possibleTypes) {
1584
+ const augmentedSelections = [];
1585
+ let augmentedFragments = { ...input.fragments };
1586
+ Object.values(possibleTypes).forEach((repository) => {
1587
+ const result = repository.augmentSelections({
1588
+ selections: [...input.selections, ...augmentedSelections],
1589
+ fragments: augmentedFragments
1590
+ });
1591
+ const typeSelections = result.selections.filter((selection) => selection.kind !== Kind.FIELD).map((selection) => {
1592
+ if (selection.kind === Kind.INLINE_FRAGMENT) {
1593
+ return {
1594
+ ...selection,
1595
+ selectionSet: {
1596
+ kind: Kind.SELECTION_SET,
1597
+ selections: selection.selectionSet.selections
1598
+ }
1599
+ };
1600
+ }
1601
+ return selection;
1602
+ });
1603
+ augmentedSelections.push(...typeSelections);
1604
+ augmentedFragments = result.fragments;
1605
+ });
1606
+ return { selections: augmentedSelections, fragments: augmentedFragments };
1607
+ }
1608
+ const GraphQLQueryJsonSchema = {
1609
+ type: "object",
1610
+ properties: {
1611
+ query: true,
1612
+ variables: { type: "object", properties: {}, required: [], additionalProperties: true },
1613
+ operationName: { type: "string" }
1614
+ },
1615
+ required: ["query"],
1616
+ additionalProperties: true
1617
+ };
1618
+ export {
1619
+ BaseArrayFieldDef,
1620
+ BaseGraphQLTypeRepository,
1621
+ BaseInterfaceRepository,
1622
+ BaseObjectFieldDef,
1623
+ BaseScalarFieldDef,
1624
+ BaseUnionRepository,
1625
+ GraphQLDocumentRootTypeRepository,
1626
+ GraphQLQueryJsonSchema,
1627
+ IdentifiableGraphQLTypeRepository,
1628
+ UnidentifiableGraphQLTypeRepository,
1629
+ addTypenameToDocument,
1630
+ buildAugmentedFieldSelection,
1631
+ buildFieldKey,
1632
+ buildGraphQLInputExtension,
1633
+ deepMerge,
1634
+ findExecutableOperation,
1635
+ missingFieldDef,
1636
+ shouldSkip
1637
+ };
1638
+ //# sourceMappingURL=index.js.map