UNPKG

4.99 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
6
7const graphql = require('graphql');
8const visitorPluginCommon = require('@graphql-codegen/visitor-plugin-common');
9const autoBind = _interopDefault(require('auto-bind'));
10const changeCaseAll = require('change-case-all');
11const path = require('path');
12
13class ReactApolloVisitor extends visitorPluginCommon.ClientSideBaseVisitor {
14 constructor(schema, fragments, rawConfig, documents) {
15 super(schema, fragments, rawConfig, {});
16 this.imports = new Set();
17 this._externalImportPrefix = this.config.importOperationTypesFrom ? `${this.config.importOperationTypesFrom}.` : '';
18 this._documents = documents;
19 autoBind(this);
20 }
21 getOffixReactHooksImport() {
22 return `import * as OffixReactHooks from "react-offix-hooks";`;
23 }
24 getDocumentNodeVariable(node, documentVariableName) {
25 return this.config.documentMode === visitorPluginCommon.DocumentMode.external ? `Operations.${node.name.value}` : documentVariableName;
26 }
27 getImports() {
28 const baseImports = super.getImports({ excludeFragments: true });
29 const hasOperations = this._collectedOperations.length > 0;
30 if (!hasOperations) {
31 return baseImports;
32 }
33 return [...baseImports, ...Array.from(this.imports)];
34 }
35 _buildHooks(node, operationType, documentVariableName, operationResultType, operationVariablesTypes) {
36 var _a, _b;
37 const operationName = this.convertName((_b = (_a = node.name) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : '', {
38 useTypesPrefix: false,
39 });
40 this.imports.add(this.getOffixReactHooksImport());
41 const hookFns = [];
42 if (operationType === 'Mutation') {
43 hookFns.push(`export function useOffline${operationName}(baseOptions?: OffixReactHooks.${operationType}HookOptions<${operationResultType}, ${operationVariablesTypes}>) {
44 return OffixReactHooks.useOfflineMutation<${operationResultType}, ${operationVariablesTypes}>(${this.getDocumentNodeVariable(node, documentVariableName)}, baseOptions);
45}`);
46 }
47 return [...hookFns].join('\n');
48 }
49 buildOperation(node, documentVariableName, operationType, operationResultType, operationVariablesTypes) {
50 operationResultType = this._externalImportPrefix + operationResultType;
51 operationVariablesTypes = this._externalImportPrefix + operationVariablesTypes;
52 const hooks = this._buildHooks(node, operationType, documentVariableName, operationResultType, operationVariablesTypes);
53 return [hooks].filter(a => a).join('\n');
54 }
55 OperationDefinition(node) {
56 if (!node.name || !node.name.value) {
57 return null;
58 }
59 this._collectedOperations.push(node);
60 const documentVariableName = this.convertName(node, {
61 suffix: this.config.documentVariableSuffix,
62 prefix: this.config.documentVariablePrefix,
63 useTypesPrefix: false,
64 });
65 const operationType = changeCaseAll.pascalCase(node.operation);
66 const operationTypeSuffix = this.getOperationSuffix(node, operationType);
67 const operationResultType = this.convertName(node, {
68 suffix: operationTypeSuffix + this._parsedConfig.operationResultSuffix,
69 });
70 const operationVariablesTypes = this.convertName(node, {
71 suffix: operationTypeSuffix + 'Variables',
72 });
73 const additional = this.buildOperation(node, documentVariableName, operationType, operationResultType, operationVariablesTypes);
74 return [additional].filter(a => a).join('\n');
75 }
76}
77
78const plugin = (schema, documents, config) => {
79 const allAst = graphql.concatAST(documents.map(v => v.document));
80 const allFragments = [
81 ...allAst.definitions.filter(d => d.kind === graphql.Kind.FRAGMENT_DEFINITION).map(fragmentDef => ({
82 node: fragmentDef,
83 name: fragmentDef.name.value,
84 onType: fragmentDef.typeCondition.name.value,
85 isExternal: false,
86 })),
87 ...(config.externalFragments || []),
88 ];
89 const visitor = new ReactApolloVisitor(schema, allFragments, config, documents);
90 const visitorResult = graphql.visit(allAst, { leave: visitor });
91 return {
92 prepend: visitor.getImports(),
93 content: [...visitorResult.definitions.filter(t => typeof t === 'string')].join('\n'),
94 };
95};
96const validate = async (_schema, _documents, _config, outputFile) => {
97 if (path.extname(outputFile) !== '.tsx' && path.extname(outputFile) !== '.ts') {
98 throw new Error(`Plugin "react-apollo" requires extension to be ".tsx" or ".ts!`);
99 }
100};
101
102exports.ReactApolloVisitor = ReactApolloVisitor;
103exports.plugin = plugin;
104exports.validate = validate;