import { ParserInterface, Schema, InferSchema } from "@miqro/parser"; import { SerializeOptions as CookieSerializeOptions } from "cookie"; import { IncomingMessage, OutgoingHttpHeaders, ServerResponse } from "node:http"; import { Socket } from "node:net"; import { Duplex } from "node:stream"; import { Logger } from "./common.js"; /** * Types */ export interface LoggerErrorEventInit { bubbles?: boolean; cancelable?: boolean; composed?: boolean; error: any; } export declare class LoggerErrorEvent extends Event { error: any; constructor(event: string, init: LoggerErrorEventInit); } export type LogLevel = "error" | "warn" | "info" | "debug" | "trace" | "none"; export interface WriteArgs { level: LogLevel; message?: any; identifier: string; optionalParams: any[]; meta: any[]; } export interface LoggerTransportWriteArgs extends WriteArgs { out: string; } export interface LoggerTransport { level?: LogLevel; write(args: LoggerTransportWriteArgs): Promise | void; } export type LoggerFormatter = (args: WriteArgs) => string; export interface MinimalLogger { log(message?: any, ...optionalParams: any[]): void; info(message?: any, ...optionalParams: any[]): void; trace(message?: any, ...optionalParams: any[]): void; debug(message?: any, ...optionalParams: any[]): void; warn(message?: any, ...optionalParams: any[]): void; error(message?: any, ...optionalParams: any[]): void; } export type ConfigOutput = { [name: string]: string; }; export interface LoadConfigOut { combined: ConfigOutput; outputs: ConfigOutput[]; } export interface LoggerFactoryArgs { identifier: string; level: LogLevel; options?: { transports?: LoggerTransport[]; formatter?: LoggerFormatter; }; } export type LoggerFactory = (args: LoggerFactoryArgs) => Logger; export declare const GroupPolicySchema: Schema; export interface SessionHandlerOptions { authService: { verify(args: { token?: string | null; req: Request; res: Response; }): Promise; }; options?: SessionHandlerOptionsOptions; } export interface SessionHandlerOptionsOptions { tokenLocation: "header" | "query" | "cookie" | "free"; tokenLocationName?: string | ((req: Request) => Promise); setCookieOptions?: { httpOnly: boolean; secure: boolean; path: string | ((req: Request) => Promise); sameSite: "lax" | "strict" | "none"; }; } export declare const SessionHandlerOptionsOptionsSchema: Schema; export declare const SessionHandlerOptionsSchema: Schema; type Dict = { [key: string]: T; }; export interface NoTokenSession extends Dict { account: string; username: string; groups: string[]; } export interface Session extends NoTokenSession { token: string; } export type GroupPolicyType = "at_least_one" | "all"; export type GroupPolicyGroups = string | string[]; export interface GroupPolicy { groups: GroupPolicyGroups[]; groupPolicy: GroupPolicyType; } export type Method = "get" | "post" | "put" | "delete" | "patch" | "options" | "head" | "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS" | "HEAD"; export interface HandlerResponse { status?: number; headers?: OutgoingHttpHeaders; body?: any; } export type Handler = ((req: Request, res: Response) => Promise) | ((req: Request, res: Response) => T); export type ErrorHandler = ((e: unknown, req: Request, res: Response) => Promise) | ((e: unknown, req: Request, res: Response) => T); export type SchemaProperties = { [key: string]: Schema | string; }; export type ParserMode = "remove_extra" | "add_extra" | "no_extra"; export declare const RouteOptionsSchema: Schema; export interface RouteOptions { name?: string; identifier?: string; apiName?: string; description?: string; policy?: GroupPolicy; request?: { body?: TBody; params?: TParams; query?: TQuery; bodyMode?: ParserMode; queryMode?: ParserMode; paramsMode?: ParserMode; headers?: string | SchemaProperties[] | SchemaProperties; headersMode?: ParserMode; }; response?: { etag?: boolean | (() => Promise | string); status?: number | number[]; headers?: string | SchemaProperties | SchemaProperties[]; headersMode?: ParserMode; body?: boolean | string | SchemaProperties | SchemaProperties[]; bodyMode?: ParserMode; middleware?: Handler | Handler[]; } | boolean; } export interface RouteJSONDoc extends RouteOptions { identifier: string; } export interface RouterJSONDoc { [path: string]: { [method: string]: RouteJSONDoc[]; }; } export declare const RouterHandlerOptionsSchema: Schema; export interface RouterHandlerOptions extends RouteOptions { parser?: ParserInterface; middleware?: Handler | Handler[]; session?: SessionHandlerOptions | Handler; } /** * Infer the TypeScript type produced by a request-part schema (body / params / query). * - string shorthand → `InferSchema` * - plain properties object `{ name: "string", age: "integer" }` → object with inferred fields * - `boolean | undefined` → `any` (pass-through, no type enforcement) */ export type InferRequestPart = [ T ] extends [boolean | undefined | null] ? any : [ T ] extends [string] ? InferSchema : T extends SchemaProperties ? InferSchema<{ type: "object"; properties: T; }> : any; /** * A `Request` narrowed to the typed `body`, `params`, and `query` shapes inferred * from the schemas declared on a route's `request` option. */ export type TypedRequest = Omit & { body?: TBody; params: TParams; query: TQuery; }; export declare const HandlerWithOptionsSchema: Schema; export interface HandlerWithOptions extends RouterHandlerOptions { handler: ((req: TypedRequest, InferRequestPart, InferRequestPart, BaseRequest>, res: Response) => Promise) | ((req: TypedRequest, InferRequestPart, InferRequestPart, BaseRequest>, res: Response) => boolean | void | HandlerResponse) | Array; } export interface RouterOptions { loggerFactory?: (uuid: string, req: Request) => MinimalLogger; etag?: boolean | ((lastResult?: { headers?: any; body?: any; status?: any; }) => Promise | string | false | null | undefined); } export interface MinimalRouter { run: (req: Request, res: Response, pathTokens?: PathPart[], prePathTokens?: PathPartToken[]) => Promise; getJSONDoc: (doc?: RouterJSONDoc, prePath?: string) => RouterJSONDoc; } export declare const MinimalRouterSchema: Schema; export declare function isMinimalRouter(obj: any): boolean; /** * # APIRoute * * src/api/comment/get.js * ```typescript *import { APIRouter } from "@miqro/core"; *const route: APIRoute = { * ... *}; *export default route; * ``` * * Use the type parameters to get typed `req.body`, `req.params`, and `req.query` * in the handler. Use `defineRoute()` for automatic schema inference. */ export interface APIRoute extends Omit { postFolder?: boolean; basePath?: string; method?: Method[] | Method | "use" | "USE"; path?: string[] | string | null; ignore?: boolean; request?: { body?: TBody; params?: TParams; query?: TQuery; bodyMode?: ParserMode; queryMode?: ParserMode; paramsMode?: ParserMode; headers?: string | SchemaProperties[] | SchemaProperties; headersMode?: ParserMode; }; handler: ((req: TypedRequest, InferRequestPart, InferRequestPart, BaseRequest>, res: Response) => Promise) | ((req: TypedRequest, InferRequestPart, InferRequestPart, BaseRequest>, res: Response) => boolean | void | HandlerResponse) | Array | MinimalRouter; init?: (route: APIRoute) => Promise; } /** * Type-safe factory for file-based API routes (`export default`). * * Wrap your route object so TypeScript automatically infers `req.body`, * `req.params`, and `req.query` from the schemas in `request`. * * @example * export default defineRoute({ * request: { body: { name: "string", age: "integer" } }, * handler: async (req) => { * req.body.name; // string * req.body.age; // number * } * }); */ export declare function defineRoute(route: APIRoute): APIRoute; export interface APIRouterOptions { dirname: string; apiName?: string; path?: string; ignore?: Array; loader?: (path: string) => Promise; extensions?: string[]; } export declare const APIRouterOptionsSchema: Schema; export declare const APIRouteSchema: Schema; export interface Request extends IncomingMessage { startMS: number; logger: MinimalLogger; session?: Session; uuid: string; path: string; hash: string; cookies: { [name: string]: string; }; params: { [name: string]: string | undefined; }; buffer?: Buffer; query: { [name: string]: string | string[]; }; results: any[]; body?: any; } export declare class Request extends IncomingMessage implements Request { startMS: number; body?: any; logger: MinimalLogger; uuid: string; path: string; hash: string; searchParams: URLSearchParams; cookies: { [name: string]: string; }; params: { [name: string]: string | undefined; }; buffer?: Buffer; query: { [name: string]: string | string[]; }; results: any[]; constructor(socket: Socket); } export interface Response extends ServerResponse { asyncClose(): Promise; asyncEnd(args?: { body?: any; status?: number; headers?: OutgoingHttpHeaders; }): Promise; asyncWrite(chunk: any): Promise; json(body: any, headers?: OutgoingHttpHeaders, status?: number): Promise; addVaryHeader(value: number | string | ReadonlyArray): ServerResponse; setCookie(name: string, value: string, options?: CookieSerializeOptions): ServerResponse; html(html: string, headers?: OutgoingHttpHeaders, status?: number): Promise; css(css: string, headers?: OutgoingHttpHeaders, status?: number): Promise; js(js: string, headers?: OutgoingHttpHeaders, status?: number): Promise; text(text: string, headers?: OutgoingHttpHeaders, status?: number): Promise; redirect(url: string, headers?: OutgoingHttpHeaders, status?: number): Promise; } export declare class Response extends ServerResponse implements Response { static IGNORE_HEADER: string[]; useETag: boolean | ((lastResult?: { headers?: any; body?: any; status?: any; }) => Promise | string | false | null | undefined); constructor(req: Request); setETag(useETag: boolean | ((lastResult?: { headers?: any; body?: any; status?: any; }) => Promise | string | false | null | undefined)): void; } export interface PathParams { [name: string]: string | undefined; } export interface PathPartToken extends PathPart { optional: boolean; wild?: string; } export interface PathPart { value: string; lower: string; } export declare const splitPath: (path?: string) => PathPart[]; export declare function tokenizePath(path?: string): PathPartToken[]; export declare function matchTokenizePath(checkAsRouter: boolean, pathTokens: PathPartToken[], requestParts: PathPart[]): { match: boolean; params?: { [name: string]: string | undefined; }; }; export declare function newURL(input: string): URL; /** * * @param input a url.pathname * @returns the pathname ignoring start slashes for example if sended "///page/hi" will return /page/hi */ export declare function removeStartingBackSlashes(input: string): string; /** * * @param input a url.pathname * @returns the first real slashindex for example if sended "///page/hi" will return 4 */ export declare function getSlashIndex(input: string): number; /** * checks the input as a string that starts with / * @param path input path * @returns the same path if it passed the checks */ export declare function normalizePath(path: string): string; export declare function parseSearchParams(search: URLSearchParams): { [name: string]: string | string[]; }; export interface ConnectionUpgrader { onUpgrade: (req: Request, socket: Duplex, head: Buffer) => Promise | void; } export interface WebSocketComplexValidateResult { uuid?: string; headers?: { name: string; value: string; }[]; } export interface WebSocketServerOptions { maxConnections?: number; maxFrameSize?: number; validate?: (req: Request) => Promise | boolean | string | WebSocketComplexValidateResult; onConnection?: (req: WebSocketClient) => void | Promise; onMessage?: (req: WebSocketClient, data: string | undefined | null) => void | Promise; onDisconnect?: (req: WebSocketClient) => void | Promise; onError?: (req: WebSocketClient, error: Error) => void | Promise; } export interface WebSocketClient { uuid: string; req: Request; socket: Duplex; head: Buffer; } export {};