alepha
Version:
Easy-to-use modern TypeScript framework for building many kind of applications.
79 lines (69 loc) • 2.45 kB
text/typescript
import {
$inject,
createPrimitive,
KIND,
PipelinePrimitive,
type PipelinePrimitiveOptions,
} from "alepha";
import { ServerReply } from "../helpers/ServerReply.ts";
import type {
RequestConfigSchema,
ServerHandler,
ServerRequest,
ServerRoute,
} from "../interfaces/ServerRequest.ts";
import { ServerRouterProvider } from "../providers/ServerRouterProvider.ts";
/**
* Create a basic endpoint.
*
* It's a low level primitive. You probably want to use `$action` instead.
*
* @see {@link $action}
* @see {@link $page}
*/
export const $route = <TConfig extends RequestConfigSchema>(
options: RoutePrimitiveOptions<TConfig>,
): RoutePrimitive<TConfig> => {
return createPrimitive(RoutePrimitive<TConfig>, options);
};
// ---------------------------------------------------------------------------------------------------------------------
export interface RoutePrimitiveOptions<
TConfig extends RequestConfigSchema = RequestConfigSchema,
> extends Omit<ServerRoute<TConfig>, "handler">,
PipelinePrimitiveOptions<ServerHandler<TConfig>> {}
// ---------------------------------------------------------------------------------------------------------------------
export class RoutePrimitive<
TConfig extends RequestConfigSchema,
> extends PipelinePrimitive<RoutePrimitiveOptions<TConfig>> {
protected readonly serverRouterProvider = $inject(ServerRouterProvider);
protected onInit() {
this.serverRouterProvider.createRoute({
...(this.options as any),
handler: this.handler,
} as ServerRoute<TConfig>);
}
/**
* Invoke this route's handler in-process (no HTTP server) and return its path
* and body. Used by the build to snapshot `static` routes to files.
*
* Only meaningful for self-contained `GET` handlers that return a string or
* Buffer (e.g. `sitemap.xml`, `robots.txt`).
*/
public async prerender(): Promise<{ path: string; body: string | Buffer }> {
const reply = new ServerReply();
const request = {
method: this.options.method ?? "GET",
url: new URL(`http://localhost${this.options.path}`),
params: {},
query: {},
headers: {},
body: undefined,
metadata: {},
reply,
} as unknown as ServerRequest<TConfig>;
const result = await this.handler.run(request);
const body = (result ?? reply.body) as string | Buffer;
return { path: this.options.path, body };
}
}
$route[KIND] = RoutePrimitive;