UNPKG

6.08 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const intermediates_1 = require("./intermediates");
4const extendedIntermediates_1 = require("./extendedIntermediates");
5const immutable_1 = require("immutable");
6const normalizableSelectionsFromExtendedFieldType = (type) => {
7 switch (type.kind) {
8 case "InlineSelection":
9 return NormalizableSelections(type);
10 case "Maybe":
11 return normalizableSelectionsFromExtendedFieldType(type.ofType);
12 case "List":
13 return normalizableSelectionsFromExtendedFieldType(type.ofType);
14 default:
15 return immutable_1.Map();
16 }
17};
18const selectTypename = (__typename) => (field) => field.type.kind == "Typename"
19 ? { type: intermediates_1.Typename(immutable_1.Set([__typename])), optional: field.optional }
20 : field;
21const NormalizableSelections = (selection) => selection.fields.reduce((normalizedSelections, fields, __typename) => fields.reduce((normalizedSelections, field) => normalizedSelections.mergeDeep(normalizableSelectionsFromExtendedFieldType(field.type)), isNormalizable(fields)
22 ? normalizedSelections.mergeDeep(immutable_1.Map({
23 [__typename]: immutable_1.List([fields.map(selectTypename(__typename))])
24 }))
25 : normalizedSelections), immutable_1.Map());
26const normalizeFieldType = (type) => {
27 switch (type.kind) {
28 case "InlineSelection":
29 return normalizeSelection(type);
30 case "Maybe":
31 return intermediates_1.Maybe(normalizeFieldType(type.ofType));
32 case "List":
33 return intermediates_1.List(normalizeFieldType(type.ofType));
34 default:
35 return type;
36 }
37};
38const normalizeField = ({ type, optional }) => ({
39 type: normalizeFieldType(type),
40 optional
41});
42const normalizeSelection = (selection) => ({
43 kind: "InlineSelection",
44 fields: selection.fields.map(fields => isNormalizable(fields)
45 ? fields.filter((_, fieldName) => fieldName == "__typename" || fieldName == "id")
46 : fields.map(normalizeField))
47});
48const returnIfEqual = (__typename, fieldName, lhs, rhs) => {
49 const differentKindsError = Error(`${lhs.kind} is not the same as ${rhs.kind}`);
50 switch (lhs.kind) {
51 case "Typename":
52 if (rhs.kind != "Typename") {
53 throw differentKindsError;
54 }
55 if (!lhs.possibleTypes.equals(rhs.possibleTypes)) {
56 throw Error(`${lhs.possibleTypes} are not the same as ${rhs.possibleTypes}`);
57 }
58 return rhs;
59 case "Enum":
60 if (rhs.kind != "Enum") {
61 throw differentKindsError;
62 }
63 if (lhs.name != rhs.name) {
64 throw Error(`${lhs.name} is different than ${rhs.name}`);
65 }
66 if (lhs.values != rhs.values) {
67 throw Error(`Possible values ${lhs.values} are not the same as ${rhs.values}`);
68 }
69 return rhs;
70 case "Scalar":
71 if (rhs.kind != "Scalar") {
72 throw differentKindsError;
73 }
74 if (lhs.name != rhs.name) {
75 throw Error(`Types ${lhs.name} and ${rhs.name} are not the same`);
76 }
77 return rhs;
78 case "InlineSelection":
79 if (rhs.kind != "InlineSelection") {
80 throw differentKindsError;
81 }
82 if (!extendedIntermediates_1.extendedSelectionsAreEqual(lhs, rhs)) {
83 throw Error(`${__typename} can't be normalized because it has conflicting definitions for "${fieldName}" that could lead to runtime bugs. Either alias the field name or make the selections the same.`);
84 }
85 return rhs;
86 case "List":
87 if (rhs.kind != "List") {
88 throw differentKindsError;
89 }
90 return intermediates_1.List(returnIfEqual(__typename, fieldName, lhs.ofType, rhs.ofType));
91 case "Maybe":
92 if (rhs.kind != "Maybe") {
93 throw differentKindsError;
94 }
95 return intermediates_1.Maybe(returnIfEqual(__typename, fieldName, lhs.ofType, rhs.ofType));
96 }
97};
98const mergeExtendedSelections = (lhs, rhs) => {
99 return {
100 kind: "InlineSelection",
101 fields: lhs.fields.mergeWith((lhs, rhs, __typename) => mergeFields(__typename)(lhs, rhs), rhs.fields)
102 };
103};
104const isNormalizable = (fields) => fields.has("__typename") && fields.has("id");
105const mergeField = (__typename) => (lhs, rhs, fieldName) => ({
106 type: lhs.type.kind == "InlineSelection" &&
107 rhs.type.kind == "InlineSelection" &&
108 !lhs.type.fields.some(isNormalizable) &&
109 !rhs.type.fields.some(isNormalizable)
110 ? mergeExtendedSelections(lhs.type, rhs.type)
111 : returnIfEqual(__typename, fieldName, lhs.type, rhs.type),
112 optional: lhs.optional || rhs.optional
113});
114const mergeFields = (__typename) => (lhs, rhs) => {
115 const intersection = immutable_1.Set(lhs.keySeq()).intersect(immutable_1.Set(rhs.keySeq()));
116 return lhs
117 .mergeWith(mergeField(__typename), rhs)
118 .map((field, fieldName) => !intersection.contains(fieldName)
119 ? { type: field.type, optional: true }
120 : field);
121};
122exports.normalizedTypes = (context) => {
123 const fragments = Object.values(context.fragments).reduce((fragments, fragment) => (Object.assign({}, fragments, { [fragment.fragmentName]: intermediates_1.InlineSelection(fragment.selectionSet) })), {});
124 const extendedSelections = Object.values(context.operations).map(operation => extendedIntermediates_1.ExtendedSelection(intermediates_1.InlineSelection(operation.selectionSet), fragments));
125 const normalizableSelections = extendedSelections.reduce((normalizedSelections, extendedSelection) => normalizedSelections.mergeDeep(NormalizableSelections(extendedSelection)), immutable_1.Map());
126 return normalizableSelections.map((fields, __typename) => fields.reduce(mergeFields(__typename)).map(normalizeField));
127};
128//# sourceMappingURL=normalization.js.map
\No newline at end of file