UNPKG

5.14 kBJavaScriptView Raw
1import { concatAST, Kind, visit } from 'graphql';
2import { ClientSideBaseVisitor, getConfigValue } from '@graphql-codegen/visitor-plugin-common';
3import autoBind from 'auto-bind';
4import { pascalCase, paramCase } from 'change-case-all';
5import { extname } from 'path';
6
7var StencilComponentType;
8(function (StencilComponentType) {
9 StencilComponentType["functional"] = "functional";
10 StencilComponentType["class"] = "class";
11})(StencilComponentType || (StencilComponentType = {}));
12
13class StencilApolloVisitor extends ClientSideBaseVisitor {
14 constructor(schema, fragments, rawConfig) {
15 super(schema, fragments, rawConfig, {
16 componentType: getConfigValue(rawConfig.componentType, StencilComponentType.functional),
17 noExport: rawConfig.componentType === StencilComponentType.class,
18 });
19 autoBind(this);
20 }
21 getImports() {
22 const baseImports = super.getImports();
23 const imports = [];
24 const hasOperations = this._collectedOperations.length > 0;
25 if (!hasOperations) {
26 return baseImports;
27 }
28 if (this.config.componentType === StencilComponentType.class) {
29 imports.push(`import 'stencil-apollo';`);
30 imports.push(`import { Component, Prop, h } from '@stencil/core';`);
31 }
32 else {
33 imports.push(`import * as StencilApollo from 'stencil-apollo';`);
34 imports.push(`import { h } from '@stencil/core';`);
35 }
36 return [...baseImports, ...imports];
37 }
38 _buildOperationFunctionalComponent(node, documentVariableName, operationType, operationResultType, operationVariablesTypes) {
39 const operationName = this.convertName(node.name.value);
40 const propsTypeName = this.convertName(operationName + 'Props');
41 const rendererSignature = pascalCase(`${operationType}Renderer`) + `<${operationResultType}, ${operationVariablesTypes}>`;
42 const apolloStencilComponentTag = paramCase(`Apollo${operationType}`);
43 const componentName = this.convertName(`${operationName}Component`);
44 const propsVar = `
45export type ${propsTypeName} = {
46 variables ?: ${operationVariablesTypes};
47 inlist ?: StencilApollo.${rendererSignature};
48};
49 `;
50 const component = `
51export const ${componentName} = (props: ${propsTypeName}, children: [StencilApollo.${rendererSignature}]) => (
52 <${apolloStencilComponentTag} ${operationType.toLowerCase()}={ ${documentVariableName} } { ...props } renderer={ children[0] } />
53);
54 `;
55 return [propsVar, component].filter(a => a).join('\n');
56 }
57 _buildClassComponent(node, documentVariableName, operationType, operationResultType, operationVariablesTypes) {
58 const componentName = this.convertName(node.name.value + 'Component');
59 const apolloStencilComponentTag = paramCase(`Apollo${operationType}`);
60 const rendererSignature = pascalCase(`${operationType}Renderer`);
61 return `
62@Component({
63 tag: '${paramCase(`Apollo${pascalCase(node.name.value)}`)}'
64})
65export class ${componentName} {
66 @Prop() renderer: import('stencil-apollo').${rendererSignature}<${operationResultType}, ${operationVariablesTypes}>;
67 @Prop() variables: ${operationVariablesTypes};
68 render() {
69 return <${apolloStencilComponentTag} ${operationType.toLowerCase()}={ ${documentVariableName} } variables={ this.variables } renderer={ this.renderer } />;
70 }
71}
72 `;
73 }
74 buildOperation(node, documentVariableName, operationType, operationResultType, operationVariablesTypes) {
75 switch (this.config.componentType) {
76 case StencilComponentType.class:
77 return this._buildClassComponent(node, documentVariableName, operationType, operationResultType, operationVariablesTypes);
78 case StencilComponentType.functional:
79 return this._buildOperationFunctionalComponent(node, documentVariableName, operationType, operationResultType, operationVariablesTypes);
80 default:
81 return '';
82 }
83 }
84}
85
86const plugin = (schema, documents, config) => {
87 const allAst = concatAST(documents.map(v => v.document));
88 const allFragments = [
89 ...allAst.definitions.filter(d => d.kind === Kind.FRAGMENT_DEFINITION).map(fragmentDef => ({
90 node: fragmentDef,
91 name: fragmentDef.name.value,
92 onType: fragmentDef.typeCondition.name.value,
93 isExternal: false,
94 })),
95 ...(config.externalFragments || []),
96 ];
97 const visitor = new StencilApolloVisitor(schema, allFragments, config);
98 const visitorResult = visit(allAst, { leave: visitor });
99 return {
100 prepend: visitor.getImports(),
101 content: ['', visitor.fragments, ...visitorResult.definitions.filter(t => typeof t === 'string')].join('\n'),
102 };
103};
104const validate = async (schema, documents, config, outputFile) => {
105 if (extname(outputFile) !== '.tsx') {
106 throw new Error(`Plugin "stencil-apollo" requires extension to be ".tsx"!`);
107 }
108};
109
110export { StencilApolloVisitor, plugin, validate };
111//# sourceMappingURL=index.esm.js.map