omermecitoglu / example-user-service

MIT License
1 stars 1 forks source link

"handler is not defined". #2

Closed antonind72 closed 1 month ago

antonind72 commented 3 months ago

Hello, I have another problem: "handler is not defined".

ReferenceError: handlers is not defined
at eval (eval at getRouteExports (webpack-internal:///(rsc)/./node_modules/@omer-x/next-openapi-json-generator/dist/index.js), 
<anonymous>:9:15)
at getRouteExports (webpack-internal:///(rsc)/./node_modules/@omer-x/next-openapi-json-generator/dist/index.js:1:2756)
at async t.default (webpack-internal:///(rsc)/./node_modules/@omer-x/next-openapi-json-generator/dist/index.js:1:5643)
at async GET (webpack-internal:///(rsc)/./src/app/api/swagger/route.ts:12:22)

image

can you help me? please I've uploaded a screenshot to show you the tree-like nature of my routes.

omermecitoglu commented 3 months ago

Hello again, I think you put something other than route handler in one of your routes. I pushed an update that will help you to determine what is the source of the error.

please update and let me see the source of error

npm i @omer-x/next-openapi-json-generator@0.2.6
antonind72 commented 3 months ago

the error comes from this export, but this one I can't modify, it's managed by next-auth

An error occured while evaluating the route exports from "C:\Users\nordi\Desktop\newproj\batisi\src\app\api\auth\[...nextauth]\route.ts"

omermecitoglu commented 3 months ago

Oh I see...

They manipulate the route handler as the same way i do

import NextAuth from "next-auth"

const handler = NextAuth({
  ...
})

export { handler as GET, handler as POST }

I could fix this problem simply ignoring next-auth routes. But I assume you want them to appear in OpenAPI .json & UI

I don't know how to make them play together in harmony since I'm not familiar with next-auth.

I'll look into this when I have more free time. Thanks for the heads up!

antonind72 commented 3 months ago
export const { auth, handlers, signIn, signOut } = NextAuth({
    adapter: PrismaAdapter(prisma) as Adapter,
    session: { strategy: "jwt" },

    ...authConfig,

    callbacks: {
        /* @ts-ignore */
        async session({ session, user, token }) {
            if (!session) return;
            try {
                const searchUser = await prisma.user.findFirst({
                    where: {
                        id: token.sub
                    }
                })

                /* @ts-ignore */
                session.user = {
                    ...session.user,
                    ...searchUser
                }

                return session
            } catch (error) {
                console.error(error)
            }
        },
    },
    pages: {
        signIn: "/",
    },
    secret: env.NEXTAUTH_SECRET
})
import { handlers } from "@/auth"
export const { GET, POST } = handlers

OK, because v5 te next auth is used like this

omermecitoglu commented 3 months ago

It should be possible to do something like this

import { handlers } from "@/auth"

export const { POST } = createRoute({
  operationId: "...",
  method: "POST",
  summary: "...",
  description: "...",
  tags: ["..."],
  action: async ({ body, pathParams, queryParams }) => {
    const url = undefined; // you need to build a proper URL with query and search params
    const request = new Request(url, {
      method: "POST",
      body,
    });
    return handlers.GET(request)
  },
  responses: {
    200: {
      description: "...",
      content: z.object({
        success: z.boolean()
      })
    },
    404: { description: "..." },
  },
});

Then json-generator will not complain about handlers since they're part of action

But you need to figure out how to pass the correct url with search and query params

antonind72 commented 3 months ago

If I leave api/auth, I can create an api/v1/ folder... so it will retrieve only those inside? or is it set to retrieve all in /api?

omermecitoglu commented 3 months ago

I'm not sure what your question is about. But let me explain what json-generator and route-handler do

route-handler injects some metadata into your next.js route handler function (GET, POST etc.) and json-generator converts that metadata into openapi.json

Also route-handler parses request body, query & path params with zod and provides them as typed object for the action

antonind72 commented 3 months ago
export async function findAppFolderPath() {
  const inSrc = path.resolve(process.cwd(), "src", "app");
  if (await directoryExists(inSrc)) {
    return inSrc;
  }
  const inRoot = path.resolve(process.cwd(), "app");
  if (await directoryExists(inRoot)) {
    return inRoot;
  }
  return null;
}

At this point is it possible to define the route the application has api/v1 so that it only takes into consideration the routes in a specific file?

omermecitoglu commented 3 months ago

Yes, it is possible. I'll see what i can do about it later today.

antonind72 commented 3 months ago
    const spec = await generateOpenApiSpec({}, {
        routesPath: "src/app/api/test"
    });
https://github.com/antonind72/next-openapi-json-generator/tree/dev

I've modified it so that we can have the option of defining a specific path, but by default it stays on src or src/app. on the other hand, if you make changes to the route, save and refresh the page, you get this error:

otherwise, if you restart the project, there's nothing to worry about, it just works.

⨯ TypeError: _omer_x_next_openapi_json_generatorWEBPACK_IMPORTED_MODULE2default(...) is not a function at DocsApi (admin/docs/api/page.tsx:19:98) at stringify () digest: "1678211790" 9 | 10 | export default async function DocsApi() {

11 | const spec = await generateOpenApiSpec({}, { | ^ 12 | routesPath: "src/app/api/test" 13 | }); 14 | return ( GET /admin/docs/api 500 in 1399ms

omermecitoglu commented 3 months ago

I released an update

npm i @omer-x/next-openapi-json-generator@0.3.0

now you can use it like this

const spec = await generateOpenApiSpec({}, {
    include: "**/route.ts"
    exclude: "excluded-path/route.ts"
});
antonind72 commented 3 months ago

i have already error this :

const spec = await generateOpenApiSpec({}, {
            include: ["**/route.ts"],
            exclude: ["auth/route.ts"]
        });```

An error occured while evaluating the route exports from "C:\Users\nordi\Desktop\newproj\batisi\src\app\api\auth[...nextauth]\route.ts" ⨯ ReferenceError: handlers is not defined at async DocsApi (admin/docs/api/page.tsx:19:18)

omermecitoglu commented 3 months ago

should be like this

exclude: ["auth/*/route.ts"]

or

exclude: ["auth/**/route.ts"]
antonind72 commented 3 months ago

I always get the error whether it is for one or the other

⨯ ReferenceError: handlers is not defined at async DocsApi (admin/docs/api/page.tsx:19:18) digest: "3626192051" GET /admin/docs/api 500 in 561ms

omermecitoglu commented 3 months ago

you need to add the same rule to generateOpenApiSpec in src/app/page.tsx

I assume you moved it to /admin/docs/api so you should update generateOpenApiSpec in there

and src/app/swagger/route.ts too

antonind72 commented 3 months ago

Is it really like that?

const spec = await generateOpenApiSpec({}, {
    exclude: ["auth/**/route.ts", "admin/docs/api/page.tsx"]
});
omermecitoglu commented 3 months ago

no. only route.ts file paths should be defined in include/exclude lists.

But in that template repo, generateOpenApiSpec was used in two places, that's what I meant

omermecitoglu commented 3 months ago

May I see this file src/app/(pages)/admin/docs/api/page.tsx

antonind72 commented 3 months ago
import ReactSwagger from "@/components/docs/api/ReactSwaggerComponents";
import { Metadata } from "next";
import generateOpenApiSpec from "@omer-x/next-openapi-json-generator";

export const metadata: Metadata = {
    title: "API Docs",
    description: "API Documentation with Swagger for Nextjs",
};

export default async function DocsApi() {
    const spec = await generateOpenApiSpec({}, {
        exclude: ["auth/**/route.ts"]
    });
    return (
        <section className="container w-full flex flex-col gap-4 justify-between max-w-6xl p-4 z-10 bg-slate-400 h-full">
            <ReactSwagger spec={spec} />
        </section>
    );
}
omermecitoglu commented 3 months ago

I checked your screenshot again. I think it should be

exclude: ["api/auth/**/route.ts"]
antonind72 commented 3 months ago

is work thanks you !

antonind72 commented 3 months ago

I forgot to ask, with the basic api with nextjs 14 and next-auth v5 we have to go through req.auth, can we still access the request?

omermecitoglu commented 3 months ago

I was thinking about adding request to action as second parameter for some rare cases like this one.

You're welcome to make a PR to next-openapi-route-handler for that or you need to wait for tomorrow.