Repository navigation
Releases: penna-org/haze
Release list
create-hazejs@1.0.0
Major Changes
-
#14
80169cfThanks @aibayanyu20! - hazejs 1.0, the first stable release. All@hazejs/*packages andcreate-hazejsshare version 1.0.0 and follow semantic versioning from here on: breaking changes only land in a new major, with an upgrade guide.Security fixes included in this release:
- Rate limiting behind proxies. With
app.trustProxy,ctx.ipis now theX-Forwarded-Forentry appended by the nearest trusted proxy (the rightmost) instead of the leftmost one, which the client can set itself; previously a client could get a freshthrottlebucket per request by sending its ownX-Forwarded-For.trustProxyalso accepts the number of trusted hops (trustProxy: 2behind a CDN and a load balancer). The Cloudflare Workers entry passescf-connecting-ipand the AWS Lambda adapter passes the event'ssourceIpas the client address, so on those platformsctx.ipworks withouttrustProxyandthrottleno longer counts every anonymous request under one shared key. NewsetClientAddress(request, ip)export for custom entries;throttlelogs a warning once when no client address is known. - Two-factor login lockout. Wrong codes are counted per user in the cache (new
twoFactor.cacheStoreoption, default store) forchallengeTtl, not in the session cookie the client holds, so replaying the login cookie no longer resetsmaxAttempts. AftermaxAttemptswrong codes the user cannot complete a challenge untilchallengeTtlhas passed, even after entering the password again. - Passkey challenges. In
challenge: 'session'mode a used challenge is also recorded in the cache, so an old session cookie cannot replay a registration or authentication response.
Packaging:
@hazejs/clidepends on@hazejs/vitewith a caret range instead of an exact version, every package hasmain/typesfallbacks for older module resolution, and@hazejs/microservicesdeclares the legacynatsclient as an optional peer dependency. - Rate limiting behind proxies. With
create-hazejs@0.5.0
Minor Changes
- #11
57b3b34Thanks @aibayanyu20! - Add auto imports. With the new@hazejs/auto-importpackage installed andautoImport: trueinhaze.config.ts(off by default), controllers, services, repositories, models, middleware, validators, events, jobs, mail, notifications and resources (app/<kind>/**andmodules/*/app/<kind>/**), plus a curated list of framework APIs from the new@hazejs/core/auto-importsand@hazejs/orm/auto-importspresets (defineRoutes,inject,env,HttpContext, the HTTP exceptions,Model,Db, …), can be used without import statements in the dev server, builds, tests and CLI commands. Imports are added after TypeScript is compiled (type-only usages add nothing), the dev server reloads when exports are added or removed, and global declarations are written to.haze/types/auto-imports.d.tsso classes work as types, generics keep their constraints and default exports get names.autoImportacceptsdirs,imports(other packages, e.g.{ from: 'valibot', imports: [['*', 'v']] }),presets(default: every installed@hazejs/*package with a preset;[]turns them off),ignoreandexclude(default:database/schema/**).haze()now returns an array of plugins (plugins: [haze()]is unchanged; usehaze()[0].apifor the plugin API),haze typegenalways writes types,haze make:*leaves out imports that would be auto-imported, andcreate-hazejs --auto-importturns the option on in new projects.
create-hazejs@0.4.0
No changes in this release.
create-hazejs@0.3.0
Minor Changes
-
940711cThanks @aibayanyu20! - Maintenance mode and server-side TSX views.haze down [--secret] [--retry] [--refresh] [--status] [--redirect] [--render] [--except] [--message],haze upandhaze maintenance:status(in productionnode dist/worker.mjs down/up/maintenance:status) put the application into maintenance mode: requests get 503 withRetry-After— the JSON error envelope (translated withhttp.maintenance) for API clients, a built-in page, a custom view or a redirect for browsers — while health checks,exceptpaths, the dev dashboard and browsers holding the signed bypass cookie (from visiting/<secret>; the secret is stored hashed) pass. The state lives in the cache store by default (config/maintenance.ts,defineMaintenanceConfig; an in-process memory store falls back tostorage/framework/downoutside tests) or a local file, is cached in each process for two seconds, and pauses queue workers and the scheduler (pauseWorkers). NewMaintenancefacade andMaintenanceModeEnabled/MaintenanceModeDisabledevents. Core now ships a zero-dependency JSX runtime (@hazejs/core/jsx-runtime,@hazejs/core/jsx-dev-runtime) that renders escaped HTML strings on every runtime, including Workers: async components,rawHtml()/dangerouslySetInnerHTML,Doctype,classarrays and objects,styleobjects and typed HTML attributes.ctx.view(<Home />, { status, headers }),ctx.view(Home, props),ctx.view('admin/Dashboard', props)(files inapp/view),view()and returning a JSX node from a handler rendertext/htmlwithout the JSON envelope;useHttpContext(),useView(),csrfField(),old()andflashInput()help with pages and forms. The Vite plugin compiles backend.tsx/.jsxfiles with this runtime in the backend environment only, so React frontends keep their own JSX. Newhaze make:view; theapitemplate renders a TSX welcome page atGET /, and template tsconfigs enablejsxImportSource: '@hazejs/core'for backend files. -
4da85a8Thanks @aibayanyu20! - Model factories and read/write splitting.defineFactory(Model, ({ faker, sequence, n, index }) => attributes)indatabase/factoriesbuilds typed models withmake(),create(),raw(),count(),createMany()/makeMany(), named and inline states,sequence(),afterMake/afterCreate, factory and function attribute values, and relations read from the model:for()(belongsTo / morphTo),has()(hasMany / hasOne / morphMany / morphOne / belongsToMany) andhasAttached()with pivot data; multi-model creates run in a transaction. Fake data comes from@faker-js/faker, an optional peer loaded on first use, with the locale fromdatabase.factories.localeor.locale(). SQL connections acceptwrite,read(one or more replicas) andsticky: reads go to a random replica, while writes, transactions,lock(),useWriter(),Model.onWriter(),Db.useWriter(fn), rawDb.execute()/Db.drizzle()andrefresh()use the primary; withsticky, reads after a write in the same request (orDb.withinScope()) stay on the primary. Works with per-tenant connections; replica queries reportreplica: trueto the dev dashboard anddb.replicaon OpenTelemetry spans.poolalso accepts{ max, idleTimeout, connectTimeout }. Core exportsgetRequestStore(). Newhaze make:factory(with--module), and the api / vue / react templates ship aUserFactoryused by their tests.
@hazejs/vite@1.0.0
Major Changes
-
#14
80169cfThanks @aibayanyu20! - hazejs 1.0, the first stable release. All@hazejs/*packages andcreate-hazejsshare version 1.0.0 and follow semantic versioning from here on: breaking changes only land in a new major, with an upgrade guide.Security fixes included in this release:
- Rate limiting behind proxies. With
app.trustProxy,ctx.ipis now theX-Forwarded-Forentry appended by the nearest trusted proxy (the rightmost) instead of the leftmost one, which the client can set itself; previously a client could get a freshthrottlebucket per request by sending its ownX-Forwarded-For.trustProxyalso accepts the number of trusted hops (trustProxy: 2behind a CDN and a load balancer). The Cloudflare Workers entry passescf-connecting-ipand the AWS Lambda adapter passes the event'ssourceIpas the client address, so on those platformsctx.ipworks withouttrustProxyandthrottleno longer counts every anonymous request under one shared key. NewsetClientAddress(request, ip)export for custom entries;throttlelogs a warning once when no client address is known. - Two-factor login lockout. Wrong codes are counted per user in the cache (new
twoFactor.cacheStoreoption, default store) forchallengeTtl, not in the session cookie the client holds, so replaying the login cookie no longer resetsmaxAttempts. AftermaxAttemptswrong codes the user cannot complete a challenge untilchallengeTtlhas passed, even after entering the password again. - Passkey challenges. In
challenge: 'session'mode a used challenge is also recorded in the cache, so an old session cookie cannot replay a registration or authentication response.
Packaging:
@hazejs/clidepends on@hazejs/vitewith a caret range instead of an exact version, every package hasmain/typesfallbacks for older module resolution, and@hazejs/microservicesdeclares the legacynatsclient as an optional peer dependency. - Rate limiting behind proxies. With
Patch Changes
- Updated dependencies [
80169cf]:- @hazejs/core@1.0.0
@hazejs/vite@0.5.0
Minor Changes
- #11
57b3b34Thanks @aibayanyu20! - Add auto imports. With the new@hazejs/auto-importpackage installed andautoImport: trueinhaze.config.ts(off by default), controllers, services, repositories, models, middleware, validators, events, jobs, mail, notifications and resources (app/<kind>/**andmodules/*/app/<kind>/**), plus a curated list of framework APIs from the new@hazejs/core/auto-importsand@hazejs/orm/auto-importspresets (defineRoutes,inject,env,HttpContext, the HTTP exceptions,Model,Db, …), can be used without import statements in the dev server, builds, tests and CLI commands. Imports are added after TypeScript is compiled (type-only usages add nothing), the dev server reloads when exports are added or removed, and global declarations are written to.haze/types/auto-imports.d.tsso classes work as types, generics keep their constraints and default exports get names.autoImportacceptsdirs,imports(other packages, e.g.{ from: 'valibot', imports: [['*', 'v']] }),presets(default: every installed@hazejs/*package with a preset;[]turns them off),ignoreandexclude(default:database/schema/**).haze()now returns an array of plugins (plugins: [haze()]is unchanged; usehaze()[0].apifor the plugin API),haze typegenalways writes types,haze make:*leaves out imports that would be auto-imported, andcreate-hazejs --auto-importturns the option on in new projects.
Patch Changes
- Updated dependencies [
57b3b34]:- @hazejs/core@0.5.0
@hazejs/vite@0.4.0
Patch Changes
- Updated dependencies [
a7d7a1b]:- @hazejs/core@0.4.0
@hazejs/vite@0.3.0
Minor Changes
-
29360c7Thanks @aibayanyu20! -haze devtools:reportwrites the app structure (overview, module graph, routes, container and events) to a static site for CI artifacts and reviews (buildReport()in@hazejs/devtools). In full-stack projects that turn on Vite DevTools (devtools: trueinvite.config.ts), thehaze()plugin registers the hazejs panels inside Vite DevTools instead of serving its own at the same/__devtools/path (setupViteDevtools()).@hazejs/viteexportsimportDevtools(), anddevtools.mcpturns the MCP endpoint off. -
011b503Thanks @aibayanyu20! - New@hazejs/devtoolspackage (experimental), built on devframe: install it as a dev dependency andhaze devserves a DevTools hub at/__devtools/with an app overview (name, mode, reload status, modules, sub-apps), a searchable route table, the/__hazedev dashboard and terminals with one-clickhazecommands. The hub runs in the dev server process, so its connection and state survive hot reloads; failed reloads show up as a status badge and a notification. In full-stack Vite projects thehaze()plugin mounts it on the Vite server and injects a floating dock into the frontend. Browsers authorize once with a one-time code printed in the terminal. Configure or turn it off withdevtoolsinhaze.config.tsor thehaze()options; production builds never include it. -
940711cThanks @aibayanyu20! - Maintenance mode and server-side TSX views.haze down [--secret] [--retry] [--refresh] [--status] [--redirect] [--render] [--except] [--message],haze upandhaze maintenance:status(in productionnode dist/worker.mjs down/up/maintenance:status) put the application into maintenance mode: requests get 503 withRetry-After— the JSON error envelope (translated withhttp.maintenance) for API clients, a built-in page, a custom view or a redirect for browsers — while health checks,exceptpaths, the dev dashboard and browsers holding the signed bypass cookie (from visiting/<secret>; the secret is stored hashed) pass. The state lives in the cache store by default (config/maintenance.ts,defineMaintenanceConfig; an in-process memory store falls back tostorage/framework/downoutside tests) or a local file, is cached in each process for two seconds, and pauses queue workers and the scheduler (pauseWorkers). NewMaintenancefacade andMaintenanceModeEnabled/MaintenanceModeDisabledevents. Core now ships a zero-dependency JSX runtime (@hazejs/core/jsx-runtime,@hazejs/core/jsx-dev-runtime) that renders escaped HTML strings on every runtime, including Workers: async components,rawHtml()/dangerouslySetInnerHTML,Doctype,classarrays and objects,styleobjects and typed HTML attributes.ctx.view(<Home />, { status, headers }),ctx.view(Home, props),ctx.view('admin/Dashboard', props)(files inapp/view),view()and returning a JSX node from a handler rendertext/htmlwithout the JSON envelope;useHttpContext(),useView(),csrfField(),old()andflashInput()help with pages and forms. The Vite plugin compiles backend.tsx/.jsxfiles with this runtime in the backend environment only, so React frontends keep their own JSX. Newhaze make:view; theapitemplate renders a TSX welcome page atGET /, and template tsconfigs enablejsxImportSource: '@hazejs/core'for backend files. -
4da85a8Thanks @aibayanyu20! - Model factories and read/write splitting.defineFactory(Model, ({ faker, sequence, n, index }) => attributes)indatabase/factoriesbuilds typed models withmake(),create(),raw(),count(),createMany()/makeMany(), named and inline states,sequence(),afterMake/afterCreate, factory and function attribute values, and relations read from the model:for()(belongsTo / morphTo),has()(hasMany / hasOne / morphMany / morphOne / belongsToMany) andhasAttached()with pivot data; multi-model creates run in a transaction. Fake data comes from@faker-js/faker, an optional peer loaded on first use, with the locale fromdatabase.factories.localeor.locale(). SQL connections acceptwrite,read(one or more replicas) andsticky: reads go to a random replica, while writes, transactions,lock(),useWriter(),Model.onWriter(),Db.useWriter(fn), rawDb.execute()/Db.drizzle()andrefresh()use the primary; withsticky, reads after a write in the same request (orDb.withinScope()) stay on the primary. Works with per-tenant connections; replica queries reportreplica: trueto the dev dashboard anddb.replicaon OpenTelemetry spans.poolalso accepts{ max, idleTimeout, connectTimeout }. Core exportsgetRequestStore(). Newhaze make:factory(with--module), and the api / vue / react templates ship aUserFactoryused by their tests.
Patch Changes
-
cb51e0aThanks @aibayanyu20! - Authentication and authorization hooks for apps with stateful sessions and data-driven permissions. JWT guards acceptresolveUser(payload, ctx)to resolve the user from the verified claims and the request (check a session id on every request, read an organisation header);HttpExceptions it throws become the response unchanged.rejectClaimsrefuses tokens carrying given claims (password-reset tickets signed with the same secret),expiresInmay be a function evaluated per login, andjwt().login(user, claims, { expiresIn })overrides it per token. Theauthmiddleware answers401withcode: 'unauthenticated'(no credentials) or'token_invalid'(expired, tampered, rejected), andauth:optional/auth:<guard>,optionallets requests through as guests. Guards exposefailure.gate.fallback((user, ability) => …)decides abilities that have no definition (permission codes stored with roles),ctx.authorizeAny([...])/gate.authorizeAny()andcan:a|bpass when any ability is granted.@hazejs/socket.io'sauthenticate({ headers })passes handshakeauthfields to the guard as request headers, and rejected handshakes carryerror.data = { status, code }with the same codes as the HTTP API (previously{ code: 401 }). Backend-only projects can serve a separately built frontend throughconfig/static.ts(dirmay come from an environment variable; relative to the project root), and the docker preset's Dockerfile has aHEALTHCHECKon/health/live.ApplicationOptions.configOverrides(and socreateTestApp({ configOverrides })) deep-merges configuration overconfig/*.tsbefore providers register, keeping class instances such as database clients by reference. -
a5fd5cfThanks @aibayanyu20! - The productionmigrate.mjsno longer prints askipped (no-migrations)line, labelled with the default connection, for every local module that has no migrations. -
d90596bThanks @aibayanyu20! - ORM connections for existing drizzle codebases. Newnode-postgresdriver (pg, drizzle's default PostgreSQL driver) next to postgres-js. Connections acceptcasing('snake_case'/'camelCase') for tables whose columns are declared without names — passed to every drizzle instance, used byupsert()/selectInsert()column lists and forwarded byhaze db:generateto drizzle-kit;timezoneto set the PostgreSQL session time zone (postgres,node-postgres,pglite); andclientto use an existingPGlite,pg.Pool/pg.Clientor postgres-js instance that the app never closes (several apps sharing one in-memory database in tests).Db.connect()opens a connection eagerly andDb.drizzleSync()returns the current drizzle instance (the transaction object inside a transaction) for code that cannot await, such as repositories with adbgetter.Db.joinTransaction(tx, fn)lets a transaction opened by another library through drizzle join the context, soDb/Modelqueries inside run in it and nested transactions become savepoints. Several applications in one process (typical in tests) no longer step on each other: inside a requestDb/ models use the manager of the application handling it, closing an application restores the previously active manager, transactions are tracked per manager, andDb.withManager(manager, fn)pins code outside requests — including timers and promises created inside — to one application's connections.resolveSessionSync(),joinTransaction()andwithDatabaseManager()are exported for custom integrations. -
a5fd5cfThanks @aibayanyu20! - Queue, scheduler and event fixes found while porting a production backend onto hazejs.Application context: queued jobs (every driver, including
Queue.fake().drain()), scheduled tasks (s.call()functions,when()/skip()filters, hooks and thedefineSchedulecallback) and event listeners now run in the context of the application that owns them, so the facades (Queue,Events,Cache,Mail,Storage,Notification,Broadcast,Redis,Http,Dbfrom@hazejs/orm),useApp(),config()an...
@hazejs/testing@1.0.0
Major Changes
-
#14
80169cfThanks @aibayanyu20! - hazejs 1.0, the first stable release. All@hazejs/*packages andcreate-hazejsshare version 1.0.0 and follow semantic versioning from here on: breaking changes only land in a new major, with an upgrade guide.Security fixes included in this release:
- Rate limiting behind proxies. With
app.trustProxy,ctx.ipis now theX-Forwarded-Forentry appended by the nearest trusted proxy (the rightmost) instead of the leftmost one, which the client can set itself; previously a client could get a freshthrottlebucket per request by sending its ownX-Forwarded-For.trustProxyalso accepts the number of trusted hops (trustProxy: 2behind a CDN and a load balancer). The Cloudflare Workers entry passescf-connecting-ipand the AWS Lambda adapter passes the event'ssourceIpas the client address, so on those platformsctx.ipworks withouttrustProxyandthrottleno longer counts every anonymous request under one shared key. NewsetClientAddress(request, ip)export for custom entries;throttlelogs a warning once when no client address is known. - Two-factor login lockout. Wrong codes are counted per user in the cache (new
twoFactor.cacheStoreoption, default store) forchallengeTtl, not in the session cookie the client holds, so replaying the login cookie no longer resetsmaxAttempts. AftermaxAttemptswrong codes the user cannot complete a challenge untilchallengeTtlhas passed, even after entering the password again. - Passkey challenges. In
challenge: 'session'mode a used challenge is also recorded in the cache, so an old session cookie cannot replay a registration or authentication response.
Packaging:
@hazejs/clidepends on@hazejs/vitewith a caret range instead of an exact version, every package hasmain/typesfallbacks for older module resolution, and@hazejs/microservicesdeclares the legacynatsclient as an optional peer dependency. - Rate limiting behind proxies. With
Patch Changes
- Updated dependencies [
80169cf]:- @hazejs/core@1.0.0
- @hazejs/vite@1.0.0
@hazejs/testing@0.5.0
Patch Changes
- Updated dependencies [
57b3b34]:- @hazejs/vite@0.5.0
- @hazejs/core@0.5.0