Skip to content

All versions since [0.3.0]

[0.3.0]

Added

  • http/paginate.js declarative pagination middleware factory. Wraps lib/paginate.js utilities into a pipeline-compatible middleware supporting offset and cursor strategies. Placed in Stage 1 (Negotiation) after url. Reads parsed query from domainAcc.url.query and stores structured pagination parameters at acc.paginate. (#114)
  • send() paginate option. When true, reads domainAcc.paginate and responseAcc.paginate to auto-generate RFC 8288 Link headers (first, prev, next, last) and X-Total-Count for offset pagination responses. Supports both offset and cursor strategies. (#114)
  • 'paginate' added to SEND_RESERVED to prevent pagination metadata from leaking as RFC 9457 extension members. (#114)
  • errorFormatter option for send() and handler(). Pluggable error body formatter for statusCode >= 400 responses. When provided, receives the RFC 9457 Problem Details object (plain object) and {requestId, statusCode, method} context. The return value becomes the response body, serialized as application/json instead of application/problem+json. Applies to both the main error path and 412 conditional responses (endWithProblem). Teams with existing error contracts can adopt ergo without changing their client-facing error format. (#110)
  • redactErrors option for handler(). Controls whether caught 5xx exception messages appear in the RFC 9457 response detail field. Defaults to true (secure — generic status text only). Set to false during development to surface err.message in error responses without exposing stack traces. (#109)
  • Typed middleware options and results. All 21 middleware factory functions now have hand-written .d.ts overrides in types-override/http/ with named options interfaces (AcceptsOptions, BodyOptions, CorsOptions, ValidateOptions, etc.) and precise return types. Consumers get autocomplete and type-checking for factory parameters and pipeline accumulator values without as any casts. Import options/result types from @centralping/ergo/types. (#108)
  • New result type interfaces: AuthorizationResult, TracingResult, IdempotencyResult. (#108)
  • New utility types: AjvFormatName (26-member string literal union tracking ajv-formats 3.x), AuthorizationStrategy, ValidateSchemas, CookieJar (now includes jar methods). (#108)
  • types-override/http/main.d.ts override provides typed re-exports for all middleware, httpErrors, fromConnect, and paginate namespace. (#108)

Changed

  • Breaking: paginate export from @centralping/ergo changed from lib/paginate.js utility namespace ({parseOffsetParams, parseCursorParams, offsetResponse, cursorResponse}) to http/paginate.js factory function. Consumers using paginate.parseOffsetParams() must switch to deep import: import {parseOffsetParams} from '@centralping/ergo/lib/paginate'. (#114)

Fixed

  • envelope callback type signature corrected. Changed from (body: unknown, statusCode: number) => unknown to (body: unknown, ctx: {requestId: string; statusCode: number; method: string}) => unknown to match the actual implementation which passes a context object, not a bare status code. Affects SendOptions and HandlerOptions. (#110)
  • PreferResult now matches runtime. Corrected from {[k: string]: {value?: string}} to {[k: string]: string | true} — the runtime returns flat preference values, not wrapped objects. (#108)
  • CookieJar now includes jar methods. Added set(), get(), clear(), toHeader(), size, and isJar to match the actual cookie jar API. Previously typed as a bare index signature. (#108)
  • LogEntry now includes trace correlation fields. Added optional traceId and spanId properties populated when the tracing middleware is active. (#108)

Removed

  • RateLimitResult removed. The rate-limit middleware only returns {response: {headers}} — it never stores a domain accumulator value. The interface described a shape that did not exist at runtime. (#108)

[0.4.0]

Changed

  • BREAKING: Middleware composition uses config objects instead of tuples. (#117) Domain-producing middleware now uses {fn, setPath} config objects instead of [fn, setPath] tuples. Response-only middleware (cors, securityHeaders, cacheControl, rateLimit, precondition, validate, jsonApiQuery) are plain functions — no wrapper needed.
    • normalizeOp() now discriminates via typeof op === 'function' (was Array.isArray)
    • MiddlewareTuple type renamed to MiddlewareOp with {fn, setPath} shape
    • All 20 middleware inner functions are now named (fn.name provides trace labels)
    • Migration: [myFn(), 'key']{fn: myFn(), setPath: 'key'}

Fixed

  • handler.js JSDoc and HandlerOptions type now document the paginate option forwarded to send(). (#118)

[0.4.1]

Added

  • Factory-time option key validation with Levenshtein suggestions. (#126) All 18 middleware factories now validate incoming option keys at factory invocation time via a shared lib/validate-options.js utility. Unknown keys emit a deduplicated process.emitWarning with {type: 'ErgoWarning'} and a “did you mean?” suggestion when the Levenshtein edit distance is within threshold. handler() validates the union of its own keys and send() keys; send() validates independently.
  • timing option on handler() for X-Response-Time header. (#127) Pass timing: true for defaults or timing: {header?, precision?} for custom configuration. Measures the full request lifecycle (pipeline + error handling + send) via a res.writeHead interception. Zero overhead when disabled (default). Shared primitive lib/response-time.js available for deep import by @centralping/ergo-router.

Changed

  • README TypeScript Quick Start updated to reflect shipped type infrastructure. (#131) Removed the forward-looking caveat about future type inference improvements — all prerequisite features have shipped (compose overloads #87, typed middleware #108, ergo-router accumulator inference ergo-router#91). Simplified the TS example by removing the AuthResult interface and explicit IncomingMessage/ServerResponse imports. Replaced the caveat with a factual note explaining when acc annotations are needed (standalone compose() with interleaved bare functions) and directing users to @centralping/ergo-router’s defineGet/definePost helpers for annotation-free inference.

[Unreleased] Latest