UNPKG

@trpc/next

Version:

The tRPC Next.js library

1 lines 8.05 kB
{"version":3,"file":"server.mjs","names":[],"sources":["../../src/app-dir/server.ts"],"sourcesContent":["/// <reference types=\"next\" />\nimport {\n clientCallTypeToProcedureType,\n createTRPCUntypedClient,\n} from '@trpc/client';\nimport type { CreateContextCallback } from '@trpc/server';\nimport { rethrowNextErrors } from '@trpc/server/adapters/next-app-dir';\nimport type {\n AnyProcedure,\n AnyRootTypes,\n AnyRouter,\n ErrorHandlerOptions,\n inferClientTypes,\n inferProcedureInput,\n MaybePromise,\n RootConfig,\n Simplify,\n TRPCResponse,\n} from '@trpc/server/unstable-core-do-not-import';\nimport {\n createRecursiveProxy,\n formDataToObject,\n getErrorShape,\n getTRPCErrorFromUnknown,\n transformTRPCResponse,\n TRPCError,\n} from '@trpc/server/unstable-core-do-not-import';\nimport { revalidateTag } from 'next/cache';\nimport { cache } from 'react';\nimport type {\n ActionHandlerDef,\n CreateTRPCNextAppRouterOptions,\n inferActionDef,\n} from './shared';\nimport { generateCacheTag, isFormData } from './shared';\nimport type { NextAppDirDecorateRouterRecord } from './types';\n\nexport type { ActionHandlerDef };\n\n// ts-prune-ignore-next\nexport function experimental_createTRPCNextAppDirServer<\n TRouter extends AnyRouter,\n>(opts: CreateTRPCNextAppRouterOptions<TRouter>) {\n const getClient = cache(() => {\n const config = opts.config();\n return createTRPCUntypedClient(config);\n });\n\n return createRecursiveProxy<\n NextAppDirDecorateRouterRecord<\n TRouter['_def']['_config']['$types'],\n TRouter['_def']['record']\n >\n >((callOpts) => {\n // lazily initialize client\n const client = getClient();\n\n const pathCopy = [...callOpts.path];\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const action = pathCopy.pop()!;\n const procedurePath = pathCopy.join('.');\n const procedureType = clientCallTypeToProcedureType(action);\n const cacheTag = generateCacheTag(procedurePath, callOpts.args[0]);\n\n if (action === 'revalidate') {\n revalidateTag(cacheTag);\n return;\n }\n\n return (client[procedureType] as any)(procedurePath, ...callOpts.args);\n });\n}\n\n/**\n * @internal\n */\nexport type TRPCActionHandler<TDef extends ActionHandlerDef> = (\n input: FormData | TDef['input'],\n) => Promise<TRPCResponse<TDef['output'], TDef['errorShape']>>;\n\nexport function experimental_createServerActionHandler<\n TInstance extends {\n _config: RootConfig<AnyRootTypes>;\n },\n>(\n t: TInstance,\n opts: CreateContextCallback<\n TInstance['_config']['$types']['ctx'],\n () => MaybePromise<TInstance['_config']['$types']['ctx']>\n > & {\n /**\n * Transform form data to a `Record` before passing it to the procedure\n * @default true\n */\n normalizeFormData?: boolean;\n /**\n * Called when an error occurs in the handler\n */\n onError?: (\n opts: ErrorHandlerOptions<TInstance['_config']['$types']['ctx']>,\n ) => void;\n\n /**\n * Rethrow errors that should be handled by Next.js\n * @default true\n */\n rethrowNextErrors?: boolean;\n },\n) {\n const config = t._config;\n const {\n normalizeFormData = true,\n createContext,\n rethrowNextErrors: shouldRethrowNextErrors = true,\n } = opts;\n\n const transformer = config.transformer;\n\n // TODO allow this to take a `TRouter` in addition to a `AnyProcedure`\n return function createServerAction<TProc extends AnyProcedure>(\n proc: TProc,\n ): TRPCActionHandler<\n Simplify<inferActionDef<inferClientTypes<TInstance>, TProc>>\n > {\n return async function actionHandler(\n rawInput: FormData | inferProcedureInput<TProc>,\n ) {\n let ctx: TInstance['_config']['$types']['ctx'] | undefined = undefined;\n try {\n ctx = (await createContext?.()) ?? {};\n if (normalizeFormData && isFormData(rawInput)) {\n // Normalizes FormData so we can use `z.object({})` etc on the server\n try {\n rawInput = formDataToObject(rawInput);\n } catch {\n throw new TRPCError({\n code: 'INTERNAL_SERVER_ERROR',\n message: 'Failed to convert FormData to an object',\n });\n }\n } else if (rawInput && !isFormData(rawInput)) {\n rawInput = transformer.input.deserialize(rawInput);\n }\n\n const data = proc._def.experimental_caller\n ? await proc(rawInput as any)\n : await proc({\n input: undefined,\n ctx,\n path: '',\n getRawInput: async () => rawInput,\n type: proc._def.type,\n // is it possible to get the AbortSignal from the request?\n signal: undefined,\n batchIndex: 0,\n });\n\n const transformedJSON = transformTRPCResponse(config, {\n result: {\n data,\n },\n });\n return transformedJSON;\n } catch (cause) {\n const error = getTRPCErrorFromUnknown(cause);\n\n opts.onError?.({\n ctx,\n error,\n input: rawInput,\n path: '',\n type: proc._def.type,\n });\n\n if (shouldRethrowNextErrors) {\n rethrowNextErrors(error);\n }\n\n const shape = getErrorShape({\n config,\n ctx,\n error,\n input: rawInput,\n path: '',\n type: proc._def.type,\n });\n\n return transformTRPCResponse(t._config, {\n error: shape,\n });\n }\n } as TRPCActionHandler<\n inferActionDef<TInstance['_config']['$types'], TProc>\n >;\n };\n}\n\n// ts-prune-ignore-next\nexport async function experimental_revalidateEndpoint(req: Request) {\n const { cacheTag } = await req.json();\n\n if (typeof cacheTag !== 'string') {\n return new Response(\n JSON.stringify({\n revalidated: false,\n error: 'cacheTag must be a string',\n }),\n { status: 400 },\n );\n }\n\n revalidateTag(cacheTag);\n return new Response(JSON.stringify({ revalidated: true, now: Date.now() }), {\n status: 200,\n });\n}\n"],"mappings":";;;;;;;AAwCA,SAAgB,wCAEd,MAA+C;CAC/C,MAAM,YAAY,YAAY;EAC5B,MAAM,SAAS,KAAK,OAAO;EAC3B,OAAO,wBAAwB,MAAM;CACvC,CAAC;CAED,OAAO,sBAKJ,aAAa;EAEd,MAAM,SAAS,UAAU;EAEzB,MAAM,WAAW,CAAC,GAAG,SAAS,IAAI;EAElC,MAAM,SAAS,SAAS,IAAI;EAC5B,MAAM,gBAAgB,SAAS,KAAK,GAAG;EACvC,MAAM,gBAAgB,8BAA8B,MAAM;EAC1D,MAAM,WAAW,iBAAiB,eAAe,SAAS,KAAK,EAAE;EAEjE,IAAI,WAAW,cAAc;GAC3B,cAAc,QAAQ;GACtB;EACF;EAEA,OAAQ,OAAO,cAAc,CAAS,eAAe,GAAG,SAAS,IAAI;CACvE,CAAC;AACH;AASA,SAAgB,uCAKd,GACA,MAsBA;CACA,MAAM,SAAS,EAAE;CACjB,MAAM,EACJ,oBAAoB,MACpB,eACA,mBAAmB,0BAA0B,SAC3C;CAEJ,MAAM,cAAc,OAAO;CAG3B,OAAO,SAAS,mBACd,MAGA;EACA,OAAO,eAAe,cACpB,UACA;GACA,IAAI,MAAyD,KAAA;GAC7D,IAAI;;IACF,OAAA,uBAAO,OAAA,kBAAA,QAAA,kBAAA,KAAA,IAAA,KAAA,IAAM,cAAgB,QAAA,QAAA,yBAAA,KAAA,IAAA,uBAAM,CAAC;IACpC,IAAI,qBAAqB,WAAW,QAAQ,GAE1C,IAAI;KACF,WAAW,iBAAiB,QAAQ;IACtC,SAAA,SAAQ;KACN,MAAM,IAAI,UAAU;MAClB,MAAM;MACN,SAAS;KACX,CAAC;IACH;SACK,IAAI,YAAY,CAAC,WAAW,QAAQ,GACzC,WAAW,YAAY,MAAM,YAAY,QAAQ;IAGnD,MAAM,OAAO,KAAK,KAAK,sBACnB,MAAM,KAAK,QAAe,IAC1B,MAAM,KAAK;KACT,OAAO,KAAA;KACP;KACA,MAAM;KACN,aAAa,YAAY;KACzB,MAAM,KAAK,KAAK;KAEhB,QAAQ,KAAA;KACR,YAAY;IACd,CAAC;IAOL,OALwB,sBAAsB,QAAQ,EACpD,QAAQ,EACN,KACF,EACF,CACqB;GACvB,SAAS,OAAO;;IACd,MAAM,QAAQ,wBAAwB,KAAK;IAE3C,CAAA,gBAAA,KAAK,aAAA,QAAA,kBAAA,KAAA,KAAA,cAAA,KAAA,MAAU;KACb;KACA;KACA,OAAO;KACP,MAAM;KACN,MAAM,KAAK,KAAK;IAClB,CAAC;IAED,IAAI,yBACF,kBAAkB,KAAK;IAGzB,MAAM,QAAQ,cAAc;KAC1B;KACA;KACA;KACA,OAAO;KACP,MAAM;KACN,MAAM,KAAK,KAAK;IAClB,CAAC;IAED,OAAO,sBAAsB,EAAE,SAAS,EACtC,OAAO,MACT,CAAC;GACH;EACF;CAGF;AACF;AAGA,eAAsB,gCAAgC,KAAc;CAClE,MAAM,EAAE,aAAa,MAAM,IAAI,KAAK;CAEpC,IAAI,OAAO,aAAa,UACtB,OAAO,IAAI,SACT,KAAK,UAAU;EACb,aAAa;EACb,OAAO;CACT,CAAC,GACD,EAAE,QAAQ,IAAI,CAChB;CAGF,cAAc,QAAQ;CACtB,OAAO,IAAI,SAAS,KAAK,UAAU;EAAE,aAAa;EAAM,KAAK,KAAK,IAAI;CAAE,CAAC,GAAG,EAC1E,QAAQ,IACV,CAAC;AACH"}