Noir::TSContractExtractor
Contract-first TypeScript routers, where routes are declared as data
(a contract object or a builder chain) rather than as app.get(...)
calls:
// ts-rest
c.router({ getPost: { method: 'GET', path: '/posts/:id' } }, { pathPrefix: '/api' })
// oRPC
os.route({ method: 'GET', path: '/planets/{id}' }).input(z.object({ id: z.number() }))
// Effect HttpApi
HttpApiGroup.make("users").add(HttpApiEndpoint.get("findById", "/users/:id")).prefix("/v1")
Zod z.object({...}) / Effect Schema.Struct({...}) keys are read as
the request fields. Top-level declarations referenced from another
router (posts: postsContract, .add(UsersGroup)) are resolved within
the file so the outer prefix applies, and are then not reported on
their own a second time.
ponytail: same-file resolution only; a router assembled from imported
sub-routers reports each one under its own prefix. Follow imports via
ImportGraph if that turns out common.
Constants
Curried schema classes: Schema.Class<X>("X")({ ...fields }).
Schema combinators whose argument contributes fields.
Key yielded by each_pair for a ...spread entry, with the spread
expression as its value.
Instance methods
createRoute({ method, path, request }), one route each wherever it
is written: handed inline to app.openapi(...) or kept as a constant
(often in a separate *.routes.ts that the app imports).