All versions since [0.1.0]
[0.1.0]
Added
- Initial development release as
ergo-router(unscoped, never published to npm). - REST-compliant router with path matching via
find-my-way. - Automatic REST compliance: 405+Allow, HEAD, OPTIONS, and PATCH enforcement.
- Transport-level middleware: security headers, CORS, rate limiting, request ID.
- Declarative pipeline builder with composable stage configuration.
- Graceful shutdown support with in-flight request draining.
- Structured error responses via RFC 9457 Problem Details.
- Pure ESM with Node.js >= 22.
[0.1.0-beta.1]
Changed
- BREAKING: Renamed package from
ergo-routerto@centralping/ergo-router. - BREAKING: Pipeline v2 — two-accumulator model integration. Route handlers now receive
domainAcc(seeded with{route: {params}}) andresponseAccinstead of a single accumulator. TheformatErrorrouter option is removed; errors flow throughresponseAcc. - Pipeline builder uses
[fn, setPath]tuple format (removedgetPathselement). - Simplified
preferoption from key string to boolean flag. - Added TypeScript declaration files (
.d.ts) generated from JSDoc. - Added
--test-force-exitto test command (prevents CI hangs from unclosed handles). - Updated release workflow to support pre-release dist-tags.
- Tightened peerDependency to
@centralping/ergo@>=0.1.0-beta.1.
[0.1.0-beta.2]
Added
- Idempotency pipeline key in pipeline builder for deduplicating repeated requests.
[0.2.0]
Added
- OpenTelemetry pipeline-builder integration.
tracingconfig key enables W3C trace context propagation and per-requestergo.pipelinespans via@centralping/ergo’s tracing middleware. Placed first in Stage 1 (before logger) for trace ID correlation in log output.auto-wrap.jsends the span aftersend()withhttp.status_codeattribute and appropriate OTEL status. Supports all code paths: success, error,catchHandler, andnoSend. Zero overhead when no OTEL SDK is registered (no-op spans). (#63) - OpenAPI 3.1 specification generation.
generateOpenAPI(router, options)produces a standards-compliant OpenAPI 3.1 document from registered route metadata. Extracts validation schemas (params, query, body), authorization strategies, content types, and manualopenapiannotations. Resolves config keys against router defaults using the same precedence as the pipeline builder. Available via@centralping/ergo-router/openapisub-path export. (#54) openapiannotation key for declarative route configs. Pass-through object for per-route OpenAPI metadata (summary, description, tags, operationId, deprecated, responses, externalDocs). Validated at registration time as a plain object. (#54)- Route metadata registry (
router._routes). Stores{method, path, config}entries for all registered routes, enabling introspection without coupling to the routing engine. (#54) useconfig key for custom per-route middleware: declarative route configs accept ausearray of[fn, setPath]tuples (or bare functions) that run after Stage 3 (Validation) and before Stage 4 (Execution). Routerdefaults.useentries are concatenated before route-level entries;use: falsedisables all custom middleware. (#51)- Pipeline debug tracing. Pass
{debug: true}in router options to enable pipeline tracing. When enabled,responseAcc._traceis initialized on each request. Thecompose-withserial and concurrent runners record each middleware label instepsand setbreakAtto the label that triggered a pipeline break. On error responses (>= 400),_traceappears as an RFC 9457 extension member. (#59) - Typed Router interface:
createRouter()returns a fully typed object withget,post,put,patch,delete,use,mount,handle, andlistenmethods instead ofobject. Route methods acceptRouteConfigtype for declarative pipeline config. (#50) RouteConfigtypedef: exported fromlib/pipeline-builder.jswith typed properties for all 18 pipeline keys, 3 route option keys, and a typedexecutecallback signature. (#50)- Typed
graceful()options:exit,onStartup,onShutdown, andlogparameters have specific function/object types instead ofFunction. (#50) - CI type validation:
tsconfig.check-types.jsonvalidates generated.d.tsfiles withstrict: trueandskipLibCheck: false.check-typesscript added topackage.json. (#50) - Config validation at registration time: declarative route config objects,
createRouter()options, andoptions.defaultsare validated for unknown keys with Levenshtein-based “did you mean?” suggestions. Unknown keys throw by default (strict: true) or warn (strict: false). (#49) - Missing or non-function
executein declarative route configs now throws at registration time with a descriptive error naming the route (method + path), instead of producing a 500 at request time. (#55) strictoption oncreateRouter()to control config validation strictness (defaulttrue).- Auto-included middleware documentation in README.md Route Config section. (#52)
- TypeScript usage example alongside the JavaScript Quick Start in
README.md. (#46) - CI
peer-compatjob that validates the peer dependency contract against published@centralping/ergoversions (minimum and newest). (#35) - Import surface smoke test (
lib/peer-surface.spec.unit.js) that asserts every@centralping/ergoimport used by ergo-router is available at module load time. (#35) - Contract tests for PATCH
application/merge-patch+jsonandapplication/json-patch+jsonbody parsing through declarative pipeline routes. (#36) - Docs dispatch step in release workflow for automatic docs site rebuild on release. (#40)
Changed
- BREAKING: Renamed route config key
authtoauthorizationfor consistency with theauthorization()middleware factory name. The accumulator pathacc.authis unchanged. (#53) - Bumped
@centralping/ergopeer dependency range to>=0.2.0 <0.3.0(was>=0.1.0 <0.2.0). Floor bumped to 0.2.0 for OpenTelemetry tracing imports (tracingmain entry,statusFromHttpfromlib/tracing). (#63) - Bounded
@centralping/ergopeer dependency range to>=0.1.0-beta.4 <0.2.0(was unbounded>=0.1.0-beta.3). Floor bumped from beta.3 to beta.4 for PATCH content-type body parsing support. (#35)
Fixed
instancefield on all error paths. The RFC 9457instancefield (urn:uuid:{requestId}) is now populated from thex-request-idresponse header on all auto-wrap error paths — pipeline breaks, caught errors (both default andcatchHandler), andendWithProblemshort-circuit responses (404, 405, 415, 429, 500). Previously,instancewas only populated in the defaultcatchblock. (#59)- Bumped
@centralping/ergopeer dependency floor from>=0.1.0-beta.1to>=0.1.0-beta.3to match actual import surface (idempotencyexport requires beta.3). (#34) - README license link changed from relative path to absolute URL (broken on npm). (#40)
- CI dispatch now includes
client-payloadidentifying ergo-router for docs site deploy. (#40)
[0.3.0]
Added
-
paginatepipeline config key. Declarative route configs accept apaginatekey that wires ergo’spaginate()middleware into Stage 1 (Negotiation), after URL parsing. Automatically includes URL parsing when active (regardless of HTTP method). When enabled,send()receivespaginate: truefor automatic Link header andX-Total-Countgeneration. Supports offset-based (paginate: true) and cursor-based (paginate: {strategy: 'cursor'}) pagination strategies via ergo’s pagination primitives. (#71) -
presets.jsonApiconvenience export. A deeply frozenRouterOptionsobject that enables transport-level request ID and security headers, and restricts content negotiation toapplication/json. Consumers spread it intocreateRouter()for one-liner JSON API configuration. Excludes deployment-specific concerns (auth, CORS origin, rate limiting). Available viaimport {presets} from '@centralping/ergo-router'. (#70) -
Typed
RouteConfigwith generic accumulator. Hand-written TypeScript declaration overrides (types-override/) provide precise type information for declarative route configuration. Each middleware key is typed with its specific ergo option interface (e.g.,AcceptsOptions,BodyOptions) instead of genericobject | boolean. Theexecutecallback’s domain accumulator accepts a generic type parameterRouteConfig<A>(defaults toRecord<string, unknown>), enabling consumers to annotate their accumulator shape for type-safe property access.RouterOptions,TransportOptions,GracefulOptions, and theRouterinstance are also fully typed. Adopts thetypes-overridepattern established in@centralping/ergo. (#68)
Changed
- Config value type validation at registration time. Declarative route config values,
createRouter()options, andoptions.defaultsare now validated for correct types at registration time. Invalid values (e.g.,timeout: 'five seconds',rateLimit: 42,validate: [1,2,3]) throw immediately with descriptive error messages instead of causing cryptic runtime errors at request time. Pipeline middleware keys acceptboolean | object; route option keys enforce their specific types (send: object,noSend: boolean,catchHandler: function); router option keys enforce per-key types. Value type errors always throw regardless ofstrictsetting. (#69) - Bumped
@centralping/ergopeer dependency range to>=0.3.0 <0.4.0(was>=0.2.0 <0.3.0). Floor bumped to 0.3.0 forpaginatemiddleware factory import. (#71)
[0.4.0]
Changed
- BREAKING: Pipeline builder uses config objects instead of tuples. (#83)
Aligned with
@centralping/ergo@0.4.0compose-with API change. Domain-producing middleware now uses{fn, setPath}config objects. Response-only middleware (rateLimit, precondition, securityHeaders, cacheControl, validate, jsonApiQuery) are plain functions.RouteConfig.useacceptsArray<function|{fn: function, setPath: string}>. Requires@centralping/ergo >= 0.4.0 < 0.5.0.
Fixed
- Transport
Referrer-Policydefault aligned with shared primitive. ChangedTRANSPORT_DEFAULTS.referrerPolicyfrom'strict-origin-when-cross-origin'to'no-referrer', matching@centralping/ergo’slib/security-headers.jsdefault, the pipeline middleware, and all website documentation. Added contract test forReferrer-Policyheader. (#80) - Generic propagation to route methods. Router route methods (
get,post,put,patch,delete) now propagate theRouteConfig<A>generic type parameter, allowing TypeScript consumers to pass typed route configs with fulldomainAccinference inexecutecallbacks. Previously, route methods accepted onlyRouteConfig(defaulting toRecord<string, unknown>), which caused type errors understrictFunctionTypeswhen passingRouteConfig<SpecificType>. The defaultA = Record<string, unknown>preserves backward compatibility. (#79)
[0.4.1]
Added
-
Accumulator type inference via
defineGet/definePost/defineRoutehelpers. (#91) New exported functions that infer the domain accumulator type from enabled middleware config keys, providing fully typedaccin execute callbacks without manual generic annotation.defineGetauto-includes{url: UrlResult}for GET/DELETE;definePostauto-includes{body: BodyResult}for POST/PUT/PATCH;defineRouteis method-agnostic. Keys set tofalsecorrectly suppress their accumulator type.paginatetransitively includes URL types.import {defineGet} from '@centralping/ergo-router';router.get('/users/:id', defineGet({authorization: true, url: true},(req, res, acc) => {acc.auth; // AuthorizationResultacc.url.query; // Record<string, string | string[]>acc.route.params; // Record<string, string>}));Known limitation: Middleware enabled via
createRouter({defaults: {...}})is not visible to type inference. Add the key explicitly to the route config for typed access. -
New type exports:
RouteConfigBase,InferAccumulator<C>,AutoGetAccumulator<C>,AutoPostAccumulator<C>— available for advanced use cases and custom inference helpers. -
timingoption oncreateRouter()forX-Response-Timeheader. (#93) Passtiming: truefor defaults ortiming: {header?, precision?}for custom configuration. Measures pipeline execution time via ares.writeHeadinterception using the sharedapplyResponseTimingprimitive from@centralping/ergo/lib/response-time. Zero overhead when disabled (default). Short-circuit responses (404, 405, 415, 429) are intentionally excluded — timing measures pipeline execution, not transport/routing overhead.
Changed
- Bumped
@centralping/ergopeer dependency floor to>=0.4.1 <0.5.0(was>=0.4.0 <0.5.0). Floor bumped to 0.4.1 forapplyResponseTimingimport fromlib/response-time. (#93)
[Unreleased] Latest
Documentation
- Route Config table now includes all valid config keys. Added
noSend,send, andcatchHandler(Route Option Keys) andidempotency(Pipeline Key) to the README Route Config table. Previously only Pipeline Keys and Annotation Keys were listed. (#98) router.use()documented in Route Methods section. Added signature, behavior description (prepended to every declarative/array pipeline), and the array-pipelines-only caveat. (#98)