UNPKG

chimp

Version:

Your development companion for doing quality, faster.

388 lines (387 loc) 21.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.executeGeneration = void 0; const tslib_1 = require("tslib"); const get_module_infos_1 = tslib_1.__importDefault(require("./parse-graphql/get-module-infos")); const fs = tslib_1.__importStar(require("node:fs")); const path = tslib_1.__importStar(require("node:path")); // @ts-ignore const shelljs = tslib_1.__importStar(require("shelljs")); const debug_1 = tslib_1.__importDefault(require("debug")); const graphql_1 = require("graphql"); const pascal_case_1 = require("pascal-case"); const getModuleNames_1 = tslib_1.__importDefault(require("./parse-graphql/getModuleNames")); const getFederatedEntities_1 = tslib_1.__importDefault(require("./parse-graphql/getFederatedEntities")); const getInterfaces_1 = tslib_1.__importDefault(require("./parse-graphql/getInterfaces")); const getScalars_1 = tslib_1.__importDefault(require("./parse-graphql/getScalars")); // import checkIfGitStateClean from './helpers/checkIfGitStateClean'; const saveRenderedTemplate_1 = require("./helpers/saveRenderedTemplate"); const findProjectMainPath_1 = require("./helpers/findProjectMainPath"); const execQuietly_1 = require("./helpers/execQuietly"); const getUnions_1 = tslib_1.__importDefault(require("./parse-graphql/getUnions")); const debug = (0, debug_1.default)('generate-module'); const generateSchema = async (projectMainPath) => { await (0, execQuietly_1.execQuietly)(`PROJECT_PATH=${projectMainPath} npx tsx -r tsconfig-paths/register ${__dirname}/templates/printSchema.ts`, {}); }; const executeGeneration = async (appPrefix = '~app', generatedPrefix = '~generated', modulesPath = 'src/') => { const capitalize = (string) => string.charAt(0).toUpperCase() + string.slice(1); const projectMainPath = (0, findProjectMainPath_1.findProjectMainPath)(); shelljs.mkdir('-p', `${projectMainPath}/generated/graphql/helpers`); // "Framework" "generated" files - initial generation const createGenericDataModelSchema = () => { const templateName = './templates/genericDataModelSchema.graphql'; const filePath = `${projectMainPath}/generated/graphql/`; const fileName = 'genericDataModelSchema.graphql'; (0, saveRenderedTemplate_1.saveRenderedTemplate)(templateName, {}, filePath, fileName); }; debug('createGenericDataModelSchema'); createGenericDataModelSchema(); const modulesResolvedPath = path.join(projectMainPath, modulesPath); const graphqlPaths = shelljs.ls(path.join(modulesResolvedPath, '**/*.graphql')); const moduleNames = (0, getModuleNames_1.default)(graphqlPaths, projectMainPath); const modules = (0, get_module_infos_1.default)(moduleNames); const createGlobalResolvers = () => { const templateName = './templates/resolvers.handlebars'; const context = { modules }; const filePath = `${projectMainPath}/generated/graphql/`; const fileName = 'resolvers.ts'; (0, saveRenderedTemplate_1.saveRenderedTemplate)(templateName, context, filePath, fileName); }; debug('createGlobalResolvers'); createGlobalResolvers(); // End of "Framework" "generated" files // Initial App Setup files debug('generateSchema'); await generateSchema(projectMainPath); const globalSchemaString = fs.readFileSync(path.join(projectMainPath, 'schema.graphql')); // read file const createGlobalSchema = () => { const templateName = './templates/schema.ts'; const context = { modules, schemaString: globalSchemaString.toString().replace(/`/g, '\\`'), generatedPrefix }; const filePath = `${projectMainPath}/generated/graphql/`; const fileName = 'schema.ts'; (0, saveRenderedTemplate_1.saveRenderedTemplate)(templateName, context, filePath, fileName); }; debug('createGlobalSchema'); createGlobalSchema(); for (const module of modules) { const moduleName = module.name; const { graphqlFileRootPath, queries, mutations } = module; const createQuery = (queryName, hasArguments) => { const templateName = './templates/query.handlebars'; const context = { queryName, moduleName, hasArguments, generatedPrefix, }; const filePath = `${projectMainPath}/src/${graphqlFileRootPath}/queries/`; const fileName = `${queryName}Query.ts`; const keepIfExists = true; (0, saveRenderedTemplate_1.saveRenderedTemplate)(templateName, context, filePath, fileName, keepIfExists); }; const createQuerySpec = (queryName, hasArguments) => { const templateName = './templates/query.spec.handlebars'; const context = { queryName, moduleName, hasArguments, generatedPrefix, pascalCasedArgName: `Query${(0, pascal_case_1.pascalCase)(queryName)}Args`, }; const filePath = `${projectMainPath}/src/${graphqlFileRootPath}/queries/`; const fileName = `${queryName}Query.spec.ts`; const keepIfExists = true; (0, saveRenderedTemplate_1.saveRenderedTemplate)(templateName, context, filePath, fileName, keepIfExists); }; const createQuerySpecWrapper = (queryName, hasArguments) => { const templateName = './templates/querySpecWrapper.handlebars'; const context = { queryName, moduleName, hasArguments, generatedPrefix, appPrefix, graphqlFileRootPath, pascalCasedArgName: `Query${(0, pascal_case_1.pascalCase)(queryName)}Args`, }; const filePath = `${projectMainPath}/generated/graphql/helpers/`; const fileName = `${queryName}QuerySpecWrapper.ts`; const keepIfExists = false; (0, saveRenderedTemplate_1.saveRenderedTemplate)(templateName, context, filePath, fileName, keepIfExists); }; if (queries && queries.length > 0) { shelljs.mkdir('-p', `${projectMainPath}/src/${graphqlFileRootPath}/queries`); for (const { name, hasArguments } of queries) { createQuery(name, hasArguments); createQuerySpec(name, hasArguments); createQuerySpecWrapper(name, hasArguments); } } const createMutation = (mutationName, hasArguments) => { const templateName = './templates/mutation.handlebars'; const context = { mutationName, moduleName, hasArguments, generatedPrefix, }; const filePath = `${projectMainPath}/src/${graphqlFileRootPath}/mutations/`; const fileName = `${mutationName}Mutation.ts`; const keepIfExists = true; (0, saveRenderedTemplate_1.saveRenderedTemplate)(templateName, context, filePath, fileName, keepIfExists); }; const createMutationSpec = (mutationName, hasArguments) => { const templateName = './templates/mutation.spec.handlebars'; const context = { mutationName, moduleName, hasArguments, generatedPrefix, appPrefix, graphqlFileRootPath, pascalCasedArgName: `Mutation${(0, pascal_case_1.pascalCase)(mutationName)}Args`, }; const filePath = `${projectMainPath}/src/${graphqlFileRootPath}/mutations/`; const fileName = `${mutationName}Mutation.spec.ts`; const keepIfExists = true; (0, saveRenderedTemplate_1.saveRenderedTemplate)(templateName, context, filePath, fileName, keepIfExists); }; const createMutationSpecWrapper = (mutationName, hasArguments) => { const templateName = './templates/mutationSpecWrapper.handlebars'; const context = { mutationName, moduleName, hasArguments, generatedPrefix, appPrefix, graphqlFileRootPath, pascalCasedArgName: `Mutation${(0, pascal_case_1.pascalCase)(mutationName)}Args`, }; const filePath = `${projectMainPath}/generated/graphql/helpers/`; const fileName = `${mutationName}MutationSpecWrapper.ts`; const keepIfExists = false; (0, saveRenderedTemplate_1.saveRenderedTemplate)(templateName, context, filePath, fileName, keepIfExists); }; if (mutations && mutations.length > 0) { shelljs.mkdir('-p', `${projectMainPath}/src/${graphqlFileRootPath}/mutations`); for (const { name, hasArguments } of mutations) { createMutation(name, hasArguments); createMutationSpec(name, hasArguments); createMutationSpecWrapper(name, hasArguments); } } } const createTypeResolvers = () => { for (const { name, typeDefinitions, types, schemaString, queries, mutations, graphqlFileRootPath } of modules) { const typeResolvers = []; if (types) { debug(`create type resolvers for module ${name}`); const federatedEntities = (0, getFederatedEntities_1.default)(schemaString); const interfaces = (0, getInterfaces_1.default)(schemaString); const unions = (0, getUnions_1.default)(schemaString); // Leaving this for now const source = new graphql_1.Source(schemaString.replace(/extend type/g, 'type')); const schema = (0, graphql_1.buildSchema)(source, { assumeValidSDL: true }); shelljs.mkdir('-p', `${projectMainPath}/src/${graphqlFileRootPath}/types/`); const createResolveType = (resolverTypeName) => { const templateName = './templates/typeTypeResolvers.handlebars'; const capitalizedFieldName = capitalize('__resolveType'); const context = { typeName: resolverTypeName, fieldName: '__resolveType', moduleName: name, resolveReferenceType: true, capitalizedFieldName, generatedPrefix, }; const filePath = `${projectMainPath}/src/${graphqlFileRootPath}/types/`; const fileName = `${resolverTypeName}${capitalizedFieldName}.ts`; const keepIfExists = true; (0, saveRenderedTemplate_1.saveRenderedTemplate)(templateName, context, filePath, fileName, keepIfExists); }; const createResolveTypeSpec = (resolverTypeName) => { const templateName = './templates/typeTypeResolvers.spec.handlebars'; const capitalizedFieldName = capitalize('__resolveType'); const context = { typeName: resolverTypeName, fieldName: '__resolveType', moduleName: name, hasArguments: false, resolveReferenceType: true, capitalizedFieldName, generatedPrefix, }; const filePath = `${projectMainPath}/src/${graphqlFileRootPath}/types/`; const fileName = `${resolverTypeName}${capitalizedFieldName}.spec.ts`; const keepIfExists = true; (0, saveRenderedTemplate_1.saveRenderedTemplate)(templateName, context, filePath, fileName, keepIfExists); }; const createResolveTypeSpecWrapper = (resolverTypeName) => { const templateName = './templates/typeTypeResolversSpecWrapper.handlebars'; const capitalizedFieldName = capitalize('__resolveType'); const context = { typeName: resolverTypeName, fieldName: '__resolveType', moduleName: name, hasArguments: false, resolveReferenceType: true, capitalizedFieldName, generatedPrefix, appPrefix, graphqlFileRootPath, }; const filePath = `${projectMainPath}/generated/graphql/helpers/`; const fileName = `${resolverTypeName}${capitalizedFieldName}SpecWrapper.ts`; const keepIfExists = false; (0, saveRenderedTemplate_1.saveRenderedTemplate)(templateName, context, filePath, fileName, keepIfExists); }; for (const interfaceName of interfaces) { createResolveType(interfaceName); createResolveTypeSpec(interfaceName); createResolveTypeSpecWrapper(interfaceName); typeResolvers.push({ typeName: interfaceName, fieldName: [{ name: '__resolveType', capitalizedName: capitalize('__resolveType') }], }); } for (const unionName of unions) { createResolveType(unionName); createResolveTypeSpec(unionName); createResolveTypeSpecWrapper(unionName); typeResolvers.push({ typeName: unionName, fieldName: [{ name: '__resolveType', capitalizedName: capitalize('__resolveType') }], }); } for (const typeDef of typeDefinitions) { let filtered = []; let type = schema.getType(typeDef.name); if (!type) { const newSchemaString = schemaString.replace(`extend type ${typeDef.name}`, `type ${typeDef.name}`); type = (0, graphql_1.buildSchema)(new graphql_1.Source(newSchemaString)).getType(typeDef.name); } if (type === null || type === void 0 ? void 0 : type.astNode) { // @ts-ignore filtered = type.astNode.fields.filter((field) => field.directives.find((d) => d.name.value === 'computed' || d.name.value === 'link' || d.name.value === 'requires' || d.name.value === 'map')); } let isFederatedAndExternal = false; if (federatedEntities.includes(typeDef.name)) { filtered.push({ name: { value: '__resolveReference' }, resolveReferenceType: true }); isFederatedAndExternal = Boolean(type.astNode) && Boolean( // @ts-ignore type === null || type === void 0 ? void 0 : type.astNode.fields.find((field) => field.directives.find((d) => d.name.value === 'external'))); } for (const { name: { value }, resolveReferenceType, } of filtered) { const templateName = './templates/typeTypeResolvers.handlebars'; const capitalizedFieldName = capitalize(value); const context = { typeName: typeDef.name, fieldName: value, moduleName: name, resolveReferenceType, capitalizedFieldName, generatedPrefix, }; const filePath = `${projectMainPath}/src/${graphqlFileRootPath}/types/`; const fileName = `${typeDef.name}${capitalizedFieldName}.ts`; const keepIfExists = true; (0, saveRenderedTemplate_1.saveRenderedTemplate)(templateName, context, filePath, fileName, keepIfExists); } const createTypeFieldResolverSpec = (value, resolveReferenceType, resolverArguments) => { const templateName = './templates/typeTypeResolvers.spec.handlebars'; const capitalizedFieldName = capitalize(value); const context = { typeName: typeDef.name, fieldName: value, moduleName: name, hasArguments: resolverArguments && resolverArguments.length > 0, resolveReferenceType, capitalizedFieldName, generatedPrefix, pascalCasedArgName: `${typeDef.name}${(0, pascal_case_1.pascalCase)(capitalizedFieldName)}Args`, }; const filePath = `${projectMainPath}/src/${graphqlFileRootPath}/types/`; const fileName = `${typeDef.name}${capitalizedFieldName}.spec.ts`; const keepIfExists = true; (0, saveRenderedTemplate_1.saveRenderedTemplate)(templateName, context, filePath, fileName, keepIfExists); }; const createTypeFieldResolverSpecWrapper = (value, resolveReferenceType, resolverArguments) => { const templateName = './templates/typeTypeResolversSpecWrapper.handlebars'; const capitalizedFieldName = capitalize(value); const context = { typeName: typeDef.name, fieldName: value, moduleName: name, hasArguments: resolverArguments && resolverArguments.length > 0, resolveReferenceType, capitalizedFieldName, generatedPrefix, appPrefix, graphqlFileRootPath, isFederatedAndExternal, pascalCasedArgName: `${typeDef.name}${(0, pascal_case_1.pascalCase)(capitalizedFieldName)}Args`, }; const filePath = `${projectMainPath}/generated/graphql/helpers/`; const fileName = `${typeDef.name}${capitalizedFieldName}SpecWrapper.ts`; const keepIfExists = true; (0, saveRenderedTemplate_1.saveRenderedTemplate)(templateName, context, filePath, fileName, keepIfExists); }; for (const { name: { value }, arguments: resolverArguments, resolveReferenceType, } of filtered) { createTypeFieldResolverSpec(value, resolveReferenceType, resolverArguments); createTypeFieldResolverSpecWrapper(value, resolveReferenceType, resolverArguments); } if (filtered.length > 0) { typeResolvers.push({ typeName: typeDef.name, fieldName: filtered.map(({ name: { value } }) => ({ name: value, capitalizedName: capitalize(value) })), }); } } } const scalars = (0, getScalars_1.default)(schemaString); const createScalarResolvers = () => { if (scalars && scalars.length > 0) { shelljs.mkdir('-p', `${projectMainPath}/src/${graphqlFileRootPath}/scalars/`); } for (const scalarName of scalars) { const templateName = './templates/scalarResolver.handlebars'; const context = { scalarName, moduleName: name, generatedPrefix, }; const filePath = `${projectMainPath}/src/${graphqlFileRootPath}/scalars/`; const fileName = `${scalarName}.ts`; const keepIfExists = true; (0, saveRenderedTemplate_1.saveRenderedTemplate)(templateName, context, filePath, fileName, keepIfExists); } }; createScalarResolvers(); const moduleName = name; const createModuleResolvers = () => { const templateName = './templates/moduleResolvers.handlebars'; const context = { moduleName, queries, mutations, typeResolvers, graphqlFileRootPath, appPrefix, scalars, }; const filePath = `${projectMainPath}/generated/graphql/`; const fileName = `${moduleName}Resolvers.ts`; (0, saveRenderedTemplate_1.saveRenderedTemplate)(templateName, context, filePath, fileName); }; createModuleResolvers(); } }; debug('createTypeResolvers'); createTypeResolvers(); }; exports.executeGeneration = executeGeneration;