UNPKG

@stryke/prisma-trpc-generator

Version:

A fork of the prisma-trpc-generator code to work in ESM with Prisma v6.

1 lines 16 kB
{"version":3,"file":"prisma-generator.mjs","names":[],"sources":["../src/prisma-generator.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Stryke\n\n This code was released as part of the Stryke project. Stryke\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/stryke.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/stryke\n Documentation: https://docs.stormsoftware.com/projects/stryke\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport type {\n DMMF,\n EnvValue,\n GeneratorOptions\n} from \"@prisma/generator-helper\";\nimport { existsSync } from \"@stryke/fs/exists\";\nimport { createDirectory, removeDirectory } from \"@stryke/fs/helpers\";\nimport { joinPaths } from \"@stryke/path/join-paths\";\nimport { lowerCaseFirst } from \"@stryke/string-format/lower-case-first\";\nimport path from \"node:path\";\nimport pluralize from \"pluralize\";\nimport { configSchema } from \"./config\";\nimport {\n constructDefaultOptions,\n constructShield,\n constructZodModels,\n generateCreateRouterImport,\n generateProcedure,\n generateRouterImport,\n generateRouterSchemaImports,\n generateTRPCExports,\n getInputTypeByOpName,\n resolveModelsComments\n} from \"./helpers\";\nimport { project } from \"./project\";\nimport type { RootType, Writeable } from \"./types\";\nimport { getPrismaInternals } from \"./utils/get-prisma-internals\";\nimport { writeFileSafely } from \"./utils/write-file-safely\";\nimport { resolveZodAggregateOperationSupport } from \"./zod/aggregate-helpers\";\nimport {\n hideZodInputObjectTypesAndRelatedFields,\n resolveZodModelsComments\n} from \"./zod/comments-helpers\";\nimport {\n generateZodEnumSchemas,\n generateZodIndex,\n generateZodModelSchemas,\n generateZodObjectSchemas\n} from \"./zod/generator-helpers\";\nimport { addMissingZodInputObjectTypes } from \"./zod/helpers\";\nimport Transformer from \"./zod/transformer\";\n\nexport async function generate(options: GeneratorOptions) {\n // eslint-disable-next-line no-console\n console.log(\"[STORM]: Running the Storm Software - Prisma tRPC generator \\n\");\n\n const internals = await getPrismaInternals();\n\n // eslint-disable-next-line no-console\n console.log(`[STORM]: Validating configuration options \\n`);\n\n const outputDir = internals.parseEnvValue(\n options.generator.output as EnvValue\n );\n const results = await configSchema.safeParseAsync(options.generator.config);\n if (!results.success) {\n throw new Error(\"Invalid options passed\");\n }\n\n const config = results.data;\n const consoleLog = (message: string) => {\n if (config.debug) {\n // eslint-disable-next-line no-console\n console.log(`[STORM]: ${message} \\n`);\n }\n };\n\n consoleLog(`Using configuration parameters: \\n${JSON.stringify(config)}`);\n\n consoleLog(`Preparing output directory: ${outputDir}`);\n\n await removeDirectory(outputDir);\n await createDirectory(outputDir);\n\n consoleLog(\"Finding Prisma Client generator\");\n\n const prismaClientProvider = options.otherGenerators.find(\n it => internals.parseEnvValue(it.provider) === \"prisma-client-js\"\n );\n if (!prismaClientProvider) {\n throw new Error(\n \"No Prisma Client generator found. Please add `prisma-client-js` to your generator list.\"\n );\n }\n\n consoleLog(\"Generating Prisma Client DMMF\");\n\n const prismaClientDmmf = (await internals.getDMMF({\n datamodel: options.datamodel,\n previewFeatures: prismaClientProvider?.previewFeatures\n })) as Writeable<DMMF.Document>;\n\n const modelOperations = prismaClientDmmf.mappings\n .modelOperations as DMMF.ModelMapping[];\n const inputObjectTypes = prismaClientDmmf.schema.inputObjectTypes\n .prisma as DMMF.InputType[];\n const outputObjectTypes = prismaClientDmmf.schema.outputObjectTypes\n .prisma as DMMF.OutputType[];\n const enumTypes = prismaClientDmmf.schema.enumTypes;\n const models = prismaClientDmmf.datamodel.models as Writeable<DMMF.Model[]>;\n const hiddenModels: string[] = [];\n const hiddenFields: string[] = [];\n\n if (config.withZod !== false) {\n consoleLog(\"Generating Zod schemas\");\n\n const zodOutputPath = internals.parseEnvValue(options.generator.output!);\n\n await createDirectory(zodOutputPath);\n Transformer.setOutputPath(zodOutputPath);\n\n if (prismaClientProvider?.isCustomOutput) {\n Transformer.setPrismaClientOutputPath(\n prismaClientProvider.output?.value as string\n );\n }\n\n await constructZodModels(\n models,\n joinPaths(zodOutputPath, \"schemas\", \"models\"),\n config,\n options\n );\n\n resolveZodModelsComments(\n models,\n modelOperations,\n enumTypes,\n hiddenModels,\n hiddenFields\n );\n\n await generateZodEnumSchemas(enumTypes.prisma, enumTypes.model!);\n\n const dataSource = options.datasources?.[0];\n if (!dataSource) {\n throw new Error(\"No datasource found\");\n }\n\n const previewFeatures = prismaClientProvider?.previewFeatures;\n Transformer.provider = dataSource.provider;\n Transformer.previewFeatures = previewFeatures;\n\n addMissingZodInputObjectTypes(\n inputObjectTypes,\n outputObjectTypes,\n models,\n modelOperations,\n dataSource.provider,\n {\n isGenerateSelect: true,\n isGenerateInclude: true\n }\n );\n\n const aggregateOperationSupport =\n resolveZodAggregateOperationSupport(inputObjectTypes);\n\n hideZodInputObjectTypesAndRelatedFields(\n inputObjectTypes,\n hiddenModels,\n hiddenFields\n );\n\n await generateZodObjectSchemas(\n inputObjectTypes as Writeable<DMMF.InputType[]>\n );\n\n await generateZodModelSchemas(\n models,\n modelOperations,\n aggregateOperationSupport\n );\n await generateZodIndex();\n } else {\n consoleLog(\"Skipping Zod schemas generation\");\n }\n\n const queries: RootType = [];\n const mutations: RootType = [];\n const subscriptions: RootType = [];\n\n prismaClientDmmf.mappings.modelOperations.forEach(modelOperation => {\n const { model: _model, plural: _plural, ...operations } = modelOperation;\n for (const [opType, opNameWithModel] of Object.entries(operations)) {\n if (\n [\n \"findUnique\",\n \"findUniqueOrThrow\",\n \"findFirst\",\n \"findFirstOrThrow\",\n \"findRaw\",\n \"findMany\",\n \"aggregateRaw\",\n \"count\",\n \"aggregate\",\n \"groupBy\"\n ].includes(opType)\n ) {\n queries.push(opNameWithModel as string);\n }\n\n if (\n [\n \"createOne\",\n \"createMany\",\n \"createManyAndReturn\",\n \"deleteOne\",\n \"deleteMany\",\n \"updateOne\",\n \"updateMany\",\n \"updateManyAndReturn\",\n \"upsertOne\"\n ].includes(opType)\n ) {\n mutations.push(opNameWithModel as string);\n }\n }\n });\n\n queries.sort();\n mutations.sort();\n subscriptions.sort();\n\n if (\n config.withShield &&\n !(\n typeof config.withShield === \"string\" &&\n (existsSync(joinPaths(outputDir, config.withShield)) ||\n existsSync(joinPaths(outputDir, `./${config.withShield}.ts`)) ||\n existsSync(joinPaths(outputDir, config.withShield, \"./shield.ts\")))\n )\n ) {\n consoleLog(`Generating tRPC Shield source file to ${outputDir}`);\n await writeFileSafely(\n joinPaths(outputDir, \"./shield.ts\"),\n await constructShield(\n { queries, mutations, subscriptions },\n config,\n options,\n outputDir\n )\n );\n } else {\n consoleLog(\"Skipping tRPC Shield generation\");\n }\n\n consoleLog(`Generating tRPC source code for ${models.length} models`);\n\n if (config.trpcOptions && typeof config.trpcOptions === \"boolean\") {\n consoleLog(`Generating tRPC options source file to ${outputDir}`);\n\n await writeFileSafely(\n joinPaths(outputDir, \"./options.ts\"),\n constructDefaultOptions(config, options, outputDir)\n );\n }\n\n resolveModelsComments(models, hiddenModels);\n\n consoleLog(\"Generating tRPC export file\");\n const trpcExports = project.createSourceFile(\n path.resolve(outputDir, \"trpc.ts\"),\n undefined,\n { overwrite: true }\n );\n\n await generateTRPCExports(trpcExports, config, options, outputDir);\n\n consoleLog(\"Generating tRPC app router\");\n const appRouter = project.createSourceFile(\n path.resolve(outputDir, \"routers\", `index.ts`),\n undefined,\n { overwrite: true }\n );\n\n consoleLog(\"Generating tRPC router imports\");\n\n generateCreateRouterImport({\n sourceFile: appRouter\n });\n\n const routerStatements = [];\n\n for (const modelOperation of modelOperations) {\n const { model, ...operations } = modelOperation;\n if (hiddenModels.includes(model)) {\n consoleLog(`Skipping model ${model} as it is hidden`);\n continue;\n }\n if (!model) {\n consoleLog(`Skipping model ${model} as it is not defined`);\n continue;\n }\n\n const modelActions = Object.keys(operations).filter<DMMF.ModelAction>(\n (opType): opType is DMMF.ModelAction =>\n // eslint-disable-next-line unicorn/prefer-includes\n config.generateModelActions.some(\n generateModelAction =>\n generateModelAction === opType.replace(\"One\", \"\")\n )\n );\n if (!modelActions.length) {\n consoleLog(`Skipping model ${model} as it has no actions to generate`);\n continue;\n }\n\n const plural = pluralize(lowerCaseFirst(model));\n\n consoleLog(`Generating tRPC router for model ${model}`);\n\n generateRouterImport(appRouter, plural, model);\n const modelRouter = project.createSourceFile(\n path.resolve(outputDir, \"routers\", `${lowerCaseFirst(model)}.router.ts`),\n undefined,\n { overwrite: true }\n );\n\n generateCreateRouterImport({\n sourceFile: modelRouter,\n config\n });\n\n if (config.withZod) {\n consoleLog(\"Generating Zod schemas imports\");\n generateRouterSchemaImports(modelRouter, model, modelActions);\n }\n\n modelRouter.addStatements(/* ts */ `\n export const ${plural}Router = t.router({`);\n\n for (const opType of modelActions) {\n const opNameWithModel = operations[opType];\n if (opNameWithModel) {\n const baseOpType = opType.replace(\"OrThrow\", \"\");\n\n generateProcedure(\n modelRouter,\n opNameWithModel,\n getInputTypeByOpName(baseOpType, model)!,\n model,\n opType,\n baseOpType,\n config\n );\n }\n }\n\n modelRouter.addStatements(/* ts */ `\n })`);\n\n modelRouter.formatText({ indentSize: 2 });\n routerStatements.push(/* ts */ `\n ${lowerCaseFirst(model)}: ${plural}Router`);\n\n consoleLog(\n `Generated tRPC router for model ${model} with ${modelActions.length} actions`\n );\n }\n\n consoleLog(\"Generating tRPC app router\");\n\n appRouter.addStatements(/* ts */ `\nexport const appRouter = t.router({${routerStatements.join()}});\n\nexport type AppRouter = typeof appRouter;`);\n\n appRouter.formatText({ indentSize: 2 });\n\n consoleLog(\"Saving tRPC router source files to disk\");\n\n await project.save();\n\n consoleLog(\"Storm Software - Prisma tRPC generator completed successfully\");\n}\n"],"mappings":"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"}