elysiajs / elysia

Ergonomic Framework for Humans
https://elysiajs.com
MIT License
9.1k stars 193 forks source link

custom model causing eden to not infer route types #646

Open feliperdamaceno opened 1 month ago

feliperdamaceno commented 1 month ago

What version of Elysia.JS is running?

1.0.20

What platform is your computer?

Linux 5.15.146.1-microsoft-standard-WSL2 x86_64 unknown

What steps can reproduce the bug?

When creating a separate Model, eden is not infering any type of the routes:

const MovieSchema = createInsertSchema(MovieTable)

export const MovieModel = new Elysia({ name: 'Model.Movie' }).model({
  'movie.insert': t.Pick(MovieSchema, ['name', 'release']),
  'movie.update': t.Pick(MovieSchema, ['name', 'release'])
})

export type Movie = Static<typeof MovieSchema>
export const MovieController = new Elysia({ prefix: '/movies' })
  .use(MovieModel)

  .decorate('Service', new MovieService(db))

  .get('/', ({ Service }) => Service.findAll())

  .get('/:id', ({ Service, params }) => Service.findOne(params.id))

  .post('/', ({ Service, body }) => Service.create(body), {
    body: 'movie.insert'
  })

  .put('/:id', ({ Service, params, body }) => Service.update(params.id, body), {
    body: 'movie.update'
  })

  .delete('/:id', ({ Service, params }) => Service.delete(params.id))
import { MovieController } from './controllers/movie.controller'

const app = new Elysia()
  .use(cors())
  .use(swagger())
  .get('/', () => 'Server working!')
  .use(MovieController)
  .listen(3000)

console.log(
  `Server running at http://${app.server?.hostname}:${app.server?.port}`
)

export type App = typeof app

What is the expected behavior?

I expect eden to pick all the correct route types, but for some reason that is not happening, only returning Any.

What do you see instead?

import { treaty } from '@elysiajs/eden'
import { App } from 'server/src/index'

export const client = treaty<App>('localhost:3000')

When hovering client it show as Any type:

image

Additional information

I'm using drizzle-typebox, but even using the default validation, the problem persists.

However, removing Model resolves the issue:

export const MovieController = new Elysia({ prefix: '/movies' })
  // .use(MovieModel)

  .decorate('Service', new MovieService(db))

  .get('/', ({ Service }) => Service.findAll())

  .get('/:id', ({ Service, params }) => Service.findOne(params.id))

  // .post('/', ({ Service, body }) => Service.create(body), {
  //   body: 'movie.insert'
  // })

  // .put('/:id', ({ Service, params, body }) => Service.update(params.id, body), {
  //   body: 'movie.update'
  // })

  .delete('/:id', ({ Service, params }) => Service.delete(params.id))

image