module

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

EFFECT_FIELDS = {"setPayload" => "payload", "setUrlParams" => "query", "setHeaders" => "header"}
EFFECT_VERBS = {"get" => "GET", "post" => "POST", "put" => "PUT", "patch" => "PATCH", "del" => "DELETE", "delete" => "DELETE", "head" => "HEAD", "options" => "OPTIONS"}
HONO_OPENAPI_FIELDS = {"query" => "query", "headers" => "header", "cookies" => "cookie"}
MAX_RESOLVES = 10000
NOT_ORPC_KEYS = {"handler", "options", "config"}
ORPC_WILDCARD = /\{\+(\w+)\}/
QUERY_METHODS = Set {"GET", "HEAD"}
SCHEMA_CLASS_CALLS = Set {"Class", "TaggedClass", "TaggedRequest", "TaggedError"}

Curried schema classes: Schema.Class<X>("X")({ ...fields }).

SCHEMA_MERGE_CALLS = Set {"extend", "merge", "and"}

Schema combinators whose argument contributes fields.

SCHEMA_OBJECT_CALLS = Set {"object", "strictObject", "looseObject", "Struct"}
SPREAD = "..."

Key yielded by each_pair for a ...spread entry, with the spread expression as its value.

TS_REST_FIELDS = {"body" => "json", "query" => "query", "headers" => "header"}

Instance methods

effect(source : String, path : String = "") : Array(Route)
Source
hono_openapi(source : String, path : String = "") : Array(Route)

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).

Source
orpc(source : String, path : String = "") : Array(Route)
Source
ts_rest(source : String, path : String = "") : Array(Route)
Source

Nested types