From 43933540fcaff70e0d682ba0a9f2ae334119984d Mon Sep 17 00:00:00 2001 From: Levi Pires Date: Sat, 26 Aug 2023 17:26:16 -0300 Subject: [PATCH 1/5] feat: flexible createRouter typings let user dictate router typing --- packages/plugins/trpc/src/generator.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/plugins/trpc/src/generator.ts b/packages/plugins/trpc/src/generator.ts index 9a4f2e894..4532cb803 100644 --- a/packages/plugins/trpc/src/generator.ts +++ b/packages/plugins/trpc/src/generator.ts @@ -131,10 +131,10 @@ function createAppRouter( appRouter .addFunction({ - name: 'createRouter', + name: 'createRouter, Proc extends ProcBuilder>', parameters: [ - { name: 'router', type: 'RouterFactory' }, - { name: 'procedure', type: 'ProcBuilder' }, + { name: 'router', type: 'Router' }, + { name: 'procedure', type: 'Proc' }, ], isExported: true, }) @@ -159,7 +159,9 @@ function createAppRouter( moduleSpecifier: `./${model}.router`, }); - writer.writeLine(`${lowerCaseFirst(model)}: create${model}Router(router, procedure),`); + writer.writeLine( + `${lowerCaseFirst(model)}: create${model}Router(router, procedure),` + ); } }); writer.write(');'); @@ -243,10 +245,10 @@ function generateModelCreateRouter( } const createRouterFunc = modelRouter.addFunction({ - name: 'createRouter', + name: 'createRouter, Proc extends ProcBuilder>', parameters: [ - { name: 'router', type: 'RouterFactory' }, - { name: 'procedure', type: 'ProcBuilder' }, + { name: 'router', type: 'Router' }, + { name: 'procedure', type: 'Proc' }, ], isExported: true, isDefaultExport: true, From 33a155ed2ff99fe511a288f4075c29af550e131c Mon Sep 17 00:00:00 2001 From: Levi Pires Date: Sun, 27 Aug 2023 18:25:13 -0300 Subject: [PATCH 2/5] second try on making a more flexible 'createRouter' typings --- packages/plugins/trpc/src/generator.ts | 74 +++++++++++++++++++++++--- packages/plugins/trpc/src/helpers.ts | 14 ++++- 2 files changed, 78 insertions(+), 10 deletions(-) diff --git a/packages/plugins/trpc/src/generator.ts b/packages/plugins/trpc/src/generator.ts index 4532cb803..12b3e740f 100644 --- a/packages/plugins/trpc/src/generator.ts +++ b/packages/plugins/trpc/src/generator.ts @@ -89,35 +89,86 @@ function createAppRouter( const prismaImport = getPrismaClientImportSpec(zmodel, path.dirname(indexFile)); appRouter.addImportDeclarations([ { - namedImports: ['AnyRootConfig'], + namedImports: ['type AnyRootConfig', 'type Procedure', 'type ProcedureParams', 'type ProcedureType'], moduleSpecifier: '@trpc/server', }, { - namedImports: ['PrismaClient'], + namedImports: ['type PrismaClient', 'type Prisma'], moduleSpecifier: prismaImport, isTypeOnly: true, }, { - namedImports: ['createRouterFactory', 'AnyRouter'], + namedImports: ['type createRouterFactory'], moduleSpecifier: '@trpc/server/dist/core/router', }, { - namedImports: ['createBuilder'], + namedImports: ['type ProcedureBuilder'], moduleSpecifier: '@trpc/server/dist/core/internals/procedureBuilder', }, + { defaultImport: 'z', moduleSpecifier: 'zod', isTypeOnly: true }, ]); appRouter.addStatements(` + ${/** to be used by the other routers without making a bigger commit */ ''} + export { PrismaClient } from '${prismaImport}'; + export type BaseConfig = AnyRootConfig; export type RouterFactory = ReturnType< typeof createRouterFactory >; - export type ProcBuilder = ReturnType< - typeof createBuilder - >; + ${ + /** this is needed in order to prevent type errors between a procedure and a middleware-extended procedure */ '' + } + export type ProcBuilder = ProcedureBuilder<{ + _config: Config; + _ctx_out: Config['$types']['ctx']; + _input_in: any; + _input_out: any; + _output_in: any; + _output_out: any; + _meta: Config['$types']['meta']; + }>; + + type ExtractParamsFromProcBuilder> = + Builder extends ProcedureBuilder ? P : never; + type FromPromise

> = P extends Promise + ? T + : never; + + ${/** workaround to avoid creating 'typeof unsetMarker & object' on the procedure output */ ''} + type Join = A extends symbol ? B : A & B; + + ${ + /** you can name it whatever you want, but this is to make sure that + the types from the middleware and the procedure are correctly merged */ '' + } + export type ProcReturns< + PType extends ProcedureType, + PBuilder extends ProcBuilder, + ZType extends z.ZodType, + PPromise extends Prisma.PrismaPromise + > = Procedure< + PType, + ProcedureParams< + ExtractParamsFromProcBuilder["_config"], + ExtractParamsFromProcBuilder["_ctx_out"], + Join["_input_in"], z.infer>, + Join["_input_out"], z.infer>, + Join< + ExtractParamsFromProcBuilder["_output_in"], + FromPromise + >, + Join< + ExtractParamsFromProcBuilder["_output_out"], + FromPromise + >, + ExtractParamsFromProcBuilder["_meta"] + > + >; + export function db(ctx: any) { if (!ctx.prisma) { throw new Error('Missing "prisma" field in trpc context'); @@ -233,7 +284,14 @@ function generateModelCreateRouter( modelRouter.addImportDeclarations([ { - namedImports: ['type RouterFactory', 'type ProcBuilder', 'type BaseConfig', 'db'], + namedImports: [ + 'type RouterFactory', + 'type ProcBuilder', + 'type BaseConfig', + 'type ProcReturns', + 'type PrismaClient', + 'db', + ], moduleSpecifier: '.', }, ]); diff --git a/packages/plugins/trpc/src/helpers.ts b/packages/plugins/trpc/src/helpers.ts index d56e42c9b..b01f9f548 100644 --- a/packages/plugins/trpc/src/helpers.ts +++ b/packages/plugins/trpc/src/helpers.ts @@ -21,14 +21,24 @@ export function generateProcedure( writer.write(` ${opType}: procedure.input(${typeName}).query(({ctx, input}) => checkRead(db(ctx).${lowerCaseFirst( modelName - )}.${prismaMethod}(input as any))), + )}.${prismaMethod}(input as any))) as ProcReturns< + "query", + Proc, + (typeof ${modelName}InputSchema)["${opType.replace('OrThrow', '')}"], + ReturnType + >, `); } else if (procType === 'mutation') { // the cast "as any" is to circumvent a TS compiler misfired error in certain cases writer.write(` ${opType}: procedure.input(${typeName}).mutation(async ({ctx, input}) => checkMutate(db(ctx).${lowerCaseFirst( modelName - )}.${prismaMethod}(input as any))), + )}.${prismaMethod}(input as any))) as ProcReturns< + "mutation", + Proc, + (typeof ${modelName}InputSchema)["${opType.replace('OrThrow', '')}"], + ReturnType + >, `); } } From f2757c509901c0497d7e57f46036d9cbd314eed1 Mon Sep 17 00:00:00 2001 From: Levi Pires Date: Sun, 27 Aug 2023 19:12:39 -0300 Subject: [PATCH 3/5] fix: remove misused 'type' in Prisma import --- packages/plugins/trpc/src/generator.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/plugins/trpc/src/generator.ts b/packages/plugins/trpc/src/generator.ts index 12b3e740f..6d327ab5f 100644 --- a/packages/plugins/trpc/src/generator.ts +++ b/packages/plugins/trpc/src/generator.ts @@ -95,7 +95,6 @@ function createAppRouter( { namedImports: ['type PrismaClient', 'type Prisma'], moduleSpecifier: prismaImport, - isTypeOnly: true, }, { namedImports: ['type createRouterFactory'], From 5a59a32c71232a5bae9963c94fa5104eca4a1b18 Mon Sep 17 00:00:00 2001 From: Mateus Pires <56934662+mateus-p@users.noreply.github.com> Date: Wed, 30 Aug 2023 12:18:14 -0300 Subject: [PATCH 4/5] Update generator.ts Add 'AnyRouter' to generated router imports --- packages/plugins/trpc/src/generator.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugins/trpc/src/generator.ts b/packages/plugins/trpc/src/generator.ts index 6d327ab5f..32530b836 100644 --- a/packages/plugins/trpc/src/generator.ts +++ b/packages/plugins/trpc/src/generator.ts @@ -97,7 +97,7 @@ function createAppRouter( moduleSpecifier: prismaImport, }, { - namedImports: ['type createRouterFactory'], + namedImports: ['type createRouterFactory', 'AnyRouter'], moduleSpecifier: '@trpc/server/dist/core/router', }, { From 633c670c5b8e45db7619f99f5f090442766fc154 Mon Sep 17 00:00:00 2001 From: Levi Pires Date: Wed, 30 Aug 2023 15:44:05 -0300 Subject: [PATCH 5/5] fix: add missing `upperCaseFirst` --- packages/plugins/trpc/src/helpers.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/plugins/trpc/src/helpers.ts b/packages/plugins/trpc/src/helpers.ts index b01f9f548..4bbe18460 100644 --- a/packages/plugins/trpc/src/helpers.ts +++ b/packages/plugins/trpc/src/helpers.ts @@ -24,7 +24,7 @@ export function generateProcedure( )}.${prismaMethod}(input as any))) as ProcReturns< "query", Proc, - (typeof ${modelName}InputSchema)["${opType.replace('OrThrow', '')}"], + (typeof ${upperCaseFirst(modelName)}InputSchema)["${opType.replace('OrThrow', '')}"], ReturnType >, `); @@ -36,7 +36,7 @@ export function generateProcedure( )}.${prismaMethod}(input as any))) as ProcReturns< "mutation", Proc, - (typeof ${modelName}InputSchema)["${opType.replace('OrThrow', '')}"], + (typeof ${upperCaseFirst(modelName)}InputSchema)["${opType.replace('OrThrow', '')}"], ReturnType >, `);