UNPKG

22.1 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.makeDirectiveNodes = exports.makeDirectiveNode = exports.makeDeprecatedDirective = exports.astFromEnumValue = exports.astFromInputField = exports.astFromField = exports.astFromScalarType = exports.astFromEnumType = exports.astFromInputObjectType = exports.astFromUnionType = exports.astFromInterfaceType = exports.astFromObjectType = exports.astFromArg = exports.getDeprecatableDirectiveNodes = exports.getDirectiveNodes = exports.astFromDirective = exports.astFromSchema = exports.printSchemaWithDirectives = exports.getDocumentNodeFromSchema = void 0;
4const graphql_1 = require("graphql");
5const astFromType_js_1 = require("./astFromType.js");
6const get_directives_js_1 = require("./get-directives.js");
7const astFromValueUntyped_js_1 = require("./astFromValueUntyped.js");
8const helpers_js_1 = require("./helpers.js");
9const rootTypes_js_1 = require("./rootTypes.js");
10function getDocumentNodeFromSchema(schema, options = {}) {
11 const pathToDirectivesInExtensions = options.pathToDirectivesInExtensions;
12 const typesMap = schema.getTypeMap();
13 const schemaNode = astFromSchema(schema, pathToDirectivesInExtensions);
14 const definitions = schemaNode != null ? [schemaNode] : [];
15 const directives = schema.getDirectives();
16 for (const directive of directives) {
17 if ((0, graphql_1.isSpecifiedDirective)(directive)) {
18 continue;
19 }
20 definitions.push(astFromDirective(directive, schema, pathToDirectivesInExtensions));
21 }
22 for (const typeName in typesMap) {
23 const type = typesMap[typeName];
24 const isPredefinedScalar = (0, graphql_1.isSpecifiedScalarType)(type);
25 const isIntrospection = (0, graphql_1.isIntrospectionType)(type);
26 if (isPredefinedScalar || isIntrospection) {
27 continue;
28 }
29 if ((0, graphql_1.isObjectType)(type)) {
30 definitions.push(astFromObjectType(type, schema, pathToDirectivesInExtensions));
31 }
32 else if ((0, graphql_1.isInterfaceType)(type)) {
33 definitions.push(astFromInterfaceType(type, schema, pathToDirectivesInExtensions));
34 }
35 else if ((0, graphql_1.isUnionType)(type)) {
36 definitions.push(astFromUnionType(type, schema, pathToDirectivesInExtensions));
37 }
38 else if ((0, graphql_1.isInputObjectType)(type)) {
39 definitions.push(astFromInputObjectType(type, schema, pathToDirectivesInExtensions));
40 }
41 else if ((0, graphql_1.isEnumType)(type)) {
42 definitions.push(astFromEnumType(type, schema, pathToDirectivesInExtensions));
43 }
44 else if ((0, graphql_1.isScalarType)(type)) {
45 definitions.push(astFromScalarType(type, schema, pathToDirectivesInExtensions));
46 }
47 else {
48 throw new Error(`Unknown type ${type}.`);
49 }
50 }
51 return {
52 kind: graphql_1.Kind.DOCUMENT,
53 definitions,
54 };
55}
56exports.getDocumentNodeFromSchema = getDocumentNodeFromSchema;
57// this approach uses the default schema printer rather than a custom solution, so may be more backwards compatible
58// currently does not allow customization of printSchema options having to do with comments.
59function printSchemaWithDirectives(schema, options = {}) {
60 const documentNode = getDocumentNodeFromSchema(schema, options);
61 return (0, graphql_1.print)(documentNode);
62}
63exports.printSchemaWithDirectives = printSchemaWithDirectives;
64function astFromSchema(schema, pathToDirectivesInExtensions) {
65 var _a, _b;
66 const operationTypeMap = new Map([
67 ['query', undefined],
68 ['mutation', undefined],
69 ['subscription', undefined],
70 ]);
71 const nodes = [];
72 if (schema.astNode != null) {
73 nodes.push(schema.astNode);
74 }
75 if (schema.extensionASTNodes != null) {
76 for (const extensionASTNode of schema.extensionASTNodes) {
77 nodes.push(extensionASTNode);
78 }
79 }
80 for (const node of nodes) {
81 if (node.operationTypes) {
82 for (const operationTypeDefinitionNode of node.operationTypes) {
83 operationTypeMap.set(operationTypeDefinitionNode.operation, operationTypeDefinitionNode);
84 }
85 }
86 }
87 const rootTypeMap = (0, rootTypes_js_1.getRootTypeMap)(schema);
88 for (const [operationTypeNode, operationTypeDefinitionNode] of operationTypeMap) {
89 const rootType = rootTypeMap.get(operationTypeNode);
90 if (rootType != null) {
91 const rootTypeAST = (0, astFromType_js_1.astFromType)(rootType);
92 if (operationTypeDefinitionNode != null) {
93 operationTypeDefinitionNode.type = rootTypeAST;
94 }
95 else {
96 operationTypeMap.set(operationTypeNode, {
97 kind: graphql_1.Kind.OPERATION_TYPE_DEFINITION,
98 operation: operationTypeNode,
99 type: rootTypeAST,
100 });
101 }
102 }
103 }
104 const operationTypes = [...operationTypeMap.values()].filter(helpers_js_1.isSome);
105 const directives = getDirectiveNodes(schema, schema, pathToDirectivesInExtensions);
106 if (!operationTypes.length && !directives.length) {
107 return null;
108 }
109 const schemaNode = {
110 kind: operationTypes != null ? graphql_1.Kind.SCHEMA_DEFINITION : graphql_1.Kind.SCHEMA_EXTENSION,
111 operationTypes,
112 // ConstXNode has been introduced in v16 but it is not compatible with XNode so we do `as any` for backwards compatibility
113 directives: directives,
114 };
115 // This code is so weird because it needs to support GraphQL.js 14
116 // In GraphQL.js 14 there is no `description` value on schemaNode
117 schemaNode.description =
118 ((_b = (_a = schema.astNode) === null || _a === void 0 ? void 0 : _a.description) !== null && _b !== void 0 ? _b : schema.description != null)
119 ? {
120 kind: graphql_1.Kind.STRING,
121 value: schema.description,
122 block: true,
123 }
124 : undefined;
125 return schemaNode;
126}
127exports.astFromSchema = astFromSchema;
128function astFromDirective(directive, schema, pathToDirectivesInExtensions) {
129 var _a, _b, _c, _d;
130 return {
131 kind: graphql_1.Kind.DIRECTIVE_DEFINITION,
132 description: (_b = (_a = directive.astNode) === null || _a === void 0 ? void 0 : _a.description) !== null && _b !== void 0 ? _b : (directive.description
133 ? {
134 kind: graphql_1.Kind.STRING,
135 value: directive.description,
136 }
137 : undefined),
138 name: {
139 kind: graphql_1.Kind.NAME,
140 value: directive.name,
141 },
142 arguments: (_c = directive.args) === null || _c === void 0 ? void 0 : _c.map(arg => astFromArg(arg, schema, pathToDirectivesInExtensions)),
143 repeatable: directive.isRepeatable,
144 locations: ((_d = directive.locations) === null || _d === void 0 ? void 0 : _d.map(location => ({
145 kind: graphql_1.Kind.NAME,
146 value: location,
147 }))) || [],
148 };
149}
150exports.astFromDirective = astFromDirective;
151function getDirectiveNodes(entity, schema, pathToDirectivesInExtensions) {
152 const directivesInExtensions = (0, get_directives_js_1.getDirectivesInExtensions)(entity, pathToDirectivesInExtensions);
153 let nodes = [];
154 if (entity.astNode != null) {
155 nodes.push(entity.astNode);
156 }
157 if ('extensionASTNodes' in entity && entity.extensionASTNodes != null) {
158 nodes = nodes.concat(entity.extensionASTNodes);
159 }
160 let directives;
161 if (directivesInExtensions != null) {
162 directives = makeDirectiveNodes(schema, directivesInExtensions);
163 }
164 else {
165 directives = [];
166 for (const node of nodes) {
167 if (node.directives) {
168 directives.push(...node.directives);
169 }
170 }
171 }
172 return directives;
173}
174exports.getDirectiveNodes = getDirectiveNodes;
175function getDeprecatableDirectiveNodes(entity, schema, pathToDirectivesInExtensions) {
176 var _a, _b;
177 let directiveNodesBesidesDeprecated = [];
178 let deprecatedDirectiveNode = null;
179 const directivesInExtensions = (0, get_directives_js_1.getDirectivesInExtensions)(entity, pathToDirectivesInExtensions);
180 let directives;
181 if (directivesInExtensions != null) {
182 directives = makeDirectiveNodes(schema, directivesInExtensions);
183 }
184 else {
185 directives = (_a = entity.astNode) === null || _a === void 0 ? void 0 : _a.directives;
186 }
187 if (directives != null) {
188 directiveNodesBesidesDeprecated = directives.filter(directive => directive.name.value !== 'deprecated');
189 if (entity.deprecationReason != null) {
190 deprecatedDirectiveNode = (_b = directives.filter(directive => directive.name.value === 'deprecated')) === null || _b === void 0 ? void 0 : _b[0];
191 }
192 }
193 if (entity.deprecationReason != null &&
194 deprecatedDirectiveNode == null) {
195 deprecatedDirectiveNode = makeDeprecatedDirective(entity.deprecationReason);
196 }
197 return deprecatedDirectiveNode == null
198 ? directiveNodesBesidesDeprecated
199 : [deprecatedDirectiveNode].concat(directiveNodesBesidesDeprecated);
200}
201exports.getDeprecatableDirectiveNodes = getDeprecatableDirectiveNodes;
202function astFromArg(arg, schema, pathToDirectivesInExtensions) {
203 var _a, _b, _c;
204 return {
205 kind: graphql_1.Kind.INPUT_VALUE_DEFINITION,
206 description: (_b = (_a = arg.astNode) === null || _a === void 0 ? void 0 : _a.description) !== null && _b !== void 0 ? _b : (arg.description
207 ? {
208 kind: graphql_1.Kind.STRING,
209 value: arg.description,
210 block: true,
211 }
212 : undefined),
213 name: {
214 kind: graphql_1.Kind.NAME,
215 value: arg.name,
216 },
217 type: (0, astFromType_js_1.astFromType)(arg.type),
218 // ConstXNode has been introduced in v16 but it is not compatible with XNode so we do `as any` for backwards compatibility
219 defaultValue: arg.defaultValue !== undefined ? (_c = (0, graphql_1.astFromValue)(arg.defaultValue, arg.type)) !== null && _c !== void 0 ? _c : undefined : undefined,
220 directives: getDeprecatableDirectiveNodes(arg, schema, pathToDirectivesInExtensions),
221 };
222}
223exports.astFromArg = astFromArg;
224function astFromObjectType(type, schema, pathToDirectivesInExtensions) {
225 var _a, _b;
226 return {
227 kind: graphql_1.Kind.OBJECT_TYPE_DEFINITION,
228 description: (_b = (_a = type.astNode) === null || _a === void 0 ? void 0 : _a.description) !== null && _b !== void 0 ? _b : (type.description
229 ? {
230 kind: graphql_1.Kind.STRING,
231 value: type.description,
232 block: true,
233 }
234 : undefined),
235 name: {
236 kind: graphql_1.Kind.NAME,
237 value: type.name,
238 },
239 fields: Object.values(type.getFields()).map(field => astFromField(field, schema, pathToDirectivesInExtensions)),
240 interfaces: Object.values(type.getInterfaces()).map(iFace => (0, astFromType_js_1.astFromType)(iFace)),
241 directives: getDirectiveNodes(type, schema, pathToDirectivesInExtensions),
242 };
243}
244exports.astFromObjectType = astFromObjectType;
245function astFromInterfaceType(type, schema, pathToDirectivesInExtensions) {
246 var _a, _b;
247 const node = {
248 kind: graphql_1.Kind.INTERFACE_TYPE_DEFINITION,
249 description: (_b = (_a = type.astNode) === null || _a === void 0 ? void 0 : _a.description) !== null && _b !== void 0 ? _b : (type.description
250 ? {
251 kind: graphql_1.Kind.STRING,
252 value: type.description,
253 block: true,
254 }
255 : undefined),
256 name: {
257 kind: graphql_1.Kind.NAME,
258 value: type.name,
259 },
260 fields: Object.values(type.getFields()).map(field => astFromField(field, schema, pathToDirectivesInExtensions)),
261 directives: getDirectiveNodes(type, schema, pathToDirectivesInExtensions),
262 };
263 if ('getInterfaces' in type) {
264 node.interfaces = Object.values(type.getInterfaces()).map(iFace => (0, astFromType_js_1.astFromType)(iFace));
265 }
266 return node;
267}
268exports.astFromInterfaceType = astFromInterfaceType;
269function astFromUnionType(type, schema, pathToDirectivesInExtensions) {
270 var _a, _b;
271 return {
272 kind: graphql_1.Kind.UNION_TYPE_DEFINITION,
273 description: (_b = (_a = type.astNode) === null || _a === void 0 ? void 0 : _a.description) !== null && _b !== void 0 ? _b : (type.description
274 ? {
275 kind: graphql_1.Kind.STRING,
276 value: type.description,
277 block: true,
278 }
279 : undefined),
280 name: {
281 kind: graphql_1.Kind.NAME,
282 value: type.name,
283 },
284 // ConstXNode has been introduced in v16 but it is not compatible with XNode so we do `as any` for backwards compatibility
285 directives: getDirectiveNodes(type, schema, pathToDirectivesInExtensions),
286 types: type.getTypes().map(type => (0, astFromType_js_1.astFromType)(type)),
287 };
288}
289exports.astFromUnionType = astFromUnionType;
290function astFromInputObjectType(type, schema, pathToDirectivesInExtensions) {
291 var _a, _b;
292 return {
293 kind: graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION,
294 description: (_b = (_a = type.astNode) === null || _a === void 0 ? void 0 : _a.description) !== null && _b !== void 0 ? _b : (type.description
295 ? {
296 kind: graphql_1.Kind.STRING,
297 value: type.description,
298 block: true,
299 }
300 : undefined),
301 name: {
302 kind: graphql_1.Kind.NAME,
303 value: type.name,
304 },
305 fields: Object.values(type.getFields()).map(field => astFromInputField(field, schema, pathToDirectivesInExtensions)),
306 // ConstXNode has been introduced in v16 but it is not compatible with XNode so we do `as any` for backwards compatibility
307 directives: getDirectiveNodes(type, schema, pathToDirectivesInExtensions),
308 };
309}
310exports.astFromInputObjectType = astFromInputObjectType;
311function astFromEnumType(type, schema, pathToDirectivesInExtensions) {
312 var _a, _b;
313 return {
314 kind: graphql_1.Kind.ENUM_TYPE_DEFINITION,
315 description: (_b = (_a = type.astNode) === null || _a === void 0 ? void 0 : _a.description) !== null && _b !== void 0 ? _b : (type.description
316 ? {
317 kind: graphql_1.Kind.STRING,
318 value: type.description,
319 block: true,
320 }
321 : undefined),
322 name: {
323 kind: graphql_1.Kind.NAME,
324 value: type.name,
325 },
326 values: Object.values(type.getValues()).map(value => astFromEnumValue(value, schema, pathToDirectivesInExtensions)),
327 // ConstXNode has been introduced in v16 but it is not compatible with XNode so we do `as any` for backwards compatibility
328 directives: getDirectiveNodes(type, schema, pathToDirectivesInExtensions),
329 };
330}
331exports.astFromEnumType = astFromEnumType;
332function astFromScalarType(type, schema, pathToDirectivesInExtensions) {
333 var _a, _b, _c;
334 const directivesInExtensions = (0, get_directives_js_1.getDirectivesInExtensions)(type, pathToDirectivesInExtensions);
335 const directives = directivesInExtensions
336 ? makeDirectiveNodes(schema, directivesInExtensions)
337 : ((_a = type.astNode) === null || _a === void 0 ? void 0 : _a.directives) || [];
338 const specifiedByValue = (type['specifiedByUrl'] || type['specifiedByURL']);
339 if (specifiedByValue && !directives.some(directiveNode => directiveNode.name.value === 'specifiedBy')) {
340 const specifiedByArgs = {
341 url: specifiedByValue,
342 };
343 directives.push(makeDirectiveNode('specifiedBy', specifiedByArgs));
344 }
345 return {
346 kind: graphql_1.Kind.SCALAR_TYPE_DEFINITION,
347 description: (_c = (_b = type.astNode) === null || _b === void 0 ? void 0 : _b.description) !== null && _c !== void 0 ? _c : (type.description
348 ? {
349 kind: graphql_1.Kind.STRING,
350 value: type.description,
351 block: true,
352 }
353 : undefined),
354 name: {
355 kind: graphql_1.Kind.NAME,
356 value: type.name,
357 },
358 // ConstXNode has been introduced in v16 but it is not compatible with XNode so we do `as any` for backwards compatibility
359 directives: directives,
360 };
361}
362exports.astFromScalarType = astFromScalarType;
363function astFromField(field, schema, pathToDirectivesInExtensions) {
364 var _a, _b;
365 return {
366 kind: graphql_1.Kind.FIELD_DEFINITION,
367 description: (_b = (_a = field.astNode) === null || _a === void 0 ? void 0 : _a.description) !== null && _b !== void 0 ? _b : (field.description
368 ? {
369 kind: graphql_1.Kind.STRING,
370 value: field.description,
371 block: true,
372 }
373 : undefined),
374 name: {
375 kind: graphql_1.Kind.NAME,
376 value: field.name,
377 },
378 arguments: field.args.map(arg => astFromArg(arg, schema, pathToDirectivesInExtensions)),
379 type: (0, astFromType_js_1.astFromType)(field.type),
380 // ConstXNode has been introduced in v16 but it is not compatible with XNode so we do `as any` for backwards compatibility
381 directives: getDeprecatableDirectiveNodes(field, schema, pathToDirectivesInExtensions),
382 };
383}
384exports.astFromField = astFromField;
385function astFromInputField(field, schema, pathToDirectivesInExtensions) {
386 var _a, _b, _c;
387 return {
388 kind: graphql_1.Kind.INPUT_VALUE_DEFINITION,
389 description: (_b = (_a = field.astNode) === null || _a === void 0 ? void 0 : _a.description) !== null && _b !== void 0 ? _b : (field.description
390 ? {
391 kind: graphql_1.Kind.STRING,
392 value: field.description,
393 block: true,
394 }
395 : undefined),
396 name: {
397 kind: graphql_1.Kind.NAME,
398 value: field.name,
399 },
400 type: (0, astFromType_js_1.astFromType)(field.type),
401 // ConstXNode has been introduced in v16 but it is not compatible with XNode so we do `as any` for backwards compatibility
402 directives: getDeprecatableDirectiveNodes(field, schema, pathToDirectivesInExtensions),
403 defaultValue: (_c = (0, graphql_1.astFromValue)(field.defaultValue, field.type)) !== null && _c !== void 0 ? _c : undefined,
404 };
405}
406exports.astFromInputField = astFromInputField;
407function astFromEnumValue(value, schema, pathToDirectivesInExtensions) {
408 var _a, _b;
409 return {
410 kind: graphql_1.Kind.ENUM_VALUE_DEFINITION,
411 description: (_b = (_a = value.astNode) === null || _a === void 0 ? void 0 : _a.description) !== null && _b !== void 0 ? _b : (value.description
412 ? {
413 kind: graphql_1.Kind.STRING,
414 value: value.description,
415 block: true,
416 }
417 : undefined),
418 name: {
419 kind: graphql_1.Kind.NAME,
420 value: value.name,
421 },
422 // ConstXNode has been introduced in v16 but it is not compatible with XNode so we do `as any` for backwards compatibility
423 directives: getDeprecatableDirectiveNodes(value, schema, pathToDirectivesInExtensions),
424 };
425}
426exports.astFromEnumValue = astFromEnumValue;
427function makeDeprecatedDirective(deprecationReason) {
428 return makeDirectiveNode('deprecated', { reason: deprecationReason }, graphql_1.GraphQLDeprecatedDirective);
429}
430exports.makeDeprecatedDirective = makeDeprecatedDirective;
431function makeDirectiveNode(name, args, directive) {
432 const directiveArguments = [];
433 if (directive != null) {
434 for (const arg of directive.args) {
435 const argName = arg.name;
436 const argValue = args[argName];
437 if (argValue !== undefined) {
438 const value = (0, graphql_1.astFromValue)(argValue, arg.type);
439 if (value) {
440 directiveArguments.push({
441 kind: graphql_1.Kind.ARGUMENT,
442 name: {
443 kind: graphql_1.Kind.NAME,
444 value: argName,
445 },
446 value,
447 });
448 }
449 }
450 }
451 }
452 else {
453 for (const argName in args) {
454 const argValue = args[argName];
455 const value = (0, astFromValueUntyped_js_1.astFromValueUntyped)(argValue);
456 if (value) {
457 directiveArguments.push({
458 kind: graphql_1.Kind.ARGUMENT,
459 name: {
460 kind: graphql_1.Kind.NAME,
461 value: argName,
462 },
463 value,
464 });
465 }
466 }
467 }
468 return {
469 kind: graphql_1.Kind.DIRECTIVE,
470 name: {
471 kind: graphql_1.Kind.NAME,
472 value: name,
473 },
474 arguments: directiveArguments,
475 };
476}
477exports.makeDirectiveNode = makeDirectiveNode;
478function makeDirectiveNodes(schema, directiveValues) {
479 const directiveNodes = [];
480 for (const directiveName in directiveValues) {
481 const arrayOrSingleValue = directiveValues[directiveName];
482 const directive = schema === null || schema === void 0 ? void 0 : schema.getDirective(directiveName);
483 if (Array.isArray(arrayOrSingleValue)) {
484 for (const value of arrayOrSingleValue) {
485 directiveNodes.push(makeDirectiveNode(directiveName, value, directive));
486 }
487 }
488 else {
489 directiveNodes.push(makeDirectiveNode(directiveName, arrayOrSingleValue, directive));
490 }
491 }
492 return directiveNodes;
493}
494exports.makeDirectiveNodes = makeDirectiveNodes;