1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 | 'use strict';
|
11 |
|
12 | var SUPPORTED_ARGUMENT_NAME = 'supported';
|
13 | var JS_FIELD_TYPE = 'JSDependency';
|
14 | var JS_FIELD_ARG = 'module';
|
15 | var JS_FIELD_NAME = 'js';
|
16 | var SCHEMA_EXTENSION = "\n directive @match on FIELD\n\n directive @module(\n name: String!\n ) on FRAGMENT_SPREAD\n";
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 | function relayMatchTransform(context) {
|
23 | return require("./GraphQLIRTransformer").transform(context, {
|
24 |
|
25 | LinkedField: visitLinkedField,
|
26 | InlineFragment: visitInlineFragment
|
27 | }, function (node) {
|
28 | return node.type;
|
29 | });
|
30 | }
|
31 |
|
32 | function visitInlineFragment(node, state) {
|
33 | return this.traverse(node, node.typeCondition);
|
34 | }
|
35 |
|
36 | function visitLinkedField(node, parentType) {
|
37 | var _transformedNode$alia;
|
38 |
|
39 | var transformedNode = this.traverse(node, node.type);
|
40 | var matchDirective = transformedNode.directives.find(function (directive) {
|
41 | return directive.name === 'match';
|
42 | });
|
43 |
|
44 | if (matchDirective == null) {
|
45 | return transformedNode;
|
46 | }
|
47 |
|
48 | var rawType = require("./GraphQLSchemaUtils").getRawType(parentType);
|
49 |
|
50 | if (!(rawType instanceof require("graphql").GraphQLInterfaceType || rawType instanceof require("graphql").GraphQLObjectType)) {
|
51 | throw require("./RelayCompilerError").createUserError('@match may only be used on fields whose parent type is an interface ' + "or object, field '".concat(node.name, "' has invalid type '").concat(String(parentType), "'"), [node.loc]);
|
52 | }
|
53 |
|
54 | var context = this.getContext();
|
55 | var schema = context.serverSchema;
|
56 | var jsModuleType = schema.getType(JS_FIELD_TYPE);
|
57 |
|
58 | if (jsModuleType == null || !(jsModuleType instanceof require("graphql").GraphQLScalarType)) {
|
59 | throw new Error("RelayMatchTransform: Expected schema to define a scalar '".concat(JS_FIELD_TYPE, "' type."));
|
60 | }
|
61 |
|
62 | var currentField = rawType.getFields()[transformedNode.name];
|
63 | var supportedArg = currentField.args.find(function (_ref2) {
|
64 | var name = _ref2.name;
|
65 | return SUPPORTED_ARGUMENT_NAME;
|
66 | });
|
67 | var supportedArgType = supportedArg != null ? require("graphql").getNullableType(supportedArg.type) : null;
|
68 | var supportedArgOfType = supportedArgType != null && supportedArgType instanceof require("graphql").GraphQLList ? supportedArgType.ofType : null;
|
69 |
|
70 | if (supportedArg == null || supportedArgType == null || supportedArgOfType == null || require("graphql").getNullableType(supportedArgOfType) !== require("graphql").GraphQLString) {
|
71 | throw new Error('RelayMatchTransform: @match used on an incompatible ' + "field '".concat(transformedNode.name, "'. @match may only ") + "be used with fields that can accept '".concat(SUPPORTED_ARGUMENT_NAME, "' ") + "argument with type '[String!]!'.");
|
72 | }
|
73 |
|
74 | var unionType = transformedNode.type;
|
75 |
|
76 | if (!(unionType instanceof require("graphql").GraphQLUnionType)) {
|
77 | throw new Error('RelayMatchTransform: You are trying to apply @match ' + "directive to a field '".concat(transformedNode.name, "' that has unsupported ") + "output type. '".concat(transformedNode.name, "' output type should be union ") + 'type of object types.');
|
78 | }
|
79 |
|
80 | var seenTypes = new Map();
|
81 | var typeToSelectionMap = {};
|
82 | var selections = [];
|
83 | transformedNode.selections.forEach(function (matchSelection) {
|
84 | var _ref, _moduleDirective$args;
|
85 |
|
86 | if (matchSelection.kind !== 'FragmentSpread') {
|
87 | throw new Error('RelayMatchTransform: all selections in a @match field should be ' + "fragment spreads, got '".concat(matchSelection.kind, "'."));
|
88 | }
|
89 |
|
90 | var fragment = context.getFragment(matchSelection.name);
|
91 |
|
92 | if (!(fragment.type instanceof require("graphql").GraphQLObjectType)) {
|
93 | throw new Error('RelayMatchTransform: all fragment spreads in a @match field should ' + 'be for fragments on an object type. Union or interface type ' + "'".concat(fragment.type.name, "' for '...").concat(fragment.name, "' is not supported."));
|
94 | }
|
95 |
|
96 | var matchedType = fragment.type;
|
97 |
|
98 | if (seenTypes.has(matchedType)) {
|
99 | throw new Error('RelayMatchTransform: Each "match" type has to appear at-most once. ' + "Type '".concat(matchedType.name, "' was matched in both ") + "'...".concat(matchSelection.name, "' and '...").concat(seenTypes.get(matchedType) || '(unknown)', "'."));
|
100 | }
|
101 |
|
102 | seenTypes.set(matchedType, matchSelection.name);
|
103 | var belongsToUnion = unionType.getTypes().includes(matchedType);
|
104 |
|
105 | if (!belongsToUnion) {
|
106 | throw new Error("RelayMatchTransform: Unsupported type '".concat(matchedType.toString(), "' in ") + 'the list of matches in the @match. Type ' + "\"".concat(matchedType.toString(), "\" does not belong to the union ") + "\"".concat(unionType.toString(), "\"."));
|
107 | }
|
108 |
|
109 | var jsField = matchedType.getFields()[JS_FIELD_NAME];
|
110 | var jsFieldArg = jsField ? jsField.args.find(function (arg) {
|
111 | return arg.name === JS_FIELD_ARG;
|
112 | }) : null;
|
113 |
|
114 | if (jsField == null || jsFieldArg == null || require("graphql").getNullableType(jsFieldArg.type) !== require("graphql").GraphQLString || jsField.type.name !== jsModuleType.name
|
115 | ) {
|
116 | throw new Error("RelayMatchTransform: expcted type '".concat(matchedType.name, "' to have a '").concat(JS_FIELD_NAME, "(").concat(JS_FIELD_ARG, ": String!): ").concat(JS_FIELD_TYPE, "' field ."));
|
117 | }
|
118 |
|
119 | var moduleDirective = matchSelection.directives.find(function (directive) {
|
120 | return directive.name === 'module';
|
121 | });
|
122 |
|
123 | if (moduleDirective == null || matchSelection.directives.length !== 1) {
|
124 | throw new Error('RelayMatchTransform: Fragment spreads in a @match field must have a ' + "'@module' directive and no other directives, got invalid directives " + "on fragment spread '...".concat(matchSelection.name, "'"));
|
125 | }
|
126 |
|
127 | var moduleDirectiveArgs = require("./getLiteralArgumentValues")(moduleDirective.args);
|
128 |
|
129 | typeToSelectionMap[String(matchedType)] = {
|
130 | component: moduleDirectiveArgs.name,
|
131 | fragment: matchSelection.name
|
132 | };
|
133 | var normalizationName = require("./getNormalizationOperationName")(matchSelection.name) + '.graphql';
|
134 | var moduleField = {
|
135 | alias: '__match_component',
|
136 | args: [{
|
137 | kind: 'Argument',
|
138 | name: JS_FIELD_ARG,
|
139 | type: jsFieldArg.type,
|
140 | value: {
|
141 | kind: 'Literal',
|
142 | loc: (_ref = (_moduleDirective$args = moduleDirective.args[0]) === null || _moduleDirective$args === void 0 ? void 0 : _moduleDirective$args.loc) !== null && _ref !== void 0 ? _ref : moduleDirective.loc,
|
143 | metadata: {},
|
144 | value: moduleDirectiveArgs.name
|
145 | },
|
146 | loc: moduleDirective.loc,
|
147 | metadata: {}
|
148 | }],
|
149 | directives: [],
|
150 | handles: null,
|
151 | kind: 'ScalarField',
|
152 | loc: moduleDirective.loc,
|
153 | metadata: {
|
154 | storageKey: '__match_component'
|
155 | },
|
156 | name: JS_FIELD_NAME,
|
157 | type: jsModuleType
|
158 | };
|
159 | var fragmentField = {
|
160 | alias: '__match_fragment',
|
161 | args: [{
|
162 | kind: 'Argument',
|
163 | name: JS_FIELD_ARG,
|
164 | type: jsFieldArg.type,
|
165 | value: {
|
166 | kind: 'Literal',
|
167 | loc: matchSelection.loc,
|
168 | metadata: {},
|
169 | value: normalizationName
|
170 | },
|
171 | loc: matchSelection.loc,
|
172 | metadata: {}
|
173 | }],
|
174 | directives: [],
|
175 | handles: null,
|
176 | kind: 'ScalarField',
|
177 | loc: matchSelection.loc,
|
178 | metadata: {
|
179 | storageKey: '__match_fragment'
|
180 | },
|
181 | name: JS_FIELD_NAME,
|
182 | type: jsModuleType
|
183 | };
|
184 | selections.push({
|
185 | kind: 'MatchBranch',
|
186 | loc: matchSelection.loc,
|
187 | module: moduleDirectiveArgs.name,
|
188 | name: matchSelection.name,
|
189 | selections: [{
|
190 | args: [],
|
191 | directives: [],
|
192 | kind: 'FragmentSpread',
|
193 | loc: matchSelection.loc,
|
194 | metadata: {},
|
195 | name: matchSelection.name
|
196 | }, {
|
197 | directives: [],
|
198 | kind: 'InlineFragment',
|
199 | loc: matchSelection.loc,
|
200 | metadata: {},
|
201 | selections: [moduleField, fragmentField],
|
202 | typeCondition: matchedType
|
203 | }],
|
204 | type: matchedType
|
205 | });
|
206 | });
|
207 | var stableArgs = [];
|
208 | Object.keys(typeToSelectionMap).sort().forEach(function (typeName) {
|
209 | var _typeToSelectionMap$t = typeToSelectionMap[typeName],
|
210 | component = _typeToSelectionMap$t.component,
|
211 | fragment = _typeToSelectionMap$t.fragment;
|
212 | stableArgs.push("".concat(fragment, ":").concat(component));
|
213 | });
|
214 | var storageKey = ((_transformedNode$alia = transformedNode.alias) !== null && _transformedNode$alia !== void 0 ? _transformedNode$alia : transformedNode.name) + "(".concat(stableArgs.join(','), ")");
|
215 | var matchField = {
|
216 | kind: 'MatchField',
|
217 | alias: transformedNode.alias,
|
218 | args: [{
|
219 | kind: 'Argument',
|
220 | name: SUPPORTED_ARGUMENT_NAME,
|
221 | type: supportedArg.type,
|
222 | value: {
|
223 | kind: 'Literal',
|
224 | loc: node.loc,
|
225 | metadata: {},
|
226 | value: Array.from(seenTypes.keys()).map(function (type) {
|
227 | return type.name;
|
228 | })
|
229 | },
|
230 | loc: node.loc,
|
231 | metadata: {}
|
232 | }],
|
233 | directives: [],
|
234 | handles: null,
|
235 | loc: node.loc,
|
236 | metadata: {
|
237 | storageKey: storageKey
|
238 | },
|
239 | name: transformedNode.name,
|
240 | type: unionType,
|
241 | selections: selections
|
242 | };
|
243 |
|
244 | return matchField;
|
245 | }
|
246 |
|
247 | module.exports = {
|
248 | SCHEMA_EXTENSION: SCHEMA_EXTENSION,
|
249 | transform: relayMatchTransform
|
250 | }; |
\ | No newline at end of file |