Skip to content

Releases: penna-org/haze

create-hazejs@1.0.0

Choose a tag to compare

@github-actions github-actions released this 30 Oct 22:03
7c10e0f

Major Changes

  • #14 80169cf Thanks @aibayanyu20! - hazejs 1.0, the first stable release. All @hazejs/* packages and create-hazejs share 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.ip is now the X-Forwarded-For entry 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 fresh throttle bucket per request by sending its own X-Forwarded-For. trustProxy also accepts the number of trusted hops (trustProxy: 2 behind a CDN and a load balancer). The Cloudflare Workers entry passes cf-connecting-ip and the AWS Lambda adapter passes the event's sourceIp as the client address, so on those platforms ctx.ip works without trustProxy and throttle no longer counts every anonymous request under one shared key. New setClientAddress(request, ip) export for custom entries; throttle logs a warning once when no client address is known.
    • Two-factor login lockout. Wrong codes are counted per user in the cache (new twoFactor.cacheStore option, default store) for challengeTtl, not in the session cookie the client holds, so replaying the login cookie no longer resets maxAttempts. After maxAttempts wrong codes the user cannot complete a challenge until challengeTtl has 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/cli depends on @hazejs/vite with a caret range instead of an exact version, every package has main / types fallbacks for older module resolution, and @hazejs/microservices declares the legacy nats client as an optional peer dependency.

create-hazejs@0.5.0

Choose a tag to compare

@github-actions github-actions released this 30 Oct 12:51
9740141

Minor Changes

  • #11 57b3b34 Thanks @aibayanyu20! - Add auto imports. With the new @hazejs/auto-import package installed and autoImport: true in haze.config.ts (off by default), controllers, services, repositories, models, middleware, validators, events, jobs, mail, notifications and resources (app/<kind>/** and modules/*/app/<kind>/**), plus a curated list of framework APIs from the new @hazejs/core/auto-imports and @hazejs/orm/auto-imports presets (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.ts so classes work as types, generics keep their constraints and default exports get names. autoImport accepts dirs, imports (other packages, e.g. { from: 'valibot', imports: [['*', 'v']] }), presets (default: every installed @hazejs/* package with a preset; [] turns them off), ignore and exclude (default: database/schema/**). haze() now returns an array of plugins (plugins: [haze()] is unchanged; use haze()[0].api for the plugin API), haze typegen always writes types, haze make:* leaves out imports that would be auto-imported, and create-hazejs --auto-import turns the option on in new projects.

create-hazejs@0.4.0

Choose a tag to compare

@github-actions github-actions released this 30 Oct 09:51
0fe65a3

No changes in this release.

create-hazejs@0.3.0

Choose a tag to compare

@github-actions github-actions released this 30 Oct 08:34
6032393

Minor Changes

  • 940711c Thanks @aibayanyu20! - Maintenance mode and server-side TSX views. haze down [--secret] [--retry] [--refresh] [--status] [--redirect] [--render] [--except] [--message], haze up and haze maintenance:status (in production node dist/worker.mjs down / up / maintenance:status) put the application into maintenance mode: requests get 503 with Retry-After — the JSON error envelope (translated with http.maintenance) for API clients, a built-in page, a custom view or a redirect for browsers — while health checks, except paths, 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 to storage/framework/down outside tests) or a local file, is cached in each process for two seconds, and pauses queue workers and the scheduler (pauseWorkers). New Maintenance facade and MaintenanceModeEnabled / MaintenanceModeDisabled events. 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, class arrays and objects, style objects and typed HTML attributes. ctx.view(<Home />, { status, headers }), ctx.view(Home, props), ctx.view('admin/Dashboard', props) (files in app/view), view() and returning a JSX node from a handler render text/html without the JSON envelope; useHttpContext(), useView(), csrfField(), old() and flashInput() help with pages and forms. The Vite plugin compiles backend .tsx / .jsx files with this runtime in the backend environment only, so React frontends keep their own JSX. New haze make:view; the api template renders a TSX welcome page at GET /, and template tsconfigs enable jsxImportSource: '@hazejs/core' for backend files.

  • 4da85a8 Thanks @aibayanyu20! - Model factories and read/write splitting. defineFactory(Model, ({ faker, sequence, n, index }) => attributes) in database/factories builds typed models with make(), 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) and hasAttached() 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 from database.factories.locale or .locale(). SQL connections accept write, read (one or more replicas) and sticky: reads go to a random replica, while writes, transactions, lock(), useWriter(), Model.onWriter(), Db.useWriter(fn), raw Db.execute() / Db.drizzle() and refresh() use the primary; with sticky, reads after a write in the same request (or Db.withinScope()) stay on the primary. Works with per-tenant connections; replica queries report replica: true to the dev dashboard and db.replica on OpenTelemetry spans. pool also accepts { max, idleTimeout, connectTimeout }. Core exports getRequestStore(). New haze make:factory (with --module), and the api / vue / react templates ship a UserFactory used by their tests.

@hazejs/vite@1.0.0

Choose a tag to compare

@github-actions github-actions released this 30 Oct 22:03
7c10e0f

Major Changes

  • #14 80169cf Thanks @aibayanyu20! - hazejs 1.0, the first stable release. All @hazejs/* packages and create-hazejs share 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.ip is now the X-Forwarded-For entry 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 fresh throttle bucket per request by sending its own X-Forwarded-For. trustProxy also accepts the number of trusted hops (trustProxy: 2 behind a CDN and a load balancer). The Cloudflare Workers entry passes cf-connecting-ip and the AWS Lambda adapter passes the event's sourceIp as the client address, so on those platforms ctx.ip works without trustProxy and throttle no longer counts every anonymous request under one shared key. New setClientAddress(request, ip) export for custom entries; throttle logs a warning once when no client address is known.
    • Two-factor login lockout. Wrong codes are counted per user in the cache (new twoFactor.cacheStore option, default store) for challengeTtl, not in the session cookie the client holds, so replaying the login cookie no longer resets maxAttempts. After maxAttempts wrong codes the user cannot complete a challenge until challengeTtl has 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/cli depends on @hazejs/vite with a caret range instead of an exact version, every package has main / types fallbacks for older module resolution, and @hazejs/microservices declares the legacy nats client as an optional peer dependency.

Patch Changes

  • Updated dependencies [80169cf]:
    • @hazejs/core@1.0.0

@hazejs/vite@0.5.0

Choose a tag to compare

@github-actions github-actions released this 30 Oct 13:03
9740141

Minor Changes

  • #11 57b3b34 Thanks @aibayanyu20! - Add auto imports. With the new @hazejs/auto-import package installed and autoImport: true in haze.config.ts (off by default), controllers, services, repositories, models, middleware, validators, events, jobs, mail, notifications and resources (app/<kind>/** and modules/*/app/<kind>/**), plus a curated list of framework APIs from the new @hazejs/core/auto-imports and @hazejs/orm/auto-imports presets (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.ts so classes work as types, generics keep their constraints and default exports get names. autoImport accepts dirs, imports (other packages, e.g. { from: 'valibot', imports: [['*', 'v']] }), presets (default: every installed @hazejs/* package with a preset; [] turns them off), ignore and exclude (default: database/schema/**). haze() now returns an array of plugins (plugins: [haze()] is unchanged; use haze()[0].api for the plugin API), haze typegen always writes types, haze make:* leaves out imports that would be auto-imported, and create-hazejs --auto-import turns the option on in new projects.

Patch Changes

  • Updated dependencies [57b3b34]:
    • @hazejs/core@0.5.0

@hazejs/vite@0.4.0

Choose a tag to compare

@github-actions github-actions released this 30 Oct 09:51
0fe65a3

Patch Changes

  • Updated dependencies [a7d7a1b]:
    • @hazejs/core@0.4.0

@hazejs/vite@0.3.0

Choose a tag to compare

@github-actions github-actions released this 30 Oct 08:35
6032393

Minor Changes

  • 29360c7 Thanks @aibayanyu20! - haze devtools:report writes 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: true in vite.config.ts), the haze() plugin registers the hazejs panels inside Vite DevTools instead of serving its own at the same /__devtools/ path (setupViteDevtools()). @hazejs/vite exports importDevtools(), and devtools.mcp turns the MCP endpoint off.

  • 011b503 Thanks @aibayanyu20! - New @hazejs/devtools package (experimental), built on devframe: install it as a dev dependency and haze dev serves a DevTools hub at /__devtools/ with an app overview (name, mode, reload status, modules, sub-apps), a searchable route table, the /__haze dev dashboard and terminals with one-click haze commands. 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 the haze() 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 with devtools in haze.config.ts or the haze() options; production builds never include it.

  • 940711c Thanks @aibayanyu20! - Maintenance mode and server-side TSX views. haze down [--secret] [--retry] [--refresh] [--status] [--redirect] [--render] [--except] [--message], haze up and haze maintenance:status (in production node dist/worker.mjs down / up / maintenance:status) put the application into maintenance mode: requests get 503 with Retry-After — the JSON error envelope (translated with http.maintenance) for API clients, a built-in page, a custom view or a redirect for browsers — while health checks, except paths, 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 to storage/framework/down outside tests) or a local file, is cached in each process for two seconds, and pauses queue workers and the scheduler (pauseWorkers). New Maintenance facade and MaintenanceModeEnabled / MaintenanceModeDisabled events. 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, class arrays and objects, style objects and typed HTML attributes. ctx.view(<Home />, { status, headers }), ctx.view(Home, props), ctx.view('admin/Dashboard', props) (files in app/view), view() and returning a JSX node from a handler render text/html without the JSON envelope; useHttpContext(), useView(), csrfField(), old() and flashInput() help with pages and forms. The Vite plugin compiles backend .tsx / .jsx files with this runtime in the backend environment only, so React frontends keep their own JSX. New haze make:view; the api template renders a TSX welcome page at GET /, and template tsconfigs enable jsxImportSource: '@hazejs/core' for backend files.

  • 4da85a8 Thanks @aibayanyu20! - Model factories and read/write splitting. defineFactory(Model, ({ faker, sequence, n, index }) => attributes) in database/factories builds typed models with make(), 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) and hasAttached() 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 from database.factories.locale or .locale(). SQL connections accept write, read (one or more replicas) and sticky: reads go to a random replica, while writes, transactions, lock(), useWriter(), Model.onWriter(), Db.useWriter(fn), raw Db.execute() / Db.drizzle() and refresh() use the primary; with sticky, reads after a write in the same request (or Db.withinScope()) stay on the primary. Works with per-tenant connections; replica queries report replica: true to the dev dashboard and db.replica on OpenTelemetry spans. pool also accepts { max, idleTimeout, connectTimeout }. Core exports getRequestStore(). New haze make:factory (with --module), and the api / vue / react templates ship a UserFactory used by their tests.

Patch Changes

  • cb51e0a Thanks @aibayanyu20! - Authentication and authorization hooks for apps with stateful sessions and data-driven permissions. JWT guards accept resolveUser(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. rejectClaims refuses tokens carrying given claims (password-reset tickets signed with the same secret), expiresIn may be a function evaluated per login, and jwt().login(user, claims, { expiresIn }) overrides it per token. The auth middleware answers 401 with code: 'unauthenticated' (no credentials) or 'token_invalid' (expired, tampered, rejected), and auth:optional / auth:<guard>,optional lets requests through as guests. Guards expose failure. gate.fallback((user, ability) => …) decides abilities that have no definition (permission codes stored with roles), ctx.authorizeAny([...]) / gate.authorizeAny() and can:a|b pass when any ability is granted. @hazejs/socket.io's authenticate({ headers }) passes handshake auth fields to the guard as request headers, and rejected handshakes carry error.data = { status, code } with the same codes as the HTTP API (previously { code: 401 }). Backend-only projects can serve a separately built frontend through config/static.ts (dir may come from an environment variable; relative to the project root), and the docker preset's Dockerfile has a HEALTHCHECK on /health/live. ApplicationOptions.configOverrides (and so createTestApp({ configOverrides })) deep-merges configuration over config/*.ts before providers register, keeping class instances such as database clients by reference.

  • a5fd5cf Thanks @aibayanyu20! - The production migrate.mjs no longer prints a skipped (no-migrations) line, labelled with the default connection, for every local module that has no migrations.

  • d90596b Thanks @aibayanyu20! - ORM connections for existing drizzle codebases. New node-postgres driver (pg, drizzle's default PostgreSQL driver) next to postgres-js. Connections accept casing ('snake_case' / 'camelCase') for tables whose columns are declared without names — passed to every drizzle instance, used by upsert() / selectInsert() column lists and forwarded by haze db:generate to drizzle-kit; timezone to set the PostgreSQL session time zone (postgres, node-postgres, pglite); and client to use an existing PGlite, pg.Pool / pg.Client or postgres-js instance that the app never closes (several apps sharing one in-memory database in tests). Db.connect() opens a connection eagerly and Db.drizzleSync() returns the current drizzle instance (the transaction object inside a transaction) for code that cannot await, such as repositories with a db getter. Db.joinTransaction(tx, fn) lets a transaction opened by another library through drizzle join the context, so Db / Model queries 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 request Db / models use the manager of the application handling it, closing an application restores the previously active manager, transactions are tracked per manager, and Db.withManager(manager, fn) pins code outside requests — including timers and promises created inside — to one application's connections. resolveSessionSync(), joinTransaction() and withDatabaseManager() are exported for custom integrations.

  • a5fd5cf Thanks @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 the defineSchedule callback) 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, Db from @hazejs/orm), useApp(), config() an...

Read more

@hazejs/testing@1.0.0

Choose a tag to compare

@github-actions github-actions released this 30 Oct 22:03
7c10e0f

Major Changes

  • #14 80169cf Thanks @aibayanyu20! - hazejs 1.0, the first stable release. All @hazejs/* packages and create-hazejs share 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.ip is now the X-Forwarded-For entry 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 fresh throttle bucket per request by sending its own X-Forwarded-For. trustProxy also accepts the number of trusted hops (trustProxy: 2 behind a CDN and a load balancer). The Cloudflare Workers entry passes cf-connecting-ip and the AWS Lambda adapter passes the event's sourceIp as the client address, so on those platforms ctx.ip works without trustProxy and throttle no longer counts every anonymous request under one shared key. New setClientAddress(request, ip) export for custom entries; throttle logs a warning once when no client address is known.
    • Two-factor login lockout. Wrong codes are counted per user in the cache (new twoFactor.cacheStore option, default store) for challengeTtl, not in the session cookie the client holds, so replaying the login cookie no longer resets maxAttempts. After maxAttempts wrong codes the user cannot complete a challenge until challengeTtl has 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/cli depends on @hazejs/vite with a caret range instead of an exact version, every package has main / types fallbacks for older module resolution, and @hazejs/microservices declares the legacy nats client as an optional peer dependency.

Patch Changes

  • Updated dependencies [80169cf]:
    • @hazejs/core@1.0.0
    • @hazejs/vite@1.0.0

@hazejs/testing@0.5.0

Choose a tag to compare

@github-actions github-actions released this 30 Oct 13:03
9740141

Patch Changes

  • Updated dependencies [57b3b34]:
    • @hazejs/vite@0.5.0
    • @hazejs/core@0.5.0