Changelog - 2026-09-11
Kernel hardening
EnhancementIn one line. The kernel's defaults: one logger per scope, singleton services, an application that binds itself, and request headers and bodies sent as written. Migration from ra-core-infra lists what differs from the old package.
What changed
- One logger per scope.
Logger.getInstance({ scope })returns one instance per scope, so a line logged byDefaultAuthServicesays[DefaultAuthService].enableDebugstays one switch for every scope. - Services are singletons by default.
application.service(Class)andapplication.injectable(scope, Class)bind withBindingScopes.SINGLETON. - The application binds itself.
start()binds the application underCoreBindings.APPLICATION_INSTANCE. A manual binding of the same key still wins. - Per-call headers reach the wire.
send({ params: { headers } })merges those headers over the computed ones. x-www-form-urlencodedis really URL-encoded.bodyType: RequestBodyTypes.FORM_URL_ENCODEDsends aURLSearchParamsbody, never multipart.- A refresh that throws synchronously is a failed refresh.
authRecovery.refreshTokenthrowing (rather than rejecting) now callsonAuthFailureand surfaces the original 401. - Browser packages compile without Bun's ambient types.
getRequestHeaderdeclaresRecord<string, string>.
Who is affected
- Applications on ARDOR. No action needed. A manual binding of
APPLICATION_INSTANCEor of a service's scope still applies. - A service that must be transient. Pass a scope explicitly:
application.bind({ key }).toClass(Class).setScope(BindingScopes.TRANSIENT). - Applications moving from ra-core-infra. The behaviours above differ from the old package; follow the migration guide.