@veloxts/core 0.8.3 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @veloxts/core
2
2
 
3
+ ## 0.9.0
4
+
5
+ ### Minor Changes
6
+
7
+ - feat(router): add raw() response primitive for redirects, cookies, custom headers and .check() post-middleware authorization primitive
8
+
9
+ ### Patch Changes
10
+
11
+ - ca6ede3: Plugin contract fixes — eliminates three workaround `addHook` blocks freehand projects need to write today.
12
+ - **`@veloxts/orm`**: `ctx.db` is now writable so middleware (e.g. transactional handlers) can swap in a tx client via `Object.assign(ctx, { db: tx })` without redefining the property.
13
+ - **`@veloxts/core`**: registers an empty-JSON-body fallback parser at app construction. POSTs with `Content-Type: application/json` and empty body now reach handlers as `input = {}` instead of being rejected with 400 by Fastify's default parser.
14
+ - **`@veloxts/events`, `@veloxts/cache`, `@veloxts/mail`, `@veloxts/queue`, `@veloxts/storage`**: each plugin now mirrors its `request.<name>` decoration onto the procedure context (`request.context.<name>`), matching the existing auth-plugin pattern. `ctx.events`, `ctx.cache`, `ctx.mail`, `ctx.queue`, `ctx.storage` are now populated automatically — no manual bridging hook required.
15
+
16
+ **Behavior changes to be aware of on upgrade:**
17
+ - `@veloxts/core` now registers an `application/json` content-type parser by default. If you previously called `app.server.addContentTypeParser('application/json', ...)` in user code, you will now hit `FST_ERR_CTP_ALREADY_PRESENT`. Call `app.server.removeContentTypeParser('application/json')` first, then register your own parser.
18
+ - `ctx.db` was previously frozen via `Object.defineProperty({ writable: false })`. Library authors who relied on the strict-mode TypeError on reassignment should switch to defensive copying (`{ ...ctx }`) instead. End-user procedures and middleware are unaffected.
19
+
3
20
  ## 0.8.3
4
21
 
5
22
  ### Patch Changes
@@ -315,7 +332,6 @@
315
332
  - ### feat(auth): Unified Adapter-Only Architecture
316
333
 
317
334
  **New Features:**
318
-
319
335
  - Add `JwtAdapter` implementing the `AuthAdapter` interface for unified JWT authentication
320
336
  - Add `jwtAuth()` convenience function for direct adapter usage with optional built-in routes (`/api/auth/refresh`, `/api/auth/logout`)
321
337
  - Add `AuthContext` discriminated union (`NativeAuthContext | AdapterAuthContext`) for type-safe auth mode handling
@@ -323,24 +339,20 @@
323
339
  - Add shared decoration utilities (`decorateAuth`, `setRequestAuth`, `checkDoubleRegistration`)
324
340
 
325
341
  **Architecture Changes:**
326
-
327
342
  - `authPlugin` now uses `JwtAdapter` internally - all authentication flows through the adapter pattern
328
343
  - Single code path for authentication (no more dual native/adapter modes)
329
344
  - `authContext.authMode` is now always `'adapter'` with `providerId='jwt'` when using `authPlugin`
330
345
 
331
346
  **Breaking Changes:**
332
-
333
347
  - Remove deprecated `LegacySessionConfig` interface (use `sessionMiddleware` instead)
334
348
  - Remove deprecated `session` field from `AuthConfig`
335
349
  - `User` interface no longer has index signature (extend via declaration merging)
336
350
 
337
351
  **Type Safety Improvements:**
338
-
339
352
  - `AuthContext` discriminated union enables exhaustive type narrowing based on `authMode`
340
353
  - Export `NativeAuthContext` and `AdapterAuthContext` types for explicit typing
341
354
 
342
355
  **Migration:**
343
-
344
356
  - Existing `authPlugin` usage remains backward-compatible
345
357
  - If checking `authContext.token`, use `authContext.session` instead (token stored in session for adapter mode)
346
358
 
@@ -355,12 +367,10 @@
355
367
  Addresses 9 user feedback items to improve DX, reduce boilerplate, and eliminate template duplications.
356
368
 
357
369
  ### Phase 1: Validation Helpers (`@veloxts/validation`)
358
-
359
370
  - Add `prismaDecimal()`, `prismaDecimalNullable()`, `prismaDecimalOptional()` for Prisma Decimal → number conversion
360
371
  - Add `dateToIso`, `dateToIsoNullable`, `dateToIsoOptional` aliases for consistency
361
372
 
362
373
  ### Phase 2: Template Deduplication (`@veloxts/auth`)
363
-
364
374
  - Export `createEnhancedTokenStore()` with token revocation and refresh token reuse detection
365
375
  - Export `parseUserRoles()` and `DEFAULT_ALLOWED_ROLES`
366
376
  - Fix memory leak: track pending timeouts for proper cleanup on `destroy()`
@@ -368,20 +378,17 @@
368
378
  - Fix jwtManager singleton pattern in templates
369
379
 
370
380
  ### Phase 3: Router Helpers (`@veloxts/router`)
371
-
372
381
  - Add `createRouter()` returning `{ collections, router }` for DRY setup
373
382
  - Add `toRouter()` for router-only use cases
374
383
  - Update all router templates to use `createRouter()`
375
384
 
376
385
  ### Phase 4: Guard Type Narrowing - Experimental (`@veloxts/auth`, `@veloxts/router`)
377
-
378
386
  - Add `NarrowingGuard` interface with phantom `_narrows` type
379
387
  - Add `authenticatedNarrow` and `hasRoleNarrow()` guards
380
388
  - Add `guardNarrow()` method to `ProcedureBuilder` for context narrowing
381
389
  - Enables `ctx.user` to be non-null after guard passes
382
390
 
383
391
  ### Phase 5: Documentation (`@veloxts/router`)
384
-
385
392
  - Document `.rest()` override patterns
386
393
  - Document `createRouter()` helper usage
387
394
  - Document `guardNarrow()` experimental API
package/dist/app.js CHANGED
@@ -10,6 +10,7 @@ import { ConflictError, isVeloxError, VeloxError } from './errors.js';
10
10
  import { isVeloxModule } from './module/define-module.js';
11
11
  import { createModulePlugin } from './module/register.js';
12
12
  import { isFastifyPlugin, isVeloxPlugin, validatePluginMetadata } from './plugin.js';
13
+ import { setupEmptyBodyParser } from './plugins/empty-body-parser.js';
13
14
  import { requestLogger } from './plugins/request-logger.js';
14
15
  import { registerStatic } from './plugins/static.js';
15
16
  import { printBanner } from './utils/banner.js';
@@ -61,6 +62,7 @@ export class VeloxApp {
61
62
  });
62
63
  this._lifecycle = new LifecycleManager();
63
64
  setupContextHook(this._server);
65
+ setupEmptyBodyParser(this._server);
64
66
  this._setupErrorHandling();
65
67
  this._lifecycle.setupSignalHandlers(async () => {
66
68
  await this.stop();
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Empty-body-tolerant JSON parser
3
+ *
4
+ * Fastify's default `application/json` parser rejects empty bodies with a 400.
5
+ * The Velox client sends `Content-Type: application/json` with an empty body
6
+ * for input-less mutations, which would otherwise fail before reaching the
7
+ * procedure pipeline. This parser returns `{}` for empty bodies and delegates
8
+ * to `JSON.parse` for everything else.
9
+ *
10
+ * Registered automatically by the VeloxApp constructor. Users who need a
11
+ * different parser can call `server.removeContentTypeParser('application/json')`
12
+ * before registering their own.
13
+ *
14
+ * @module plugins/empty-body-parser
15
+ */
16
+ import type { FastifyInstance } from 'fastify';
17
+ export declare function setupEmptyBodyParser(server: FastifyInstance): void;
@@ -0,0 +1,17 @@
1
+ export function setupEmptyBodyParser(server) {
2
+ server.addContentTypeParser('application/json', { parseAs: 'string' }, (_request, body, done) => {
3
+ const raw = typeof body === 'string' ? body.trim() : '';
4
+ if (raw === '') {
5
+ done(null, {});
6
+ return;
7
+ }
8
+ try {
9
+ done(null, JSON.parse(raw));
10
+ }
11
+ catch (error) {
12
+ const err = error;
13
+ err.statusCode = 400;
14
+ done(err);
15
+ }
16
+ });
17
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@veloxts/core",
3
- "version": "0.8.3",
3
+ "version": "0.9.0",
4
4
  "description": "Fastify wrapper and plugin system for VeloxTS framework",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",