Upgrading to 0.7
Moost 0.7.0 builds on wooks 0.8. All moost / @moostjs/* packages share one version: upgrade them together, and upgrade @prostojs/wf to ^0.3.0 if your app lists it. This page is a checklist; each item links to the page that documents the current behaviour. The full list is in the changelog; the wooks side is in the wooks 0.8.0 changelog.
Check these in your app
Interceptors
- After and error hooks now run as one chain over the current value, innermost first: each hook sees what the previous one replied, a throw switches the rest of the chain to error hooks, and a non-Error
reply()recovers it. - An outer error-only hook (logger, audit trail) no longer sees an error that an inner
CATCH_ERRORhook recovered — read the third argumentoriginal(class-based:useInterceptOriginal()) in itsafterhook. - An outer
afterenvelope now also wraps error bodies that an error hook replied with.
Details and examples: The after/error chain.
HTTP
- Default status: PUT, PATCH and DELETE with a body answer
200(were201/202/202). Add@SetStatus()where clients rely on the old codes. → Setting status codes.@moostjs/swaggerdocuments the same defaults → Swagger responses. - Durations are seconds: a numeric cookie
maxAgeorCache-ControlmaxAgeis seconds (was milliseconds); bare digit strings like'3600'now throw. Remove any* 1000. → Setting cookies. - Error responses are never cacheable: they carry
Cache-Control: no-store, also replacing acache-controlset with@SetHeader(…, { when: 'error' | 'always' }). → Setting headers. - Conditional requests: a GET/HEAD
200with anETagorLast-Modifiednow answers304/412automatically, also when the handler set theETag. → Conditional requests. - Proxies are untrusted by default:
@Ip({ trustProxy: true })is deprecated and now trusts one hop (the right-mostX-Forwarded-Forentry). ConfiguretrustProxyonMoostHttpand use@Ip(). → IP address. @Query()resolves{}instead ofundefinedwhen there is no query string. → Query parameters.- Programmatic
fetch()/request()outside a request has an unknown client address (@Ip()is'', was127.0.0.1). On a fetch runtime pass the peer:http.fetch(req, { remoteAddress }). → Serving a fetch runtime.
@moostjs/vite
- An unmatched route under
prefixreturns Moost's JSON404(after a static-file attempt for GET/HEAD) instead of the SPA shell or SSR page.prefixFallthrough: truekeeps the old behaviour. → Middleware Mode. sirvis a regular dependency now — you can drop it from your owndependenciesif you added it only for the generated server.
Workflows
- Trigger refusals are thrown
HttpErrors with acode(WF_EXPIRED,WF_FORBIDDEN, …) and reach your error interceptors; the text moved frombody.errortobody.message. Clients readingbody.message ?? body.errorwork with both. → Access control and refusals. allow: []admits nothing (it allowed everything), andallow/blockalso apply on resume.- Run scopes: create
createOutletHandler(wooksWf)afternew MoostWf(wooksWf), or useMoostWf.handleOutlet()— a handler built before it misses the scope release. →getWfApp().
Shutdown
app.dispose()awaits in-flightrunDetachedruns before the dispose hooks, and ignores hooks registered afterdispose()was called. → Application Dispose.
New in 0.7
app.runDetached(name, fn)— background work with its own event scope;app.addDisposeHook(fn).@Locale(),useLocale(),setTranslator()/useTranslate()— per-event locale and a translation hook for your own i18n library.- Error
codeandparamsonHttpErrorbodies, andtransformErrorBodyonMoostHttp. MoostWf.mint()(headless start that returns a resume token),resolveSchemaId(), and the trigger hooksaround,beforePersist,renderEnvelope,restoreOnError→ Outlets configuration.