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