UNPKG

5.88 kBJavaScriptView Raw
1import autoBind from 'auto-bind';
2import { DEFAULT_SCALARS } from './scalars.js';
3import { DeclarationBlock, getConfigValue, buildScalarsFromConfig } from './utils.js';
4import { OperationVariablesToObject } from './variables-to-object.js';
5import { BaseVisitor } from './base-visitor.js';
6import { pascalCase } from 'change-case-all';
7function getRootType(operation, schema) {
8 switch (operation) {
9 case 'query':
10 return schema.getQueryType();
11 case 'mutation':
12 return schema.getMutationType();
13 case 'subscription':
14 return schema.getSubscriptionType();
15 }
16 throw new Error(`Unknown operation type: ${operation}`);
17}
18export class BaseDocumentsVisitor extends BaseVisitor {
19 constructor(rawConfig, additionalConfig, _schema, defaultScalars = DEFAULT_SCALARS) {
20 super(rawConfig, {
21 exportFragmentSpreadSubTypes: getConfigValue(rawConfig.exportFragmentSpreadSubTypes, false),
22 enumPrefix: getConfigValue(rawConfig.enumPrefix, true),
23 preResolveTypes: getConfigValue(rawConfig.preResolveTypes, true),
24 dedupeOperationSuffix: getConfigValue(rawConfig.dedupeOperationSuffix, false),
25 omitOperationSuffix: getConfigValue(rawConfig.omitOperationSuffix, false),
26 skipTypeNameForRoot: getConfigValue(rawConfig.skipTypeNameForRoot, false),
27 namespacedImportName: getConfigValue(rawConfig.namespacedImportName, null),
28 experimentalFragmentVariables: getConfigValue(rawConfig.experimentalFragmentVariables, false),
29 addTypename: !rawConfig.skipTypename,
30 globalNamespace: !!rawConfig.globalNamespace,
31 operationResultSuffix: getConfigValue(rawConfig.operationResultSuffix, ''),
32 scalars: buildScalarsFromConfig(_schema, rawConfig, defaultScalars),
33 ...(additionalConfig || {}),
34 });
35 this._schema = _schema;
36 this._unnamedCounter = 1;
37 this._globalDeclarations = new Set();
38 autoBind(this);
39 this._variablesTransfomer = new OperationVariablesToObject(this.scalars, this.convertName, this.config.namespacedImportName);
40 }
41 getGlobalDeclarations(noExport = false) {
42 return Array.from(this._globalDeclarations).map(t => (noExport ? t : `export ${t}`));
43 }
44 setSelectionSetHandler(handler) {
45 this._selectionSetToObject = handler;
46 }
47 setDeclarationBlockConfig(config) {
48 this._declarationBlockConfig = config;
49 }
50 setVariablesTransformer(variablesTransfomer) {
51 this._variablesTransfomer = variablesTransfomer;
52 }
53 get schema() {
54 return this._schema;
55 }
56 get addTypename() {
57 return this._parsedConfig.addTypename;
58 }
59 handleAnonymousOperation(node) {
60 const name = node.name && node.name.value;
61 if (name) {
62 return this.convertName(name, {
63 useTypesPrefix: false,
64 useTypesSuffix: false,
65 });
66 }
67 return this.convertName(this._unnamedCounter++ + '', {
68 prefix: 'Unnamed_',
69 suffix: '_',
70 useTypesPrefix: false,
71 useTypesSuffix: false,
72 });
73 }
74 FragmentDefinition(node) {
75 const fragmentRootType = this._schema.getType(node.typeCondition.name.value);
76 const selectionSet = this._selectionSetToObject.createNext(fragmentRootType, node.selectionSet);
77 const fragmentSuffix = this.getFragmentSuffix(node);
78 return [
79 selectionSet.transformFragmentSelectionSetToTypes(node.name.value, fragmentSuffix, this._declarationBlockConfig),
80 this.config.experimentalFragmentVariables
81 ? new DeclarationBlock({
82 ...this._declarationBlockConfig,
83 blockTransformer: t => this.applyVariablesWrapper(t),
84 })
85 .export()
86 .asKind('type')
87 .withName(this.convertName(node.name.value, {
88 suffix: fragmentSuffix + 'Variables',
89 }))
90 .withBlock(this._variablesTransfomer.transform(node.variableDefinitions)).string
91 : undefined,
92 ]
93 .filter(r => r)
94 .join('\n\n');
95 }
96 applyVariablesWrapper(variablesBlock) {
97 return variablesBlock;
98 }
99 OperationDefinition(node) {
100 const name = this.handleAnonymousOperation(node);
101 const operationRootType = getRootType(node.operation, this._schema);
102 if (!operationRootType) {
103 throw new Error(`Unable to find root schema type for operation type "${node.operation}"!`);
104 }
105 const selectionSet = this._selectionSetToObject.createNext(operationRootType, node.selectionSet);
106 const visitedOperationVariables = this._variablesTransfomer.transform(node.variableDefinitions);
107 const operationType = pascalCase(node.operation);
108 const operationTypeSuffix = this.getOperationSuffix(name, operationType);
109 const operationResult = new DeclarationBlock(this._declarationBlockConfig)
110 .export()
111 .asKind('type')
112 .withName(this.convertName(name, {
113 suffix: operationTypeSuffix + this._parsedConfig.operationResultSuffix,
114 }))
115 .withContent(selectionSet.transformSelectionSet()).string;
116 const operationVariables = new DeclarationBlock({
117 ...this._declarationBlockConfig,
118 blockTransformer: t => this.applyVariablesWrapper(t),
119 })
120 .export()
121 .asKind('type')
122 .withName(this.convertName(name, {
123 suffix: operationTypeSuffix + 'Variables',
124 }))
125 .withBlock(visitedOperationVariables).string;
126 return [operationVariables, operationResult].filter(r => r).join('\n\n');
127 }
128}