@graphql-codegen/typescript-rtk-query
Version:
GraphQL Code Generator plugin for injecting graphql endpoints into a preconfigured RTK Query api
99 lines (97 loc) • 4.18 kB
JavaScript
import autoBind from 'auto-bind';
import { pascalCase } from 'change-case-all';
import { ClientSideBaseVisitor, DocumentMode, getConfigValue, } from '@graphql-codegen/visitor-plugin-common';
export class RTKQueryVisitor extends ClientSideBaseVisitor {
constructor(schema, fragments, rawConfig, documents) {
super(schema, fragments, rawConfig, {
documentMode: DocumentMode.string,
importBaseApiFrom: getConfigValue(rawConfig.importBaseApiFrom, ''),
importBaseApiAlternateName: getConfigValue(rawConfig.importBaseApiAlternateName, 'api'),
addTransformResponse: getConfigValue(rawConfig.addTransformResponse, false),
exportHooks: getConfigValue(rawConfig.exportHooks, false),
overrideExisting: getConfigValue(rawConfig.overrideExisting, ''),
});
this.rawConfig = rawConfig;
this._endpoints = [];
this._hooks = [];
this._externalImportPrefix = this.config.importOperationTypesFrom
? `${this.config.importOperationTypesFrom}.`
: '';
this._documents = documents;
autoBind(this);
}
get imports() {
return this._imports;
}
get hasOperations() {
return this._collectedOperations.length > 0;
}
getImports() {
const baseImports = super.getImports();
if (!this.hasOperations) {
return baseImports;
}
return [
...baseImports,
`import { ${this.config.importBaseApiAlternateName} } from '${this.config.importBaseApiFrom}';`,
];
}
getInjectCall() {
if (!this.hasOperations) {
return '';
}
return (`
const injectedRtkApi = ${this.config.importBaseApiAlternateName}.injectEndpoints({
${!this.config.overrideExisting
? ''
: `overrideExisting: ${this.config.overrideExisting},
`}endpoints: (build) => ({${this._endpoints.join('')}
}),
});
export { injectedRtkApi as api };
` +
(this.config.exportHooks
? `export const { ${this._hooks.join(', ')} } = injectedRtkApi;`
: '') +
'\n\n');
}
injectTransformResponse(Generics) {
if (this.config.addTransformResponse) {
const responseType = Generics.split(',')[0];
return `transformResponse: (response: ${responseType}) => response`;
}
return '';
}
buildOperation(node, documentVariableName, operationType, operationResultType, operationVariablesTypes, hasRequiredVariables) {
var _a, _b;
operationResultType = this._externalImportPrefix + operationResultType;
operationVariablesTypes = this._externalImportPrefix + operationVariablesTypes;
const operationName = (_a = node.name) === null || _a === void 0 ? void 0 : _a.value;
if (!operationName)
return '';
if (operationType === 'Subscription') {
// eslint-disable-next-line no-console
console.warn(`Plugin "typescript-rtk-query" does not support GraphQL Subscriptions at the moment! Skipping "${(_b = node.name) === null || _b === void 0 ? void 0 : _b.value}"...`);
return '';
}
const Generics = `${operationResultType}, ${operationVariablesTypes}${hasRequiredVariables ? '' : ' | void'}`;
const operationTypeString = operationType.toLowerCase();
const functionsString = `query: (variables) => ({ document: ${documentVariableName}, variables })
${this.injectTransformResponse(Generics)}`.trim();
const endpointString = `
${operationName}: build.${operationTypeString}<${Generics}>({
${functionsString}
}),`;
this._endpoints.push(endpointString);
if (this.config.exportHooks) {
if (operationType === 'Query') {
this._hooks.push(`use${pascalCase(operationName)}Query`);
this._hooks.push(`useLazy${pascalCase(operationName)}Query`);
}
if (operationType === 'Mutation') {
this._hooks.push(`use${pascalCase(operationName)}Mutation`);
}
}
return '';
}
}