@beignet/core
Version:
Core framework primitives for Beignet
94 lines • 2.63 kB
JavaScript
import { resolveContract } from "./contract-like.js";
const ROUTE_GROUP_KIND = "beignet.route-group";
/**
* Define one route registration with hook-aware handler typing.
*
* Direct route objects are still supported. Use this helper when route-scoped
* hooks enrich `ctx` for a single handler and you want TypeScript to infer the
* added fields.
*/
function createRouteBuilder() {
function define(route) {
return route;
}
return define;
}
export function defineRoutes(routes) {
const flattened = [];
for (const route of routes) {
if (isRouteGroup(route)) {
for (const groupRoute of route.routes) {
flattened.push({
...groupRoute,
hooks: [...(route.hooks ?? []), ...(groupRoute.hooks ?? [])],
});
}
}
else {
flattened.push(route);
}
}
return flattened;
}
/**
* Extract contract configs from a route list.
*
* Use this to drive clients, OpenAPI, and docs from the same route list passed
* to `createServer(...)`.
*/
export function contractsFromRoutes(routes) {
return routes.map((route) => resolveContract(route.contract));
}
/**
* Define a named group of related route registrations.
*
* Route groups are flattened by defineRoutes, so createServer still receives
* a regular route list while app code can keep feature route wiring and scoped
* hooks colocated.
*
* @example
* ```ts
* const { defineRouteGroup } = createRoutes<AppContext>();
* const todoRoutes = defineRouteGroup({
* name: "todos",
* hooks: [auth.optional()],
* routes: [
* { contract: listTodos, useCase: listTodosUseCase },
* ]
* });
* ```
*/
function createRouteGroupBuilder() {
const createGroup = (input) => ({
kind: ROUTE_GROUP_KIND,
name: input.name,
hooks: input.hooks,
routes: input.routes,
});
return createGroup;
}
/**
* Create route declaration builders bound to an application context type.
*
* Call this once in `lib/routes.ts`, then import the app-bound builders from
* feature route files.
*
* @example
* ```ts
* export const { defineRoute, defineRouteGroup } =
* createRoutes<AppContext>();
* ```
*/
export function createRoutes() {
return {
defineRoute: createRouteBuilder(),
defineRouteGroup: createRouteGroupBuilder(),
};
}
function isRouteGroup(route) {
return (typeof route === "object" &&
route !== null &&
"kind" in route &&
route.kind === ROUTE_GROUP_KIND);
}
//# sourceMappingURL=route-definitions.js.map