Skip to content
This repository was archived by the owner on Nov 19, 2024. It is now read-only.
This repository was archived by the owner on Nov 19, 2024. It is now read-only.

Unknown Procedure Type - Next.js App Router #431

Open
@alex-streza

Description

@alex-streza

I'm running a project using create-t3-turbo and wanted to add OpenAPI support to trpc routers but I keep getting this error, any help is much appreciated, kinda counting on getting OpenAPI support this way.

@morrow/nextjs:dev:  ⨯ Error: Unknown procedure type
@morrow/nextjs:dev:     at getProcedureType (/Users/alex/Documents/GitHub/morrow/node_modules/trpc-openapi/dist/utils/procedure.js:26:11)

I went in the procedure.js file to debug and saw that procedure._def doesn't seem to exist in my trpc: next version (11.0.0-next-alpha.149+11361b82d)

I'm not 100% certain if it's because of this but I'm also using trpc in app router and trpc-openapi in pages/api

pages/api/[...trpc].ts

import type { NextApiRequest, NextApiResponse } from "next";
import { createOpenApiNextHandler } from "trpc-openapi";

import { appRouter } from "@morrow/api";
import { createTRPCOpenAPIContext } from "@morrow/api/src/trpc";

const handler = async (req: NextApiRequest, res: NextApiResponse) => {
  return createOpenApiNextHandler({
    router: appRouter,
    createContext: () => createTRPCOpenAPIContext(),
    onError({ error, path }) {
      console.error(`>>> tRPC OpenAPI Error on '${path}'`, error);
    },
    responseMeta: undefined,
  })(req, res);
};

export default handler;

trpc.ts

/**
 * YOU PROBABLY DON'T NEED TO EDIT THIS FILE, UNLESS:
 * 1. You want to modify request context (see Part 1)
 * 2. You want to create a new middleware or type of procedure (see Part 3)
 *
 * tl;dr - this is where all the tRPC server stuff is created and plugged in.
 * The pieces you will need to use are documented accordingly near the end
 */
import type { NextApiRequest } from "next";
import type {
  SignedInAuthObject,
  SignedOutAuthObject,
} from "@clerk/clerk-sdk-node";
import { getAuth } from "@clerk/nextjs/server";
import { initTRPC, TRPCError } from "@trpc/server";
import superjson from "superjson";
import type { OpenApiMeta } from "trpc-openapi";
import { ZodError } from "zod";

import { prisma } from "@morrow/db";

import { cloudflare } from "./cloudflare";

/**
 * 1. CONTEXT
 *
 * This section defines the "contexts" that are available in the backend API
 *
 * These allow you to access things like the database, the session, etc, when
 * processing a request
 *
 */

interface CreateContextOptions {
  auth?: SignedInAuthObject | SignedOutAuthObject;
}

/**
 * This helper generates the "internals" for a tRPC context. If you need to use
 * it, you can export it from here
 *
 * Examples of things you may need it for:
 * - testing, so we dont have to mock Next.js' req/res
 * - trpc's `createSSGHelpers` where we don't have req/res
 * @see https://create.t3.gg/en/usage/trpc#-servertrpccontextts
 */
const createInnerTRPCContext = (_opts: CreateContextOptions) => {
  return { ..._opts, prisma, cloudflare };
};

export const createTRPCOpenAPIContext = () => {
  return createInnerTRPCContext({});
};

export const createTRPCContext = (_opts: { req: Request }) => {
  return createInnerTRPCContext({
    auth: getAuth(_opts.req as unknown as NextApiRequest),
  });
};

/**
 * 2. INITIALIZATION
 *
 * This is where the trpc api is initialized, connecting the context and
 * transformer
 */
const t = initTRPC
  .context<typeof createTRPCContext>()
  .meta<OpenApiMeta>()
  .create({
    transformer: superjson,
    errorFormatter({ shape, error }) {
      return {
        ...shape,
        data: {
          ...shape.data,
          zodError:
            error.cause instanceof ZodError ? error.cause.flatten() : null,
        },
      };
    },
  });

/**
 * 3. ROUTER & PROCEDURE (THE IMPORTANT BIT)
 *
 * These are the pieces you use to build your tRPC API. You should import these
 * a lot in the /src/server/api/routers folder
 */

/**
 * This is how you create new routers and subrouters in your tRPC API
 * @see https://trpc.io/docs/router
 */
export const createTRPCRouter = t.router;

/**
 * Public (unauthed) procedure
 *
 * This is the base piece you use to build new queries and mutations on your
 * tRPC API. It does not guarantee that a user querying is authorized, but you
 * can still access user session data if they are logged in
 */
export const publicProcedure = t.procedure;

// check if the user is signed in, otherwise throw a UNAUTHORIZED CODE
const isAuthed = t.middleware(({ next, ctx }) => {
  if (!ctx.auth.userId) {
    throw new TRPCError({ code: "UNAUTHORIZED" });
  }
  return next({
    ctx: {
      auth: ctx.auth,
    },
  });
});

/**
 * Protected (authed) procedure
 *
 * If you want a query or mutation to ONLY be accessible to logged in users, use
 * this. It verifies the session is valid and guarantees ctx.session.user is not
 * null
 *
 * @see https://trpc.io/docs/procedures
 */

export const protectedProcedure = t.procedure.use(isAuthed);

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions