UNPKG

@stryke/prisma-trpc-generator

Version:

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

1 lines 23.3 kB
{"version":3,"file":"helpers.mjs","names":[],"sources":["../src/helpers.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\n/* eslint-disable ts/no-use-before-define */\n\nimport type {\n DMMF,\n EnvValue,\n GeneratorOptions\n} from \"@prisma/generator-helper\";\nimport { relativePath } from \"@stryke/path/file-path-fns\";\nimport { joinPaths } from \"@stryke/path/join-paths\";\nimport { lowerCaseFirst } from \"@stryke/string-format/lower-case-first\";\nimport type { SourceFile } from \"ts-morph\";\nimport type { Config } from \"./config\";\nimport { project } from \"./project\";\nimport type { Writeable } from \"./types\";\nimport { getPrismaInternals } from \"./utils/get-prisma-internals\";\nimport { generateBarrelFile, populateModelFile } from \"./zod/model-helpers\";\n\nconst getProcedureName = (config: Config) => {\n return config.withShield\n ? \"shieldedProcedure\"\n : config.withMiddleware\n ? \"protectedProcedure\"\n : \"publicProcedure\";\n};\n\nexport const generateCreateRouterImport = ({\n sourceFile,\n config\n}: {\n sourceFile: SourceFile;\n config?: Config;\n}) => {\n const imports = [\"t\"];\n\n if (config) {\n imports.push(getProcedureName(config));\n }\n\n sourceFile.addImportDeclaration({\n moduleSpecifier: \"../trpc\",\n namedImports: imports\n });\n};\n\nexport const generateRPCImport = (sourceFile: SourceFile) => {\n sourceFile.addImportDeclaration({\n moduleSpecifier: \"@trpc/server\",\n namespaceImport: \"trpc\"\n });\n};\n\nexport const generateMiddlewareImport = async (\n sourceFile: SourceFile,\n options: GeneratorOptions\n) => {\n const internals = await getPrismaInternals();\n\n const outputDir = internals.parseEnvValue(\n options.generator.output as EnvValue\n );\n sourceFile.addImportDeclaration({\n moduleSpecifier: relativePath(\n outputDir,\n joinPaths(outputDir, \"middleware\")\n ),\n namedImports: [\"permissions\"]\n });\n};\n\nexport const generateRouterImport = (\n sourceFile: SourceFile,\n modelNamePlural: string,\n modelNameCamelCase: string\n) => {\n sourceFile.addImportDeclaration({\n moduleSpecifier: `./${lowerCaseFirst(modelNameCamelCase)}.router`,\n namedImports: [`${modelNamePlural}Router`]\n });\n};\n\nexport async function generateTRPCExports(\n sourceFile: SourceFile,\n config: Config,\n options: GeneratorOptions,\n outputDir: string\n) {\n if (config.withShield) {\n sourceFile.addImportDeclaration({\n moduleSpecifier: relativePath(\n outputDir,\n joinPaths(\n outputDir,\n typeof config.withShield === \"string\" ? config.withShield : \"shield\"\n )\n ),\n namedImports: [\"permissions\"]\n });\n }\n\n sourceFile.addStatements(\n /* ts */ `import type { Context } from '${relativePath(\n outputDir,\n joinPaths(outputDir, config.contextPath)\n )}';`\n );\n\n if (config.trpcOptions) {\n sourceFile.addStatements(\n /* ts */ `import trpcOptions from '${\n typeof config.trpcOptions === \"string\"\n ? relativePath(outputDir, joinPaths(outputDir, config.trpcOptions))\n : \"./options\"\n }';`\n );\n }\n\n if (config.withNext) {\n sourceFile.addStatements(/* ts */ `import { createContext } from '${relativePath(\n outputDir,\n joinPaths(outputDir, config.contextPath)\n )}';\nimport { initTRPC } from '@trpc/server';\nimport { createTRPCServerActionHandler } from '@stryke/trpc-next/action-handler';\nimport { cookies } from \"next/headers\";`);\n }\n\n sourceFile.addStatements(/* ts */ `\nexport const t = initTRPC.context<Context>().create(${\n config.trpcOptions ? \"trpcOptions\" : \"\"\n });`);\n\n const middlewares = [];\n\n if (config.withMiddleware && typeof config.withMiddleware === \"boolean\") {\n sourceFile.addStatements(/* ts */ `\nexport const globalMiddleware = t.middleware(async ({ ctx, next }) => {\n console.log('inside middleware!')\n return next()\n});`);\n middlewares.push({\n type: \"global\",\n value: /* ts */ `.use(globalMiddleware)`\n });\n }\n\n if (config.withMiddleware && typeof config.withMiddleware === \"string\") {\n sourceFile.addStatements(/* ts */ `\nimport middleware from '${relativePath(\n outputDir,\n joinPaths(\n outputDir,\n typeof config.withMiddleware === \"string\"\n ? config.withMiddleware\n : \"middleware\"\n )\n )}';\n `);\n sourceFile.addStatements(/* ts */ `\nexport const globalMiddleware = t.middleware(middleware);`);\n middlewares.push({\n type: \"global\",\n value: /* ts */ `.use(globalMiddleware)`\n });\n }\n\n if (config.withShield) {\n sourceFile.addStatements(/* ts */ `\nexport const permissionsMiddleware = t.middleware(permissions);\n `);\n\n middlewares.push({\n type: \"shield\",\n value: /* ts */ `\n .use(permissions)`\n });\n }\n\n sourceFile.addStatements(/* ts */ `\n/**\n * Create a server-side caller\n * @see https://trpc.io/docs/server/server-side-calls\n */\nexport const createCallerFactory = t.createCallerFactory;`);\n\n sourceFile.addStatements(/* ts */ `\nexport const publicProcedure = t.procedure; `);\n\n if (middlewares.length > 0) {\n const procName = getProcedureName(config);\n\n middlewares.forEach((middleware, i) => {\n if (i === 0) {\n sourceFile.addStatements(/* ts */ `\nexport const ${procName} = t.procedure`);\n }\n\n sourceFile.addStatements(\n /* ts */ `.use(${\n middleware.type === \"shield\"\n ? \"permissionsMiddleware\"\n : \"globalMiddleware\"\n })`\n );\n });\n }\n\n if (config.withNext) {\n sourceFile.addStatements(/* ts */ `\nexport const createAction: ReturnType<typeof createTRPCServerActionHandler> =\n createTRPCServerActionHandler(cookies, t, createContext);\n`);\n }\n\n sourceFile.formatText({\n indentSize: 2\n });\n}\n\nexport function generateProcedure(\n sourceFile: SourceFile,\n name: string,\n typeName: string,\n modelName: string,\n opType: string,\n baseOpType: string,\n config: Config\n) {\n let input = `input${!config.withZod ? \" as any\" : \"\"}`;\n const nameWithoutModel = name.replace(modelName, \"\");\n if (nameWithoutModel === \"groupBy\" && config.withZod) {\n input =\n \"{ where: input.where, orderBy: input.orderBy, by: input.by, having: input.having, take: input.take, skip: input.skip }\";\n }\n sourceFile.addStatements(/* ts */ `${\n config.showModelNameInProcedure ? name : nameWithoutModel\n }: ${getProcedureName(config)}\n ${config.withZod ? `.input(${lowerCaseFirst(typeName)})` : \"\"}.${getProcedureTypeByOpName(\n baseOpType\n )}(async ({ ctx, input }) => {\n const ${name} = await ctx.prisma.${lowerCaseFirst(\n modelName\n )}.${opType.replace(\"One\", \"\")}(${input});\n return ${name};\n }),`);\n}\n\nexport function generateRouterSchemaImports(\n sourceFile: SourceFile,\n modelName: string,\n modelActions: string[]\n) {\n sourceFile.addStatements(\n /* ts */\n [\n // remove any duplicate import statements\n ...new Set(\n modelActions.map(opName =>\n getRouterSchemaImportByOpName(opName, modelName)\n )\n )\n ].join(\"\\n\")\n );\n}\n\nexport const getRouterSchemaImportByOpName = (\n opName: string,\n modelName: string\n) => {\n const opType = opName.replace(\"OrThrow\", \"\").replace(\"ManyAndReturn\", \"\");\n const inputType = getInputTypeByOpName(opType, modelName);\n\n return inputType\n ? `import { ${lowerCaseFirst(inputType)} } from \"../schemas/${lowerCaseFirst(opType)}${modelName}.schema\"; `\n : \"\";\n};\n\nexport const getInputTypeByOpName = (opName: string, modelName: string) => {\n let inputType;\n switch (opName) {\n case \"findUnique\":\n inputType = `${modelName}FindUniqueSchema`;\n break;\n case \"findFirst\":\n inputType = `${modelName}FindFirstSchema`;\n break;\n case \"findMany\":\n inputType = `${modelName}FindManySchema`;\n break;\n case \"findRaw\":\n inputType = `${modelName}FindRawObjectSchema`;\n break;\n case \"createOne\":\n inputType = `${modelName}CreateOneSchema`;\n break;\n case \"createMany\":\n inputType = `${modelName}CreateManySchema`;\n break;\n case \"createManyAndReturn\":\n inputType = `${modelName}CreateManySchema`;\n break;\n case \"deleteOne\":\n inputType = `${modelName}DeleteOneSchema`;\n break;\n case \"deleteMany\":\n inputType = `${modelName}DeleteManySchema`;\n break;\n case \"updateOne\":\n inputType = `${modelName}UpdateOneSchema`;\n break;\n case \"updateMany\":\n inputType = `${modelName}UpdateManySchema`;\n break;\n case \"updateManyAndReturn\":\n inputType = `${modelName}UpdateManySchema`;\n break;\n case \"upsertOne\":\n inputType = `${modelName}UpsertSchema`;\n break;\n case \"aggregate\":\n inputType = `${modelName}AggregateSchema`;\n break;\n case \"aggregateRaw\":\n inputType = `${modelName}AggregateRawObjectSchema`;\n break;\n case \"groupBy\":\n inputType = `${modelName}GroupBySchema`;\n break;\n default:\n // eslint-disable-next-line no-console\n console.log(\"getInputTypeByOpName: \", { opName, modelName });\n }\n return inputType;\n};\n\nexport const getProcedureTypeByOpName = (opName: string) => {\n let procType;\n switch (opName) {\n case \"findUnique\":\n case \"findFirst\":\n case \"findMany\":\n case \"findRaw\":\n case \"aggregate\":\n case \"aggregateRaw\":\n case \"groupBy\":\n procType = \"query\";\n break;\n case \"createOne\":\n case \"createMany\":\n case \"createManyAndReturn\":\n case \"deleteOne\":\n case \"updateOne\":\n case \"deleteMany\":\n case \"updateMany\":\n case \"updateManyAndReturn\":\n case \"upsertOne\":\n procType = \"mutation\";\n break;\n default:\n // eslint-disable-next-line no-console\n console.log(\"getProcedureTypeByOpName: \", { opName });\n }\n return procType;\n};\n\nexport function resolveModelsComments(\n models: DMMF.Model[],\n hiddenModels: string[]\n) {\n // eslint-disable-next-line regexp/no-obscure-range\n const modelAttributeRegex = /(?:@@Gen\\.)+[A-z]+\\(.+\\)/;\n const attributeNameRegex = /\\.+[A-Z]+\\(+/i;\n const attributeArgsRegex = /\\(+[A-Z]+:.+\\)/i;\n\n for (const model of models) {\n if (model.documentation) {\n const attribute = model.documentation?.match(modelAttributeRegex)?.[0];\n const attributeName = attribute\n ?.match(attributeNameRegex)?.[0]\n ?.slice(1, -1);\n if (attributeName !== \"model\") continue;\n const rawAttributeArgs = attribute\n ?.match(attributeArgsRegex)?.[0]\n ?.slice(1, -1);\n\n const parsedAttributeArgs: Record<string, unknown> = {};\n if (rawAttributeArgs) {\n const rawAttributeArgsParts = rawAttributeArgs\n .split(\":\")\n .map(it => it.trim())\n .map(part => (part.startsWith(\"[\") ? part : part.split(\",\")))\n .flat()\n .map(it => it.trim());\n\n for (let i = 0; i < rawAttributeArgsParts.length; i += 2) {\n const key = rawAttributeArgsParts[i];\n const value = rawAttributeArgsParts[i + 1];\n parsedAttributeArgs[key!] = JSON.parse(value!);\n }\n }\n\n if (parsedAttributeArgs.hide) {\n hiddenModels.push(model.name);\n }\n }\n }\n}\n\nexport const getImports = (\n type: \"trpc\" | \"trpc-shield\" | \"context\",\n newPath?: string\n) => {\n let statement = \"\";\n if (type === \"trpc\") {\n statement = \"import * as trpc from '@trpc/server';\\n\";\n } else if (type === \"trpc-shield\") {\n statement = \"import { shield, allow } from '@stryke/trpc-next/shield';\\n\";\n } else if (type === \"context\") {\n statement = `import type { Context } from '${newPath}';\\n`;\n }\n\n return statement;\n};\n\nexport const wrapWithObject = ({\n shieldItemLines\n}: {\n shieldItemLines: Array<string> | string;\n}) => {\n let wrapped = \"{\";\n wrapped += \"\\n\";\n wrapped += Array.isArray(shieldItemLines)\n ? ` ${shieldItemLines.join(\",\\r\\n\")}`\n : ` ${shieldItemLines}`;\n wrapped += \"\\n\";\n wrapped += \"}\";\n return wrapped;\n};\n\nexport const wrapWithTrpcShieldCall = ({\n shieldObjectTextWrapped\n}: {\n shieldObjectTextWrapped: string;\n}) => {\n let wrapped = \"shield<Context>(\";\n wrapped += \"\\n\";\n wrapped += ` ${shieldObjectTextWrapped}`;\n wrapped += \"\\n\";\n wrapped += \")\";\n return wrapped;\n};\n\nexport const wrapWithExport = ({\n shieldObjectText\n}: {\n shieldObjectText: string;\n}) => {\n return `export const permissions: ReturnType<typeof shield<Context>> = ${shieldObjectText};`;\n};\n\nexport const constructShield = async (\n {\n queries,\n mutations,\n subscriptions\n }: {\n queries: Array<string>;\n mutations: Array<string>;\n subscriptions: Array<string>;\n },\n config: Config,\n options: GeneratorOptions,\n outputDir: string\n) => {\n if (\n queries.length === 0 &&\n mutations.length === 0 &&\n subscriptions.length === 0\n ) {\n return \"\";\n }\n\n let rootItems = \"\";\n if (queries.length > 0) {\n const queryLinesWrapped = `query: ${wrapWithObject({\n shieldItemLines: queries.map(query => `${query}: allow`)\n })},`;\n rootItems += queryLinesWrapped;\n }\n if (mutations.length > 0) {\n const mutationLinesWrapped = `mutation: ${wrapWithObject({\n shieldItemLines: mutations.map(mutation => `${mutation}: allow`)\n })},`;\n rootItems += mutationLinesWrapped;\n }\n\n if (subscriptions.length > 0) {\n const subscriptionLinesWrapped = `subscription: ${wrapWithObject({\n shieldItemLines: subscriptions.map(\n subscription => `${subscription}: allow`\n )\n })},`;\n rootItems += subscriptionLinesWrapped;\n }\n\n if (rootItems.length === 0) {\n return \"\";\n }\n\n let shieldText = getImports(\"trpc-shield\");\n shieldText += getImports(\n \"context\",\n relativePath(outputDir, joinPaths(outputDir, config.contextPath))\n );\n shieldText += \"\\n\\n\";\n shieldText += wrapWithExport({\n shieldObjectText: wrapWithTrpcShieldCall({\n shieldObjectTextWrapped: wrapWithObject({ shieldItemLines: rootItems })\n })\n });\n\n return shieldText;\n};\n\nexport const constructDefaultOptions = (\n config: Config,\n options: GeneratorOptions,\n outputDir: string\n) => {\n return `import { ZodError } from 'zod';${config.withNext ? '\\nimport { transformer } from \"@stryke/trpc-next/shared\";' : \"\"}\nimport type {\n DataTransformerOptions,\n RootConfig\n} from \"@trpc/server/unstable-core-do-not-import\";\nimport type { Context } from \"${relativePath(outputDir, joinPaths(outputDir, config.contextPath))}\";\n\ninterface RuntimeConfigOptions<\n TContext extends object,\n TMeta extends object = object\n> extends Partial<\n Omit<\n RootConfig<{\n ctx: TContext;\n meta: TMeta;\n errorShape: any;\n transformer: any;\n }>,\n \"$types\" | \"transformer\"\n >\n > {\n /**\n * Use a data transformer\n * @see https://trpc.io/docs/v11/data-transformers\n */\n transformer?: DataTransformerOptions;\n}\n\nconst options: RuntimeConfigOptions<Context> = {${config.withNext ? \"\\n transformer,\" : \"\"}\n errorFormatter({ shape, error }) {\n return {\n ...shape,\n data: {\n ...shape.data,\n zodError:\n error.code === \"BAD_REQUEST\" && error.cause instanceof ZodError\n ? error.cause.flatten()\n : null\n }\n };\n }\n};\n\nexport default options;\n`;\n};\n\nexport const constructZodModels = async (\n models: Writeable<DMMF.Model[]>,\n outputPath: string,\n config: Config,\n options: GeneratorOptions\n) => {\n const indexFile = project.createSourceFile(\n `${outputPath}/index.ts`,\n {},\n { overwrite: true }\n );\n\n generateBarrelFile(models, indexFile);\n\n indexFile.formatText({\n indentSize: 2\n });\n\n await Promise.all(\n models.map(async model => {\n const sourceFile = project.createSourceFile(\n `${outputPath}/${lowerCaseFirst(model.name)}.schema.ts`,\n {},\n { overwrite: true }\n );\n\n await populateModelFile(model, sourceFile, config, options);\n\n sourceFile.formatText({\n indentSize: 2\n });\n })\n );\n};\n"],"mappings":"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"}