Skip to content

Instantly share code, notes, and snippets.

@LeonardDrs
Created October 25, 2021 15:11
Show Gist options
  • Save LeonardDrs/4b976b1303b538fc389141fd9b737bef to your computer and use it in GitHub Desktop.
Save LeonardDrs/4b976b1303b538fc389141fd9b737bef to your computer and use it in GitHub Desktop.
Basic `typePolicies` plugin for Graphql Codegen. Will generate a typePolicies object with relay-style query fields configured for pagination.
const graphql = require('graphql');
function isRelayConnection(typeField, type) {
if (!typeField.type) {
return false;
}
if (!typeField.type.toString().includes('Connection')) { // This might be too opiniated
return false;
}
const fieldsNames = Object.keys(type.getFields()).filter(
(f) => !f.startsWith('__'),
);
if (!fieldsNames.includes('edges') || !fieldsNames.includes('pageInfo')) {
return false;
}
return true;
}
module.exports = {
/**
* Generates typePolicies argument for Apollo's InMemoryCache
* for the schema's relay connection
* @param {graphql.GraphQLSchema} schema
*/
plugin: (schema) => {
const typeMap = schema.getTypeMap();
const typePolicies = [];
Object.keys(typeMap).forEach((typeName) => {
const type = typeMap[typeName];
if (
typeName.startsWith('__') ||
(!graphql.isObjectType(type) && !graphql.isInterfaceType(type))
) {
return;
}
const fields = type.getFields();
let connectionFieldChilds = [];
for (const fieldIndex in fields) {
const field = fields[fieldIndex];
const fieldType = field.type.toString();
const fieldTypeName = fieldType.endsWith('!')
? fieldType.substring(0, fieldType.length - 1)
: fieldType;
if (
!graphql.isObjectType(typeMap[fieldTypeName]) &&
!graphql.isInterfaceType(typeMap[fieldTypeName])
) {
continue;
}
if (isRelayConnection(fields[fieldIndex], typeMap[fieldTypeName])) {
connectionFieldChilds.push(`${field.name}: relayStylePagination(),`);
}
}
if (connectionFieldChilds.length) {
typePolicies.push(
`${typeName}: {
fields: {
${connectionFieldChilds.join('\n ')}
},
},`,
);
}
});
if (!typePolicies.length) {
return;
}
return `import { relayStylePagination } from "@apollo/client/utilities";
export default {
${typePolicies.join('\n')}
};`;
},
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment