UNPKG

6.89 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.buildServiceDefinition = void 0;
4const graphql_1 = require("graphql");
5const graphql_2 = require("./utilities/graphql");
6const predicates_1 = require("./utilities/predicates");
7function flattened(arr) {
8 return new Array().concat(...arr);
9}
10function buildServiceDefinition(modules) {
11 const errors = [];
12 const typeDefinitionsMap = Object.create(null);
13 const typeExtensionsMap = Object.create(null);
14 const directivesMap = Object.create(null);
15 const schemaDefinitions = [];
16 const schemaExtensions = [];
17 for (let module of modules) {
18 if ((0, graphql_2.isNode)(module) && (0, graphql_2.isDocumentNode)(module)) {
19 module = { typeDefs: module };
20 }
21 for (const definition of module.typeDefs.definitions) {
22 if ((0, graphql_1.isTypeDefinitionNode)(definition)) {
23 const typeName = definition.name.value;
24 if (typeDefinitionsMap[typeName]) {
25 typeDefinitionsMap[typeName].push(definition);
26 }
27 else {
28 typeDefinitionsMap[typeName] = [definition];
29 }
30 }
31 else if ((0, graphql_1.isTypeExtensionNode)(definition)) {
32 const typeName = definition.name.value;
33 if (typeExtensionsMap[typeName]) {
34 typeExtensionsMap[typeName].push(definition);
35 }
36 else {
37 typeExtensionsMap[typeName] = [definition];
38 }
39 }
40 else if (definition.kind === graphql_1.Kind.DIRECTIVE_DEFINITION) {
41 const directiveName = definition.name.value;
42 if (directivesMap[directiveName]) {
43 directivesMap[directiveName].push(definition);
44 }
45 else {
46 directivesMap[directiveName] = [definition];
47 }
48 }
49 else if (definition.kind === graphql_1.Kind.SCHEMA_DEFINITION) {
50 schemaDefinitions.push(definition);
51 }
52 else if (definition.kind === graphql_1.Kind.SCHEMA_EXTENSION) {
53 schemaExtensions.push(definition);
54 }
55 }
56 }
57 for (const [typeName, typeDefinitions] of Object.entries(typeDefinitionsMap)) {
58 if (typeDefinitions.length > 1) {
59 errors.push(new graphql_1.GraphQLError(`Type "${typeName}" was defined more than once.`, typeDefinitions));
60 }
61 }
62 for (const [directiveName, directives] of Object.entries(directivesMap)) {
63 if (directives.length > 1) {
64 errors.push(new graphql_1.GraphQLError(`Directive "${directiveName}" was defined more than once.`, directives));
65 }
66 }
67 let operationTypeMap;
68 if (schemaDefinitions.length > 0 || schemaExtensions.length > 0) {
69 operationTypeMap = {};
70 const schemaDefinition = schemaDefinitions[schemaDefinitions.length - 1];
71 const operationTypes = flattened([schemaDefinition, ...schemaExtensions]
72 .map((node) => node.operationTypes)
73 .filter(predicates_1.isNotNullOrUndefined));
74 for (const operationType of operationTypes) {
75 const typeName = operationType.type.name.value;
76 const operation = operationType.operation;
77 if (operationTypeMap[operation]) {
78 throw new graphql_1.GraphQLError(`Must provide only one ${operation} type in schema.`, [schemaDefinition]);
79 }
80 if (!(typeDefinitionsMap[typeName] || typeExtensionsMap[typeName])) {
81 throw new graphql_1.GraphQLError(`Specified ${operation} type "${typeName}" not found in document.`, [schemaDefinition]);
82 }
83 operationTypeMap[operation] = typeName;
84 }
85 }
86 else {
87 operationTypeMap = {
88 query: "Query",
89 mutation: "Mutation",
90 subscription: "Subscription",
91 };
92 }
93 for (const [typeName, typeExtensions] of Object.entries(typeExtensionsMap)) {
94 if (!typeDefinitionsMap[typeName]) {
95 if (Object.values(operationTypeMap).includes(typeName)) {
96 typeDefinitionsMap[typeName] = [
97 {
98 kind: graphql_1.Kind.OBJECT_TYPE_DEFINITION,
99 name: {
100 kind: graphql_1.Kind.NAME,
101 value: typeName,
102 },
103 },
104 ];
105 }
106 else {
107 errors.push(new graphql_1.GraphQLError(`Cannot extend type "${typeName}" because it does not exist in the existing schema.`, typeExtensions));
108 }
109 }
110 }
111 if (errors.length > 0) {
112 return { errors };
113 }
114 try {
115 const typeDefinitions = flattened(Object.values(typeDefinitionsMap));
116 const directives = flattened(Object.values(directivesMap));
117 let schema = (0, graphql_1.buildASTSchema)({
118 kind: graphql_1.Kind.DOCUMENT,
119 definitions: [...typeDefinitions, ...directives],
120 });
121 const typeExtensions = flattened(Object.values(typeExtensionsMap));
122 if (typeExtensions.length > 0) {
123 schema = (0, graphql_1.extendSchema)(schema, {
124 kind: graphql_1.Kind.DOCUMENT,
125 definitions: typeExtensions,
126 });
127 }
128 for (const module of modules) {
129 if ("kind" in module || !module.resolvers)
130 continue;
131 addResolversToSchema(schema, module.resolvers);
132 }
133 return { schema };
134 }
135 catch (error) {
136 return { errors: [error] };
137 }
138}
139exports.buildServiceDefinition = buildServiceDefinition;
140function addResolversToSchema(schema, resolvers) {
141 for (const [typeName, fieldConfigs] of Object.entries(resolvers)) {
142 const type = schema.getType(typeName);
143 if (!(0, graphql_1.isObjectType)(type))
144 continue;
145 const fieldMap = type.getFields();
146 for (const [fieldName, fieldConfig] of Object.entries(fieldConfigs)) {
147 if (fieldName.startsWith("__")) {
148 type[fieldName.substring(2)] = fieldConfig;
149 continue;
150 }
151 const field = fieldMap[fieldName];
152 if (!field)
153 continue;
154 if (typeof fieldConfig === "function") {
155 field.resolve = fieldConfig;
156 }
157 else {
158 if (fieldConfig.resolve) {
159 field.resolve = fieldConfig.resolve;
160 }
161 if (fieldConfig.subscribe) {
162 field.subscribe = fieldConfig.subscribe;
163 }
164 }
165 }
166 }
167}
168//# sourceMappingURL=buildServiceDefinition.js.map
\No newline at end of file