1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.buildModule = void 0;
|
4 | const graphql_1 = require("graphql");
|
5 | const change_case_all_1 = require("change-case-all");
|
6 | const utils_js_1 = require("./utils.js");
|
7 | const registryKeys = ['objects', 'inputs', 'interfaces', 'scalars', 'unions', 'enums'];
|
8 | const resolverKeys = ['scalars', 'objects', 'enums'];
|
9 | function buildModule(name, doc, { importNamespace, importPath, encapsulate, requireRootResolvers, shouldDeclare, rootTypes, schema, baseVisitor, useGraphQLModules, useTypeImports = false, }) {
|
10 | const picks = (0, utils_js_1.createObject)(registryKeys, () => ({}));
|
11 | const defined = (0, utils_js_1.createObject)(registryKeys, () => []);
|
12 | const extended = (0, utils_js_1.createObject)(registryKeys, () => []);
|
13 |
|
14 | const usedTypes = (0, utils_js_1.collectUsedTypes)(doc);
|
15 | (0, graphql_1.visit)(doc, {
|
16 | ObjectTypeDefinition(node) {
|
17 | collectTypeDefinition(node);
|
18 | },
|
19 | ObjectTypeExtension(node) {
|
20 | collectTypeExtension(node);
|
21 | },
|
22 | InputObjectTypeDefinition(node) {
|
23 | collectTypeDefinition(node);
|
24 | },
|
25 | InputObjectTypeExtension(node) {
|
26 | collectTypeExtension(node);
|
27 | },
|
28 | InterfaceTypeDefinition(node) {
|
29 | collectTypeDefinition(node);
|
30 | },
|
31 | InterfaceTypeExtension(node) {
|
32 | collectTypeExtension(node);
|
33 | },
|
34 | ScalarTypeDefinition(node) {
|
35 | collectTypeDefinition(node);
|
36 | },
|
37 | UnionTypeDefinition(node) {
|
38 | collectTypeDefinition(node);
|
39 | },
|
40 | UnionTypeExtension(node) {
|
41 | collectTypeExtension(node);
|
42 | },
|
43 | EnumTypeDefinition(node) {
|
44 | collectTypeDefinition(node);
|
45 | },
|
46 | EnumTypeExtension(node) {
|
47 | collectTypeExtension(node);
|
48 | },
|
49 | });
|
50 |
|
51 | const visited = (0, utils_js_1.createObject)(registryKeys, key => (0, utils_js_1.concatByKey)(defined, extended, key));
|
52 |
|
53 | const external = (0, utils_js_1.createObject)(registryKeys, key => (0, utils_js_1.uniqueByKey)(extended, defined, key));
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 | const imports = [`import${useTypeImports ? ' type' : ''} * as ${importNamespace} from "${importPath}";`];
|
63 | if (useGraphQLModules) {
|
64 | imports.push(`import${useTypeImports ? ' type' : ''} * as gm from "graphql-modules";`);
|
65 | }
|
66 | let content = [
|
67 | printDefinedFields(),
|
68 | printDefinedEnumValues(),
|
69 | printDefinedInputFields(),
|
70 | printSchemaTypes(usedTypes),
|
71 | printScalars(visited),
|
72 | printResolveSignaturesPerType(visited),
|
73 | printResolversType(visited),
|
74 | useGraphQLModules ? printResolveMiddlewareMap() : undefined,
|
75 | ]
|
76 | .filter(Boolean)
|
77 | .join('\n\n');
|
78 | if (encapsulate === 'namespace') {
|
79 | content =
|
80 | `${shouldDeclare ? 'declare' : 'export'} namespace ${baseVisitor.convertName(name, {
|
81 | suffix: 'Module',
|
82 | useTypesPrefix: false,
|
83 | useTypesSuffix: false,
|
84 | })} {\n` +
|
85 | (shouldDeclare ? `${(0, utils_js_1.indent)(2)(imports.join('\n'))}\n` : '') +
|
86 | (0, utils_js_1.indent)(2)(content) +
|
87 | '\n}';
|
88 | }
|
89 | return [...(!shouldDeclare ? imports : []), content].filter(Boolean).join('\n');
|
90 | |
91 |
|
92 |
|
93 | function printDefinedFields() {
|
94 | return (0, utils_js_1.buildBlock)({
|
95 | name: `interface DefinedFields`,
|
96 | lines: [...visited.objects, ...visited.interfaces].map(typeName => `${typeName}: ${printPicks(typeName, {
|
97 | ...picks.objects,
|
98 | ...picks.interfaces,
|
99 | })};`),
|
100 | });
|
101 | }
|
102 | |
103 |
|
104 |
|
105 | function printDefinedEnumValues() {
|
106 | return (0, utils_js_1.buildBlock)({
|
107 | name: `interface DefinedEnumValues`,
|
108 | lines: visited.enums.map(typeName => `${typeName}: ${printPicks(typeName, picks.enums)};`),
|
109 | });
|
110 | }
|
111 | function encapsulateTypeName(typeName) {
|
112 | if (encapsulate === 'prefix') {
|
113 | return `${(0, change_case_all_1.pascalCase)(name)}_${typeName}`;
|
114 | }
|
115 | return typeName;
|
116 | }
|
117 | |
118 |
|
119 |
|
120 | function printDefinedInputFields() {
|
121 | return (0, utils_js_1.buildBlock)({
|
122 | name: `interface DefinedInputFields`,
|
123 | lines: visited.inputs.map(typeName => `${typeName}: ${printPicks(typeName, picks.inputs)};`),
|
124 | });
|
125 | }
|
126 | |
127 |
|
128 |
|
129 | function printSchemaTypes(types) {
|
130 | return types
|
131 | .filter(type => !visited.scalars.includes(type))
|
132 | .map(printExportType)
|
133 | .join('\n');
|
134 | }
|
135 | function printResolveSignaturesPerType(registry) {
|
136 | return [
|
137 | [...registry.objects, ...registry.interfaces]
|
138 | .map(name => printResolverType(name, 'DefinedFields',
|
139 |
|
140 | requireRootResolvers && rootTypes.includes(name), !rootTypes.includes(name) && defined.objects.includes(name) ? ` | '__isTypeOf'` : ''))
|
141 | .join('\n'),
|
142 | ].join('\n');
|
143 | }
|
144 | function printScalars(registry) {
|
145 | if (!registry.scalars.length) {
|
146 | return '';
|
147 | }
|
148 | return [
|
149 | `export type ${encapsulateTypeName('Scalars')} = Pick<${importNamespace}.Scalars, ${registry.scalars
|
150 | .map(utils_js_1.withQuotes)
|
151 | .join(' | ')}>;`,
|
152 | ...registry.scalars.map(scalar => {
|
153 | const convertedName = baseVisitor.convertName(scalar, {
|
154 | suffix: 'ScalarConfig',
|
155 | });
|
156 | return `export type ${encapsulateTypeName(convertedName)} = ${importNamespace}.${convertedName};`;
|
157 | }),
|
158 | ].join('\n');
|
159 | }
|
160 | |
161 |
|
162 |
|
163 | function printResolversType(registry) {
|
164 | const lines = [];
|
165 | for (const kind in registry) {
|
166 | const k = kind;
|
167 | if (registry.hasOwnProperty(k) && resolverKeys.includes(k)) {
|
168 | const types = registry[k];
|
169 | types.forEach(typeName => {
|
170 | if (k === 'enums') {
|
171 | return;
|
172 | }
|
173 | if (k === 'scalars') {
|
174 | lines.push(`${typeName}?: ${encapsulateTypeName(importNamespace)}.Resolvers['${typeName}'];`);
|
175 | }
|
176 | else {
|
177 |
|
178 | const fieldModifier = requireRootResolvers && rootTypes.includes(typeName) ? '' : '?';
|
179 | lines.push(`${typeName}${fieldModifier}: ${encapsulateTypeName(typeName)}Resolvers;`);
|
180 | }
|
181 | });
|
182 | }
|
183 | }
|
184 | return (0, utils_js_1.buildBlock)({
|
185 | name: `export interface ${encapsulateTypeName('Resolvers')}`,
|
186 | lines,
|
187 | });
|
188 | }
|
189 | |
190 |
|
191 |
|
192 | function printResolveMiddlewareMap() {
|
193 | const wildcardField = printResolveMiddlewareRecord((0, utils_js_1.withQuotes)('*'));
|
194 | const blocks = [(0, utils_js_1.buildBlock)({ name: `${(0, utils_js_1.withQuotes)('*')}?:`, lines: [wildcardField] })];
|
195 |
|
196 | for (const typeName in picks.objects) {
|
197 | if (picks.objects.hasOwnProperty(typeName)) {
|
198 | const fields = picks.objects[typeName];
|
199 | const lines = [wildcardField].concat(fields.map(field => printResolveMiddlewareRecord(field)));
|
200 | blocks.push((0, utils_js_1.buildBlock)({
|
201 | name: `${typeName}?:`,
|
202 | lines,
|
203 | }));
|
204 | }
|
205 | }
|
206 | return (0, utils_js_1.buildBlock)({
|
207 | name: `export interface ${encapsulateTypeName('MiddlewareMap')}`,
|
208 | lines: blocks,
|
209 | });
|
210 | }
|
211 | function printResolveMiddlewareRecord(path) {
|
212 | return `${path}?: gm.Middleware[];`;
|
213 | }
|
214 | function printResolverType(typeName, picksTypeName, requireFieldsResolvers = false, extraKeys = '') {
|
215 | const typeSignature = `Pick<${importNamespace}.${baseVisitor.convertName(typeName, {
|
216 | suffix: 'Resolvers',
|
217 | })}, ${picksTypeName}['${typeName}']${extraKeys}>`;
|
218 | return `export type ${encapsulateTypeName(`${typeName}Resolvers`)} = ${requireFieldsResolvers ? `Required<${typeSignature}>` : typeSignature};`;
|
219 | }
|
220 | function printPicks(typeName, records) {
|
221 | return records[typeName].filter(utils_js_1.unique).map(utils_js_1.withQuotes).join(' | ');
|
222 | }
|
223 | function printTypeBody(typeName) {
|
224 | const coreType = `${importNamespace}.${baseVisitor.convertName(typeName, {
|
225 | useTypesSuffix: true,
|
226 | useTypesPrefix: true,
|
227 | })}`;
|
228 | if (external.enums.includes(typeName) || external.objects.includes(typeName)) {
|
229 | if (schema && (0, graphql_1.isScalarType)(schema.getType(typeName))) {
|
230 | return `${importNamespace}.Scalars['${typeName}']`;
|
231 | }
|
232 | return coreType;
|
233 | }
|
234 | if (defined.enums.includes(typeName) && picks.enums[typeName]) {
|
235 | return `DefinedEnumValues['${typeName}']`;
|
236 | }
|
237 | if (defined.objects.includes(typeName) && picks.objects[typeName]) {
|
238 | return `Pick<${coreType}, DefinedFields['${typeName}']>`;
|
239 | }
|
240 | if (defined.interfaces.includes(typeName) && picks.interfaces[typeName]) {
|
241 | return `Pick<${coreType}, DefinedFields['${typeName}']>`;
|
242 | }
|
243 | if (defined.inputs.includes(typeName) && picks.inputs[typeName]) {
|
244 | return `Pick<${coreType}, DefinedInputFields['${typeName}']>`;
|
245 | }
|
246 | return coreType;
|
247 | }
|
248 | function printExportType(typeName) {
|
249 | return `export type ${encapsulateTypeName(typeName)} = ${printTypeBody(typeName)};`;
|
250 | }
|
251 |
|
252 |
|
253 |
|
254 |
|
255 |
|
256 |
|
257 |
|
258 | function collectFields(node, picksObj) {
|
259 | const name = node.name.value;
|
260 | if (node.fields) {
|
261 | if (!picksObj[name]) {
|
262 | picksObj[name] = [];
|
263 | }
|
264 | node.fields.forEach(field => {
|
265 | picksObj[name].push(field.name.value);
|
266 | });
|
267 | }
|
268 | }
|
269 | function collectValuesFromEnum(node) {
|
270 | const name = node.name.value;
|
271 | if (node.values) {
|
272 | if (!picks.enums[name]) {
|
273 | picks.enums[name] = [];
|
274 | }
|
275 | node.values.forEach(field => {
|
276 | picks.enums[name].push(field.name.value);
|
277 | });
|
278 | }
|
279 | }
|
280 | function collectTypeDefinition(node) {
|
281 | const name = node.name.value;
|
282 | switch (node.kind) {
|
283 | case graphql_1.Kind.OBJECT_TYPE_DEFINITION: {
|
284 | defined.objects.push(name);
|
285 | collectFields(node, picks.objects);
|
286 | break;
|
287 | }
|
288 | case graphql_1.Kind.ENUM_TYPE_DEFINITION: {
|
289 | defined.enums.push(name);
|
290 | collectValuesFromEnum(node);
|
291 | break;
|
292 | }
|
293 | case graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION: {
|
294 | defined.inputs.push(name);
|
295 | collectFields(node, picks.inputs);
|
296 | break;
|
297 | }
|
298 | case graphql_1.Kind.SCALAR_TYPE_DEFINITION: {
|
299 | defined.scalars.push(name);
|
300 | break;
|
301 | }
|
302 | case graphql_1.Kind.INTERFACE_TYPE_DEFINITION: {
|
303 | defined.interfaces.push(name);
|
304 | collectFields(node, picks.interfaces);
|
305 | break;
|
306 | }
|
307 | case graphql_1.Kind.UNION_TYPE_DEFINITION: {
|
308 | defined.unions.push(name);
|
309 | break;
|
310 | }
|
311 | }
|
312 | }
|
313 | function collectTypeExtension(node) {
|
314 | const name = node.name.value;
|
315 | switch (node.kind) {
|
316 | case graphql_1.Kind.OBJECT_TYPE_EXTENSION: {
|
317 | collectFields(node, picks.objects);
|
318 |
|
319 |
|
320 | if (rootTypes.includes(name)) {
|
321 | (0, utils_js_1.pushUnique)(defined.objects, name);
|
322 | return;
|
323 | }
|
324 | (0, utils_js_1.pushUnique)(extended.objects, name);
|
325 | break;
|
326 | }
|
327 | case graphql_1.Kind.ENUM_TYPE_EXTENSION: {
|
328 | collectValuesFromEnum(node);
|
329 | (0, utils_js_1.pushUnique)(extended.enums, name);
|
330 | break;
|
331 | }
|
332 | case graphql_1.Kind.INPUT_OBJECT_TYPE_EXTENSION: {
|
333 | collectFields(node, picks.inputs);
|
334 | (0, utils_js_1.pushUnique)(extended.inputs, name);
|
335 | break;
|
336 | }
|
337 | case graphql_1.Kind.INTERFACE_TYPE_EXTENSION: {
|
338 | collectFields(node, picks.interfaces);
|
339 | (0, utils_js_1.pushUnique)(extended.interfaces, name);
|
340 | break;
|
341 | }
|
342 | case graphql_1.Kind.UNION_TYPE_EXTENSION: {
|
343 | (0, utils_js_1.pushUnique)(extended.unions, name);
|
344 | break;
|
345 | }
|
346 | }
|
347 | }
|
348 | }
|
349 | exports.buildModule = buildModule;
|