Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swagger unable to detect routes when used in another Elysia instance #121

Open
Itoukee opened this issue May 14, 2024 · 5 comments
Open

Comments

@Itoukee
Copy link

Itoukee commented May 14, 2024

I tried separating Elysia instances in case of local or prod mode. With different configurations so there is no need to add many conditions. But when I plug it to the main Elysia instance, the routes aren't shown in Swagger.

server.ts

const doc = swagger({ path: "/doc" });

const devPresets = new Elysia()
  //@ts-expect-error loggers are not typed as they should
  .use(Logestic.preset("fancy"))
  //@ts-expect-error and so are their returns
  .use(doc);

const prodPresets = new Elysia()
  //@ts-expect-error loggers are not typed as they should
  .use(Logestic.preset("common"));

export default { devPresets, prodPresets };

index.ts

const app = new Elysia()
  .use(process.env.BUN_ENV === "development" ? server.devPresets : server.prodPresets)
  //@ts-expect-error some mistyped warnings because of Logestic
  .use(GeolocController)
  .get("/status", () => true)
  .listen(8080);

The routes still work. They are just not detected by swagger. Is it a fixable issue ? Or am I doing it wrong ?
Thanks

@darr1s
Copy link

darr1s commented May 19, 2024

Facing the same issues, Swagger must be in root Elysia otherwise it can't load any routes.

@MilesWuCode
Copy link

MilesWuCode commented May 20, 2024

const elysia = new Elysia();

if (Bun.env.NODE_ENV !== "production") {
  elysia.use(swagger());
}

elysia
  .group("/api", (app) => app.use(todosRoute))
  .onError(({ code }) => {
    if (code === "NOT_FOUND") return "Route not found :(";
  })
  .listen(3000);

@nxht
Copy link
Contributor

nxht commented May 23, 2024

I think you need to use functional callback if you want to use swagger in separate plugin.

Functional callback allows us to access the existing property of the main instance. For example, checking if specific routes or stores existed.

The route information is saved on the main Elysia instance and swagger needs to access them.

So in your case, you should

const doc = swagger({ path: "/doc" });

const devPresets = (app: Elysia) => app
  //@ts-expect-error loggers are not typed as they should
  .use(Logestic.preset("fancy"))
  //@ts-expect-error and so are their returns
  .use(doc);

const prodPresets = (app: Elysia) => app
  //@ts-expect-error loggers are not typed as they should
  .use(Logestic.preset("common"));

export default { devPresets, prodPresets };

@darr1s
Copy link

darr1s commented May 23, 2024

Thank you @nxht , this solved the issue.

@TheOrdinaryWow
Copy link

TheOrdinaryWow commented Jun 21, 2024

I think you need to use functional callback if you want to use swagger in separate plugin.

Functional callback allows us to access the existing property of the main instance. For example, checking if specific routes or stores existed.

The route information is saved on the main Elysia instance and swagger needs to access them.

So in your case, you should

const doc = swagger({ path: "/doc" });

const devPresets = (app: Elysia) => app
  //@ts-expect-error loggers are not typed as they should
  .use(Logestic.preset("fancy"))
  //@ts-expect-error and so are their returns
  .use(doc);

const prodPresets = (app: Elysia) => app
  //@ts-expect-error loggers are not typed as they should
  .use(Logestic.preset("common"));

export default { devPresets, prodPresets };

Found quite a suspicious problem:

Suggest example code:

// lib/swagger.ts
export const swagger = (app: Elysia) =>
  app.use(
    swaggerPlugin(/* custom config */),
  );
// index.ts
const app = new Elysia()
  .use(swagger) // <- custom plugin is called here
  .get("/", ({}) => "Hello world.");

In following case, after plugin is called, the codes after will be unable to recognize types from Elysia.

// index.ts
const app = new Elysia()
  .use(swagger) // <- custom plugin is called here
  .get("/", ({ body }) => "Hello world.");
//             ^ typescript: Binding element 'body' implicitly has an 'any' type.

While it's fine when calling custom plugin at the bottom.

// index.ts
const app = new Elysia()
  .get("/", ({ body }) => "Hello world.")
//^ Typescript works.
  .use(swagger); // <- custom plugin is called here

Any suggestions on how to solve this please?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants