module
Noir::TreeSitterElysiaExtractor
Overview
Tree-sitter-backed Elysia extractor.
Elysia uses a chained-method DSL similar to Hono / Itty:
const app = new Elysia()
.get('/users', () => ...)
.post('/users', ({ body }) => body)
.get('/users/:id', ({ params }) => params.id)
.group('/api/v1', (app) =>
app
.get('/health', () => 'ok')
.post('/submit', ({ body }) => body)
)
.listen(3000)
Recognised:
- Verb methods on any chain receiver:
.get.post.put.delete.patch.head.options.all(the wildcard verb fans out to GET/POST/PUT/DELETE/PATCH). .group(prefix, fn)—fn's body is walked with the prefix joined onto the surrounding scope..guard(opts, fn)and.use(plugin)— pass-through wrappers; descend the inner body without changing prefix.- Handler-body scanning for
query.X,headers.X,cookie.X, and barebodyaccess.params.Xis intentionally skipped — the URL placeholder already gives the path Param via the optimizer. Receiver name isn't enforced ((ctx) => ctx.query.foo,({ query }) => query.foo, and even(c) => c.query.fooall surface signals).
Out of scope for this first cut:
.use(somePlugin)doesn't follow into the plugin file — plugin-defined routes need cross-file resolution.- Typed schema (
{ body: t.Object({...}) }) constraint synthesis. ThebodyParam is emitted but itsvaluestays empty (the schema is a typebox literal). .derive/.state/.decorateare pass-through wrappers conceptually but none of them register routes — skipping them also skips any inner verb calls. Real-world usage rarely puts routes inside these blocks.
Extended Modules
Defined in:
miniparsers/elysia_extractor_ts.crConstant Summary
-
ALL_VERBS =
["GET", "POST", "PUT", "DELETE", "PATCH"] -
GROUP_METHODS =
Set {"group"} -
HTTP_VERB_METHODS =
{"get" => "GET", "post" => "POST", "put" => "PUT", "delete" => "DELETE", "patch" => "PATCH", "head" => "HEAD", "options" => "OPTIONS", "trace" => "TRACE", "connect" => "CONNECT"} -
TRANSPARENT_METHODS =
Set {"guard", "use"}