elysiajs / eden

Fully type-safe Elysia client
MIT License
147 stars 37 forks source link

Eden is not recognizing routes when using plugin (router) structure. #75

Closed mateusz-kurowskiUG closed 5 months ago

mateusz-kurowskiUG commented 5 months ago

admin-router.ts:

   const adminRouter = new Elysia({ name: 'Admin', prefix: '/admin' })
    adminRouter.get('/hello', () => 'hello')
    export type adminRouter = typeof adminRouter
    export default adminRouter

index.ts:

    import adminRouter from './admin-router.ts'
    const app = new Elysia({ prefix: '/api' }).use(adminRouter).listen(5000)

test.ts:

    import type { adminRouter } from '../admin'
    import { treaty } from '@elysiajs/eden'
    const app = treaty<adminRouter>('localhost:5000/')
    const x = await app.api.admin.hello.get() // admin does not exist on type adminRouter

Seems like treaty does not work properly using plugin with prefix approach. Does it only work with .group approach or am I doing something wrong?

ReyJust commented 5 months ago

Hello, I am having the same issue when using decorate on methods:

const db = new Elysia({ name: "db" }).decorate("db", await init_database());

export const controller = new Elysia({
  prefix: "/a"
})
  .get("/works", () => {
    return "ok";
  })
  .use(db)
...(all below, will not work)

Trying to use treaty in tests.

import { describe, expect, it } from "bun:test";
import { treaty } from "@elysiajs/eden";
import { app } from "../app";

const api = treaty(app);

describe("Tests", () => {
  it("Work", async () => {

    const response = await api.a.works.get();

    expect(response.data).toBe("ok");
  });

  it("Doesn't work", async () => {

    const response = await api.a.[ # cannot find the method # ];

    ...
  });
});
mateusz-kurowskiUG commented 5 months ago

Well, some workaround could be using a new instance of eden for each elysia instance, but... It works only if we have unique paths, e.g: Eden works for me:

.get('/a',()=>'a')

.post('/b',()=>'b')

But for now it is completely useless if we have routes like:

.get('/',()=>'a')

.post('/',()=>'b')
kidqueb commented 5 months ago

You need to chain methods on the Elysia instance for them to be recognized.


const adminRouter = new Elysia({ name: 'Admin', prefix: '/admin' })
-  adminRouter.get('/hello', () => 'hello')
+  .get('/hello', () => 'hello')
export type adminRouter = typeof adminRouter
export default adminRouter```
kidqueb commented 5 months ago

@ReyJust I used your snippet and was able to use it in a controller in my project. Would need a reproduction to debug.

async function init_database() {
  return { foo: 'bar' }
}

const db = new Elysia({ name: "db" }).decorate("db", await init_database());
ReyJust commented 5 months ago

@kidqueb Thank for the help. I couldn't reproduce the situation. It seems to work now but routes are available from the property index. Is that normal?

import { treaty } from "@elysiajs/eden";
import { app } from "../app";

const api = treaty(app);

describe("Elysia", () => {
  it("return a response", async () => {
    const res = api.example.index.get({ query: { q: "test" } });

  });
});
kidqueb commented 5 months ago

There's something going on with .index over at https://github.com/elysiajs/eden/issues/71