@spfn/core
Version:
SPFN Framework Core - File-based routing, transactions, repository pattern
61 lines (58 loc) • 2.4 kB
TypeScript
import { Context } from 'hono';
import { ContentfulStatusCode } from 'hono/utils/http-status';
import { TSchema, Static } from '@sinclair/typebox';
import { ApiSuccessResponse } from './types/index.js';
/**
* File-based Routing System Type Definitions
*/
type HeaderRecord = Record<string, string | string[]>;
type RouteMeta = {
public?: boolean;
skipMiddlewares?: string[];
tags?: string[];
description?: string;
deprecated?: boolean;
};
/**
* Route Contract: TypeBox-based type-safe route definition
*
* Defines the shape of request/response for a route endpoint
*/
type RouteContract = {
method: HttpMethod;
path: string;
params?: TSchema;
query?: TSchema;
body?: TSchema;
response: TSchema;
meta?: RouteMeta;
};
/**
* Infer types from RouteContract
*
* Extracts TypeScript types from TypeBox schemas
*/
type InferContract<TContract extends RouteContract> = {
params: TContract['params'] extends TSchema ? Static<TContract['params']> : Record<string, never>;
query: TContract['query'] extends TSchema ? Static<TContract['query']> : Record<string, never>;
body: TContract['body'] extends TSchema ? Static<TContract['body']> : Record<string, never>;
response: TContract['response'] extends TSchema ? Static<TContract['response']> : unknown;
};
/**
* RouteContext: Route Handler Dedicated Context
*
* Generic version with contract-based type inference
*/
type RouteContext<TContract extends RouteContract = any> = {
params: InferContract<TContract>['params'];
query: InferContract<TContract>['query'];
data(): Promise<InferContract<TContract>['body']>;
json(data: InferContract<TContract>['response'], status?: ContentfulStatusCode, headers?: HeaderRecord): Response;
success<T>(data: T, meta?: ApiSuccessResponse<T>['meta'], status?: number): Response;
paginated<T>(data: T[], page: number, limit: number, total: number): Response;
raw: Context;
};
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
type RouteHandler<TContract extends RouteContract = any> = (c: RouteContext<TContract>) => Response | Promise<Response>;
declare function isHttpMethod(value: unknown): value is HttpMethod;
export { type HttpMethod as H, type InferContract as I, type RouteContext as R, type RouteContract as a, type RouteHandler as b, type HeaderRecord as c, type RouteMeta as d, isHttpMethod as i };