@graphql-codegen/named-operations-object
Version:
GraphQL Code Generator plugin for generating an enum with all loaded operations, for simpler and type-safe access
57 lines (56 loc) • 2.21 kB
JavaScript
import { capitalCase } from 'change-case-all';
import { concatAST } from 'graphql';
import { oldVisit } from '@graphql-codegen/plugin-helpers';
export const plugin = (schema, documents, config) => {
const identifierName = config.identifierName || 'namedOperations';
const allAst = concatAST(documents.map(v => v.document));
const allOperationsNames = {
query: new Set(),
mutation: new Set(),
subscription: new Set(),
fragment: new Set(),
};
const duplicateOperationNames = [];
oldVisit(allAst, {
enter: {
OperationDefinition: node => {
var _a;
if ((_a = node.name) === null || _a === void 0 ? void 0 : _a.value) {
if (allOperationsNames[node.operation].has(node.name.value)) {
duplicateOperationNames.push(node.name.value);
return;
}
allOperationsNames[node.operation].add(node.name.value);
}
},
FragmentDefinition: node => {
allOperationsNames.fragment.add(node.name.value);
},
},
});
if (config.throwOnDuplicate && duplicateOperationNames.length > 0) {
throw new Error(`Duplicated operation name(s): ${duplicateOperationNames.join(', ')}`);
}
const objectItems = Object.keys(allOperationsNames)
.map(operationType => {
const relevantOperations = allOperationsNames[operationType];
if (relevantOperations && relevantOperations.size > 0) {
const rootFieldName = capitalCase(operationType);
return ` ${rootFieldName}: {
${Array.from(relevantOperations)
.map(t => ` ${t}: '${t}'${config.useConsts ? ' as const' : ''}`)
.join(',\n')}
}`;
}
return null;
})
.filter(Boolean);
if (objectItems.length === 0) {
// eslint-disable-next-line no-console
console.warn(`Plugin "named-operations-object" has an empty output, since there are no valid operations!`);
return '';
}
return `export const ${identifierName} = {
${objectItems.join(',\n')}
}`;
};