UNPKG

typegraphql-prisma-nestjs

Version:

This project is a fork of another with minor changes, created for personal use.

229 lines 16.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = generateCode; const tslib_1 = require("tslib"); const ts_morph_1 = require("ts-morph"); const path_1 = tslib_1.__importDefault(require("path")); const node_child_process_1 = require("node:child_process"); const node_util_1 = require("node:util"); const execa = (0, node_util_1.promisify)(node_child_process_1.exec); const helpers_1 = require("./helpers"); const enum_1 = tslib_1.__importDefault(require("./enum")); const model_type_class_1 = tslib_1.__importDefault(require("./model-type-class")); const relations_1 = tslib_1.__importDefault(require("./resolvers/relations")); const type_class_1 = require("./type-class"); const full_crud_1 = tslib_1.__importDefault(require("./resolvers/full-crud")); const config_1 = require("./config"); const imports_1 = require("./imports"); const dmmf_document_1 = require("./dmmf/dmmf-document"); const args_class_1 = tslib_1.__importDefault(require("./args-class")); const separate_action_1 = tslib_1.__importDefault(require("./resolvers/separate-action")); const prisma_version_1 = require("../utils/prisma-version"); const generate_enhance_1 = require("./generate-enhance"); const generate_scalars_1 = require("./generate-scalars"); const generate_helpers_1 = require("./generate-helpers"); const emit_block_1 = require("./emit-block"); const baseCompilerOptions = { target: ts_morph_1.ScriptTarget.ES2021, module: ts_morph_1.ModuleKind.CommonJS, emitDecoratorMetadata: true, experimentalDecorators: true, esModuleInterop: true, skipLibCheck: true, }; async function generateCode(dmmf, baseOptions, log = helpers_1.noop) { (0, prisma_version_1.ensureInstalledCorrectPrismaPackage)(); const options = { ...baseOptions, blocksToEmit: (0, emit_block_1.getBlocksToEmit)(baseOptions.emitOnly), contextPrismaKey: baseOptions.contextPrismaKey ?? "prisma", relativePrismaOutputPath: (0, helpers_1.toUnixPath)(path_1.default.relative(baseOptions.outputDirPath, baseOptions.prismaClientPath)), absolutePrismaOutputPath: !baseOptions.customPrismaImportPath && baseOptions.prismaClientPath.includes("node_modules") ? "@prisma/client" : undefined, formatGeneratedCode: baseOptions.formatGeneratedCode ?? "tsc", // default for backward compatibility }; const baseDirPath = options.outputDirPath; const emitTranspiledCode = options.emitTranspiledCode ?? options.outputDirPath.includes("node_modules"); const project = new ts_morph_1.Project({ compilerOptions: { ...baseCompilerOptions, ...(emitTranspiledCode && { declaration: true, importHelpers: true, }), }, }); log("Transforming dmmfDocument..."); const dmmfDocument = new dmmf_document_1.DmmfDocument(dmmf, options); if (dmmfDocument.shouldGenerateBlock("enums")) { log("Generating enums..."); const datamodelEnumNames = dmmfDocument.datamodel.enums.map(enumDef => enumDef.typeName); dmmfDocument.datamodel.enums.forEach(enumDef => (0, enum_1.default)(project, baseDirPath, enumDef, options)); dmmfDocument.schema.enums // skip enums from datamodel .filter(enumDef => !datamodelEnumNames.includes(enumDef.typeName)) .forEach(enumDef => (0, enum_1.default)(project, baseDirPath, enumDef, options)); const emittedEnumNames = [ ...new Set([ ...dmmfDocument.schema.enums.map(it => it.typeName), ...dmmfDocument.datamodel.enums.map(it => it.typeName), ]), ]; const enumsBarrelExportSourceFile = project.createSourceFile(path_1.default.resolve(baseDirPath, config_1.enumsFolderName, "index.ts"), undefined, { overwrite: true }); (0, imports_1.generateEnumsBarrelFile)(enumsBarrelExportSourceFile, emittedEnumNames); } if (dmmfDocument.shouldGenerateBlock("models")) { log("Generating models..."); dmmfDocument.datamodel.models.forEach(model => { const modelOutputType = dmmfDocument.schema.outputTypes.find(type => type.name === model.name); return (0, model_type_class_1.default)(project, baseDirPath, model, modelOutputType, dmmfDocument); }); const modelsBarrelExportSourceFile = project.createSourceFile(path_1.default.resolve(baseDirPath, config_1.modelsFolderName, "index.ts"), undefined, { overwrite: true }); (0, imports_1.generateModelsBarrelFile)(modelsBarrelExportSourceFile, dmmfDocument.datamodel.models.map(it => it.typeName)); } const resolversDirPath = path_1.default.resolve(baseDirPath, config_1.resolversFolderName); let outputTypesToGenerate = []; if (dmmfDocument.shouldGenerateBlock("outputs")) { log("Generating output types..."); const rootTypes = dmmfDocument.schema.outputTypes.filter(type => ["Query", "Mutation"].includes(type.name)); const modelNames = dmmfDocument.datamodel.models.map(model => model.name); outputTypesToGenerate = dmmfDocument.schema.outputTypes.filter( // skip generating models and root resolvers type => !modelNames.includes(type.name) && !rootTypes.includes(type)); const outputTypesFieldsArgsToGenerate = outputTypesToGenerate .map(it => it.fields) .reduce((a, b) => a.concat(b), []) .filter(it => it.argsTypeName); outputTypesToGenerate.forEach(type => (0, type_class_1.generateOutputTypeClassFromType)(project, resolversDirPath, type, dmmfDocument)); const outputsBarrelExportSourceFile = project.createSourceFile(path_1.default.resolve(baseDirPath, config_1.resolversFolderName, config_1.outputsFolderName, "index.ts"), undefined, { overwrite: true }); (0, imports_1.generateOutputsBarrelFile)(outputsBarrelExportSourceFile, outputTypesToGenerate.map(it => it.typeName), outputTypesFieldsArgsToGenerate.length > 0); if (outputTypesFieldsArgsToGenerate.length > 0) { log("Generating output types args..."); outputTypesFieldsArgsToGenerate.forEach(async (field) => { (0, args_class_1.default)(project, path_1.default.resolve(resolversDirPath, config_1.outputsFolderName), field.args, field.argsTypeName, dmmfDocument, 2); }); const outputsArgsBarrelExportSourceFile = project.createSourceFile(path_1.default.resolve(baseDirPath, config_1.resolversFolderName, config_1.outputsFolderName, config_1.argsFolderName, "index.ts"), undefined, { overwrite: true }); (0, imports_1.generateArgsBarrelFile)(outputsArgsBarrelExportSourceFile, outputTypesFieldsArgsToGenerate.map(it => it.argsTypeName)); } } if (dmmfDocument.shouldGenerateBlock("inputs")) { log("Generating input types..."); dmmfDocument.schema.inputTypes.forEach(type => (0, type_class_1.generateInputTypeClassFromType)(project, resolversDirPath, type, options)); const inputsBarrelExportSourceFile = project.createSourceFile(path_1.default.resolve(baseDirPath, config_1.resolversFolderName, config_1.inputsFolderName, "index.ts"), undefined, { overwrite: true }); (0, imports_1.generateInputsBarrelFile)(inputsBarrelExportSourceFile, dmmfDocument.schema.inputTypes.map(it => it.typeName)); } if (dmmfDocument.relationModels.length > 0 && dmmfDocument.shouldGenerateBlock("relationResolvers")) { log("Generating relation resolvers..."); dmmfDocument.relationModels.forEach(relationModel => (0, relations_1.default)(project, baseDirPath, dmmfDocument, relationModel, options)); const relationResolversBarrelExportSourceFile = project.createSourceFile(path_1.default.resolve(baseDirPath, config_1.resolversFolderName, config_1.relationsResolversFolderName, "resolvers.index.ts"), undefined, { overwrite: true }); (0, imports_1.generateResolversBarrelFile)(relationResolversBarrelExportSourceFile, dmmfDocument.relationModels.map(relationModel => ({ resolverName: relationModel.resolverName, modelName: relationModel.model.typeName, }))); log("Generating relation resolver args..."); dmmfDocument.relationModels.forEach(async (relationModelData) => { const resolverDirPath = path_1.default.resolve(baseDirPath, config_1.resolversFolderName, config_1.relationsResolversFolderName, relationModelData.model.typeName); relationModelData.relationFields .filter(field => field.argsTypeName) .forEach(async (field) => { (0, args_class_1.default)(project, resolverDirPath, field.outputTypeField.args, field.argsTypeName, dmmfDocument); }); const argTypeNames = relationModelData.relationFields .filter(it => it.argsTypeName !== undefined) .map(it => it.argsTypeName); if (argTypeNames.length) { const barrelExportSourceFile = project.createSourceFile(path_1.default.resolve(resolverDirPath, config_1.argsFolderName, "index.ts"), undefined, { overwrite: true }); (0, imports_1.generateArgsBarrelFile)(barrelExportSourceFile, argTypeNames); } }); const relationModelsWithArgs = dmmfDocument.relationModels.filter(relationModelData => relationModelData.relationFields.some(it => it.argsTypeName !== undefined)); if (relationModelsWithArgs.length > 0) { const relationResolversArgsIndexSourceFile = project.createSourceFile(path_1.default.resolve(baseDirPath, config_1.resolversFolderName, config_1.relationsResolversFolderName, "args.index.ts"), undefined, { overwrite: true }); (0, imports_1.generateArgsIndexFile)(relationResolversArgsIndexSourceFile, relationModelsWithArgs.map(relationModelData => relationModelData.model.typeName)); } const relationResolversIndexSourceFile = project.createSourceFile(path_1.default.resolve(baseDirPath, config_1.resolversFolderName, config_1.relationsResolversFolderName, "index.ts"), undefined, { overwrite: true }); (0, imports_1.generateResolversIndexFile)(relationResolversIndexSourceFile, "relations", relationModelsWithArgs.length > 0); } if (dmmfDocument.shouldGenerateBlock("crudResolvers")) { log("Generating crud resolvers..."); dmmfDocument.modelMappings.forEach(async (mapping) => { const model = dmmfDocument.datamodel.models.find(model => model.name === mapping.modelName); (0, full_crud_1.default)(project, baseDirPath, mapping, model, dmmfDocument, options); mapping.actions .filter(a => !options.emitActions?.includes(a.prismaMethod)) .forEach(async (action) => { const model = dmmfDocument.datamodel.models.find(model => model.name === mapping.modelName); (0, separate_action_1.default)(project, baseDirPath, model, action, mapping, dmmfDocument, options); }); }); const generateMappingData = dmmfDocument.modelMappings.map(mapping => { const model = dmmfDocument.datamodel.models.find(model => model.name === mapping.modelName); return { modelName: model.typeName, resolverName: mapping.resolverName, actionResolverNames: mapping.actions .filter(a => !options.emitActions?.includes(a.prismaMethod)) .map(it => it.actionResolverName), }; }); const crudResolversBarrelExportSourceFile = project.createSourceFile(path_1.default.resolve(baseDirPath, config_1.resolversFolderName, config_1.crudResolversFolderName, "resolvers-crud.index.ts"), undefined, { overwrite: true }); (0, imports_1.generateResolversBarrelFile)(crudResolversBarrelExportSourceFile, generateMappingData); const crudResolversActionsBarrelExportSourceFile = project.createSourceFile(path_1.default.resolve(baseDirPath, config_1.resolversFolderName, config_1.crudResolversFolderName, "resolvers-actions.index.ts"), undefined, { overwrite: true }); (0, imports_1.generateResolversActionsBarrelFile)(crudResolversActionsBarrelExportSourceFile, generateMappingData); const crudResolversIndexSourceFile = project.createSourceFile(path_1.default.resolve(baseDirPath, config_1.resolversFolderName, config_1.crudResolversFolderName, "index.ts"), undefined, { overwrite: true }); (0, imports_1.generateResolversIndexFile)(crudResolversIndexSourceFile, "crud", true); log("Generating crud resolvers args..."); dmmfDocument.modelMappings.forEach(async (mapping) => { const actionsWithArgs = mapping.actions .filter(a => !options.emitActions?.includes(a.prismaMethod)) .filter(it => it.argsTypeName !== undefined); if (actionsWithArgs.length) { const model = dmmfDocument.datamodel.models.find(model => model.name === mapping.modelName); const resolverDirPath = path_1.default.resolve(baseDirPath, config_1.resolversFolderName, config_1.crudResolversFolderName, model.typeName); actionsWithArgs.forEach(async (action) => { (0, args_class_1.default)(project, resolverDirPath, action.method.args, action.argsTypeName, dmmfDocument); }); const barrelExportSourceFile = project.createSourceFile(path_1.default.resolve(resolverDirPath, config_1.argsFolderName, "index.ts"), undefined, { overwrite: true }); (0, imports_1.generateArgsBarrelFile)(barrelExportSourceFile, actionsWithArgs.map(it => it.argsTypeName)); } }); const crudResolversArgsIndexSourceFile = project.createSourceFile(path_1.default.resolve(baseDirPath, config_1.resolversFolderName, config_1.crudResolversFolderName, "args.index.ts"), undefined, { overwrite: true }); (0, imports_1.generateArgsIndexFile)(crudResolversArgsIndexSourceFile, dmmfDocument.modelMappings .filter(mapping => mapping.actions .filter(a => !options.emitActions?.includes(a.prismaMethod)) .some(it => it.argsTypeName !== undefined)) .map(mapping => mapping.modelTypeName)); } log("Generate enhance map"); const enhanceSourceFile = project.createSourceFile(baseDirPath + "/enhance.ts", undefined, { overwrite: true }); (0, generate_enhance_1.generateEnhanceMap)(enhanceSourceFile, dmmfDocument, dmmfDocument.modelMappings, dmmfDocument.relationModels, dmmfDocument.datamodel.models, dmmfDocument.schema.inputTypes, outputTypesToGenerate, dmmfDocument.options); log("Generate custom scalars"); const scalarsSourceFile = project.createSourceFile(baseDirPath + "/scalars.ts", undefined, { overwrite: true }); (0, generate_scalars_1.generateCustomScalars)(scalarsSourceFile, dmmfDocument.options); log("Generate custom helpers"); const helpersSourceFile = project.createSourceFile(baseDirPath + "/helpers.ts", undefined, { overwrite: true }); (0, generate_helpers_1.generateHelpersFile)(helpersSourceFile, dmmfDocument.options); log("Generating index file"); const indexSourceFile = project.createSourceFile(baseDirPath + "/index.ts", undefined, { overwrite: true }); (0, imports_1.generateIndexFile)(indexSourceFile, dmmfDocument.relationModels.length > 0, dmmfDocument.options.blocksToEmit); log("Emitting generated code files"); if (emitTranspiledCode) { await project.emit(); } else { if (options.formatGeneratedCode === "tsc") { for (const file of project.getSourceFiles()) { file.formatText({ indentSize: 2 }); } } await project.save(); if (options.formatGeneratedCode === "prettier") { await execa(`npx prettier --write --ignore-path .prettierignore ${baseDirPath}`); } } } //# sourceMappingURL=generate-code.js.map