UNPKG

128 kBJavaScriptView Raw
1import { Kind, isScalarType, isEqualType, isListType, isNonNullType, isObjectType, isAbstractType, isEnumType, isInterfaceType, GraphQLObjectType, isUnionType, visit, print, isTypeSubTypeOf, SchemaMetaFieldDef, TypeMetaFieldDef } from 'graphql';
2import { resolveExternalModuleAndFn, DetailedError, ApolloFederation, getBaseType, removeNonNullWrapper } from '@graphql-codegen/plugin-helpers';
3import { pascalCase } from 'change-case-all';
4import { resolve, relative, dirname, join, isAbsolute, extname, basename } from 'path';
5import parse from 'parse-filepath';
6import autoBind from 'auto-bind';
7import flatMap from 'array.prototype.flatmap';
8import { DepGraph } from 'dependency-graph';
9import gqlTag from 'graphql-tag';
10import { optimizeDocumentNode } from '@graphql-tools/optimize';
11import { optimizeDocuments } from '@graphql-tools/relay-operation-optimizer';
12
13const DEFAULT_SCALARS = {
14 ID: 'string',
15 String: 'string',
16 Boolean: 'boolean',
17 Int: 'number',
18 Float: 'number',
19};
20
21function isExternalMapperType(m) {
22 return !!m.import;
23}
24var MapperKind;
25(function (MapperKind) {
26 MapperKind[MapperKind["Namespace"] = 0] = "Namespace";
27 MapperKind[MapperKind["Default"] = 1] = "Default";
28 MapperKind[MapperKind["Regular"] = 2] = "Regular";
29})(MapperKind || (MapperKind = {}));
30function prepareLegacy(mapper) {
31 const items = mapper.split('#');
32 const isNamespace = items.length === 3;
33 const isDefault = items[1].trim() === 'default' || items[1].startsWith('default ');
34 const hasAlias = items[1].includes(' as ');
35 return {
36 items,
37 isDefault,
38 isNamespace,
39 hasAlias,
40 };
41}
42function prepare(mapper) {
43 const [source, path] = mapper.split('#');
44 const isNamespace = path.includes('.');
45 const isDefault = path.trim() === 'default' || path.startsWith('default ');
46 const hasAlias = path.includes(' as ');
47 return {
48 items: isNamespace ? [source, ...path.split('.')] : [source, path],
49 isDefault,
50 isNamespace,
51 hasAlias,
52 };
53}
54function isLegacyMode(mapper) {
55 return mapper.split('#').length === 3;
56}
57function parseMapper(mapper, gqlTypeName = null, suffix) {
58 if (isExternalMapper(mapper)) {
59 const { isNamespace, isDefault, hasAlias, items } = isLegacyMode(mapper) ? prepareLegacy(mapper) : prepare(mapper);
60 const mapperKind = isNamespace
61 ? MapperKind.Namespace
62 : isDefault
63 ? MapperKind.Default
64 : MapperKind.Regular;
65 function handleAlias(isDefault = false) {
66 const [importedType, aliasType] = items[1].split(/\s+as\s+/);
67 const type = maybeSuffix(aliasType);
68 return {
69 importElement: isDefault ? type : `${importedType} as ${type}`,
70 type: type,
71 };
72 }
73 function maybeSuffix(type) {
74 if (suffix) {
75 return addSuffix(type, suffix);
76 }
77 return type;
78 }
79 function handle() {
80 switch (mapperKind) {
81 // ./my/module#Namespace#Identifier
82 case MapperKind.Namespace: {
83 const [, ns, identifier] = items;
84 return {
85 type: `${ns}.${identifier}`,
86 importElement: ns,
87 };
88 }
89 case MapperKind.Default: {
90 // ./my/module#default as alias
91 if (hasAlias) {
92 return handleAlias(true);
93 }
94 const type = maybeSuffix(`${gqlTypeName}`);
95 // ./my/module#default
96 return {
97 importElement: type,
98 type,
99 };
100 }
101 case MapperKind.Regular: {
102 // ./my/module#Identifier as alias
103 if (hasAlias) {
104 return handleAlias();
105 }
106 const identifier = items[1];
107 const type = maybeSuffix(identifier);
108 // ./my/module#Identifier
109 return {
110 type,
111 importElement: suffix ? `${identifier} as ${type}` : type,
112 };
113 }
114 }
115 }
116 const { type, importElement } = handle();
117 return {
118 default: isDefault,
119 isExternal: true,
120 source: items[0],
121 type,
122 import: importElement.replace(/<(.*?)>/g, ''),
123 };
124 }
125 return {
126 isExternal: false,
127 type: mapper,
128 };
129}
130function addSuffix(element, suffix) {
131 const generic = element.indexOf('<');
132 if (generic === -1) {
133 return `${element}${suffix}`;
134 }
135 return `${element.slice(0, generic)}${suffix}${element.slice(generic)}`;
136}
137function isExternalMapper(value) {
138 return value.includes('#');
139}
140function transformMappers(rawMappers, mapperTypeSuffix) {
141 const result = {};
142 Object.keys(rawMappers).forEach(gqlTypeName => {
143 const mapperDef = rawMappers[gqlTypeName];
144 const parsedMapper = parseMapper(mapperDef, gqlTypeName, mapperTypeSuffix);
145 result[gqlTypeName] = parsedMapper;
146 });
147 return result;
148}
149function buildMapperImport(source, types, useTypeImports) {
150 if (!types || types.length === 0) {
151 return null;
152 }
153 const defaultType = types.find(t => t.asDefault === true);
154 let namedTypes = types.filter(t => !t.asDefault);
155 if (useTypeImports) {
156 if (defaultType) {
157 // default as Baz
158 namedTypes = [{ identifier: `default as ${defaultType.identifier}` }, ...namedTypes];
159 }
160 // { Foo, Bar as BarModel }
161 const namedImports = namedTypes.length ? `{ ${namedTypes.map(t => t.identifier).join(', ')} }` : '';
162 // { default as Baz, Foo, Bar as BarModel }
163 return `import type ${[namedImports].filter(Boolean).join(', ')} from '${source}';`;
164 }
165 // { Foo, Bar as BarModel }
166 const namedImports = namedTypes.length ? `{ ${namedTypes.map(t => t.identifier).join(', ')} }` : '';
167 // Baz
168 const defaultImport = defaultType ? defaultType.identifier : '';
169 // Baz, { Foo, Bar as BarModel }
170 return `import ${[defaultImport, namedImports].filter(Boolean).join(', ')} from '${source}';`;
171}
172
173const getConfigValue = (value, defaultValue) => {
174 if (value === null || value === undefined) {
175 return defaultValue;
176 }
177 return value;
178};
179function quoteIfNeeded(array, joinWith = ' & ') {
180 if (array.length === 0) {
181 return '';
182 }
183 else if (array.length === 1) {
184 return array[0];
185 }
186 else {
187 return `(${array.join(joinWith)})`;
188 }
189}
190function block(array) {
191 return array && array.length !== 0 ? '{\n' + array.join('\n') + '\n}' : '';
192}
193function wrapWithSingleQuotes(value, skipNumericCheck = false) {
194 if (skipNumericCheck) {
195 if (typeof value === 'number') {
196 return `${value}`;
197 }
198 else {
199 return `'${value}'`;
200 }
201 }
202 if (typeof value === 'number' ||
203 (typeof value === 'string' && !isNaN(parseInt(value)) && parseFloat(value).toString() === value)) {
204 return `${value}`;
205 }
206 return `'${value}'`;
207}
208function breakLine(str) {
209 return str + '\n';
210}
211function indent(str, count = 1) {
212 return new Array(count).fill(' ').join('') + str;
213}
214function indentMultiline(str, count = 1) {
215 const indentation = new Array(count).fill(' ').join('');
216 const replaceWith = '\n' + indentation;
217 return indentation + str.replace(/\n/g, replaceWith);
218}
219function transformComment(comment, indentLevel = 0, disabled = false) {
220 if (!comment || comment === '' || disabled) {
221 return '';
222 }
223 if (isStringValueNode(comment)) {
224 comment = comment.value;
225 }
226 comment = comment.split('*/').join('*\\/');
227 let lines = comment.split('\n');
228 if (lines.length === 1) {
229 return indent(`/** ${lines[0]} */\n`, indentLevel);
230 }
231 lines = ['/**', ...lines.map(line => ` * ${line}`), ' */\n'];
232 return stripTrailingSpaces(lines.map(line => indent(line, indentLevel)).join('\n'));
233}
234class DeclarationBlock {
235 constructor(_config) {
236 this._config = _config;
237 this._decorator = null;
238 this._export = false;
239 this._name = null;
240 this._kind = null;
241 this._methodName = null;
242 this._content = null;
243 this._block = null;
244 this._nameGenerics = null;
245 this._comment = null;
246 this._ignoreBlockWrapper = false;
247 this._config = {
248 blockWrapper: '',
249 blockTransformer: block => block,
250 enumNameValueSeparator: ':',
251 ...this._config,
252 };
253 }
254 withDecorator(decorator) {
255 this._decorator = decorator;
256 return this;
257 }
258 export(exp = true) {
259 if (!this._config.ignoreExport) {
260 this._export = exp;
261 }
262 return this;
263 }
264 asKind(kind) {
265 this._kind = kind;
266 return this;
267 }
268 withComment(comment, disabled = false) {
269 const nonEmptyComment = isStringValueNode(comment) ? !!comment.value : !!comment;
270 if (nonEmptyComment && !disabled) {
271 this._comment = transformComment(comment, 0);
272 }
273 return this;
274 }
275 withMethodCall(methodName, ignoreBlockWrapper = false) {
276 this._methodName = methodName;
277 this._ignoreBlockWrapper = ignoreBlockWrapper;
278 return this;
279 }
280 withBlock(block) {
281 this._block = block;
282 return this;
283 }
284 withContent(content) {
285 this._content = content;
286 return this;
287 }
288 withName(name, generics = null) {
289 this._name = name;
290 this._nameGenerics = generics;
291 return this;
292 }
293 get string() {
294 let result = '';
295 if (this._decorator) {
296 result += this._decorator + '\n';
297 }
298 if (this._export) {
299 result += 'export ';
300 }
301 if (this._kind) {
302 let extra = '';
303 let name = '';
304 if (['type', 'const', 'var', 'let'].includes(this._kind)) {
305 extra = '= ';
306 }
307 if (this._name) {
308 name = this._name + (this._nameGenerics || '') + ' ';
309 }
310 result += this._kind + ' ' + name + extra;
311 }
312 if (this._block) {
313 if (this._content) {
314 result += this._content;
315 }
316 const blockWrapper = this._ignoreBlockWrapper ? '' : this._config.blockWrapper;
317 const before = '{' + blockWrapper;
318 const after = blockWrapper + '}';
319 const block = [before, this._block, after].filter(val => !!val).join('\n');
320 if (this._methodName) {
321 result += `${this._methodName}(${this._config.blockTransformer(block)})`;
322 }
323 else {
324 result += this._config.blockTransformer(block);
325 }
326 }
327 else if (this._content) {
328 result += this._content;
329 }
330 else if (this._kind) {
331 result += this._config.blockTransformer('{}');
332 }
333 return stripTrailingSpaces((this._comment ? this._comment : '') +
334 result +
335 (this._kind === 'interface' || this._kind === 'enum' || this._kind === 'namespace' || this._kind === 'function'
336 ? ''
337 : ';') +
338 '\n');
339 }
340}
341function getBaseTypeNode(typeNode) {
342 if (typeNode.kind === Kind.LIST_TYPE || typeNode.kind === Kind.NON_NULL_TYPE) {
343 return getBaseTypeNode(typeNode.type);
344 }
345 return typeNode;
346}
347function convertNameParts(str, func, removeUnderscore = false) {
348 if (removeUnderscore) {
349 return func(str);
350 }
351 return str
352 .split('_')
353 .map(s => func(s))
354 .join('_');
355}
356function buildScalars(schema, scalarsMapping, defaultScalarsMapping = DEFAULT_SCALARS, defaultScalarType = 'any') {
357 const result = {};
358 Object.keys(defaultScalarsMapping).forEach(name => {
359 result[name] = parseMapper(defaultScalarsMapping[name]);
360 });
361 if (schema) {
362 const typeMap = schema.getTypeMap();
363 Object.keys(typeMap)
364 .map(typeName => typeMap[typeName])
365 .filter(type => isScalarType(type))
366 .map((scalarType) => {
367 const name = scalarType.name;
368 if (typeof scalarsMapping === 'string') {
369 const value = parseMapper(scalarsMapping + '#' + name, name);
370 result[name] = value;
371 }
372 else if (scalarsMapping && typeof scalarsMapping[name] === 'string') {
373 const value = parseMapper(scalarsMapping[name], name);
374 result[name] = value;
375 }
376 else if (scalarsMapping && scalarsMapping[name]) {
377 result[name] = {
378 isExternal: false,
379 type: JSON.stringify(scalarsMapping[name]),
380 };
381 }
382 else if (!defaultScalarsMapping[name]) {
383 result[name] = {
384 isExternal: false,
385 type: defaultScalarType,
386 };
387 }
388 });
389 }
390 else if (scalarsMapping) {
391 if (typeof scalarsMapping === 'string') {
392 throw new Error('Cannot use string scalars mapping when building without a schema');
393 }
394 Object.keys(scalarsMapping).forEach(name => {
395 if (typeof scalarsMapping[name] === 'string') {
396 const value = parseMapper(scalarsMapping[name], name);
397 result[name] = value;
398 }
399 else {
400 result[name] = {
401 isExternal: false,
402 type: JSON.stringify(scalarsMapping[name]),
403 };
404 }
405 });
406 }
407 return result;
408}
409function isStringValueNode(node) {
410 return node && typeof node === 'object' && node.kind === Kind.STRING;
411}
412function isRootType(type, schema) {
413 return (isEqualType(type, schema.getQueryType()) ||
414 isEqualType(type, schema.getMutationType()) ||
415 isEqualType(type, schema.getSubscriptionType()));
416}
417function getRootTypeNames(schema) {
418 return [schema.getQueryType(), schema.getMutationType(), schema.getSubscriptionType()]
419 .filter(t => t)
420 .map(t => t.name);
421}
422function stripMapperTypeInterpolation(identifier) {
423 return identifier.trim().replace(/<{.*}>/, '');
424}
425const OMIT_TYPE = 'export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;';
426const REQUIRE_FIELDS_TYPE = `export type RequireFields<T, K extends keyof T> = { [X in Exclude<keyof T, K>]?: T[X] } & { [P in K]-?: NonNullable<T[P]> };`;
427function mergeSelectionSets(selectionSet1, selectionSet2) {
428 const newSelections = [...selectionSet1.selections];
429 for (const selection2 of selectionSet2.selections) {
430 if (selection2.kind === 'FragmentSpread') {
431 newSelections.push(selection2);
432 continue;
433 }
434 if (selection2.kind !== 'Field') {
435 throw new TypeError('Invalid state.');
436 }
437 const match = newSelections.find(selection1 => selection1.kind === 'Field' && getFieldNodeNameValue(selection1) === getFieldNodeNameValue(selection2));
438 if (match) {
439 // recursively merge all selection sets
440 if (match.kind === 'Field' && match.selectionSet && selection2.selectionSet) {
441 mergeSelectionSets(match.selectionSet, selection2.selectionSet);
442 }
443 continue;
444 }
445 newSelections.push(selection2);
446 }
447 // replace existing selections
448 selectionSet1.selections = newSelections;
449}
450const getFieldNodeNameValue = (node) => {
451 return (node.alias || node.name).value;
452};
453function separateSelectionSet(selections) {
454 return {
455 fields: selections.filter(s => s.kind === Kind.FIELD),
456 inlines: selections.filter(s => s.kind === Kind.INLINE_FRAGMENT),
457 spreads: selections.filter(s => s.kind === Kind.FRAGMENT_SPREAD),
458 };
459}
460function getPossibleTypes(schema, type) {
461 if (isListType(type) || isNonNullType(type)) {
462 return getPossibleTypes(schema, type.ofType);
463 }
464 else if (isObjectType(type)) {
465 return [type];
466 }
467 else if (isAbstractType(type)) {
468 return schema.getPossibleTypes(type);
469 }
470 return [];
471}
472function hasConditionalDirectives(directives) {
473 if (directives.length === 0)
474 return false;
475 for (const directive of directives) {
476 if (['skip', 'include'].includes(directive.name.value)) {
477 return true;
478 }
479 }
480 return false;
481}
482function wrapTypeWithModifiers(baseType, type, options) {
483 let currentType = type;
484 const modifiers = [];
485 while (currentType) {
486 if (isNonNullType(currentType)) {
487 currentType = currentType.ofType;
488 }
489 else {
490 modifiers.push(options.wrapOptional);
491 }
492 if (isListType(currentType)) {
493 modifiers.push(options.wrapArray);
494 currentType = currentType.ofType;
495 }
496 else {
497 break;
498 }
499 }
500 return modifiers.reduceRight((result, modifier) => modifier(result), baseType);
501}
502function removeDescription(nodes) {
503 return nodes.map(node => ({ ...node, description: undefined }));
504}
505function wrapTypeNodeWithModifiers(baseType, typeNode) {
506 switch (typeNode.kind) {
507 case Kind.NAMED_TYPE: {
508 return `Maybe<${baseType}>`;
509 }
510 case Kind.NON_NULL_TYPE: {
511 const innerType = wrapTypeNodeWithModifiers(baseType, typeNode.type);
512 return clearOptional(innerType);
513 }
514 case Kind.LIST_TYPE: {
515 const innerType = wrapTypeNodeWithModifiers(baseType, typeNode.type);
516 return `Maybe<Array<${innerType}>>`;
517 }
518 }
519}
520function clearOptional(str) {
521 const rgx = new RegExp(`^Maybe<(.*?)>$`, 'i');
522 if (str.startsWith(`Maybe`)) {
523 return str.replace(rgx, '$1');
524 }
525 return str;
526}
527function stripTrailingSpaces(str) {
528 return str.replace(/ +\n/g, '\n');
529}
530
531function getKind(node) {
532 if (typeof node === 'string') {
533 return 'typeNames';
534 }
535 if (['EnumValueDefinition', 'EnumValue'].includes(node.kind)) {
536 return 'enumValues';
537 }
538 return 'typeNames';
539}
540function getName(node) {
541 if (node == null) {
542 return undefined;
543 }
544 if (typeof node === 'string') {
545 return node;
546 }
547 switch (node.kind) {
548 case 'OperationDefinition':
549 case 'Variable':
550 case 'Argument':
551 case 'FragmentSpread':
552 case 'FragmentDefinition':
553 case 'ObjectField':
554 case 'Directive':
555 case 'NamedType':
556 case 'ScalarTypeDefinition':
557 case 'ObjectTypeDefinition':
558 case 'FieldDefinition':
559 case 'InputValueDefinition':
560 case 'InterfaceTypeDefinition':
561 case 'UnionTypeDefinition':
562 case 'EnumTypeDefinition':
563 case 'EnumValueDefinition':
564 case 'InputObjectTypeDefinition':
565 case 'DirectiveDefinition': {
566 return getName(node.name);
567 }
568 case 'Name': {
569 return node.value;
570 }
571 case 'Field': {
572 return getName(node.alias || node.name);
573 }
574 case 'VariableDefinition': {
575 return getName(node.variable);
576 }
577 }
578 return undefined;
579}
580function convertFactory(config) {
581 function resolveConventionName(type) {
582 if (!config.namingConvention) {
583 return (str, opts = {}) => {
584 return convertNameParts(str, pascalCase, getConfigValue((opts || {}).transformUnderscore, false));
585 };
586 }
587 if (typeof config.namingConvention === 'string') {
588 if (config.namingConvention === 'keep') {
589 return str => str;
590 }
591 return (str, opts = {}) => {
592 return convertNameParts(str, resolveExternalModuleAndFn(config.namingConvention), getConfigValue((opts || {}).transformUnderscore, false));
593 };
594 }
595 if (typeof config.namingConvention === 'function') {
596 return (str, opts = {}) => {
597 return convertNameParts(str, config.namingConvention, getConfigValue((opts || {}).transformUnderscore, false));
598 };
599 }
600 if (typeof config.namingConvention === 'object' && config.namingConvention[type] === 'keep') {
601 return str => str;
602 }
603 if (typeof config.namingConvention === 'object') {
604 if (!config.namingConvention[type]) {
605 return (str, opts = {}) => {
606 const transformUnderscore = config.namingConvention.transformUnderscore || (opts || {}).transformUnderscore;
607 return convertNameParts(str, pascalCase, getConfigValue(transformUnderscore, false));
608 };
609 }
610 return (str, opts = {}) => {
611 return convertNameParts(str, resolveExternalModuleAndFn(config.namingConvention[type]), getConfigValue((opts || {}).transformUnderscore, true));
612 };
613 }
614 return config.namingConvention[type];
615 }
616 return (node, opts) => {
617 const prefix = opts && opts.prefix;
618 const suffix = opts && opts.suffix;
619 const kind = getKind(node);
620 const str = [prefix || '', getName(node), suffix || ''].join('');
621 return resolveConventionName(kind)(str, opts);
622 };
623}
624
625function escapeString(str) {
626 return str.replace(/\\/g, '\\\\').replace(/\n/g, '\\n').replace(/'/g, "\\'");
627}
628function parseEnumValues({ schema, mapOrStr = {}, ignoreEnumValuesFromSchema, }) {
629 const allTypes = schema.getTypeMap();
630 const allEnums = Object.keys(allTypes).filter(t => isEnumType(allTypes[t]));
631 if (typeof mapOrStr === 'object') {
632 if (!ignoreEnumValuesFromSchema) {
633 for (const enumTypeName of allEnums) {
634 const enumType = schema.getType(enumTypeName);
635 for (const { name, value } of enumType.getValues()) {
636 if (value && value !== name) {
637 mapOrStr[enumTypeName] = mapOrStr[enumTypeName] || {};
638 if (typeof mapOrStr[enumTypeName] !== 'string' && !mapOrStr[enumTypeName][name]) {
639 mapOrStr[enumTypeName][name] = typeof value === 'string' ? escapeString(value) : value;
640 }
641 }
642 }
643 }
644 }
645 const invalidMappings = Object.keys(mapOrStr).filter(gqlName => !allEnums.includes(gqlName));
646 if (invalidMappings.length > 0) {
647 throw new DetailedError(`Invalid 'enumValues' mapping!`, `The following types does not exist in your GraphQL schema: ${invalidMappings.join(', ')}`);
648 }
649 return Object.keys(mapOrStr).reduce((prev, gqlIdentifier) => {
650 const pointer = mapOrStr[gqlIdentifier];
651 if (typeof pointer === 'string') {
652 const mapper = parseMapper(pointer, gqlIdentifier);
653 return {
654 ...prev,
655 [gqlIdentifier]: {
656 isDefault: mapper.isExternal && mapper.default,
657 typeIdentifier: gqlIdentifier,
658 sourceFile: mapper.isExternal ? mapper.source : null,
659 sourceIdentifier: mapper.type,
660 importIdentifier: mapper.isExternal ? mapper.import : null,
661 mappedValues: null,
662 },
663 };
664 }
665 else if (typeof pointer === 'object') {
666 return {
667 ...prev,
668 [gqlIdentifier]: {
669 isDefault: false,
670 typeIdentifier: gqlIdentifier,
671 sourceFile: null,
672 sourceIdentifier: null,
673 importIdentifier: null,
674 mappedValues: pointer,
675 },
676 };
677 }
678 else {
679 throw new DetailedError(`Invalid "enumValues" configuration`, `Enum "${gqlIdentifier}": expected string or object (with enum values mapping)`);
680 }
681 }, {});
682 }
683 else if (typeof mapOrStr === 'string') {
684 return allEnums
685 .filter(enumName => !enumName.startsWith('__'))
686 .reduce((prev, enumName) => {
687 return {
688 ...prev,
689 [enumName]: {
690 isDefault: false,
691 typeIdentifier: enumName,
692 sourceFile: mapOrStr,
693 sourceIdentifier: enumName,
694 importIdentifier: enumName,
695 mappedValues: null,
696 },
697 };
698 }, {});
699 }
700 return {};
701}
702
703const DEFAULT_DECLARATION_KINDS = {
704 scalar: 'type',
705 input: 'type',
706 type: 'type',
707 interface: 'type',
708 arguments: 'type',
709};
710function normalizeDeclarationKind(declarationKind) {
711 if (typeof declarationKind === 'string') {
712 return {
713 scalar: declarationKind,
714 input: declarationKind,
715 type: declarationKind,
716 interface: declarationKind,
717 arguments: declarationKind,
718 };
719 }
720 return {
721 ...DEFAULT_DECLARATION_KINDS,
722 ...declarationKind,
723 };
724}
725
726const DEFAULT_AVOID_OPTIONALS = {
727 object: false,
728 inputValue: false,
729 field: false,
730 defaultValue: false,
731};
732function normalizeAvoidOptionals(avoidOptionals) {
733 if (typeof avoidOptionals === 'boolean') {
734 return {
735 object: avoidOptionals,
736 inputValue: avoidOptionals,
737 field: avoidOptionals,
738 defaultValue: avoidOptionals,
739 };
740 }
741 return {
742 ...DEFAULT_AVOID_OPTIONALS,
743 ...avoidOptionals,
744 };
745}
746
747function generateFragmentImportStatement(statement, kind) {
748 const { importSource: fragmentImportSource, ...rest } = statement;
749 const { identifiers, path, namespace } = fragmentImportSource;
750 const importSource = {
751 identifiers: identifiers
752 .filter(fragmentImport => kind === 'both' || kind === fragmentImport.kind)
753 .map(({ name }) => name),
754 path,
755 namespace,
756 };
757 return generateImportStatement({
758 importSource,
759 ...rest,
760 typesImport: kind === 'type' ? statement.typesImport : false,
761 });
762}
763function generateImportStatement(statement) {
764 const { baseDir, importSource, outputPath, typesImport } = statement;
765 const importPath = resolveImportPath(baseDir, outputPath, importSource.path);
766 const importNames = importSource.identifiers && importSource.identifiers.length
767 ? `{ ${Array.from(new Set(importSource.identifiers)).join(', ')} }`
768 : '*';
769 const importAlias = importSource.namespace ? ` as ${importSource.namespace}` : '';
770 const importStatement = typesImport ? 'import type' : 'import';
771 return `${importStatement} ${importNames}${importAlias} from '${importPath}';${importAlias ? '\n' : ''}`;
772}
773function resolveImportPath(baseDir, outputPath, sourcePath) {
774 const shouldAbsolute = !sourcePath.startsWith('~');
775 if (shouldAbsolute) {
776 const absGeneratedFilePath = resolve(baseDir, outputPath);
777 const absImportFilePath = resolve(baseDir, sourcePath);
778 return resolveRelativeImport(absGeneratedFilePath, absImportFilePath);
779 }
780 else {
781 return sourcePath.replace(`~`, '');
782 }
783}
784function resolveRelativeImport(from, to) {
785 if (!isAbsolute(from)) {
786 throw new Error(`Argument 'from' must be an absolute path, '${from}' given.`);
787 }
788 if (!isAbsolute(to)) {
789 throw new Error(`Argument 'to' must be an absolute path, '${to}' given.`);
790 }
791 return fixLocalFilePath(clearExtension(relative(dirname(from), to)));
792}
793function resolveImportSource(source) {
794 return typeof source === 'string' ? { path: source } : source;
795}
796function clearExtension(path) {
797 const parsedPath = parse(path);
798 return join(parsedPath.dir, parsedPath.name).replace(/\\/g, '/');
799}
800function fixLocalFilePath(path) {
801 return !path.startsWith('..') ? `./${path}` : path;
802}
803
804class BaseVisitor {
805 constructor(rawConfig, additionalConfig) {
806 this._declarationBlockConfig = {};
807 this._parsedConfig = {
808 convert: convertFactory(rawConfig),
809 typesPrefix: rawConfig.typesPrefix || '',
810 typesSuffix: rawConfig.typesSuffix || '',
811 externalFragments: rawConfig.externalFragments || [],
812 fragmentImports: rawConfig.fragmentImports || [],
813 addTypename: !rawConfig.skipTypename,
814 nonOptionalTypename: !!rawConfig.nonOptionalTypename,
815 useTypeImports: !!rawConfig.useTypeImports,
816 ...(additionalConfig || {}),
817 };
818 this.scalars = {};
819 Object.keys(this.config.scalars || {}).forEach(key => {
820 this.scalars[key] = this.config.scalars[key].type;
821 });
822 autoBind(this);
823 }
824 getVisitorKindContextFromAncestors(ancestors) {
825 if (!ancestors) {
826 return [];
827 }
828 return ancestors.map(t => t.kind).filter(Boolean);
829 }
830 get config() {
831 return this._parsedConfig;
832 }
833 convertName(node, options) {
834 const useTypesPrefix = typeof (options && options.useTypesPrefix) === 'boolean' ? options.useTypesPrefix : true;
835 const useTypesSuffix = typeof (options && options.useTypesSuffix) === 'boolean' ? options.useTypesSuffix : true;
836 let convertedName = '';
837 if (useTypesPrefix) {
838 convertedName += this.config.typesPrefix;
839 }
840 convertedName += this.config.convert(node, options);
841 if (useTypesSuffix) {
842 convertedName += this.config.typesSuffix;
843 }
844 return convertedName;
845 }
846 getOperationSuffix(node, operationType) {
847 const { omitOperationSuffix = false, dedupeOperationSuffix = false } = this.config;
848 const operationName = typeof node === 'string' ? node : node.name ? node.name.value : '';
849 return omitOperationSuffix
850 ? ''
851 : dedupeOperationSuffix && operationName.toLowerCase().endsWith(operationType.toLowerCase())
852 ? ''
853 : operationType;
854 }
855 getFragmentSuffix(node) {
856 return this.getOperationSuffix(node, 'Fragment');
857 }
858 getFragmentName(node) {
859 return this.convertName(node, {
860 suffix: this.getFragmentSuffix(node),
861 useTypesPrefix: false,
862 });
863 }
864 getFragmentVariableName(node) {
865 const { omitOperationSuffix = false, dedupeOperationSuffix = false, fragmentVariableSuffix = 'FragmentDoc', fragmentVariablePrefix = '', } = this.config;
866 const fragmentName = typeof node === 'string' ? node : node.name.value;
867 const suffix = omitOperationSuffix
868 ? ''
869 : dedupeOperationSuffix &&
870 fragmentName.toLowerCase().endsWith('fragment') &&
871 fragmentVariableSuffix.toLowerCase().startsWith('fragment')
872 ? fragmentVariableSuffix.substring('fragment'.length)
873 : fragmentVariableSuffix;
874 return this.convertName(node, {
875 prefix: fragmentVariablePrefix,
876 suffix,
877 useTypesPrefix: false,
878 });
879 }
880 getPunctuation(_declarationKind) {
881 return '';
882 }
883}
884
885class OperationVariablesToObject {
886 constructor(_scalars, _convertName, _namespacedImportName = null, _enumNames = [], _enumPrefix = true, _enumValues = {}, _applyCoercion = false) {
887 this._scalars = _scalars;
888 this._convertName = _convertName;
889 this._namespacedImportName = _namespacedImportName;
890 this._enumNames = _enumNames;
891 this._enumPrefix = _enumPrefix;
892 this._enumValues = _enumValues;
893 this._applyCoercion = _applyCoercion;
894 autoBind(this);
895 }
896 getName(node) {
897 if (node.name) {
898 if (typeof node.name === 'string') {
899 return node.name;
900 }
901 return node.name.value;
902 }
903 else if (node.variable) {
904 return node.variable.name.value;
905 }
906 return null;
907 }
908 transform(variablesNode) {
909 if (!variablesNode || variablesNode.length === 0) {
910 return null;
911 }
912 return (variablesNode.map(variable => indent(this.transformVariable(variable))).join(`${this.getPunctuation()}\n`) +
913 this.getPunctuation());
914 }
915 getScalar(name) {
916 const prefix = this._namespacedImportName ? `${this._namespacedImportName}.` : '';
917 return `${prefix}Scalars['${name}']`;
918 }
919 transformVariable(variable) {
920 let typeValue = null;
921 const prefix = this._namespacedImportName ? `${this._namespacedImportName}.` : '';
922 if (typeof variable.type === 'string') {
923 typeValue = variable.type;
924 }
925 else {
926 const baseType = getBaseTypeNode(variable.type);
927 const typeName = baseType.name.value;
928 if (this._scalars[typeName]) {
929 typeValue = this.getScalar(typeName);
930 }
931 else if (this._enumValues[typeName] && this._enumValues[typeName].sourceFile) {
932 typeValue = this._enumValues[typeName].typeIdentifier || this._enumValues[typeName].sourceIdentifier;
933 }
934 else {
935 typeValue = `${prefix}${this._convertName(baseType, {
936 useTypesPrefix: this._enumNames.includes(typeName) ? this._enumPrefix : true,
937 })}`;
938 }
939 }
940 const fieldName = this.getName(variable);
941 const fieldType = this.wrapAstTypeWithModifiers(typeValue, variable.type, this._applyCoercion);
942 const hasDefaultValue = variable.defaultValue != null && typeof variable.defaultValue !== 'undefined';
943 const isNonNullType = variable.type.kind === Kind.NON_NULL_TYPE;
944 const formattedFieldString = this.formatFieldString(fieldName, isNonNullType, hasDefaultValue);
945 const formattedTypeString = this.formatTypeString(fieldType, isNonNullType, hasDefaultValue);
946 return `${formattedFieldString}: ${formattedTypeString}`;
947 }
948 wrapAstTypeWithModifiers(_baseType, _typeNode, _applyCoercion) {
949 throw new Error(`You must override "wrapAstTypeWithModifiers" of OperationVariablesToObject!`);
950 }
951 formatFieldString(fieldName, isNonNullType, _hasDefaultValue) {
952 return fieldName;
953 }
954 formatTypeString(fieldType, isNonNullType, hasDefaultValue) {
955 const prefix = this._namespacedImportName ? `${this._namespacedImportName}.` : '';
956 if (hasDefaultValue) {
957 return `${prefix}Maybe<${fieldType}>`;
958 }
959 return fieldType;
960 }
961 getPunctuation() {
962 return ',';
963 }
964}
965
966class BaseTypesVisitor extends BaseVisitor {
967 constructor(_schema, rawConfig, additionalConfig, defaultScalars = DEFAULT_SCALARS) {
968 super(rawConfig, {
969 enumPrefix: getConfigValue(rawConfig.enumPrefix, true),
970 onlyOperationTypes: getConfigValue(rawConfig.onlyOperationTypes, false),
971 addUnderscoreToArgsType: getConfigValue(rawConfig.addUnderscoreToArgsType, false),
972 enumValues: parseEnumValues({
973 schema: _schema,
974 mapOrStr: rawConfig.enumValues,
975 ignoreEnumValuesFromSchema: rawConfig.ignoreEnumValuesFromSchema,
976 }),
977 declarationKind: normalizeDeclarationKind(rawConfig.declarationKind),
978 scalars: buildScalars(_schema, rawConfig.scalars, defaultScalars),
979 fieldWrapperValue: getConfigValue(rawConfig.fieldWrapperValue, 'T'),
980 wrapFieldDefinitions: getConfigValue(rawConfig.wrapFieldDefinitions, false),
981 ignoreEnumValuesFromSchema: getConfigValue(rawConfig.ignoreEnumValuesFromSchema, false),
982 ...additionalConfig,
983 });
984 this._schema = _schema;
985 this._argumentsTransformer = new OperationVariablesToObject(this.scalars, this.convertName);
986 }
987 getExportPrefix() {
988 return 'export ';
989 }
990 getFieldWrapperValue() {
991 if (this.config.fieldWrapperValue) {
992 return `${this.getExportPrefix()}type FieldWrapper<T> = ${this.config.fieldWrapperValue};`;
993 }
994 return '';
995 }
996 getScalarsImports() {
997 return Object.keys(this.config.scalars)
998 .map(enumName => {
999 const mappedValue = this.config.scalars[enumName];
1000 if (mappedValue.isExternal) {
1001 return this._buildTypeImport(mappedValue.import, mappedValue.source, mappedValue.default);
1002 }
1003 return null;
1004 })
1005 .filter(a => a);
1006 }
1007 get scalarsDefinition() {
1008 const allScalars = Object.keys(this.config.scalars).map(scalarName => {
1009 const scalarValue = this.config.scalars[scalarName].type;
1010 const scalarType = this._schema.getType(scalarName);
1011 const comment = scalarType && scalarType.astNode && scalarType.description ? transformComment(scalarType.description, 1) : '';
1012 const { scalar } = this._parsedConfig.declarationKind;
1013 return comment + indent(`${scalarName}: ${scalarValue}${this.getPunctuation(scalar)}`);
1014 });
1015 return new DeclarationBlock(this._declarationBlockConfig)
1016 .export()
1017 .asKind(this._parsedConfig.declarationKind.scalar)
1018 .withName('Scalars')
1019 .withComment('All built-in and custom scalars, mapped to their actual values')
1020 .withBlock(allScalars.join('\n')).string;
1021 }
1022 setDeclarationBlockConfig(config) {
1023 this._declarationBlockConfig = config;
1024 }
1025 setArgumentsTransformer(argumentsTransfomer) {
1026 this._argumentsTransformer = argumentsTransfomer;
1027 }
1028 NonNullType(node) {
1029 const asString = node.type;
1030 return asString;
1031 }
1032 getInputObjectDeclarationBlock(node) {
1033 return new DeclarationBlock(this._declarationBlockConfig)
1034 .export()
1035 .asKind(this._parsedConfig.declarationKind.input)
1036 .withName(this.convertName(node))
1037 .withComment(node.description)
1038 .withBlock(node.fields.join('\n'));
1039 }
1040 InputObjectTypeDefinition(node) {
1041 return this.getInputObjectDeclarationBlock(node).string;
1042 }
1043 InputValueDefinition(node) {
1044 const comment = transformComment(node.description, 1);
1045 const { input } = this._parsedConfig.declarationKind;
1046 return comment + indent(`${node.name}: ${node.type}${this.getPunctuation(input)}`);
1047 }
1048 Name(node) {
1049 return node.value;
1050 }
1051 FieldDefinition(node) {
1052 const typeString = node.type;
1053 const { type } = this._parsedConfig.declarationKind;
1054 const comment = this.getFieldComment(node);
1055 return comment + indent(`${node.name}: ${typeString}${this.getPunctuation(type)}`);
1056 }
1057 UnionTypeDefinition(node, key, parent) {
1058 if (this.config.onlyOperationTypes)
1059 return '';
1060 const originalNode = parent[key];
1061 const possibleTypes = originalNode.types
1062 .map(t => (this.scalars[t.name.value] ? this._getScalar(t.name.value) : this.convertName(t)))
1063 .join(' | ');
1064 return new DeclarationBlock(this._declarationBlockConfig)
1065 .export()
1066 .asKind('type')
1067 .withName(this.convertName(node))
1068 .withComment(node.description)
1069 .withContent(possibleTypes).string;
1070 }
1071 mergeInterfaces(interfaces, hasOtherFields) {
1072 return interfaces.join(' & ') + (interfaces.length && hasOtherFields ? ' & ' : '');
1073 }
1074 appendInterfacesAndFieldsToBlock(block, interfaces, fields) {
1075 block.withContent(this.mergeInterfaces(interfaces, fields.length > 0));
1076 block.withBlock(this.mergeAllFields(fields, interfaces.length > 0));
1077 }
1078 getObjectTypeDeclarationBlock(node, originalNode) {
1079 const optionalTypename = this.config.nonOptionalTypename ? '__typename' : '__typename?';
1080 const { type, interface: interfacesType } = this._parsedConfig.declarationKind;
1081 const allFields = [
1082 ...(this.config.addTypename
1083 ? [
1084 indent(`${this.config.immutableTypes ? 'readonly ' : ''}${optionalTypename}: '${node.name}'${this.getPunctuation(type)}`),
1085 ]
1086 : []),
1087 ...node.fields,
1088 ];
1089 const interfacesNames = originalNode.interfaces ? originalNode.interfaces.map(i => this.convertName(i)) : [];
1090 const declarationBlock = new DeclarationBlock(this._declarationBlockConfig)
1091 .export()
1092 .asKind(type)
1093 .withName(this.convertName(node))
1094 .withComment(node.description);
1095 if (type === 'interface' || type === 'class') {
1096 if (interfacesNames.length > 0) {
1097 const keyword = interfacesType === 'interface' && type === 'class' ? 'implements' : 'extends';
1098 declarationBlock.withContent(`${keyword} ` + interfacesNames.join(', ') + (allFields.length > 0 ? ' ' : ' {}'));
1099 }
1100 declarationBlock.withBlock(this.mergeAllFields(allFields, false));
1101 }
1102 else {
1103 this.appendInterfacesAndFieldsToBlock(declarationBlock, interfacesNames, allFields);
1104 }
1105 return declarationBlock;
1106 }
1107 getFieldComment(node) {
1108 let commentText = node.description;
1109 const deprecationDirective = node.directives.find((v) => v.name === 'deprecated');
1110 if (deprecationDirective) {
1111 const deprecationReason = this.getDeprecationReason(deprecationDirective);
1112 commentText = `${commentText ? `${commentText}\n` : ''}@deprecated ${deprecationReason}`;
1113 }
1114 const comment = transformComment(commentText, 1);
1115 return comment;
1116 }
1117 mergeAllFields(allFields, _hasInterfaces) {
1118 return allFields.join('\n');
1119 }
1120 ObjectTypeDefinition(node, key, parent) {
1121 if (this.config.onlyOperationTypes)
1122 return '';
1123 const originalNode = parent[key];
1124 return [this.getObjectTypeDeclarationBlock(node, originalNode).string, this.buildArgumentsBlock(originalNode)]
1125 .filter(f => f)
1126 .join('\n\n');
1127 }
1128 getInterfaceTypeDeclarationBlock(node, _originalNode) {
1129 const declarationBlock = new DeclarationBlock(this._declarationBlockConfig)
1130 .export()
1131 .asKind(this._parsedConfig.declarationKind.interface)
1132 .withName(this.convertName(node))
1133 .withComment(node.description);
1134 return declarationBlock.withBlock(node.fields.join('\n'));
1135 }
1136 InterfaceTypeDefinition(node, key, parent) {
1137 if (this.config.onlyOperationTypes)
1138 return '';
1139 const originalNode = parent[key];
1140 return [this.getInterfaceTypeDeclarationBlock(node, originalNode).string, this.buildArgumentsBlock(originalNode)]
1141 .filter(f => f)
1142 .join('\n\n');
1143 }
1144 ScalarTypeDefinition(_node) {
1145 // We empty this because we handle scalars in a different way, see constructor.
1146 return '';
1147 }
1148 _buildTypeImport(identifier, source, asDefault = false) {
1149 const { useTypeImports } = this.config;
1150 if (asDefault) {
1151 if (useTypeImports) {
1152 return `import type { default as ${identifier} } from '${source}';`;
1153 }
1154 return `import ${identifier} from '${source}';`;
1155 }
1156 return `import${useTypeImports ? ' type' : ''} { ${identifier} } from '${source}';`;
1157 }
1158 handleEnumValueMapper(typeIdentifier, importIdentifier, sourceIdentifier, sourceFile) {
1159 const importStatement = this._buildTypeImport(importIdentifier || sourceIdentifier, sourceFile);
1160 if (importIdentifier !== sourceIdentifier || sourceIdentifier !== typeIdentifier) {
1161 return [importStatement, `import ${typeIdentifier} = ${sourceIdentifier};`];
1162 }
1163 return [importStatement];
1164 }
1165 getEnumsImports() {
1166 return flatMap(Object.keys(this.config.enumValues), enumName => {
1167 const mappedValue = this.config.enumValues[enumName];
1168 if (mappedValue.sourceFile) {
1169 if (mappedValue.isDefault) {
1170 return [this._buildTypeImport(mappedValue.typeIdentifier, mappedValue.sourceFile, true)];
1171 }
1172 return this.handleEnumValueMapper(mappedValue.typeIdentifier, mappedValue.importIdentifier, mappedValue.sourceIdentifier, mappedValue.sourceFile);
1173 }
1174 return [];
1175 }).filter(a => a);
1176 }
1177 EnumTypeDefinition(node) {
1178 const enumName = node.name;
1179 // In case of mapped external enum string
1180 if (this.config.enumValues[enumName] && this.config.enumValues[enumName].sourceFile) {
1181 return null;
1182 }
1183 return new DeclarationBlock(this._declarationBlockConfig)
1184 .export()
1185 .asKind('enum')
1186 .withName(this.convertName(node, { useTypesPrefix: this.config.enumPrefix }))
1187 .withComment(node.description)
1188 .withBlock(this.buildEnumValuesBlock(enumName, node.values)).string;
1189 }
1190 // We are using it in order to transform "description" field
1191 StringValue(node) {
1192 return node.value;
1193 }
1194 makeValidEnumIdentifier(identifier) {
1195 if (/^[0-9]/.exec(identifier)) {
1196 return wrapWithSingleQuotes(identifier, true);
1197 }
1198 return identifier;
1199 }
1200 buildEnumValuesBlock(typeName, values) {
1201 const schemaEnumType = this._schema
1202 ? this._schema.getType(typeName)
1203 : undefined;
1204 return values
1205 .map(enumOption => {
1206 const optionName = this.makeValidEnumIdentifier(this.convertName(enumOption, { useTypesPrefix: false, transformUnderscore: true }));
1207 const comment = transformComment(enumOption.description, 1);
1208 const schemaEnumValue = schemaEnumType && !this.config.ignoreEnumValuesFromSchema
1209 ? schemaEnumType.getValue(enumOption.name).value
1210 : undefined;
1211 let enumValue = typeof schemaEnumValue !== 'undefined' ? schemaEnumValue : enumOption.name;
1212 if (this.config.enumValues[typeName] &&
1213 this.config.enumValues[typeName].mappedValues &&
1214 typeof this.config.enumValues[typeName].mappedValues[enumValue] !== 'undefined') {
1215 enumValue = this.config.enumValues[typeName].mappedValues[enumValue];
1216 }
1217 return (comment +
1218 indent(`${optionName}${this._declarationBlockConfig.enumNameValueSeparator} ${wrapWithSingleQuotes(enumValue, typeof schemaEnumValue !== 'undefined')}`));
1219 })
1220 .join(',\n');
1221 }
1222 DirectiveDefinition(_node) {
1223 return '';
1224 }
1225 getArgumentsObjectDeclarationBlock(node, name, field) {
1226 return new DeclarationBlock(this._declarationBlockConfig)
1227 .export()
1228 .asKind(this._parsedConfig.declarationKind.arguments)
1229 .withName(this.convertName(name))
1230 .withComment(node.description)
1231 .withBlock(this._argumentsTransformer.transform(field.arguments));
1232 }
1233 getArgumentsObjectTypeDefinition(node, name, field) {
1234 return this.getArgumentsObjectDeclarationBlock(node, name, field).string;
1235 }
1236 buildArgumentsBlock(node) {
1237 const fieldsWithArguments = node.fields.filter(field => field.arguments && field.arguments.length > 0) || [];
1238 return fieldsWithArguments
1239 .map(field => {
1240 const name = node.name.value +
1241 (this.config.addUnderscoreToArgsType ? '_' : '') +
1242 this.convertName(field, {
1243 useTypesPrefix: false,
1244 useTypesSuffix: false,
1245 }) +
1246 'Args';
1247 return this.getArgumentsObjectTypeDefinition(node, name, field);
1248 })
1249 .join('\n\n');
1250 }
1251 _getScalar(name) {
1252 return `Scalars['${name}']`;
1253 }
1254 _getTypeForNode(node) {
1255 const typeAsString = node.name;
1256 if (this.scalars[typeAsString]) {
1257 return this._getScalar(typeAsString);
1258 }
1259 else if (this.config.enumValues[typeAsString]) {
1260 return this.config.enumValues[typeAsString].typeIdentifier;
1261 }
1262 const schemaType = this._schema.getType(node.name);
1263 if (schemaType && isEnumType(schemaType)) {
1264 return this.convertName(node, { useTypesPrefix: this.config.enumPrefix });
1265 }
1266 return this.convertName(node);
1267 }
1268 NamedType(node, key, parent, path, ancestors) {
1269 const currentVisitContext = this.getVisitorKindContextFromAncestors(ancestors);
1270 const isVisitingInputType = currentVisitContext.includes(Kind.INPUT_OBJECT_TYPE_DEFINITION);
1271 const typeToUse = this._getTypeForNode(node);
1272 if (!isVisitingInputType && this.config.fieldWrapperValue && this.config.wrapFieldDefinitions) {
1273 return `FieldWrapper<${typeToUse}>`;
1274 }
1275 return typeToUse;
1276 }
1277 ListType(node) {
1278 const asString = node.type;
1279 return this.wrapWithListType(asString);
1280 }
1281 SchemaDefinition() {
1282 return null;
1283 }
1284 getDeprecationReason(directive) {
1285 if (directive.name === 'deprecated') {
1286 const hasArguments = directive.arguments.length > 0;
1287 let reason = 'Field no longer supported';
1288 if (hasArguments) {
1289 reason = directive.arguments[0].value;
1290 }
1291 return reason;
1292 }
1293 }
1294 wrapWithListType(str) {
1295 return `Array<${str}>`;
1296 }
1297}
1298
1299function getRootType(operation, schema) {
1300 switch (operation) {
1301 case 'query':
1302 return schema.getQueryType();
1303 case 'mutation':
1304 return schema.getMutationType();
1305 case 'subscription':
1306 return schema.getSubscriptionType();
1307 }
1308}
1309class BaseDocumentsVisitor extends BaseVisitor {
1310 constructor(rawConfig, additionalConfig, _schema, defaultScalars = DEFAULT_SCALARS) {
1311 super(rawConfig, {
1312 exportFragmentSpreadSubTypes: getConfigValue(rawConfig.exportFragmentSpreadSubTypes, false),
1313 enumPrefix: getConfigValue(rawConfig.enumPrefix, true),
1314 preResolveTypes: getConfigValue(rawConfig.preResolveTypes, false),
1315 dedupeOperationSuffix: getConfigValue(rawConfig.dedupeOperationSuffix, false),
1316 omitOperationSuffix: getConfigValue(rawConfig.omitOperationSuffix, false),
1317 skipTypeNameForRoot: getConfigValue(rawConfig.skipTypeNameForRoot, false),
1318 namespacedImportName: getConfigValue(rawConfig.namespacedImportName, null),
1319 experimentalFragmentVariables: getConfigValue(rawConfig.experimentalFragmentVariables, false),
1320 addTypename: !rawConfig.skipTypename,
1321 globalNamespace: !!rawConfig.globalNamespace,
1322 operationResultSuffix: getConfigValue(rawConfig.operationResultSuffix, ''),
1323 scalars: buildScalars(_schema, rawConfig.scalars, defaultScalars),
1324 ...(additionalConfig || {}),
1325 });
1326 this._schema = _schema;
1327 this._unnamedCounter = 1;
1328 this._globalDeclarations = new Set();
1329 autoBind(this);
1330 this._variablesTransfomer = new OperationVariablesToObject(this.scalars, this.convertName, this.config.namespacedImportName);
1331 }
1332 getGlobalDeclarations(noExport = false) {
1333 return Array.from(this._globalDeclarations).map(t => (noExport ? t : `export ${t}`));
1334 }
1335 setSelectionSetHandler(handler) {
1336 this._selectionSetToObject = handler;
1337 }
1338 setDeclarationBlockConfig(config) {
1339 this._declarationBlockConfig = config;
1340 }
1341 setVariablesTransformer(variablesTransfomer) {
1342 this._variablesTransfomer = variablesTransfomer;
1343 }
1344 get schema() {
1345 return this._schema;
1346 }
1347 get addTypename() {
1348 return this._parsedConfig.addTypename;
1349 }
1350 handleAnonymousOperation(node) {
1351 const name = node.name && node.name.value;
1352 if (name) {
1353 return this.convertName(name, {
1354 useTypesPrefix: false,
1355 useTypesSuffix: false,
1356 });
1357 }
1358 return this.convertName(this._unnamedCounter++ + '', {
1359 prefix: 'Unnamed_',
1360 suffix: '_',
1361 useTypesPrefix: false,
1362 useTypesSuffix: false,
1363 });
1364 }
1365 FragmentDefinition(node) {
1366 const fragmentRootType = this._schema.getType(node.typeCondition.name.value);
1367 const selectionSet = this._selectionSetToObject.createNext(fragmentRootType, node.selectionSet);
1368 const fragmentSuffix = this.getFragmentSuffix(node);
1369 return [
1370 selectionSet.transformFragmentSelectionSetToTypes(node.name.value, fragmentSuffix, this._declarationBlockConfig),
1371 this.config.experimentalFragmentVariables
1372 ? new DeclarationBlock({
1373 ...this._declarationBlockConfig,
1374 blockTransformer: t => this.applyVariablesWrapper(t),
1375 })
1376 .export()
1377 .asKind('type')
1378 .withName(this.convertName(node.name.value, {
1379 suffix: fragmentSuffix + 'Variables',
1380 }))
1381 .withBlock(this._variablesTransfomer.transform(node.variableDefinitions)).string
1382 : undefined,
1383 ]
1384 .filter(r => r)
1385 .join('\n\n');
1386 }
1387 applyVariablesWrapper(variablesBlock) {
1388 return variablesBlock;
1389 }
1390 OperationDefinition(node) {
1391 const name = this.handleAnonymousOperation(node);
1392 const operationRootType = getRootType(node.operation, this._schema);
1393 if (!operationRootType) {
1394 throw new Error(`Unable to find root schema type for operation type "${node.operation}"!`);
1395 }
1396 const selectionSet = this._selectionSetToObject.createNext(operationRootType, node.selectionSet);
1397 const visitedOperationVariables = this._variablesTransfomer.transform(node.variableDefinitions);
1398 const operationType = pascalCase(node.operation);
1399 const operationTypeSuffix = this.getOperationSuffix(name, operationType);
1400 const operationResult = new DeclarationBlock(this._declarationBlockConfig)
1401 .export()
1402 .asKind('type')
1403 .withName(this.convertName(name, {
1404 suffix: operationTypeSuffix + this._parsedConfig.operationResultSuffix,
1405 }))
1406 .withContent(selectionSet.transformSelectionSet()).string;
1407 const operationVariables = new DeclarationBlock({
1408 ...this._declarationBlockConfig,
1409 blockTransformer: t => this.applyVariablesWrapper(t),
1410 })
1411 .export()
1412 .asKind('type')
1413 .withName(this.convertName(name, {
1414 suffix: operationTypeSuffix + 'Variables',
1415 }))
1416 .withBlock(visitedOperationVariables).string;
1417 return [operationVariables, operationResult].filter(r => r).join('\n\n');
1418 }
1419}
1420
1421class BaseResolversVisitor extends BaseVisitor {
1422 constructor(rawConfig, additionalConfig, _schema, defaultScalars = DEFAULT_SCALARS) {
1423 super(rawConfig, {
1424 immutableTypes: getConfigValue(rawConfig.immutableTypes, false),
1425 optionalResolveType: getConfigValue(rawConfig.optionalResolveType, false),
1426 enumPrefix: getConfigValue(rawConfig.enumPrefix, true),
1427 federation: getConfigValue(rawConfig.federation, false),
1428 resolverTypeWrapperSignature: getConfigValue(rawConfig.resolverTypeWrapperSignature, 'Promise<T> | T'),
1429 enumValues: parseEnumValues({
1430 schema: _schema,
1431 mapOrStr: rawConfig.enumValues,
1432 }),
1433 addUnderscoreToArgsType: getConfigValue(rawConfig.addUnderscoreToArgsType, false),
1434 onlyResolveTypeForInterfaces: getConfigValue(rawConfig.onlyResolveTypeForInterfaces, false),
1435 contextType: parseMapper(rawConfig.contextType || 'any', 'ContextType'),
1436 fieldContextTypes: getConfigValue(rawConfig.fieldContextTypes, []),
1437 resolverTypeSuffix: getConfigValue(rawConfig.resolverTypeSuffix, 'Resolvers'),
1438 allResolversTypeName: getConfigValue(rawConfig.allResolversTypeName, 'Resolvers'),
1439 rootValueType: parseMapper(rawConfig.rootValueType || '{}', 'RootValueType'),
1440 namespacedImportName: getConfigValue(rawConfig.namespacedImportName, ''),
1441 avoidOptionals: getConfigValue(rawConfig.avoidOptionals, false),
1442 defaultMapper: rawConfig.defaultMapper
1443 ? parseMapper(rawConfig.defaultMapper || 'any', 'DefaultMapperType')
1444 : null,
1445 mappers: transformMappers(rawConfig.mappers || {}, rawConfig.mapperTypeSuffix),
1446 scalars: buildScalars(_schema, rawConfig.scalars, defaultScalars),
1447 internalResolversPrefix: getConfigValue(rawConfig.internalResolversPrefix, '__'),
1448 ...(additionalConfig || {}),
1449 });
1450 this._schema = _schema;
1451 this._declarationBlockConfig = {};
1452 this._collectedResolvers = {};
1453 this._collectedDirectiveResolvers = {};
1454 this._usedMappers = {};
1455 this._resolversTypes = {};
1456 this._resolversParentTypes = {};
1457 this._rootTypeNames = [];
1458 this._globalDeclarations = new Set();
1459 this._hasScalars = false;
1460 this._hasFederation = false;
1461 autoBind(this);
1462 this._federation = new ApolloFederation({ enabled: this.config.federation, schema: this.schema });
1463 this._rootTypeNames = getRootTypeNames(_schema);
1464 this._variablesTransfomer = new OperationVariablesToObject(this.scalars, this.convertName, this.config.namespacedImportName);
1465 this._resolversTypes = this.createResolversFields(type => this.applyResolverTypeWrapper(type), type => this.clearResolverTypeWrapper(type), name => this.getTypeToUse(name));
1466 this._resolversParentTypes = this.createResolversFields(type => type, type => type, name => this.getParentTypeToUse(name), namedType => !isEnumType(namedType));
1467 this._fieldContextTypeMap = this.createFieldContextTypeMap();
1468 }
1469 getResolverTypeWrapperSignature() {
1470 return `export type ResolverTypeWrapper<T> = ${this.config.resolverTypeWrapperSignature};`;
1471 }
1472 shouldMapType(type, checkedBefore = {}, duringCheck = []) {
1473 if (checkedBefore[type.name] !== undefined) {
1474 return checkedBefore[type.name];
1475 }
1476 if (type.name.startsWith('__') || this.config.scalars[type.name]) {
1477 return false;
1478 }
1479 if (this.config.mappers[type.name]) {
1480 return true;
1481 }
1482 if (isObjectType(type) || isInterfaceType(type)) {
1483 const fields = type.getFields();
1484 return Object.keys(fields)
1485 .filter(fieldName => {
1486 const field = fields[fieldName];
1487 const fieldType = getBaseType(field.type);
1488 return !duringCheck.includes(fieldType.name);
1489 })
1490 .some(fieldName => {
1491 const field = fields[fieldName];
1492 const fieldType = getBaseType(field.type);
1493 if (checkedBefore[fieldType.name] !== undefined) {
1494 return checkedBefore[fieldType.name];
1495 }
1496 if (this.config.mappers[type.name]) {
1497 return true;
1498 }
1499 duringCheck.push(type.name);
1500 const innerResult = this.shouldMapType(fieldType, checkedBefore, duringCheck);
1501 return innerResult;
1502 });
1503 }
1504 return false;
1505 }
1506 convertName(node, options, applyNamespacedImport = false) {
1507 const sourceType = super.convertName(node, options);
1508 return `${applyNamespacedImport && this.config.namespacedImportName ? this.config.namespacedImportName + '.' : ''}${sourceType}`;
1509 }
1510 // Kamil: this one is heeeeavvyyyy
1511 createResolversFields(applyWrapper, clearWrapper, getTypeToUse, shouldInclude) {
1512 const allSchemaTypes = this._schema.getTypeMap();
1513 const nestedMapping = {};
1514 const typeNames = this._federation.filterTypeNames(Object.keys(allSchemaTypes));
1515 typeNames.forEach(typeName => {
1516 const schemaType = allSchemaTypes[typeName];
1517 nestedMapping[typeName] = this.shouldMapType(schemaType, nestedMapping);
1518 });
1519 return typeNames.reduce((prev, typeName) => {
1520 const schemaType = allSchemaTypes[typeName];
1521 if (typeName.startsWith('__') || (shouldInclude && !shouldInclude(schemaType))) {
1522 return prev;
1523 }
1524 let shouldApplyOmit = false;
1525 const isRootType = this._rootTypeNames.includes(typeName);
1526 const isMapped = this.config.mappers[typeName];
1527 const isScalar = this.config.scalars[typeName];
1528 const hasDefaultMapper = !!(this.config.defaultMapper && this.config.defaultMapper.type);
1529 if (isRootType) {
1530 prev[typeName] = applyWrapper(this.config.rootValueType.type);
1531 return prev;
1532 }
1533 else if (isMapped && this.config.mappers[typeName].type) {
1534 this.markMapperAsUsed(typeName);
1535 prev[typeName] = applyWrapper(this.config.mappers[typeName].type);
1536 }
1537 else if (isInterfaceType(schemaType)) {
1538 const allTypesMap = this._schema.getTypeMap();
1539 const implementingTypes = [];
1540 for (const graphqlType of Object.values(allTypesMap)) {
1541 if (graphqlType instanceof GraphQLObjectType) {
1542 const allInterfaces = graphqlType.getInterfaces();
1543 if (allInterfaces.some(int => int.name === schemaType.name)) {
1544 implementingTypes.push(graphqlType.name);
1545 }
1546 }
1547 }
1548 const possibleTypes = implementingTypes.map(name => getTypeToUse(name)).join(' | ') || 'never';
1549 prev[typeName] = possibleTypes;
1550 return prev;
1551 }
1552 else if (isEnumType(schemaType) && this.config.enumValues[typeName]) {
1553 prev[typeName] =
1554 this.config.enumValues[typeName].sourceIdentifier ||
1555 this.convertName(this.config.enumValues[typeName].typeIdentifier);
1556 }
1557 else if (hasDefaultMapper && !hasPlaceholder(this.config.defaultMapper.type)) {
1558 prev[typeName] = applyWrapper(this.config.defaultMapper.type);
1559 }
1560 else if (isScalar) {
1561 prev[typeName] = applyWrapper(this._getScalar(typeName));
1562 }
1563 else if (isUnionType(schemaType)) {
1564 prev[typeName] = schemaType
1565 .getTypes()
1566 .map(type => getTypeToUse(type.name))
1567 .join(' | ');
1568 }
1569 else {
1570 shouldApplyOmit = true;
1571 prev[typeName] = this.convertName(typeName, { useTypesPrefix: this.config.enumPrefix }, true);
1572 }
1573 if (shouldApplyOmit && prev[typeName] !== 'any' && isObjectType(schemaType)) {
1574 const fields = schemaType.getFields();
1575 const relevantFields = this._federation
1576 .filterFieldNames(Object.keys(fields))
1577 .map(fieldName => {
1578 const field = fields[fieldName];
1579 const baseType = getBaseType(field.type);
1580 const isUnion = isUnionType(baseType);
1581 if (!this.config.mappers[baseType.name] && !isUnion && !nestedMapping[baseType.name]) {
1582 return null;
1583 }
1584 const addOptionalSign = !this.config.avoidOptionals && !isNonNullType(field.type);
1585 return {
1586 addOptionalSign,
1587 fieldName,
1588 replaceWithType: wrapTypeWithModifiers(getTypeToUse(baseType.name), field.type, {
1589 wrapOptional: this.applyMaybe,
1590 wrapArray: this.wrapWithArray,
1591 }),
1592 };
1593 })
1594 .filter(a => a);
1595 if (relevantFields.length > 0) {
1596 // Puts ResolverTypeWrapper on top of an entire type
1597 prev[typeName] = applyWrapper(this.replaceFieldsInType(prev[typeName], relevantFields));
1598 }
1599 else {
1600 // We still want to use ResolverTypeWrapper, even if we don't touch any fields
1601 prev[typeName] = applyWrapper(prev[typeName]);
1602 }
1603 }
1604 if (isMapped && hasPlaceholder(prev[typeName])) {
1605 prev[typeName] = replacePlaceholder(prev[typeName], typeName);
1606 }
1607 if (!isMapped && hasDefaultMapper && hasPlaceholder(this.config.defaultMapper.type)) {
1608 // Make sure the inner type has no ResolverTypeWrapper
1609 const name = clearWrapper(isScalar ? this._getScalar(typeName) : prev[typeName]);
1610 const replaced = replacePlaceholder(this.config.defaultMapper.type, name);
1611 // Don't wrap Union with ResolverTypeWrapper, each inner type already has it
1612 if (isUnionType(schemaType)) {
1613 prev[typeName] = replaced;
1614 }
1615 else {
1616 prev[typeName] = applyWrapper(replacePlaceholder(this.config.defaultMapper.type, name));
1617 }
1618 }
1619 return prev;
1620 }, {});
1621 }
1622 replaceFieldsInType(typeName, relevantFields) {
1623 this._globalDeclarations.add(OMIT_TYPE);
1624 return `Omit<${typeName}, ${relevantFields.map(f => `'${f.fieldName}'`).join(' | ')}> & { ${relevantFields
1625 .map(f => `${f.fieldName}${f.addOptionalSign ? '?' : ''}: ${f.replaceWithType}`)
1626 .join(', ')} }`;
1627 }
1628 applyMaybe(str) {
1629 const namespacedImportPrefix = this.config.namespacedImportName ? this.config.namespacedImportName + '.' : '';
1630 return `${namespacedImportPrefix}Maybe<${str}>`;
1631 }
1632 applyResolverTypeWrapper(str) {
1633 return `ResolverTypeWrapper<${this.clearResolverTypeWrapper(str)}>`;
1634 }
1635 clearMaybe(str) {
1636 const namespacedImportPrefix = this.config.namespacedImportName ? this.config.namespacedImportName + '.' : '';
1637 if (str.startsWith(`${namespacedImportPrefix}Maybe<`)) {
1638 const maybeRe = new RegExp(`${namespacedImportPrefix.replace('.', '\\.')}Maybe<(.*?)>$`);
1639 return str.replace(maybeRe, '$1');
1640 }
1641 return str;
1642 }
1643 clearResolverTypeWrapper(str) {
1644 if (str.startsWith('ResolverTypeWrapper<')) {
1645 return str.replace(/ResolverTypeWrapper<(.*?)>$/, '$1');
1646 }
1647 return str;
1648 }
1649 wrapWithArray(t) {
1650 if (this.config.immutableTypes) {
1651 return `ReadonlyArray<${t}>`;
1652 }
1653 return `Array<${t}>`;
1654 }
1655 createFieldContextTypeMap() {
1656 return this.config.fieldContextTypes.reduce((prev, fieldContextType) => {
1657 const items = fieldContextType.split('#');
1658 if (items.length === 3) {
1659 const [path, source, contextTypeName] = items;
1660 return { ...prev, [path]: parseMapper(`${source}#${contextTypeName}`) };
1661 }
1662 const [path, contextType] = items;
1663 return { ...prev, [path]: parseMapper(contextType) };
1664 }, {});
1665 }
1666 buildResolversTypes() {
1667 const declarationKind = 'type';
1668 return new DeclarationBlock(this._declarationBlockConfig)
1669 .export()
1670 .asKind(declarationKind)
1671 .withName(this.convertName('ResolversTypes'))
1672 .withComment('Mapping between all available schema types and the resolvers types')
1673 .withBlock(Object.keys(this._resolversTypes)
1674 .map(typeName => indent(`${typeName}: ${this._resolversTypes[typeName]}${this.getPunctuation(declarationKind)}`))
1675 .join('\n')).string;
1676 }
1677 buildResolversParentTypes() {
1678 const declarationKind = 'type';
1679 return new DeclarationBlock(this._declarationBlockConfig)
1680 .export()
1681 .asKind(declarationKind)
1682 .withName(this.convertName('ResolversParentTypes'))
1683 .withComment('Mapping between all available schema types and the resolvers parents')
1684 .withBlock(Object.keys(this._resolversParentTypes)
1685 .map(typeName => indent(`${typeName}: ${this._resolversParentTypes[typeName]}${this.getPunctuation(declarationKind)}`))
1686 .join('\n')).string;
1687 }
1688 get schema() {
1689 return this._schema;
1690 }
1691 get defaultMapperType() {
1692 return this.config.defaultMapper.type;
1693 }
1694 get unusedMappers() {
1695 return Object.keys(this.config.mappers).filter(name => !this._usedMappers[name]);
1696 }
1697 get globalDeclarations() {
1698 return Array.from(this._globalDeclarations);
1699 }
1700 isMapperImported(groupedMappers, identifier, source) {
1701 const exists = !groupedMappers[source] ? false : !!groupedMappers[source].find(m => m.identifier === identifier);
1702 const existsFromEnums = !!Object.keys(this.config.enumValues)
1703 .map(key => this.config.enumValues[key])
1704 .find(o => o.sourceFile === source && o.typeIdentifier === identifier);
1705 return exists || existsFromEnums;
1706 }
1707 get mappersImports() {
1708 const groupedMappers = {};
1709 const addMapper = (source, identifier, asDefault) => {
1710 if (!this.isMapperImported(groupedMappers, identifier, source)) {
1711 if (!groupedMappers[source]) {
1712 groupedMappers[source] = [];
1713 }
1714 groupedMappers[source].push({ identifier, asDefault });
1715 }
1716 };
1717 Object.keys(this.config.mappers)
1718 .map(gqlTypeName => ({ gqlType: gqlTypeName, mapper: this.config.mappers[gqlTypeName] }))
1719 .filter(({ mapper }) => mapper.isExternal)
1720 .forEach(({ mapper }) => {
1721 const externalMapper = mapper;
1722 const identifier = stripMapperTypeInterpolation(externalMapper.import);
1723 addMapper(externalMapper.source, identifier, externalMapper.default);
1724 });
1725 if (this.config.contextType.isExternal) {
1726 addMapper(this.config.contextType.source, this.config.contextType.import, this.config.contextType.default);
1727 }
1728 if (this.config.rootValueType.isExternal) {
1729 addMapper(this.config.rootValueType.source, this.config.rootValueType.import, this.config.rootValueType.default);
1730 }
1731 if (this.config.defaultMapper && this.config.defaultMapper.isExternal) {
1732 const identifier = stripMapperTypeInterpolation(this.config.defaultMapper.import);
1733 addMapper(this.config.defaultMapper.source, identifier, this.config.defaultMapper.default);
1734 }
1735 Object.values(this._fieldContextTypeMap).forEach(parsedMapper => {
1736 if (parsedMapper.isExternal) {
1737 addMapper(parsedMapper.source, parsedMapper.import, parsedMapper.default);
1738 }
1739 });
1740 return Object.keys(groupedMappers)
1741 .map(source => buildMapperImport(source, groupedMappers[source], this.config.useTypeImports))
1742 .filter(Boolean);
1743 }
1744 setDeclarationBlockConfig(config) {
1745 this._declarationBlockConfig = config;
1746 }
1747 setVariablesTransformer(variablesTransfomer) {
1748 this._variablesTransfomer = variablesTransfomer;
1749 }
1750 hasScalars() {
1751 return this._hasScalars;
1752 }
1753 hasFederation() {
1754 return this._hasFederation;
1755 }
1756 getRootResolver() {
1757 const name = this.convertName(this.config.allResolversTypeName);
1758 const declarationKind = 'type';
1759 const contextType = `<ContextType = ${this.config.contextType.type}>`;
1760 // This is here because we don't want to break IResolvers, so there is a mapping by default,
1761 // and if the developer is overriding typesPrefix, it won't get generated at all.
1762 const deprecatedIResolvers = !this.config.typesPrefix
1763 ? `
1764/**
1765 * @deprecated
1766 * Use "Resolvers" root object instead. If you wish to get "IResolvers", add "typesPrefix: I" to your config.
1767 */
1768export type IResolvers${contextType} = ${name}<ContextType>;`
1769 : '';
1770 return [
1771 new DeclarationBlock(this._declarationBlockConfig)
1772 .export()
1773 .asKind(declarationKind)
1774 .withName(name, contextType)
1775 .withBlock(Object.keys(this._collectedResolvers)
1776 .map(schemaTypeName => {
1777 const resolverType = this._collectedResolvers[schemaTypeName];
1778 return indent(this.formatRootResolver(schemaTypeName, resolverType, declarationKind));
1779 })
1780 .join('\n')).string,
1781 deprecatedIResolvers,
1782 ].join('\n');
1783 }
1784 formatRootResolver(schemaTypeName, resolverType, declarationKind) {
1785 return `${schemaTypeName}${this.config.avoidOptionals ? '' : '?'}: ${resolverType}${this.getPunctuation(declarationKind)}`;
1786 }
1787 getAllDirectiveResolvers() {
1788 if (Object.keys(this._collectedDirectiveResolvers).length) {
1789 const declarationKind = 'type';
1790 const name = this.convertName('DirectiveResolvers');
1791 const contextType = `<ContextType = ${this.config.contextType.type}>`;
1792 // This is here because we don't want to break IResolvers, so there is a mapping by default,
1793 // and if the developer is overriding typesPrefix, it won't get generated at all.
1794 const deprecatedIResolvers = !this.config.typesPrefix
1795 ? `
1796/**
1797 * @deprecated
1798 * Use "DirectiveResolvers" root object instead. If you wish to get "IDirectiveResolvers", add "typesPrefix: I" to your config.
1799 */
1800export type IDirectiveResolvers${contextType} = ${name}<ContextType>;`
1801 : '';
1802 return [
1803 new DeclarationBlock(this._declarationBlockConfig)
1804 .export()
1805 .asKind(declarationKind)
1806 .withName(name, contextType)
1807 .withBlock(Object.keys(this._collectedDirectiveResolvers)
1808 .map(schemaTypeName => {
1809 const resolverType = this._collectedDirectiveResolvers[schemaTypeName];
1810 return indent(this.formatRootResolver(schemaTypeName, resolverType, declarationKind));
1811 })
1812 .join('\n')).string,
1813 deprecatedIResolvers,
1814 ].join('\n');
1815 }
1816 return '';
1817 }
1818 Name(node) {
1819 return node.value;
1820 }
1821 ListType(node) {
1822 const asString = node.type;
1823 return this.wrapWithArray(asString);
1824 }
1825 _getScalar(name) {
1826 return `${this.config.namespacedImportName ? this.config.namespacedImportName + '.' : ''}Scalars['${name}']`;
1827 }
1828 NamedType(node) {
1829 const nameStr = node.name;
1830 if (this.config.scalars[nameStr]) {
1831 return this._getScalar(nameStr);
1832 }
1833 return this.convertName(node, null, true);
1834 }
1835 NonNullType(node) {
1836 const asString = node.type;
1837 return asString;
1838 }
1839 markMapperAsUsed(name) {
1840 this._usedMappers[name] = true;
1841 }
1842 getTypeToUse(name) {
1843 const resolversType = this.convertName('ResolversTypes');
1844 return `${resolversType}['${name}']`;
1845 }
1846 getParentTypeToUse(name) {
1847 const resolversType = this.convertName('ResolversParentTypes');
1848 return `${resolversType}['${name}']`;
1849 }
1850 getParentTypeForSignature(_node) {
1851 return 'ParentType';
1852 }
1853 transformParentGenericType(parentType) {
1854 return `ParentType extends ${parentType} = ${parentType}`;
1855 }
1856 FieldDefinition(node, key, parent) {
1857 const hasArguments = node.arguments && node.arguments.length > 0;
1858 const declarationKind = 'type';
1859 return (parentName) => {
1860 const original = parent[key];
1861 const baseType = getBaseTypeNode(original.type);
1862 const realType = baseType.name.value;
1863 const parentType = this.schema.getType(parentName);
1864 if (this._federation.skipField({ fieldNode: original, parentType: parentType })) {
1865 return null;
1866 }
1867 const typeToUse = this.getTypeToUse(realType);
1868 const mappedType = this._variablesTransfomer.wrapAstTypeWithModifiers(typeToUse, original.type);
1869 const subscriptionType = this._schema.getSubscriptionType();
1870 const isSubscriptionType = subscriptionType && subscriptionType.name === parentName;
1871 let argsType = hasArguments
1872 ? this.convertName(parentName +
1873 (this.config.addUnderscoreToArgsType ? '_' : '') +
1874 this.convertName(node.name, {
1875 useTypesPrefix: false,
1876 useTypesSuffix: false,
1877 }) +
1878 'Args', {
1879 useTypesPrefix: true,
1880 }, true)
1881 : null;
1882 if (argsType !== null) {
1883 const argsToForceRequire = original.arguments.filter(arg => !!arg.defaultValue || arg.type.kind === 'NonNullType');
1884 if (argsToForceRequire.length > 0) {
1885 argsType = this.applyRequireFields(argsType, argsToForceRequire);
1886 }
1887 else if (original.arguments.length > 0) {
1888 argsType = this.applyOptionalFields(argsType, original.arguments);
1889 }
1890 }
1891 const parentTypeSignature = this._federation.transformParentType({
1892 fieldNode: original,
1893 parentType,
1894 parentTypeSignature: this.getParentTypeForSignature(node),
1895 });
1896 const mappedTypeKey = isSubscriptionType ? `${mappedType}, "${node.name}"` : mappedType;
1897 const signature = {
1898 name: node.name,
1899 modifier: this.config.avoidOptionals ? '' : '?',
1900 type: isSubscriptionType ? 'SubscriptionResolver' : 'Resolver',
1901 genericTypes: [
1902 mappedTypeKey,
1903 parentTypeSignature,
1904 this._fieldContextTypeMap[`${parentName}.${node.name}`]
1905 ? this._fieldContextTypeMap[`${parentName}.${node.name}`].type
1906 : 'ContextType',
1907 argsType,
1908 ].filter(f => f),
1909 };
1910 if (this._federation.isResolveReferenceField(node)) {
1911 this._hasFederation = true;
1912 signature.type = 'ReferenceResolver';
1913 if (signature.genericTypes.length >= 3) {
1914 signature.genericTypes = signature.genericTypes.slice(0, 3);
1915 }
1916 }
1917 return indent(`${signature.name}${signature.modifier}: ${signature.type}<${signature.genericTypes.join(', ')}>${this.getPunctuation(declarationKind)}`);
1918 };
1919 }
1920 applyRequireFields(argsType, fields) {
1921 this._globalDeclarations.add(REQUIRE_FIELDS_TYPE);
1922 return `RequireFields<${argsType}, ${fields.map(f => `'${f.name.value}'`).join(' | ')}>`;
1923 }
1924 applyOptionalFields(argsType, _fields) {
1925 this._globalDeclarations.add(REQUIRE_FIELDS_TYPE);
1926 return `RequireFields<${argsType}, never>`;
1927 }
1928 ObjectTypeDefinition(node) {
1929 var _a, _b, _c;
1930 const declarationKind = 'type';
1931 const name = this.convertName(node, {
1932 suffix: this.config.resolverTypeSuffix,
1933 });
1934 const typeName = node.name;
1935 const parentType = this.getParentTypeToUse(typeName);
1936 const isRootType = [
1937 (_a = this.schema.getQueryType()) === null || _a === void 0 ? void 0 : _a.name,
1938 (_b = this.schema.getMutationType()) === null || _b === void 0 ? void 0 : _b.name,
1939 (_c = this.schema.getSubscriptionType()) === null || _c === void 0 ? void 0 : _c.name,
1940 ].includes(typeName);
1941 const fieldsContent = node.fields.map((f) => f(node.name));
1942 if (!isRootType) {
1943 fieldsContent.push(indent(`${this.config.internalResolversPrefix}isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>${this.getPunctuation(declarationKind)}`));
1944 }
1945 const block = new DeclarationBlock(this._declarationBlockConfig)
1946 .export()
1947 .asKind(declarationKind)
1948 .withName(name, `<ContextType = ${this.config.contextType.type}, ${this.transformParentGenericType(parentType)}>`)
1949 .withBlock(fieldsContent.join('\n'));
1950 this._collectedResolvers[node.name] = name + '<ContextType>';
1951 return block.string;
1952 }
1953 UnionTypeDefinition(node, key, parent) {
1954 const declarationKind = 'type';
1955 const name = this.convertName(node, {
1956 suffix: this.config.resolverTypeSuffix,
1957 });
1958 const originalNode = parent[key];
1959 const possibleTypes = originalNode.types
1960 .map(node => node.name.value)
1961 .map(f => `'${f}'`)
1962 .join(' | ');
1963 this._collectedResolvers[node.name] = name + '<ContextType>';
1964 const parentType = this.getParentTypeToUse(node.name);
1965 return new DeclarationBlock(this._declarationBlockConfig)
1966 .export()
1967 .asKind(declarationKind)
1968 .withName(name, `<ContextType = ${this.config.contextType.type}, ${this.transformParentGenericType(parentType)}>`)
1969 .withBlock(indent(`${this.config.internalResolversPrefix}resolveType${this.config.optionalResolveType ? '?' : ''}: TypeResolveFn<${possibleTypes}, ParentType, ContextType>${this.getPunctuation(declarationKind)}`)).string;
1970 }
1971 ScalarTypeDefinition(node) {
1972 const nameAsString = node.name;
1973 const baseName = this.getTypeToUse(nameAsString);
1974 if (this._federation.skipScalar(nameAsString)) {
1975 return null;
1976 }
1977 this._hasScalars = true;
1978 this._collectedResolvers[node.name] = 'GraphQLScalarType';
1979 return new DeclarationBlock({
1980 ...this._declarationBlockConfig,
1981 blockTransformer(block) {
1982 return block;
1983 },
1984 })
1985 .export()
1986 .asKind('interface')
1987 .withName(this.convertName(node, {
1988 suffix: 'ScalarConfig',
1989 }), ` extends GraphQLScalarTypeConfig<${baseName}, any>`)
1990 .withBlock(indent(`name: '${node.name}'${this.getPunctuation('interface')}`)).string;
1991 }
1992 DirectiveDefinition(node, key, parent) {
1993 if (this._federation.skipDirective(node.name)) {
1994 return null;
1995 }
1996 const directiveName = this.convertName(node, {
1997 suffix: 'DirectiveResolver',
1998 });
1999 const sourceNode = parent[key];
2000 const hasArguments = sourceNode.arguments && sourceNode.arguments.length > 0;
2001 this._collectedDirectiveResolvers[node.name] = directiveName + '<any, any, ContextType>';
2002 const directiveArgsTypeName = this.convertName(node, {
2003 suffix: 'DirectiveArgs',
2004 });
2005 return [
2006 new DeclarationBlock({
2007 ...this._declarationBlockConfig,
2008 blockTransformer(block) {
2009 return block;
2010 },
2011 })
2012 .export()
2013 .asKind('type')
2014 .withName(directiveArgsTypeName)
2015 .withContent(`{ ${hasArguments ? this._variablesTransfomer.transform(sourceNode.arguments) : ''} }`).string,
2016 new DeclarationBlock({
2017 ...this._declarationBlockConfig,
2018 blockTransformer(block) {
2019 return block;
2020 },
2021 })
2022 .export()
2023 .asKind('type')
2024 .withName(directiveName, `<Result, Parent, ContextType = ${this.config.contextType.type}, Args = ${directiveArgsTypeName}>`)
2025 .withContent(`DirectiveResolverFn<Result, Parent, ContextType, Args>`).string,
2026 ].join('\n');
2027 }
2028 buildEnumResolverContentBlock(_node, _mappedEnumType) {
2029 throw new Error(`buildEnumResolverContentBlock is not implemented!`);
2030 }
2031 buildEnumResolversExplicitMappedValues(_node, _valuesMapping) {
2032 throw new Error(`buildEnumResolversExplicitMappedValues is not implemented!`);
2033 }
2034 EnumTypeDefinition(node) {
2035 const rawTypeName = node.name;
2036 // If we have enumValues set, and it's point to an external enum - we need to allow internal values resolvers
2037 // In case we have enumValues set but as explicit values, no need to to do mapping since it's already
2038 // have type validation (the original enum has been modified by base types plugin).
2039 // If we have mapper for that type - we can skip
2040 if (!this.config.mappers[rawTypeName] && !this.config.enumValues[rawTypeName]) {
2041 return null;
2042 }
2043 const name = this.convertName(node, { suffix: this.config.resolverTypeSuffix });
2044 this._collectedResolvers[rawTypeName] = name;
2045 const hasExplicitValues = this.config.enumValues[rawTypeName] && this.config.enumValues[rawTypeName].mappedValues;
2046 return new DeclarationBlock(this._declarationBlockConfig)
2047 .export()
2048 .asKind('type')
2049 .withName(name)
2050 .withContent(hasExplicitValues
2051 ? this.buildEnumResolversExplicitMappedValues(node, this.config.enumValues[rawTypeName].mappedValues)
2052 : this.buildEnumResolverContentBlock(node, this.getTypeToUse(rawTypeName))).string;
2053 }
2054 InterfaceTypeDefinition(node) {
2055 const name = this.convertName(node, {
2056 suffix: this.config.resolverTypeSuffix,
2057 });
2058 const declarationKind = 'type';
2059 const allTypesMap = this._schema.getTypeMap();
2060 const implementingTypes = [];
2061 this._collectedResolvers[node.name] = name + '<ContextType>';
2062 for (const graphqlType of Object.values(allTypesMap)) {
2063 if (graphqlType instanceof GraphQLObjectType) {
2064 const allInterfaces = graphqlType.getInterfaces();
2065 if (allInterfaces.find(int => int.name === node.name)) {
2066 implementingTypes.push(graphqlType.name);
2067 }
2068 }
2069 }
2070 const parentType = this.getParentTypeToUse(node.name);
2071 const possibleTypes = implementingTypes.map(name => `'${name}'`).join(' | ') || 'null';
2072 const fields = this.config.onlyResolveTypeForInterfaces ? [] : node.fields || [];
2073 return new DeclarationBlock(this._declarationBlockConfig)
2074 .export()
2075 .asKind(declarationKind)
2076 .withName(name, `<ContextType = ${this.config.contextType.type}, ${this.transformParentGenericType(parentType)}>`)
2077 .withBlock([
2078 indent(`${this.config.internalResolversPrefix}resolveType${this.config.optionalResolveType ? '?' : ''}: TypeResolveFn<${possibleTypes}, ParentType, ContextType>${this.getPunctuation(declarationKind)}`),
2079 ...fields.map((f) => f(node.name)),
2080 ].join('\n')).string;
2081 }
2082 SchemaDefinition() {
2083 return null;
2084 }
2085}
2086function replacePlaceholder(pattern, typename) {
2087 return pattern.replace('{T}', typename);
2088}
2089function hasPlaceholder(pattern) {
2090 return pattern.includes('{T}');
2091}
2092
2093gqlTag.enableExperimentalFragmentVariables();
2094var DocumentMode;
2095(function (DocumentMode) {
2096 DocumentMode["graphQLTag"] = "graphQLTag";
2097 DocumentMode["documentNode"] = "documentNode";
2098 DocumentMode["documentNodeImportFragments"] = "documentNodeImportFragments";
2099 DocumentMode["external"] = "external";
2100 DocumentMode["string"] = "string";
2101})(DocumentMode || (DocumentMode = {}));
2102const EXTENSIONS_TO_REMOVE = ['.ts', '.tsx', '.js', '.jsx'];
2103class ClientSideBaseVisitor extends BaseVisitor {
2104 constructor(_schema, _fragments, rawConfig, additionalConfig, documents) {
2105 super(rawConfig, {
2106 scalars: buildScalars(_schema, rawConfig.scalars, DEFAULT_SCALARS),
2107 dedupeOperationSuffix: getConfigValue(rawConfig.dedupeOperationSuffix, false),
2108 optimizeDocumentNode: getConfigValue(rawConfig.optimizeDocumentNode, true),
2109 omitOperationSuffix: getConfigValue(rawConfig.omitOperationSuffix, false),
2110 gqlImport: rawConfig.gqlImport || null,
2111 documentNodeImport: rawConfig.documentNodeImport || null,
2112 noExport: !!rawConfig.noExport,
2113 importOperationTypesFrom: getConfigValue(rawConfig.importOperationTypesFrom, null),
2114 operationResultSuffix: getConfigValue(rawConfig.operationResultSuffix, ''),
2115 documentVariablePrefix: getConfigValue(rawConfig.documentVariablePrefix, ''),
2116 documentVariableSuffix: getConfigValue(rawConfig.documentVariableSuffix, 'Document'),
2117 fragmentVariablePrefix: getConfigValue(rawConfig.fragmentVariablePrefix, ''),
2118 fragmentVariableSuffix: getConfigValue(rawConfig.fragmentVariableSuffix, 'FragmentDoc'),
2119 documentMode: ((rawConfig) => {
2120 if (typeof rawConfig.noGraphQLTag === 'boolean') {
2121 return rawConfig.noGraphQLTag ? DocumentMode.documentNode : DocumentMode.graphQLTag;
2122 }
2123 return getConfigValue(rawConfig.documentMode, DocumentMode.graphQLTag);
2124 })(rawConfig),
2125 importDocumentNodeExternallyFrom: getConfigValue(rawConfig.importDocumentNodeExternallyFrom, ''),
2126 pureMagicComment: getConfigValue(rawConfig.pureMagicComment, false),
2127 experimentalFragmentVariables: getConfigValue(rawConfig.experimentalFragmentVariables, false),
2128 ...additionalConfig,
2129 });
2130 this._schema = _schema;
2131 this._fragments = _fragments;
2132 this._collectedOperations = [];
2133 this._documents = [];
2134 this._additionalImports = [];
2135 this._imports = new Set();
2136 this._documents = documents;
2137 autoBind(this);
2138 }
2139 _extractFragments(document, withNested = false) {
2140 if (!document) {
2141 return [];
2142 }
2143 const names = new Set();
2144 visit(document, {
2145 enter: {
2146 FragmentSpread: (node) => {
2147 names.add(node.name.value);
2148 if (withNested) {
2149 const foundFragment = this._fragments.find(f => f.name === node.name.value);
2150 if (foundFragment) {
2151 const childItems = this._extractFragments(foundFragment.node, true);
2152 if (childItems && childItems.length > 0) {
2153 for (const item of childItems) {
2154 names.add(item);
2155 }
2156 }
2157 }
2158 }
2159 },
2160 },
2161 });
2162 return Array.from(names);
2163 }
2164 _transformFragments(document) {
2165 const includeNestedFragments = this.config.documentMode === DocumentMode.documentNode;
2166 return this._extractFragments(document, includeNestedFragments).map(document => this.getFragmentVariableName(document));
2167 }
2168 _includeFragments(fragments) {
2169 if (fragments && fragments.length > 0) {
2170 if (this.config.documentMode === DocumentMode.documentNode) {
2171 return this._fragments
2172 .filter(f => fragments.includes(this.getFragmentVariableName(f.name)))
2173 .map(fragment => print(fragment.node))
2174 .join('\n');
2175 }
2176 else if (this.config.documentMode === DocumentMode.documentNodeImportFragments) {
2177 return '';
2178 }
2179 else {
2180 return `${fragments.map(name => '${' + name + '}').join('\n')}`;
2181 }
2182 }
2183 return '';
2184 }
2185 _prepareDocument(documentStr) {
2186 return documentStr;
2187 }
2188 _gql(node) {
2189 const fragments = this._transformFragments(node);
2190 const doc = this._prepareDocument(`
2191 ${print(node).split('\\').join('\\\\') /* Re-escape escaped values in GraphQL syntax */}
2192 ${this._includeFragments(fragments)}`);
2193 if (this.config.documentMode === DocumentMode.documentNode) {
2194 let gqlObj = gqlTag([doc]);
2195 if (this.config.optimizeDocumentNode) {
2196 gqlObj = optimizeDocumentNode(gqlObj);
2197 }
2198 return JSON.stringify(gqlObj);
2199 }
2200 else if (this.config.documentMode === DocumentMode.documentNodeImportFragments) {
2201 let gqlObj = gqlTag([doc]);
2202 if (this.config.optimizeDocumentNode) {
2203 gqlObj = optimizeDocumentNode(gqlObj);
2204 }
2205 if (fragments.length > 0) {
2206 const definitions = [
2207 ...gqlObj.definitions.map(t => JSON.stringify(t)),
2208 ...fragments.map(name => `...${name}.definitions`),
2209 ].join();
2210 return `{"kind":"${Kind.DOCUMENT}","definitions":[${definitions}]}`;
2211 }
2212 return JSON.stringify(gqlObj);
2213 }
2214 else if (this.config.documentMode === DocumentMode.string) {
2215 return '`' + doc + '`';
2216 }
2217 const gqlImport = this._parseImport(this.config.gqlImport || 'graphql-tag');
2218 return (gqlImport.propName || 'gql') + '`' + doc + '`';
2219 }
2220 _generateFragment(fragmentDocument) {
2221 const name = this.getFragmentVariableName(fragmentDocument);
2222 const fragmentTypeSuffix = this.getFragmentSuffix(fragmentDocument);
2223 return `export const ${name}${this.getDocumentNodeSignature(this.convertName(fragmentDocument.name.value, {
2224 useTypesPrefix: true,
2225 suffix: fragmentTypeSuffix,
2226 }), this.config.experimentalFragmentVariables
2227 ? this.convertName(fragmentDocument.name.value, {
2228 suffix: fragmentTypeSuffix + 'Variables',
2229 })
2230 : 'unknown', fragmentDocument)} =${this.config.pureMagicComment ? ' /*#__PURE__*/' : ''} ${this._gql(fragmentDocument)};`;
2231 }
2232 get fragmentsGraph() {
2233 const graph = new DepGraph({ circular: true });
2234 for (const fragment of this._fragments) {
2235 if (graph.hasNode(fragment.name)) {
2236 const cachedAsString = print(graph.getNodeData(fragment.name).node);
2237 const asString = print(fragment.node);
2238 if (cachedAsString !== asString) {
2239 throw new Error(`Duplicated fragment called '${fragment.name}'!`);
2240 }
2241 }
2242 graph.addNode(fragment.name, fragment);
2243 }
2244 this._fragments.forEach(fragment => {
2245 const depends = this._extractFragments(fragment.node);
2246 if (depends && depends.length > 0) {
2247 depends.forEach(name => {
2248 graph.addDependency(fragment.name, name);
2249 });
2250 }
2251 });
2252 return graph;
2253 }
2254 get fragments() {
2255 if (this._fragments.length === 0 || this.config.documentMode === DocumentMode.external) {
2256 return '';
2257 }
2258 const graph = this.fragmentsGraph;
2259 const orderedDeps = graph.overallOrder();
2260 const localFragments = orderedDeps
2261 .filter(name => !graph.getNodeData(name).isExternal)
2262 .map(name => this._generateFragment(graph.getNodeData(name).node));
2263 return localFragments.join('\n');
2264 }
2265 _parseImport(importStr) {
2266 // This is a special case when we want to ignore importing, and just use `gql` provided from somewhere else
2267 // Plugins that uses that will need to ensure to add import/declaration for the gql identifier
2268 if (importStr === 'gql') {
2269 return {
2270 moduleName: null,
2271 propName: 'gql',
2272 };
2273 }
2274 // This is a special use case, when we don't want this plugin to manage the import statement
2275 // of the gql tag. In this case, we provide something like `Namespace.gql` and it will be used instead.
2276 if (importStr.includes('.gql')) {
2277 return {
2278 moduleName: null,
2279 propName: importStr,
2280 };
2281 }
2282 const [moduleName, propName] = importStr.split('#');
2283 return {
2284 moduleName,
2285 propName,
2286 };
2287 }
2288 _generateImport({ moduleName, propName }, varName, isTypeImport) {
2289 const typeImport = isTypeImport && this.config.useTypeImports ? 'import type' : 'import';
2290 const propAlias = propName === varName ? '' : ` as ${varName}`;
2291 if (moduleName) {
2292 return `${typeImport} ${propName ? `{ ${propName}${propAlias} }` : varName} from '${moduleName}';`;
2293 }
2294 return null;
2295 }
2296 clearExtension(path) {
2297 const extension = extname(path);
2298 if (EXTENSIONS_TO_REMOVE.includes(extension)) {
2299 return path.replace(/\.[^/.]+$/, '');
2300 }
2301 return path;
2302 }
2303 getImports(options = {}) {
2304 (this._additionalImports || []).forEach(i => this._imports.add(i));
2305 switch (this.config.documentMode) {
2306 case DocumentMode.documentNode:
2307 case DocumentMode.documentNodeImportFragments: {
2308 const documentNodeImport = this._parseImport(this.config.documentNodeImport || 'graphql#DocumentNode');
2309 const tagImport = this._generateImport(documentNodeImport, 'DocumentNode', true);
2310 if (tagImport) {
2311 this._imports.add(tagImport);
2312 }
2313 break;
2314 }
2315 case DocumentMode.graphQLTag: {
2316 const gqlImport = this._parseImport(this.config.gqlImport || 'graphql-tag');
2317 const tagImport = this._generateImport(gqlImport, 'gql', false);
2318 if (tagImport) {
2319 this._imports.add(tagImport);
2320 }
2321 break;
2322 }
2323 case DocumentMode.external: {
2324 if (this._collectedOperations.length > 0) {
2325 if (this.config.importDocumentNodeExternallyFrom === 'near-operation-file' && this._documents.length === 1) {
2326 this._imports.add(`import * as Operations from './${this.clearExtension(basename(this._documents[0].location))}';`);
2327 }
2328 else {
2329 if (!this.config.importDocumentNodeExternallyFrom) {
2330 // eslint-disable-next-line no-console
2331 console.warn('importDocumentNodeExternallyFrom must be provided if documentMode=external');
2332 }
2333 this._imports.add(`import * as Operations from '${this.clearExtension(this.config.importDocumentNodeExternallyFrom)}';`);
2334 }
2335 }
2336 break;
2337 }
2338 }
2339 if (!options.excludeFragments && !this.config.globalNamespace) {
2340 const { documentMode, fragmentImports } = this.config;
2341 if (documentMode === DocumentMode.graphQLTag ||
2342 documentMode === DocumentMode.string ||
2343 documentMode === DocumentMode.documentNodeImportFragments) {
2344 fragmentImports.forEach(fragmentImport => {
2345 this._imports.add(generateFragmentImportStatement(fragmentImport, 'document'));
2346 });
2347 }
2348 }
2349 return Array.from(this._imports);
2350 }
2351 buildOperation(_node, _documentVariableName, _operationType, _operationResultType, _operationVariablesTypes, _hasRequiredVariables) {
2352 return null;
2353 }
2354 getDocumentNodeSignature(_resultType, _variablesTypes, _node) {
2355 if (this.config.documentMode === DocumentMode.documentNode ||
2356 this.config.documentMode === DocumentMode.documentNodeImportFragments) {
2357 return `: DocumentNode`;
2358 }
2359 return '';
2360 }
2361 /**
2362 * Checks if the specific operation has variables that are non-null (required), and also doesn't have default.
2363 * This is useful for deciding of `variables` should be optional or not.
2364 * @param node
2365 */
2366 checkVariablesRequirements(node) {
2367 const variables = node.variableDefinitions || [];
2368 if (variables.length === 0) {
2369 return false;
2370 }
2371 return variables.some(variableDef => variableDef.type.kind === Kind.NON_NULL_TYPE && !variableDef.defaultValue);
2372 }
2373 OperationDefinition(node) {
2374 this._collectedOperations.push(node);
2375 const documentVariableName = this.convertName(node, {
2376 suffix: this.config.documentVariableSuffix,
2377 prefix: this.config.documentVariablePrefix,
2378 useTypesPrefix: false,
2379 });
2380 const operationType = pascalCase(node.operation);
2381 const operationTypeSuffix = this.getOperationSuffix(node, operationType);
2382 const operationResultType = this.convertName(node, {
2383 suffix: operationTypeSuffix + this._parsedConfig.operationResultSuffix,
2384 });
2385 const operationVariablesTypes = this.convertName(node, {
2386 suffix: operationTypeSuffix + 'Variables',
2387 });
2388 let documentString = '';
2389 if (this.config.documentMode !== DocumentMode.external) {
2390 // only generate exports for named queries
2391 if (documentVariableName !== '') {
2392 documentString = `${this.config.noExport ? '' : 'export'} const ${documentVariableName}${this.getDocumentNodeSignature(operationResultType, operationVariablesTypes, node)} =${this.config.pureMagicComment ? ' /*#__PURE__*/' : ''} ${this._gql(node)};`;
2393 }
2394 }
2395 const hasRequiredVariables = this.checkVariablesRequirements(node);
2396 const additional = this.buildOperation(node, documentVariableName, operationType, operationResultType, operationVariablesTypes, hasRequiredVariables);
2397 return [documentString, additional].filter(a => a).join('\n');
2398 }
2399}
2400
2401function isMetadataFieldName(name) {
2402 return ['__schema', '__type'].includes(name);
2403}
2404const metadataFieldMap = {
2405 __schema: SchemaMetaFieldDef,
2406 __type: TypeMetaFieldDef,
2407};
2408class SelectionSetToObject {
2409 constructor(_processor, _scalars, _schema, _convertName, _getFragmentSuffix, _loadedFragments, _config, _parentSchemaType, _selectionSet) {
2410 this._processor = _processor;
2411 this._scalars = _scalars;
2412 this._schema = _schema;
2413 this._convertName = _convertName;
2414 this._getFragmentSuffix = _getFragmentSuffix;
2415 this._loadedFragments = _loadedFragments;
2416 this._config = _config;
2417 this._parentSchemaType = _parentSchemaType;
2418 this._selectionSet = _selectionSet;
2419 this._primitiveFields = [];
2420 this._primitiveAliasedFields = [];
2421 this._linksFields = [];
2422 this._queriedForTypename = false;
2423 autoBind(this);
2424 }
2425 createNext(parentSchemaType, selectionSet) {
2426 return new SelectionSetToObject(this._processor, this._scalars, this._schema, this._convertName.bind(this), this._getFragmentSuffix.bind(this), this._loadedFragments, this._config, parentSchemaType, selectionSet);
2427 }
2428 /**
2429 * traverse the inline fragment nodes recursively for colleting the selectionSets on each type
2430 */
2431 _collectInlineFragments(parentType, nodes, types) {
2432 if (isListType(parentType) || isNonNullType(parentType)) {
2433 return this._collectInlineFragments(parentType.ofType, nodes, types);
2434 }
2435 else if (isObjectType(parentType)) {
2436 for (const node of nodes) {
2437 const typeOnSchema = node.typeCondition ? this._schema.getType(node.typeCondition.name.value) : parentType;
2438 const { fields, inlines, spreads } = separateSelectionSet(node.selectionSet.selections);
2439 const spreadsUsage = this.buildFragmentSpreadsUsage(spreads);
2440 if (isObjectType(typeOnSchema)) {
2441 this._appendToTypeMap(types, typeOnSchema.name, fields);
2442 this._appendToTypeMap(types, typeOnSchema.name, spreadsUsage[typeOnSchema.name]);
2443 this._collectInlineFragments(typeOnSchema, inlines, types);
2444 }
2445 else if (isInterfaceType(typeOnSchema) && parentType.getInterfaces().includes(typeOnSchema)) {
2446 this._appendToTypeMap(types, parentType.name, fields);
2447 this._appendToTypeMap(types, parentType.name, spreadsUsage[parentType.name]);
2448 this._collectInlineFragments(typeOnSchema, inlines, types);
2449 }
2450 }
2451 }
2452 else if (isInterfaceType(parentType)) {
2453 const possibleTypes = getPossibleTypes(this._schema, parentType);
2454 for (const node of nodes) {
2455 const schemaType = node.typeCondition ? this._schema.getType(node.typeCondition.name.value) : parentType;
2456 const { fields, inlines, spreads } = separateSelectionSet(node.selectionSet.selections);
2457 const spreadsUsage = this.buildFragmentSpreadsUsage(spreads);
2458 if (isObjectType(schemaType) && possibleTypes.find(possibleType => possibleType.name === schemaType.name)) {
2459 this._appendToTypeMap(types, schemaType.name, fields);
2460 this._appendToTypeMap(types, schemaType.name, spreadsUsage[schemaType.name]);
2461 this._collectInlineFragments(schemaType, inlines, types);
2462 }
2463 else if (isInterfaceType(schemaType) && schemaType.name === parentType.name) {
2464 for (const possibleType of possibleTypes) {
2465 this._appendToTypeMap(types, possibleType.name, fields);
2466 this._appendToTypeMap(types, possibleType.name, spreadsUsage[possibleType.name]);
2467 this._collectInlineFragments(schemaType, inlines, types);
2468 }
2469 }
2470 else {
2471 // it must be an interface type that is spread on an interface field
2472 for (const possibleType of possibleTypes) {
2473 if (!node.typeCondition) {
2474 throw new Error('Invalid state. Expected type condition for interface spread on a interface field.');
2475 }
2476 const fragmentSpreadType = this._schema.getType(node.typeCondition.name.value);
2477 // the field should only be added to the valid selections
2478 // in case the possible type actually implements the given interface
2479 if (isTypeSubTypeOf(this._schema, possibleType, fragmentSpreadType)) {
2480 this._appendToTypeMap(types, possibleType.name, fields);
2481 this._appendToTypeMap(types, possibleType.name, spreadsUsage[possibleType.name]);
2482 }
2483 }
2484 }
2485 }
2486 }
2487 else if (isUnionType(parentType)) {
2488 const possibleTypes = parentType.getTypes();
2489 for (const node of nodes) {
2490 const schemaType = node.typeCondition ? this._schema.getType(node.typeCondition.name.value) : parentType;
2491 const { fields, inlines, spreads } = separateSelectionSet(node.selectionSet.selections);
2492 const spreadsUsage = this.buildFragmentSpreadsUsage(spreads);
2493 if (isObjectType(schemaType) && possibleTypes.find(possibleType => possibleType.name === schemaType.name)) {
2494 this._appendToTypeMap(types, schemaType.name, fields);
2495 this._appendToTypeMap(types, schemaType.name, spreadsUsage[schemaType.name]);
2496 this._collectInlineFragments(schemaType, inlines, types);
2497 }
2498 else if (isInterfaceType(schemaType)) {
2499 const possibleInterfaceTypes = getPossibleTypes(this._schema, schemaType);
2500 for (const possibleType of possibleTypes) {
2501 if (possibleInterfaceTypes.find(possibleInterfaceType => possibleInterfaceType.name === possibleType.name)) {
2502 this._appendToTypeMap(types, possibleType.name, fields);
2503 this._appendToTypeMap(types, possibleType.name, spreadsUsage[possibleType.name]);
2504 this._collectInlineFragments(schemaType, inlines, types);
2505 }
2506 }
2507 }
2508 else {
2509 for (const possibleType of possibleTypes) {
2510 this._appendToTypeMap(types, possibleType.name, fields);
2511 this._appendToTypeMap(types, possibleType.name, spreadsUsage[possibleType.name]);
2512 }
2513 }
2514 }
2515 }
2516 }
2517 _createInlineFragmentForFieldNodes(parentType, fieldNodes) {
2518 return {
2519 kind: Kind.INLINE_FRAGMENT,
2520 typeCondition: {
2521 kind: Kind.NAMED_TYPE,
2522 name: {
2523 kind: Kind.NAME,
2524 value: parentType.name,
2525 },
2526 },
2527 directives: [],
2528 selectionSet: {
2529 kind: Kind.SELECTION_SET,
2530 selections: fieldNodes,
2531 },
2532 };
2533 }
2534 buildFragmentSpreadsUsage(spreads) {
2535 const selectionNodesByTypeName = {};
2536 for (const spread of spreads) {
2537 const fragmentSpreadObject = this._loadedFragments.find(lf => lf.name === spread.name.value);
2538 if (fragmentSpreadObject) {
2539 const schemaType = this._schema.getType(fragmentSpreadObject.onType);
2540 const possibleTypesForFragment = getPossibleTypes(this._schema, schemaType);
2541 for (const possibleType of possibleTypesForFragment) {
2542 const fragmentSuffix = this._getFragmentSuffix(spread.name.value);
2543 const usage = this.buildFragmentTypeName(spread.name.value, fragmentSuffix, possibleTypesForFragment.length === 1 ? null : possibleType.name);
2544 if (!selectionNodesByTypeName[possibleType.name]) {
2545 selectionNodesByTypeName[possibleType.name] = [];
2546 }
2547 selectionNodesByTypeName[possibleType.name].push(usage);
2548 }
2549 }
2550 }
2551 return selectionNodesByTypeName;
2552 }
2553 flattenSelectionSet(selections) {
2554 const selectionNodesByTypeName = new Map();
2555 const inlineFragmentSelections = [];
2556 const fieldNodes = [];
2557 const fragmentSpreads = [];
2558 for (const selection of selections) {
2559 switch (selection.kind) {
2560 case Kind.FIELD:
2561 fieldNodes.push(selection);
2562 break;
2563 case Kind.INLINE_FRAGMENT:
2564 inlineFragmentSelections.push(selection);
2565 break;
2566 case Kind.FRAGMENT_SPREAD:
2567 fragmentSpreads.push(selection);
2568 break;
2569 }
2570 }
2571 if (fieldNodes.length) {
2572 inlineFragmentSelections.push(this._createInlineFragmentForFieldNodes(this._parentSchemaType, fieldNodes));
2573 }
2574 this._collectInlineFragments(this._parentSchemaType, inlineFragmentSelections, selectionNodesByTypeName);
2575 const fragmentsUsage = this.buildFragmentSpreadsUsage(fragmentSpreads);
2576 Object.keys(fragmentsUsage).forEach(typeName => {
2577 this._appendToTypeMap(selectionNodesByTypeName, typeName, fragmentsUsage[typeName]);
2578 });
2579 return selectionNodesByTypeName;
2580 }
2581 _appendToTypeMap(types, typeName, nodes) {
2582 if (!types.has(typeName)) {
2583 types.set(typeName, []);
2584 }
2585 if (nodes && nodes.length > 0) {
2586 types.get(typeName).push(...nodes);
2587 }
2588 }
2589 _buildGroupedSelections() {
2590 if (!this._selectionSet || !this._selectionSet.selections || this._selectionSet.selections.length === 0) {
2591 return {};
2592 }
2593 const selectionNodesByTypeName = this.flattenSelectionSet(this._selectionSet.selections);
2594 const grouped = getPossibleTypes(this._schema, this._parentSchemaType).reduce((prev, type) => {
2595 const typeName = type.name;
2596 const schemaType = this._schema.getType(typeName);
2597 if (!isObjectType(schemaType)) {
2598 throw new TypeError(`Invalid state! Schema type ${typeName} is not a valid GraphQL object!`);
2599 }
2600 const selectionNodes = selectionNodesByTypeName.get(typeName) || [];
2601 if (!prev[typeName]) {
2602 prev[typeName] = [];
2603 }
2604 const transformedSet = this.buildSelectionSetString(schemaType, selectionNodes);
2605 if (transformedSet) {
2606 prev[typeName].push(transformedSet);
2607 }
2608 return prev;
2609 }, {});
2610 return grouped;
2611 }
2612 buildSelectionSetString(parentSchemaType, selectionNodes) {
2613 const primitiveFields = new Map();
2614 const primitiveAliasFields = new Map();
2615 const linkFieldSelectionSets = new Map();
2616 let requireTypename = false;
2617 const fragmentsSpreadUsages = [];
2618 for (const selectionNode of selectionNodes) {
2619 if (typeof selectionNode === 'string') {
2620 fragmentsSpreadUsages.push(selectionNode);
2621 }
2622 else if (selectionNode.kind === 'Field') {
2623 if (!selectionNode.selectionSet) {
2624 if (selectionNode.alias) {
2625 primitiveAliasFields.set(selectionNode.alias.value, selectionNode);
2626 }
2627 else if (selectionNode.name.value === '__typename') {
2628 requireTypename = true;
2629 }
2630 else {
2631 primitiveFields.set(selectionNode.name.value, selectionNode);
2632 }
2633 }
2634 else {
2635 let selectedField = null;
2636 const fields = parentSchemaType.getFields();
2637 selectedField = fields[selectionNode.name.value];
2638 if (isMetadataFieldName(selectionNode.name.value)) {
2639 selectedField = metadataFieldMap[selectionNode.name.value];
2640 }
2641 if (!selectedField) {
2642 continue;
2643 }
2644 const fieldName = getFieldNodeNameValue(selectionNode);
2645 let linkFieldNode = linkFieldSelectionSets.get(fieldName);
2646 if (!linkFieldNode) {
2647 linkFieldNode = {
2648 selectedFieldType: selectedField.type,
2649 field: selectionNode,
2650 };
2651 linkFieldSelectionSets.set(fieldName, linkFieldNode);
2652 }
2653 else {
2654 mergeSelectionSets(linkFieldNode.field.selectionSet, selectionNode.selectionSet);
2655 }
2656 }
2657 }
2658 }
2659 const linkFields = [];
2660 for (const { field, selectedFieldType } of linkFieldSelectionSets.values()) {
2661 const realSelectedFieldType = getBaseType(selectedFieldType);
2662 const selectionSet = this.createNext(realSelectedFieldType, field.selectionSet);
2663 const isConditional = hasConditionalDirectives(field.directives);
2664 linkFields.push({
2665 alias: field.alias ? this._processor.config.formatNamedField(field.alias.value, selectedFieldType) : undefined,
2666 name: this._processor.config.formatNamedField(field.name.value, selectedFieldType, isConditional),
2667 type: realSelectedFieldType.name,
2668 selectionSet: this._processor.config.wrapTypeWithModifiers(selectionSet.transformSelectionSet().split(`\n`).join(`\n `), isConditional ? removeNonNullWrapper(selectedFieldType) : selectedFieldType),
2669 });
2670 }
2671 const typeInfoField = this.buildTypeNameField(parentSchemaType, this._config.nonOptionalTypename, this._config.addTypename, requireTypename, this._config.skipTypeNameForRoot);
2672 const transformed = [
2673 ...(typeInfoField ? this._processor.transformTypenameField(typeInfoField.type, typeInfoField.name) : []),
2674 ...this._processor.transformPrimitiveFields(parentSchemaType, Array.from(primitiveFields.values()).map(field => ({
2675 isConditional: hasConditionalDirectives(field.directives),
2676 fieldName: field.name.value,
2677 }))),
2678 ...this._processor.transformAliasesPrimitiveFields(parentSchemaType, Array.from(primitiveAliasFields.values()).map(field => ({
2679 alias: field.alias.value,
2680 fieldName: field.name.value,
2681 }))),
2682 ...this._processor.transformLinkFields(linkFields),
2683 ].filter(Boolean);
2684 const allStrings = transformed.filter(t => typeof t === 'string');
2685 const allObjectsMerged = transformed
2686 .filter(t => typeof t !== 'string')
2687 .map((t) => `${t.name}: ${t.type}`);
2688 let mergedObjectsAsString = null;
2689 if (allObjectsMerged.length > 0) {
2690 mergedObjectsAsString = this._processor.buildFieldsIntoObject(allObjectsMerged);
2691 }
2692 const fields = [...allStrings, mergedObjectsAsString, ...fragmentsSpreadUsages].filter(Boolean);
2693 return this._processor.buildSelectionSetFromStrings(fields);
2694 }
2695 isRootType(type) {
2696 const rootType = [this._schema.getQueryType(), this._schema.getMutationType(), this._schema.getSubscriptionType()]
2697 .filter(Boolean)
2698 .map(t => t.name);
2699 return rootType.includes(type.name);
2700 }
2701 buildTypeNameField(type, nonOptionalTypename = this._config.nonOptionalTypename, addTypename = this._config.addTypename, queriedForTypename = this._queriedForTypename, skipTypeNameForRoot = this._config.skipTypeNameForRoot) {
2702 if (this.isRootType(type) && skipTypeNameForRoot && !queriedForTypename) {
2703 return null;
2704 }
2705 if (nonOptionalTypename || addTypename || queriedForTypename) {
2706 const optionalTypename = !queriedForTypename && !nonOptionalTypename;
2707 return {
2708 name: `${this._processor.config.formatNamedField('__typename')}${optionalTypename ? '?' : ''}`,
2709 type: `'${type.name}'`,
2710 };
2711 }
2712 return null;
2713 }
2714 getUnknownType() {
2715 return 'never';
2716 }
2717 transformSelectionSet() {
2718 const grouped = this._buildGroupedSelections();
2719 // This might happen in case we have an interface, that is being queries, without any GraphQL
2720 // "type" that implements it. It will lead to a runtime error, but we aim to try to reflect that in
2721 // build time as well.
2722 if (Object.keys(grouped).length === 0) {
2723 return this.getUnknownType();
2724 }
2725 return Object.keys(grouped)
2726 .map(typeName => {
2727 const relevant = grouped[typeName].filter(Boolean);
2728 if (relevant.length === 0) {
2729 return null;
2730 }
2731 else if (relevant.length === 1) {
2732 return relevant[0];
2733 }
2734 else {
2735 return `( ${relevant.join(' & ')} )`;
2736 }
2737 })
2738 .filter(Boolean)
2739 .join(' | ');
2740 }
2741 transformFragmentSelectionSetToTypes(fragmentName, fragmentSuffix, declarationBlockConfig) {
2742 const grouped = this._buildGroupedSelections();
2743 const subTypes = Object.keys(grouped)
2744 .map(typeName => {
2745 const possibleFields = grouped[typeName].filter(Boolean);
2746 if (possibleFields.length === 0) {
2747 return null;
2748 }
2749 const declarationName = this.buildFragmentTypeName(fragmentName, fragmentSuffix, typeName);
2750 return { name: declarationName, content: possibleFields.join(' & ') };
2751 })
2752 .filter(Boolean);
2753 if (subTypes.length === 1) {
2754 return new DeclarationBlock(declarationBlockConfig)
2755 .export()
2756 .asKind('type')
2757 .withName(this.buildFragmentTypeName(fragmentName, fragmentSuffix))
2758 .withContent(subTypes[0].content).string;
2759 }
2760 return [
2761 ...subTypes.map(t => new DeclarationBlock(declarationBlockConfig)
2762 .export(this._config.exportFragmentSpreadSubTypes)
2763 .asKind('type')
2764 .withName(t.name)
2765 .withContent(t.content).string),
2766 new DeclarationBlock(declarationBlockConfig)
2767 .export()
2768 .asKind('type')
2769 .withName(this.buildFragmentTypeName(fragmentName, fragmentSuffix))
2770 .withContent(subTypes.map(t => t.name).join(' | ')).string,
2771 ].join('\n');
2772 }
2773 buildFragmentTypeName(name, suffix, typeName = '') {
2774 return this._convertName(name, {
2775 useTypesPrefix: true,
2776 suffix: typeName ? `_${typeName}_${suffix}` : suffix,
2777 });
2778 }
2779}
2780
2781class BaseSelectionSetProcessor {
2782 constructor(config) {
2783 this.config = config;
2784 }
2785 buildFieldsIntoObject(allObjectsMerged) {
2786 return `{ ${allObjectsMerged.join(', ')} }`;
2787 }
2788 buildSelectionSetFromStrings(pieces) {
2789 if (pieces.length === 0) {
2790 return null;
2791 }
2792 else if (pieces.length === 1) {
2793 return pieces[0];
2794 }
2795 else {
2796 return `(\n ${pieces.join(`\n & `)}\n)`;
2797 }
2798 }
2799 transformPrimitiveFields(_schemaType, _fields) {
2800 throw new Error(`Please override "transformPrimitiveFields" as part of your BaseSelectionSetProcessor implementation!`);
2801 }
2802 transformAliasesPrimitiveFields(_schemaType, _fields) {
2803 throw new Error(`Please override "transformAliasesPrimitiveFields" as part of your BaseSelectionSetProcessor implementation!`);
2804 }
2805 transformLinkFields(_fields) {
2806 throw new Error(`Please override "transformLinkFields" as part of your BaseSelectionSetProcessor implementation!`);
2807 }
2808 transformTypenameField(_type, _name) {
2809 throw new Error(`Please override "transformTypenameField" as part of your BaseSelectionSetProcessor implementation!`);
2810 }
2811}
2812
2813class PreResolveTypesProcessor extends BaseSelectionSetProcessor {
2814 transformTypenameField(type, name) {
2815 return [
2816 {
2817 type,
2818 name,
2819 },
2820 ];
2821 }
2822 transformPrimitiveFields(schemaType, fields) {
2823 if (fields.length === 0) {
2824 return [];
2825 }
2826 return fields.map(field => {
2827 const fieldObj = schemaType.getFields()[field.fieldName];
2828 const baseType = getBaseType(fieldObj.type);
2829 let typeToUse = baseType.name;
2830 const useInnerType = field.isConditional && isNonNullType(fieldObj.type);
2831 if (isEnumType(baseType)) {
2832 typeToUse =
2833 (this.config.namespacedImportName ? `${this.config.namespacedImportName}.` : '') +
2834 this.config.convertName(baseType.name, { useTypesPrefix: this.config.enumPrefix });
2835 }
2836 else if (this.config.scalars[baseType.name]) {
2837 typeToUse = this.config.scalars[baseType.name];
2838 }
2839 const name = this.config.formatNamedField(field.fieldName, useInnerType ? baseType : fieldObj.type);
2840 const wrappedType = this.config.wrapTypeWithModifiers(typeToUse, useInnerType ? baseType : fieldObj.type);
2841 return {
2842 name,
2843 type: wrappedType,
2844 };
2845 });
2846 }
2847 transformAliasesPrimitiveFields(schemaType, fields) {
2848 if (fields.length === 0) {
2849 return [];
2850 }
2851 return fields.map(aliasedField => {
2852 if (aliasedField.fieldName === '__typename') {
2853 const name = this.config.formatNamedField(aliasedField.alias, null);
2854 return {
2855 name,
2856 type: `'${schemaType.name}'`,
2857 };
2858 }
2859 else {
2860 const fieldObj = schemaType.getFields()[aliasedField.fieldName];
2861 const baseType = getBaseType(fieldObj.type);
2862 let typeToUse = this.config.scalars[baseType.name] || baseType.name;
2863 if (isEnumType(baseType)) {
2864 typeToUse =
2865 (this.config.namespacedImportName ? `${this.config.namespacedImportName}.` : '') +
2866 this.config.convertName(baseType.name, { useTypesPrefix: this.config.enumPrefix });
2867 }
2868 const name = this.config.formatNamedField(aliasedField.alias, fieldObj.type);
2869 const wrappedType = this.config.wrapTypeWithModifiers(typeToUse, fieldObj.type);
2870 return {
2871 name,
2872 type: wrappedType,
2873 };
2874 }
2875 });
2876 }
2877 transformLinkFields(fields) {
2878 if (fields.length === 0) {
2879 return [];
2880 }
2881 return fields.map(field => ({
2882 name: field.alias || field.name,
2883 type: field.selectionSet,
2884 }));
2885 }
2886}
2887
2888function optimizeOperations(schema, documents, options) {
2889 const newDocuments = optimizeDocuments(schema, documents.map(s => s.document), options);
2890 return newDocuments.map(document => ({
2891 location: 'optimized by relay',
2892 document,
2893 }));
2894}
2895
2896export { BaseDocumentsVisitor, BaseResolversVisitor, BaseSelectionSetProcessor, BaseTypesVisitor, BaseVisitor, ClientSideBaseVisitor, DEFAULT_AVOID_OPTIONALS, DEFAULT_DECLARATION_KINDS, DEFAULT_SCALARS, DeclarationBlock, DocumentMode, OMIT_TYPE, OperationVariablesToObject, PreResolveTypesProcessor, REQUIRE_FIELDS_TYPE, SelectionSetToObject, block, breakLine, buildMapperImport, buildScalars, clearExtension, convertFactory, convertNameParts, fixLocalFilePath, generateFragmentImportStatement, generateImportStatement, getBaseTypeNode, getConfigValue, getFieldNodeNameValue, getPossibleTypes, getRootTypeNames, hasConditionalDirectives, indent, indentMultiline, isExternalMapper, isExternalMapperType, isRootType, mergeSelectionSets, normalizeAvoidOptionals, normalizeDeclarationKind, optimizeOperations, parseEnumValues, parseMapper, quoteIfNeeded, removeDescription, resolveImportSource, resolveRelativeImport, separateSelectionSet, stripMapperTypeInterpolation, transformComment, transformMappers, wrapTypeNodeWithModifiers, wrapTypeWithModifiers, wrapWithSingleQuotes };
2897//# sourceMappingURL=index.esm.js.map