1 | var __assign = (this && this.__assign) || function () {
|
2 | __assign = Object.assign || function(t) {
|
3 | for (var s, i = 1, n = arguments.length; i < n; i++) {
|
4 | s = arguments[i];
|
5 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
6 | t[p] = s[p];
|
7 | }
|
8 | return t;
|
9 | };
|
10 | return __assign.apply(this, arguments);
|
11 | };
|
12 | Object.defineProperty(exports, "__esModule", { value: true });
|
13 | var graphql_1 = require("graphql");
|
14 | var implementsAbstractType_1 = require("../implementsAbstractType");
|
15 | var ExpandAbstractTypes = (function () {
|
16 | function ExpandAbstractTypes(transformedSchema, targetSchema) {
|
17 | this.targetSchema = targetSchema;
|
18 | this.mapping = extractPossibleTypes(transformedSchema, targetSchema);
|
19 | this.reverseMapping = flipMapping(this.mapping);
|
20 | }
|
21 | ExpandAbstractTypes.prototype.transformRequest = function (originalRequest) {
|
22 | var document = expandAbstractTypes(this.targetSchema, this.mapping, this.reverseMapping, originalRequest.document);
|
23 | return __assign({}, originalRequest, { document: document });
|
24 | };
|
25 | return ExpandAbstractTypes;
|
26 | }());
|
27 | exports.default = ExpandAbstractTypes;
|
28 | function extractPossibleTypes(transformedSchema, targetSchema) {
|
29 | var typeMap = transformedSchema.getTypeMap();
|
30 | var mapping = {};
|
31 | Object.keys(typeMap).forEach(function (typeName) {
|
32 | var type = typeMap[typeName];
|
33 | if (graphql_1.isAbstractType(type)) {
|
34 | var targetType = targetSchema.getType(typeName);
|
35 | if (!graphql_1.isAbstractType(targetType)) {
|
36 | var implementations = transformedSchema.getPossibleTypes(type) || [];
|
37 | mapping[typeName] = implementations
|
38 | .filter(function (impl) { return targetSchema.getType(impl.name); })
|
39 | .map(function (impl) { return impl.name; });
|
40 | }
|
41 | }
|
42 | });
|
43 | return mapping;
|
44 | }
|
45 | function flipMapping(mapping) {
|
46 | var result = {};
|
47 | Object.keys(mapping).forEach(function (typeName) {
|
48 | var toTypeNames = mapping[typeName];
|
49 | toTypeNames.forEach(function (toTypeName) {
|
50 | if (!result[toTypeName]) {
|
51 | result[toTypeName] = [];
|
52 | }
|
53 | result[toTypeName].push(typeName);
|
54 | });
|
55 | });
|
56 | return result;
|
57 | }
|
58 | function expandAbstractTypes(targetSchema, mapping, reverseMapping, document) {
|
59 | var _a;
|
60 | var operations = document.definitions.filter(function (def) { return def.kind === graphql_1.Kind.OPERATION_DEFINITION; });
|
61 | var fragments = document.definitions.filter(function (def) { return def.kind === graphql_1.Kind.FRAGMENT_DEFINITION; });
|
62 | var existingFragmentNames = fragments.map(function (fragment) { return fragment.name.value; });
|
63 | var fragmentCounter = 0;
|
64 | var generateFragmentName = function (typeName) {
|
65 | var fragmentName;
|
66 | do {
|
67 | fragmentName = "_" + typeName + "_Fragment" + fragmentCounter;
|
68 | fragmentCounter++;
|
69 | } while (existingFragmentNames.indexOf(fragmentName) !== -1);
|
70 | return fragmentName;
|
71 | };
|
72 | var newFragments = [];
|
73 | var fragmentReplacements = {};
|
74 | fragments.forEach(function (fragment) {
|
75 | newFragments.push(fragment);
|
76 | var possibleTypes = mapping[fragment.typeCondition.name.value];
|
77 | if (possibleTypes) {
|
78 | fragmentReplacements[fragment.name.value] = [];
|
79 | possibleTypes.forEach(function (possibleTypeName) {
|
80 | var name = generateFragmentName(possibleTypeName);
|
81 | existingFragmentNames.push(name);
|
82 | var newFragment = {
|
83 | kind: graphql_1.Kind.FRAGMENT_DEFINITION,
|
84 | name: {
|
85 | kind: graphql_1.Kind.NAME,
|
86 | value: name,
|
87 | },
|
88 | typeCondition: {
|
89 | kind: graphql_1.Kind.NAMED_TYPE,
|
90 | name: {
|
91 | kind: graphql_1.Kind.NAME,
|
92 | value: possibleTypeName,
|
93 | },
|
94 | },
|
95 | selectionSet: fragment.selectionSet,
|
96 | };
|
97 | newFragments.push(newFragment);
|
98 | fragmentReplacements[fragment.name.value].push({
|
99 | fragmentName: name,
|
100 | typeName: possibleTypeName,
|
101 | });
|
102 | });
|
103 | }
|
104 | });
|
105 | var newDocument = __assign({}, document, { definitions: operations.concat(newFragments) });
|
106 | var typeInfo = new graphql_1.TypeInfo(targetSchema);
|
107 | return graphql_1.visit(newDocument, graphql_1.visitWithTypeInfo(typeInfo, (_a = {},
|
108 | _a[graphql_1.Kind.SELECTION_SET] = function (node) {
|
109 | var newSelections = node.selections.slice();
|
110 | var parentType = graphql_1.getNamedType(typeInfo.getParentType());
|
111 | node.selections.forEach(function (selection) {
|
112 | if (selection.kind === graphql_1.Kind.INLINE_FRAGMENT) {
|
113 | var possibleTypes = mapping[selection.typeCondition.name.value];
|
114 | if (possibleTypes) {
|
115 | possibleTypes.forEach(function (possibleType) {
|
116 | if (implementsAbstractType_1.default(targetSchema, parentType, targetSchema.getType(possibleType))) {
|
117 | newSelections.push({
|
118 | kind: graphql_1.Kind.INLINE_FRAGMENT,
|
119 | typeCondition: {
|
120 | kind: graphql_1.Kind.NAMED_TYPE,
|
121 | name: {
|
122 | kind: graphql_1.Kind.NAME,
|
123 | value: possibleType,
|
124 | },
|
125 | },
|
126 | selectionSet: selection.selectionSet,
|
127 | });
|
128 | }
|
129 | });
|
130 | }
|
131 | }
|
132 | else if (selection.kind === graphql_1.Kind.FRAGMENT_SPREAD) {
|
133 | var fragmentName = selection.name.value;
|
134 | var replacements = fragmentReplacements[fragmentName];
|
135 | if (replacements) {
|
136 | replacements.forEach(function (replacement) {
|
137 | var typeName = replacement.typeName;
|
138 | if (implementsAbstractType_1.default(targetSchema, parentType, targetSchema.getType(typeName))) {
|
139 | newSelections.push({
|
140 | kind: graphql_1.Kind.FRAGMENT_SPREAD,
|
141 | name: {
|
142 | kind: graphql_1.Kind.NAME,
|
143 | value: replacement.fragmentName,
|
144 | },
|
145 | });
|
146 | }
|
147 | });
|
148 | }
|
149 | }
|
150 | });
|
151 | if (parentType && reverseMapping[parentType.name]) {
|
152 | newSelections.push({
|
153 | kind: graphql_1.Kind.FIELD,
|
154 | name: {
|
155 | kind: graphql_1.Kind.NAME,
|
156 | value: '__typename',
|
157 | },
|
158 | });
|
159 | }
|
160 | if (newSelections.length !== node.selections.length) {
|
161 | return __assign({}, node, { selections: newSelections });
|
162 | }
|
163 | },
|
164 | _a)));
|
165 | }
|
166 |
|
\ | No newline at end of file |