@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 +17 -10
- package/dist/app.js +2 -0
- package/dist/plugins/empty-body-parser.d.ts +17 -0
- package/dist/plugins/empty-body-parser.js +17 -0
- package/package.json +1 -1
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
|
+
}
|