UNPKG

prisma-trpc-generator

Version:

Prisma 2+ generator to emit fully implemented tRPC routers

268 lines 11.2 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getProcedureTypeByOpName = exports.getInputTypeByOpName = exports.getRouterSchemaImportByOpName = exports.generateRouterImport = exports.generateMiddlewareImport = exports.generateShieldImport = exports.generatetRPCImport = exports.generateCreateRouterImport = void 0; exports.generateBaseRouter = generateBaseRouter; exports.generateProcedure = generateProcedure; exports.generateRouterSchemaImports = generateRouterSchemaImports; exports.resolveModelsComments = resolveModelsComments; const internals_1 = require("@prisma/internals"); const getRelativePath_1 = __importDefault(require("./utils/getRelativePath")); const uncapitalizeFirstLetter_1 = require("./utils/uncapitalizeFirstLetter"); const getProcedureName = (config) => { return config.withShield ? 'shieldedProcedure' : config.withMiddleware ? 'protectedProcedure' : 'publicProcedure'; }; const generateCreateRouterImport = ({ sourceFile, config, }) => { const imports = ['t']; if (config) { imports.push(getProcedureName(config)); } sourceFile.addImportDeclaration({ moduleSpecifier: './helpers/createRouter', namedImports: imports, }); }; exports.generateCreateRouterImport = generateCreateRouterImport; const generatetRPCImport = (sourceFile) => { sourceFile.addImportDeclaration({ moduleSpecifier: '@trpc/server', namespaceImport: 'trpc', }); }; exports.generatetRPCImport = generatetRPCImport; const generateShieldImport = (sourceFile, options, value) => { const outputDir = (0, internals_1.parseEnvValue)(options.generator.output); let shieldPath = (0, getRelativePath_1.default)(outputDir, 'shield/shield'); if (typeof value === 'string') { shieldPath = (0, getRelativePath_1.default)(outputDir, value, true, options.schemaPath); } sourceFile.addImportDeclaration({ moduleSpecifier: shieldPath, namedImports: ['permissions'], }); }; exports.generateShieldImport = generateShieldImport; const generateMiddlewareImport = (sourceFile, options) => { const outputDir = (0, internals_1.parseEnvValue)(options.generator.output); sourceFile.addImportDeclaration({ moduleSpecifier: (0, getRelativePath_1.default)(outputDir, 'middleware'), namedImports: ['permissions'], }); }; exports.generateMiddlewareImport = generateMiddlewareImport; const generateRouterImport = (sourceFile, modelNamePlural, modelNameCamelCase) => { sourceFile.addImportDeclaration({ moduleSpecifier: `./${modelNameCamelCase}.router`, namedImports: [`${modelNamePlural}Router`], }); }; exports.generateRouterImport = generateRouterImport; function generateBaseRouter(sourceFile, config, options) { const outputDir = (0, internals_1.parseEnvValue)(options.generator.output); sourceFile.addStatements(/* ts */ ` import type { Context } from '${(0, getRelativePath_1.default)(outputDir, config.contextPath, true, options.schemaPath)}'; `); if (config.trpcOptionsPath) { sourceFile.addStatements(/* ts */ ` import trpcOptions from '${(0, getRelativePath_1.default)(outputDir, config.trpcOptionsPath, true, options.schemaPath)}'; `); } sourceFile.addStatements(/* ts */ ` export const t = trpc.initTRPC.context<Context>().create(${config.trpcOptionsPath ? 'trpcOptions' : ''}); `); const middlewares = []; if (config.withMiddleware && typeof config.withMiddleware === 'boolean') { sourceFile.addStatements(/* ts */ ` export const globalMiddleware = t.middleware(async ({ ctx, next }) => { // Add your middleware logic here return next() });`); middlewares.push({ type: 'global', value: /* ts */ `.use(globalMiddleware)`, }); } if (config.withMiddleware && typeof config.withMiddleware === 'string') { sourceFile.addStatements(/* ts */ ` import defaultMiddleware from '${(0, getRelativePath_1.default)(outputDir, config.withMiddleware, true, options.schemaPath)}'; `); sourceFile.addStatements(/* ts */ ` export const globalMiddleware = t.middleware(defaultMiddleware);`); middlewares.push({ type: 'global', value: /* ts */ `.use(globalMiddleware)`, }); } if (config.withShield) { sourceFile.addStatements(/* ts */ ` export const permissionsMiddleware = t.middleware(permissions); `); middlewares.push({ type: 'shield', value: /* ts */ ` .use(permissions)`, }); } sourceFile.addStatements(/* ts */ ` export const publicProcedure = t.procedure; `); if (middlewares.length > 0) { const procName = getProcedureName(config); middlewares.forEach((middleware, i) => { if (i === 0) { sourceFile.addStatements(/* ts */ ` export const ${procName} = t.procedure `); } sourceFile.addStatements(/* ts */ ` .use(${middleware.type === 'shield' ? 'permissionsMiddleware' : 'globalMiddleware'}) `); }); } } function generateProcedure(sourceFile, name, typeName, modelName, opType, baseOpType, config) { let input = `input${!config.withZod ? ' as any' : ''}`; const nameWithoutModel = name.replace(modelName, ''); if (nameWithoutModel === 'groupBy' && config.withZod) { input = '{ where: input.where, orderBy: input.orderBy, by: input.by, having: input.having, take: input.take, skip: input.skip }'; } sourceFile.addStatements(/* ts */ `${config.showModelNameInProcedure ? name : nameWithoutModel}: ${getProcedureName(config)} ${config.withZod ? `.input(${typeName})` : ''}.${(0, exports.getProcedureTypeByOpName)(baseOpType)}(async ({ ctx, input }) => { const ${name} = await ctx.prisma.${(0, uncapitalizeFirstLetter_1.uncapitalizeFirstLetter)(modelName)}.${opType.replace('One', '')}(${input}); return ${name}; }),`); } function generateRouterSchemaImports(sourceFile, modelName, modelActions) { sourceFile.addStatements( /* ts */ [ // remove any duplicate import statements ...new Set(modelActions.map((opName) => (0, exports.getRouterSchemaImportByOpName)(opName, modelName))), ].join('\n')); } const getRouterSchemaImportByOpName = (opName, modelName) => { const opType = opName.replace('OrThrow', ''); const inputType = (0, exports.getInputTypeByOpName)(opType, modelName); return inputType ? `import { ${inputType} } from "../schemas/${opType}${modelName}.schema"; ` : ''; }; exports.getRouterSchemaImportByOpName = getRouterSchemaImportByOpName; const getInputTypeByOpName = (opName, modelName) => { let inputType; switch (opName) { case 'findUnique': inputType = `${modelName}FindUniqueSchema`; break; case 'findFirst': inputType = `${modelName}FindFirstSchema`; break; case 'findMany': inputType = `${modelName}FindManySchema`; break; case 'findRaw': inputType = `${modelName}FindRawObjectSchema`; break; case 'createOne': inputType = `${modelName}CreateOneSchema`; break; case 'createMany': inputType = `${modelName}CreateManySchema`; break; case 'deleteOne': inputType = `${modelName}DeleteOneSchema`; break; case 'updateOne': inputType = `${modelName}UpdateOneSchema`; break; case 'deleteMany': inputType = `${modelName}DeleteManySchema`; break; case 'updateMany': inputType = `${modelName}UpdateManySchema`; break; case 'upsertOne': inputType = `${modelName}UpsertSchema`; break; case 'aggregate': inputType = `${modelName}AggregateSchema`; break; case 'aggregateRaw': inputType = `${modelName}AggregateRawObjectSchema`; break; case 'groupBy': inputType = `${modelName}GroupBySchema`; break; default: // Fallback for unknown operation types } return inputType; }; exports.getInputTypeByOpName = getInputTypeByOpName; const getProcedureTypeByOpName = (opName) => { let procType; switch (opName) { case 'findUnique': case 'findFirst': case 'findMany': case 'findRaw': case 'aggregate': case 'aggregateRaw': case 'groupBy': procType = 'query'; break; case 'createOne': case 'createMany': case 'deleteOne': case 'updateOne': case 'deleteMany': case 'updateMany': case 'upsertOne': procType = 'mutation'; break; default: // Fallback for unknown operation types } return procType; }; exports.getProcedureTypeByOpName = getProcedureTypeByOpName; function resolveModelsComments(models, hiddenModels) { var _a, _b, _c, _d, _e, _f; const modelAttributeRegex = /(@@Gen\.)+([A-z])+(\()+(.+)+(\))+/; const attributeNameRegex = /(?:\.)+([A-Za-z])+(?:\()+/; const attributeArgsRegex = /(?:\()+([A-Za-z])+:+(.+)+(?:\))+/; for (const model of models) { if (model.documentation) { const attribute = (_b = (_a = model.documentation) === null || _a === void 0 ? void 0 : _a.match(modelAttributeRegex)) === null || _b === void 0 ? void 0 : _b[0]; const attributeName = (_d = (_c = attribute === null || attribute === void 0 ? void 0 : attribute.match(attributeNameRegex)) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.slice(1, -1); if (attributeName !== 'model') continue; const rawAttributeArgs = (_f = (_e = attribute === null || attribute === void 0 ? void 0 : attribute.match(attributeArgsRegex)) === null || _e === void 0 ? void 0 : _e[0]) === null || _f === void 0 ? void 0 : _f.slice(1, -1); const parsedAttributeArgs = {}; if (rawAttributeArgs) { const rawAttributeArgsParts = rawAttributeArgs .split(':') .map((it) => it.trim()) .map((part) => (part.startsWith('[') ? part : part.split(','))) .flat() .map((it) => it.trim()); for (let i = 0; i < rawAttributeArgsParts.length; i += 2) { const key = rawAttributeArgsParts[i]; const value = rawAttributeArgsParts[i + 1]; parsedAttributeArgs[key] = JSON.parse(value); } } if (parsedAttributeArgs.hide) { hiddenModels.push(model.name); } } } } //# sourceMappingURL=helpers.js.map