Skip to main content

Changelog

Release notes are generated by release-please from Conventional Commits into CHANGELOG.md in the library repository. This page summarizes each release; upgrade steps with before and after code are in the migration guide.

0.2.0

A production-readiness pass over errors, logging, the app builder, datasources, the KV cache and the environment readers.

Breaking changes

  • The request-scoped logger variable is renamed from c.var.logger to c.var.cwbLogger; use getRequestLogger(c).
  • DrizzleD1Datasource and DrizzleD1TenantDatasource are abstract: subclass them with a unique readonly name (the old default names shared one cache namespace).
  • scopedSelect(table, ...conditions) becomes scopedSelect(table, {where, orderBy, limit, offset}).
  • Response helper status parameters are ContentfulStatusCode (204 and 304 no longer compile; use respondNoContent()).
  • ApiResponse<T> is a discriminated union (ApiSuccessResponse<T> | ApiErrorResponse).
  • BaseContextVariables no longer has an index signature.
  • json* OpenAPI helpers require zod schemas.
  • buildPaginationMeta / respondPaginated throw a 400 BAD_REQUEST ApiError for invalid page, limit or total. PaginationMetaSchema has integer fields, a required totalPages and no defaults.
  • The global logshipper type declaration is removed (runtime forwarding is unchanged).
  • ApiError.toJSON() no longer includes stack.
  • createApp throws for unsupported route methods and duplicate method and path routes.
  • timing (Server-Timing) defaults to development only.
  • Request ids no longer use cf-request-id; cf-ray is validated.
  • Env readers: bool accepts true/false/1/0/yes/no/on/off and returns the default for anything else; int, float and date return the default instead of NaN or an Invalid Date; JSON-typed wrangler vars are accepted.
  • Cache keys for Map, Set and bigint params changed; circular params and class instances without toJSON() throw TypeError.

Features and fixes

  • Errors: 5xx and critical errors are never throttled, with a N errors suppressed warning after a throttle window. ErrorInfo.stack is the original throw site and ErrorInfo.cause holds the serialized cause chain. details are always in logs and reports (masked only in responses). Error logs carry requestId. errors.context.includeClientInfo omits IP and user agent.
  • ApiError is recognized by a Symbol.for brand (ApiError.isApiError), so errors from a second copy of the library keep their status.
  • Non-Error throws get the error envelope instead of escaping app.fetch.
  • Logging: the logger never throws (BigInt, circular values); serializers.req accepts c.req; serializers.err keeps the cause chain (serializeError is exported); an invalid LOG_LEVEL falls back with a warning (resolveLogLevel, LOG_LEVELS).
  • New redaction name fragments: hmac, private, cert, saml, assertion, auth_code, authcode.
  • App builder: AppConfig.logger and AppConfig.requestLogging; requestId: {trustIncomingHeader: false}; module middleware only runs for its own module's routes.
  • Response helpers: respondNoContent keeps previously set headers; meta.pagination.totalPages is added and MetaSchema.traceId is documented.
  • Datasources: scopedCount, ordering and paging in scopedSelect, requestId in datasource and cache logs, an overridable cacheBinding getter.
  • KV cache: CacheOptions.revive, a documented JSON-only value contract, KVCacheOptions.logger, and notes on eventual consistency.
  • Docs: migration guide, support policy, and consumer TypeScript setup notes.

0.1.0 (2026-09-14)

Replaced Prisma with Drizzle ORM, moved the toolchain to TypeScript 7, and hardened errors, logging, caching and multi-tenancy.

Breaking changes

  • Datasources: the Prisma datasources and tenant extension are removed. Use DrizzleD1Datasource and DrizzleD1TenantDatasource (tenant state is per instance; use the scoped* helpers). drizzle-orm 0.45.x is an optional peer dependency.
  • hono (^4.13), chanfana (^3.4) and zod (^4.4.3) are peer dependencies. The published types work with TypeScript 5.9 to 7 consumers and need Workers globals.
  • The registry singleton export is removed; createApp creates one EndpointRegistry per app.
  • AppConfig.openApi must return the chanfana router (OpenAPIRouter).
  • The KVCache constructor takes an options object; cached values are wrapped as {value} and keys changed (SHA-256, null significant, toJSON honored), so existing entries are ignored.
  • KVCache.invalidate/clearAll and AbstractDatasource.clear stay within a KV operation budget and return {deleted, complete, cursor, failed}.
  • AbstractDatasource.updateLoggerName() is removed; withCache defaults to the datasource name namespace.
  • Only NODE_ENV values development, dev, test and local count as non-production.
  • 5xx messages and details are masked in production; 4xx messages are returned for ApiError and HTTPException, and other errors need a transformer-supplied message. Stack traces are logged by default, never returned.
  • globalThis.requestContext log enrichment is removed (it mixed concurrent requests) in favor of a request-scoped logger.
  • DrizzleD1TenantDatasource.scopedSelect resolves to rows instead of a query builder.
  • Log lines use time (ISO) instead of timestamp.

Features and fixes

  • createApp({middleware}) and ApiModule.middleware run middleware such as auth before module routes.
  • chanfana errors (schema validation, InputValidationException, NotFoundException, ...) use the standard envelope; validation failures return 422 VALIDATION_ERROR with {field, message, code} details.
  • Unknown routes return the JSON NOT_FOUND envelope.
  • MIT license and complete package metadata; CI, release, commitlint, PR title, zizmor and Dependabot workflows.
  • Tenant datasource caches are namespaced per tenant; scopedUpsert updates only the current tenant's conflicting rows and accepts sql values; scoped write helpers return narrow query objects.
  • Sensitive query parameters are redacted in error context and logged URLs (excludeQueryParams, addSensitiveQueryParams, redactQueryParams, redactUrl).
  • createErrorHandler(config) implements custom logger, error reporter via waitUntil, header redaction, message truncation, classifier, transformer, rate-limited reporting and getMetrics().
  • Hono HTTPExceptions keep their status; respondError bodies include error.id; respondPaginated adds hasNext/hasPrev.
  • Route paths are normalized; request logs show the real request path.
  • The logger redacts sensitive headers and includes env, service and runtime; SERVICE_NAME sets the service name.
  • KV cache: SHA-256 keys, falsy values cached, background writes via waitUntil, cursor pagination on invalidate, TTL clamped to KV's 60-second minimum; KVCache is exported.
  • Tooling: tsdown with TypeScript 7 declarations, oxlint with type-aware rules, a bun test suite against local D1 and KV.