import * as _web_ts_toolkit_express_response_handler from '@web-ts-toolkit/express-response-handler'; import { MaybePromise, ExpressResponseHandler, OK, Created, Accepted, NonAuthoritativeInfo, NoContent, ResetContent, PartialContent, MultiStatus, AlreadyReported, IMUsed, createHandler } from '@web-ts-toolkit/express-response-handler'; import * as _web_ts_toolkit_express_response_handler_responses_csv from '@web-ts-toolkit/express-response-handler/responses/csv'; import * as clientErrors from '@web-ts-toolkit/http-errors'; import express, { Request, Response, NextFunction, RequestHandler } from 'express'; declare const DEFAULT_RESPONSE_HANDLER: ExpressResponseHandler; declare const SUPPORTED_ROUTE_METHODS: readonly ["acl", "all", "bind", "checkout", "connect", "copy", "delete", "get", "head", "link", "lock", "merge", "mkactivity", "mkcalendar", "mkcol", "move", "m-search", "notify", "options", "patch", "post", "propfind", "proppatch", "purge", "put", "query", "rebind", "report", "search", "source", "subscribe", "trace", "unbind", "unlink", "unlock", "unsubscribe"]; /** HTTP methods supported by `JsonRouter` registration and endpoint metadata. */ type JsonRouterMethod = (typeof SUPPORTED_ROUTE_METHODS)[number]; /** Snapshot entry returned by `JsonRouter#getEndpoints()`. */ type JsonRouterEndpoint = { method: Uppercase; path: string; }; type JsonRouterParams = Record; type JsonRouterQuery = Record; /** Route handler callback accepted by `JsonRouter` methods and route builders. */ type JsonRouterCallback = Record, Return = unknown> = (req: Request, res: Response, next: NextFunction) => MaybePromise; /** Recursive callback input accepted by router-level middleware and route registrations. */ type JsonRouterHandlerInput = Record, Return = unknown> = JsonRouterCallback | readonly JsonRouterHandlerInput[]; type JsonRouterMiddlewareInput = JsonRouterCallback | RequestHandler | readonly JsonRouterMiddlewareInput[]; /** Middleware callback or nested callback array accepted by the constructor. */ type JsonRouterMiddlewares = JsonRouterMiddlewareInput | readonly JsonRouterMiddlewareInput[]; /** Registrar function exposed for each supported HTTP method on a `JsonRouter`. */ type JsonRouterRouteRegistrar = = Record, Return = unknown>(path: string, ...callbacks: JsonRouterHandlerInput[]) => JsonRouter; /** Fluent builder returned by `JsonRouter#route(path)`. */ type JsonRouteBuilder = { [Method in JsonRouterMethod]: = Record, Return = unknown>(...callbacks: JsonRouterHandlerInput[]) => JsonRouteBuilder; }; type JsonRouterRouteRegistrars = { readonly [Method in JsonRouterMethod]: JsonRouterRouteRegistrar; }; type JsonRouterConstructor = Omit & { new (basePath?: string, middlewares?: JsonRouterMiddlewares, responseHandler?: ExpressResponseHandler): JsonRouter; readonly prototype: JsonRouter; }; type ExpressRouter = ReturnType; /** * Express router that serializes route handler return values as JSON and * converts thrown `HttpError`s into structured error responses. * * @example * import JsonRouter from '@web-ts-toolkit/express-json-router'; * const router = new JsonRouter('/api'); * router.get('/health', () => ({ ok: true })); */ declare class JsonRouterBase { private readonly _methods; private readonly _endpoints; private readonly _middlewares; /** Normalized base path prepended to every registered route. */ readonly basePath: string; /** Response handler instance captured when this router is constructed. */ readonly responseHandler: ExpressResponseHandler; private readonly _router; private static defaultHandlerDefaults; private static getSharedHandlerProperty; private static setSharedHandlerProperty; static readonly clientErrors: typeof clientErrors; static readonly success: { OK: typeof OK; Created: typeof Created; Accepted: typeof Accepted; NonAuthoritativeInfo: typeof NonAuthoritativeInfo; NoContent: typeof NoContent; ResetContent: typeof ResetContent; PartialContent: typeof PartialContent; MultiStatus: typeof MultiStatus; AlreadyReported: typeof AlreadyReported; IMUsed: typeof IMUsed; }; static readonly HttpResponse: { ok: (data: T) => OK; created: (data: T) => Created; accepted: (data: T) => Accepted; nonAuthoritativeInfo: (data: T) => NonAuthoritativeInfo; noContent: () => NoContent; resetContent: (data: T) => ResetContent; partialContent: (data: T) => PartialContent; multiStatus: (data: T) => MultiStatus; alreadyReported: (data: T) => AlreadyReported; imUsed: (data: T) => IMUsed; badRequest: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.BadRequestError; unauthorized: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.UnauthorizedError; forbidden: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.ForbiddenError; notFound: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.NotFoundError; methodNotAllowed: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.MethodNotAllowedError; notAcceptable: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.NotAcceptableError; proxyAuthRequired: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.ProxyAuthRequiredError; requestTimeout: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.RequestTimeoutError; conflict: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.ConflictError; gone: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.GoneError; lengthRequired: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.LengthRequiredError; preconditionFailed: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.PreconditionFailedError; payloadTooLarge: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.PayloadTooLargeError; uriTooLong: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.UriTooLongError; unsupportedMediaType: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.UnsupportedMediaTypeError; requestedRangeNotSatisfiable: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.RequestedRangeNotSatisfiableError; expectationFailed: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.ExpectationFailedError; teapot: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.TeapotError; misdirectedRequest: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.MisdirectedRequestError; unprocessableEntity: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.UnprocessableEntityError; locked: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.LockedError; failedDependency: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.FailedDependencyError; upgradeRequired: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.UpgradeRequiredError; preconditionRequired: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.PreconditionRequiredError; tooManyRequests: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.TooManyRequestsError; requestHeaderFieldsTooLarge: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.RequestHeaderFieldsTooLargeError; unavailableForLegalReasons: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.UnavailableForLegalReasonsError; json: (data: T) => OK; csv: (dataset?: unknown, options?: _web_ts_toolkit_express_response_handler_responses_csv.CsvResponseOptions | undefined) => _web_ts_toolkit_express_response_handler.CSVResponse; }; static readonly ErrorFormats: { readonly simple: "simple"; readonly aip193: "aip193"; readonly rfc9457: "rfc9457"; }; static readonly createHandler: typeof createHandler; static readonly supportedMethods: readonly ["acl", "all", "bind", "checkout", "connect", "copy", "delete", "get", "head", "link", "lock", "merge", "mkactivity", "mkcalendar", "mkcol", "move", "m-search", "notify", "options", "patch", "post", "propfind", "proppatch", "purge", "put", "query", "rebind", "report", "search", "source", "subscribe", "trace", "unbind", "unlink", "unlock", "unsubscribe"]; /** * Creates a fresh response handler from the current static defaults. * Existing routers keep the handler instance captured during construction. */ static get defaultHandler(): ExpressResponseHandler; static get errorMessageProvider(): typeof DEFAULT_RESPONSE_HANDLER.errorMessageProvider; static set errorMessageProvider(customErrorMessageProvider: typeof DEFAULT_RESPONSE_HANDLER.errorMessageProvider); static get preJson(): typeof DEFAULT_RESPONSE_HANDLER.preJson; static set preJson(preJsonHookFn: typeof DEFAULT_RESPONSE_HANDLER.preJson); static get postJson(): typeof DEFAULT_RESPONSE_HANDLER.postJson; static set postJson(postJsonHookFn: typeof DEFAULT_RESPONSE_HANDLER.postJson); static get preError(): typeof DEFAULT_RESPONSE_HANDLER.preError; static set preError(preErrorHookFn: typeof DEFAULT_RESPONSE_HANDLER.preError); static get postError(): typeof DEFAULT_RESPONSE_HANDLER.postError; static set postError(postErrorHookFn: typeof DEFAULT_RESPONSE_HANDLER.postError); /** * Creates a JSON router with a normalized base path, optional shared middleware, * and a snapshot of the current static response-handler defaults. */ constructor(basePath?: string, middlewares?: JsonRouterMiddlewares, responseHandler?: ExpressResponseHandler); /** Middleware callbacks captured during construction. */ get middlewares(): JsonRouterCallback[]; /** Underlying Express router to mount with `app.use(router.original)`. */ get original(): ExpressRouter; /** * Native `param` delegation to the underlying Express router. * * Boundary: `param` callbacks are native Express callbacks, not JSON-wrapped * registrations. Thrown/rejected `param` failures reach application error * middleware; they are not JSON-formatted by this router's response handler. * Returns the underlying native router (`router.original`), not this * `JsonRouter`, so chaining continues with native Express registration. * Nothing registered here appears in `getEndpoints()`. */ param(...args: Parameters): ReturnType; /** * Native `use` delegation to the underlying Express router. * * Boundary: `use` callbacks are native Express middleware, not JSON-wrapped * registrations. Thrown/rejected `use` failures and explicit `next(error)` * reach application error middleware; they are not JSON-formatted by this * router's response handler. `basePath` is not prepended here, so pass an * explicit mount path for scoped middleware. Native middleware mounted * without a path runs before JSON routes on the same underlying router in * mount order. Returns the underlying native router (`router.original`), * not this `JsonRouter`, so `.use(...).get(...)` continues with native * Express registration. Use separate `router.get(...)` statements for JSON * routes. Nothing registered here appears in `getEndpoints()`. * * @example * const router = new JsonRouter('/api'); * router.use('/', authMiddleware); * router.get('/health', () => ({ ok: true })); */ use(...args: Parameters): ReturnType; /** * Starts a fluent route builder for one path. * * Retained contract (independent-registration sugar): each builder method * call is exactly equivalent to a direct `router.METHOD(path, ...)` call. * Every call creates a separate native route with its own response-handler * wrapper (including constructor-middleware copies) and its own * `getEndpoints()` entry in call order. This is not native * `express.Router().route(path)` grouping, so `next('route')` from an * `.all()` guard cannot skip a later builder registration, HEAD requests * fall back to the separately registered GET handler, and constructor * middleware re-runs for each chained registration crossed by `next()`. * Registered handlers still pass through this router's response handler. */ route(path: string): JsonRouteBuilder; private addEndpoint; /** Returns a defensive copy of registered JSON endpoint method/path metadata. Native `use`/`param`/router registrations are not recorded. */ getEndpoints(): JsonRouterEndpoint[]; private normalizePath; } interface JsonRouter extends JsonRouterBase, JsonRouterRouteRegistrars { } declare const JsonRouter: JsonRouterConstructor; export { type JsonRouteBuilder, type JsonRouterCallback, type JsonRouterEndpoint, type JsonRouterHandlerInput, type JsonRouterMethod, type JsonRouterMiddlewares, type JsonRouterRouteRegistrar, JsonRouter as default };