@eddeee888/gcg-typescript-resolver-files
Version:
This [GraphQL Code Generator](https://www.the-guild.dev/graphql/codegen) plugin creates resolvers given GraphQL schema.
114 lines • 5.7 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.handleGraphQLObjectType = void 0;
const utils_1 = require("../utils");
const handleGraphQLObjectType = ({ fieldFilePath, resolverName, isFileAlreadyOnFilesystem, normalizedResolverName, resolversTypeMeta, moduleName, relativePathFromBaseToModule, fieldsToPick = [], // If fieldsToPick.length === 0, it means the current object handles all resolvers
generatedTypesFileMeta, }, { result, config: { resolverGeneration, typeMappersMap, graphQLObjectTypeResolversToGenerate, emitLegacyCommonJSImports, }, }) => {
var _a;
const matchedPatternToGenerate = (0, utils_1.isMatchResolverNamePattern)({
pattern: resolverGeneration.object,
value: normalizedResolverName.withModule,
});
const mapperDetails = typeMappersMap[normalizedResolverName.base];
if (!matchedPatternToGenerate &&
!mapperDetails &&
!isFileAlreadyOnFilesystem) {
utils_1.logger.debug(`Skipped Object resolver generation: "${normalizedResolverName.withModule}". "Pattern: ${resolverGeneration.object}".`);
return;
}
const forcedGenerationWarning = (() => {
if (!matchedPatternToGenerate && mapperDetails) {
utils_1.logger.debug(`Object resolver generation was NOT skipped because there is a associated mapper: "${normalizedResolverName.withModule}". "Pattern: ${resolverGeneration.object}". Mapper: ${mapperDetails.mapper.name}`);
return `/*
* Note: This object type is generated because "${mapperDetails.mapper.name}" is declared. This is to ensure runtime safety.
*
* When a mapper is used, it is possible to hit runtime errors in some scenarios:
* - given a field name, the schema type's field type does not match mapper's field type
* - or a schema type's field does not exist in the mapper's fields
*
* If you want to skip this file generation, remove the mapper or update the pattern in the \`resolverGeneration.object\` config.
*/\n`;
}
return '';
})();
const hasFieldsToPick = fieldsToPick.length > 0;
// __isTypeOf is required to resolve abstract types, should user chooses this approach.
// TODO: Run static analysis to enforce only one __isTypeOf per Object type, so users cannot accidentally implement/override it across modules
if (hasFieldsToPick) {
fieldsToPick.push('__isTypeOf');
}
if (hasFieldsToPick &&
((_a = generatedTypesFileMeta.generatedResolverTypes.userDefined[normalizedResolverName.base].federation) === null || _a === void 0 ? void 0 : _a.hasResolveReference)) {
fieldsToPick.push('__resolveReference');
}
// - `typeString` contains the resolver type
// If there's fieldsToPick, we must only pick said fields from the original resolver type
// - `otherTypeStringVariants` contains other types that are the same as `typeString` but formatted differently
// This is used to check if the resolver type is the same when running static analysis
// We want to use string comparison instead of true AST check because it's a lot faster and simpler
const { typeString, otherTypeStringVariants } = (() => {
if (hasFieldsToPick) {
return {
typeString: `Pick<${resolversTypeMeta.typeString}, ${fieldsToPick
.map((fieldName) => `'${fieldName}'`)
.join('|')}>`,
otherTypeStringVariants: [
`Pick<${resolversTypeMeta.typeString}, |${fieldsToPick
.map((fieldName) => `'${fieldName}'`)
.join('|')}>`,
],
};
}
return {
typeString: resolversTypeMeta.typeString,
otherTypeStringVariants: [],
};
})();
// Array of all resolvers that may need type checking
// If there's fieldsToPick, we must only generate said fields
const allResolversToGenerate = graphQLObjectTypeResolversToGenerate[resolverName];
const resolversToGenerate = hasFieldsToPick
? fieldsToPick.reduce((res, fieldToPick) => {
if (allResolversToGenerate && allResolversToGenerate[fieldToPick]) {
res[fieldToPick] = allResolversToGenerate[fieldToPick];
}
return res;
}, {})
: allResolversToGenerate;
const variableStatement = `${forcedGenerationWarning}export const ${resolverName}: ${typeString} = {
/* Implement ${resolverName} resolver logic here */
};`;
const resolverTypeImportDeclaration = (0, utils_1.printImportLine)({
isTypeImport: true,
module: resolversTypeMeta.module,
moduleType: resolversTypeMeta.moduleType,
namedImports: [resolversTypeMeta.typeNamedImport],
emitLegacyCommonJSImports,
});
result.files[fieldFilePath] = {
__filetype: 'objectType',
filesystem: {
type: 'virtual',
contentUpdated: false,
},
content: `
${resolverTypeImportDeclaration}
${variableStatement}`,
mainImportIdentifier: resolverName,
meta: {
moduleName,
relativePathFromBaseToModule,
normalizedResolverName,
resolverTypeImportDeclaration,
variableStatement,
resolverType: {
baseImport: resolversTypeMeta.typeNamedImport,
final: typeString,
otherVariants: otherTypeStringVariants,
},
resolversToGenerate,
},
};
};
exports.handleGraphQLObjectType = handleGraphQLObjectType;
//# sourceMappingURL=handleGraphQLObjectType.js.map
;