veloce-ts 0.4.18 → 1.0.1

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.
Files changed (96) hide show
  1. package/CHANGELOG.md +124 -1
  2. package/MIGRATION.md +109 -0
  3. package/README.md +33 -3
  4. package/dist/cjs/src/adapters/hono.js +2 -2
  5. package/dist/cjs/src/adapters/hono.js.map +3 -3
  6. package/dist/cjs/src/auth/index.js +3 -16
  7. package/dist/cjs/src/auth/index.js.map +12 -16
  8. package/dist/cjs/src/graphql/index.js +14 -27
  9. package/dist/cjs/src/graphql/index.js.map +6 -7
  10. package/dist/cjs/src/index.js +49 -62
  11. package/dist/cjs/src/index.js.map +38 -57
  12. package/dist/cjs/src/middleware/index.js +8 -8
  13. package/dist/cjs/src/middleware/index.js.map +4 -4
  14. package/dist/cjs/src/plugins/index.js +41 -54
  15. package/dist/cjs/src/plugins/index.js.map +7 -8
  16. package/dist/cjs/src/testing/index.js +32 -45
  17. package/dist/cjs/src/testing/index.js.map +12 -37
  18. package/dist/cjs/src/validation/index.js +2 -2
  19. package/dist/cjs/src/validation/index.js.map +3 -3
  20. package/dist/cjs/src/websocket/index.js +2 -15
  21. package/dist/cjs/src/websocket/index.js.map +5 -6
  22. package/dist/esm/src/adapters/express.js +3 -3
  23. package/dist/esm/src/adapters/express.js.map +2 -2
  24. package/dist/esm/src/adapters/hono.js +2 -2
  25. package/dist/esm/src/adapters/hono.js.map +3 -3
  26. package/dist/esm/src/auth/index.js +3 -16
  27. package/dist/esm/src/auth/index.js.map +12 -16
  28. package/dist/esm/src/cli/index.js +32 -32
  29. package/dist/esm/src/cli/index.js.map +2 -2
  30. package/dist/esm/src/docs/index.js +3 -3
  31. package/dist/esm/src/docs/index.js.map +2 -2
  32. package/dist/esm/src/errors/index.js +7 -7
  33. package/dist/esm/src/errors/index.js.map +2 -2
  34. package/dist/esm/src/graphql/index.js +17 -30
  35. package/dist/esm/src/graphql/index.js.map +6 -7
  36. package/dist/esm/src/index.js +49 -62
  37. package/dist/esm/src/index.js.map +38 -57
  38. package/dist/esm/src/middleware/index.js +8 -8
  39. package/dist/esm/src/middleware/index.js.map +4 -4
  40. package/dist/esm/src/plugins/index.js +41 -54
  41. package/dist/esm/src/plugins/index.js.map +7 -8
  42. package/dist/esm/src/testing/index.js +32 -45
  43. package/dist/esm/src/testing/index.js.map +12 -37
  44. package/dist/esm/src/types/index.js +2 -2
  45. package/dist/esm/src/types/index.js.map +2 -2
  46. package/dist/esm/src/validation/index.js +2 -2
  47. package/dist/esm/src/validation/index.js.map +3 -3
  48. package/dist/esm/src/websocket/index.js +2 -15
  49. package/dist/esm/src/websocket/index.js.map +5 -6
  50. package/dist/types/auth/auth-plugin.d.ts.map +1 -1
  51. package/dist/types/auth/auth-service.d.ts.map +1 -1
  52. package/dist/types/auth/jwt-provider.d.ts +4 -4
  53. package/dist/types/auth/jwt-provider.d.ts.map +1 -1
  54. package/dist/types/auth/oauth-plugin.d.ts +2 -0
  55. package/dist/types/auth/oauth-plugin.d.ts.map +1 -1
  56. package/dist/types/auth/permission-plugin.d.ts.map +1 -1
  57. package/dist/types/auth/permissions.d.ts +12 -12
  58. package/dist/types/auth/rbac-plugin.d.ts.map +1 -1
  59. package/dist/types/auth/session.d.ts +2 -0
  60. package/dist/types/auth/session.d.ts.map +1 -1
  61. package/dist/types/cache/manager.d.ts +4 -0
  62. package/dist/types/cache/manager.d.ts.map +1 -1
  63. package/dist/types/core/application.d.ts.map +1 -1
  64. package/dist/types/core/compiled-metadata.d.ts.map +1 -1
  65. package/dist/types/core/metadata.d.ts.map +1 -1
  66. package/dist/types/core/router-compiler.d.ts +0 -1
  67. package/dist/types/core/router-compiler.d.ts.map +1 -1
  68. package/dist/types/dependencies/prisma.d.ts +40 -0
  69. package/dist/types/dependencies/prisma.d.ts.map +1 -0
  70. package/dist/types/dependencies/typeorm.d.ts +41 -0
  71. package/dist/types/dependencies/typeorm.d.ts.map +1 -0
  72. package/dist/types/graphql/plugin.d.ts +12 -0
  73. package/dist/types/graphql/plugin.d.ts.map +1 -1
  74. package/dist/types/graphql/schema-builder.d.ts +4 -5
  75. package/dist/types/graphql/schema-builder.d.ts.map +1 -1
  76. package/dist/types/index.d.ts +5 -4
  77. package/dist/types/index.d.ts.map +1 -1
  78. package/dist/types/middleware/rate-limit.d.ts.map +1 -1
  79. package/dist/types/orm/base-repository.d.ts.map +1 -1
  80. package/dist/types/orm/drizzle/plugin.d.ts +0 -22
  81. package/dist/types/orm/drizzle/plugin.d.ts.map +1 -1
  82. package/dist/types/orm/drizzle/repository.d.ts.map +1 -1
  83. package/dist/types/orm/drizzle/transaction-manager.d.ts.map +1 -1
  84. package/dist/types/orm/prisma/plugin.d.ts +1 -1
  85. package/dist/types/orm/prisma/repository.d.ts.map +1 -1
  86. package/dist/types/orm/prisma/types.d.ts +3 -0
  87. package/dist/types/orm/prisma/types.d.ts.map +1 -1
  88. package/dist/types/orm/transaction-plugin.d.ts +1 -1
  89. package/dist/types/orm/typeorm/decorators.d.ts +1 -1
  90. package/dist/types/orm/typeorm/plugin.d.ts +1 -1
  91. package/dist/types/orm/typeorm/repository.d.ts.map +1 -1
  92. package/dist/types/orm/typeorm/transaction-manager.d.ts.map +1 -1
  93. package/dist/types/validation/validator.d.ts.map +1 -1
  94. package/dist/types/websocket/plugin.d.ts +0 -4
  95. package/dist/types/websocket/plugin.d.ts.map +1 -1
  96. package/package.json +3 -2
package/CHANGELOG.md CHANGED
@@ -7,6 +7,126 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.0.1] - 2026-06-26
11
+
12
+ ### Fixed
13
+
14
+ - **GraphQL decorator pipeline wired up.** `@Resolver`, `@GQLQuery`, `@GQLMutation`, `@GQLSubscription`, and `@Arg` decorators now correctly connect to `GraphQLPlugin`. Previously the decorators wrote metadata using local symbols that `GraphQLSchemaBuilder` never read — the schema was always empty.
15
+
16
+ Pass resolver classes to the plugin via the new `resolvers` option:
17
+ ```typescript
18
+ app.usePlugin(new GraphQLPlugin({ resolvers: [UserResolver, PostResolver] }));
19
+ ```
20
+ Or register them with `app.include()` before calling `usePlugin()`:
21
+ ```typescript
22
+ app.include(UserResolver);
23
+ app.usePlugin(new GraphQLPlugin());
24
+ ```
25
+
26
+ - **`PermissionManager.revokePermission()` bug fixed.** When called without a `resourceId`, the filter condition `resourceId ? p.resourceId !== resourceId : true` always returned `true` (kept all records, removed nothing). Now correctly removes all permissions for the user+resource pair when no `resourceId` is specified.
27
+
28
+ - **`app.include()` now recognises `@Resolver` classes.** Previously silently ignored — now registers resolver metadata into `MetadataRegistry` so `GraphQLPlugin` can pick it up automatically.
29
+
30
+ ### Added
31
+
32
+ - **89 new tests** (507 total, 0 failures) covering:
33
+ - GraphQL decorator metadata pipeline end-to-end
34
+ - `app.include()` + `resolvers: []` option merge
35
+ - `PermissionPlugin` construction, `PermissionManager` unit logic, management route auth guards
36
+ - `HealthCheckPlugin` `/health`, `/ready`, `/live` endpoints, custom check logic, `HealthCheckers` factory
37
+ - `OAuthPlugin` route behavior, `BaseOAuthProvider`/`GoogleOAuthProvider`/`GitHubOAuthProvider`, `OAuthStateManager`, `PKCEUtils`
38
+ - Logger (`createLogger`, `getLogger`, `initializeLogger`, `createChildLogger`, child context propagation)
39
+
40
+ ## [1.0.0] - 2026-06-26
41
+
42
+ First stable release. Establishes a frozen public API with semver guarantees going forward.
43
+
44
+ ### Breaking Changes
45
+
46
+ - **`FastAPITS` export removed.** Use `VeloceTS` or the `Veloce` alias instead.
47
+ ```typescript
48
+ // Before
49
+ import { FastAPITS } from 'veloce-ts';
50
+ // After
51
+ import { Veloce } from 'veloce-ts';
52
+ ```
53
+
54
+ - **`WebSocketPlugin` throws on Node.js at install time** instead of silently returning 501 at request time. If you were catching the 501 response, catch the constructor error instead. WebSocket is supported on Bun and Deno only.
55
+ ```typescript
56
+ // Node.js — throws Error('WebSocketPlugin requires Bun or Deno runtime...')
57
+ app.usePlugin(new WebSocketPlugin({ ... }));
58
+ ```
59
+
60
+ - **`@InjectDrizzleRepository` decorator removed.** It was a no-op stub. Remove any usages — the decorator did nothing at runtime.
61
+
62
+ ### Added
63
+
64
+ - **`OAuthPlugin`, `PermissionPlugin`, `SessionPlugin`** now exported from the main `'veloce-ts'` barrel (previously only from `'veloce-ts/auth'`).
65
+ - **`registerPrisma(app, client)`** — thin DI helper for Prisma, mirrors `registerDrizzle`. Exports `PRISMA_TOKEN`.
66
+ - **`registerTypeORM(app, dataSource)`** — thin DI helper for TypeORM. Exports `TYPEORM_TOKEN`.
67
+
68
+ ### Fixed
69
+
70
+ - **TypeScript errors** — 12 pre-existing errors resolved: route param casts in auth plugins, `PrismaDelegate` missing `createMany`, middleware spread type mismatch in `RouterCompiler`.
71
+ - **RouterCompiler** dead `compiledRoutes` Map removed — it was write-only and shared the same class-name collision bug that was already fixed in `MetadataCompiler`.
72
+ - **Branding** — "FastAPI-TS" replaced with "Veloce-TS" in all error messages and JSDoc across `src/adapters/hono.ts`, `src/orm/prisma/plugin.ts`, `src/orm/typeorm/plugin.ts`, `src/orm/typeorm/decorators.ts`, `src/orm/transaction-plugin.ts`.
73
+
74
+ ### Test coverage
75
+
76
+ 413 tests passing, 0 failures across 21 files. New files added:
77
+ - `tests/websocket.test.ts` — 11 tests (decorator registration, plugin construction on Bun, upgrade route, auth guards)
78
+ - `tests/graphql.test.ts` — 10 tests (plugin install, invalid JSON, GET/POST, playground, introspection)
79
+
80
+ ## [0.4.18] - 2026-06-25
81
+
82
+ Full security & correctness audit across the framework core, auth layer, ORM integrations, and build pipeline. 375 tests passing, 0 failures.
83
+
84
+ ### Fixed
85
+
86
+ **Auth / Security**
87
+ - **RBAC plugin:** all 7 management routes (`/roles`, `/users/:id/roles`, etc.) now correctly require `requireAuth`. Previously they were publicly accessible.
88
+ - **Permission plugin:** all 7 permission management routes now correctly require `requireAuth`. Same gap as RBAC.
89
+ - **JWT blacklist:** replaced the `Set<string>` with `Map<string, number>` (token → expiry timestamp). Provides O(1) lookup and enables `cleanupBlacklist()` to auto-purge expired entries without scanning the entire set.
90
+ - **OAuth plugin:** `login()` returned 401 on valid credentials due to an inverted conditional; fixed. PKCE code TTL was set to `Date.now()` (milliseconds) instead of `Date.now() / 1000` (seconds), causing immediate expiry.
91
+ - **Auth plugin:** removed 5 `console.log()` debug calls leaking tokens and user data to stdout in production builds.
92
+ - **Auth service:** `hashPassword()` was gated by an incorrect production guard that blocked legitimate use; removed.
93
+
94
+ **Core**
95
+ - **MetadataCompiler:** cache key changed from `"ClassName:methodName"` to a WeakMap-based numeric class identity (`targetId:methodName`). Fixes 36 test failures when running Bun's shared-process test runner: classes with the same name in different test files no longer share a cache slot, so each app instance compiles its own routes with its own DI/JWT context.
96
+ - **MetadataRegistry:** `getRouteMethods()` now walks the full prototype chain. Inherited route methods from a base controller were previously invisible to the router compiler.
97
+ - **Application:** `createAdapter()` is now `async` and properly `await`ed. `listen()` is awaited. Timeout middleware and cache configuration now propagate correctly to the adapter.
98
+ - **CacheManager:** added `static reset()` to clear all stores and registered names — required for test isolation between app instances in the same process.
99
+
100
+ **ORM**
101
+ - **Base repository:** `createMany()` now uses `Promise.all()` for parallel execution instead of sequential `await` in a loop.
102
+ - **Prisma repository:** fixed double insert in `create()` — the entity was being saved twice.
103
+ - **Drizzle transaction manager:** `commit()` was called inside `finally` block, running even after a successful commit. Moved to the normal path only.
104
+ - **TypeORM transaction manager:** `QueryRunner` was not released on error, leaking database connections.
105
+ - **Drizzle repository:** static `import` of `drizzle-orm` at module top level replaced with lazy `require()` via `getDrizzleOps()`. Fixes build failure when `drizzle-orm` is not installed (optional peer dep).
106
+ - **TypeORM repository:** same fix — static `import` of `typeorm` replaced with lazy `getTypeORMOps()`.
107
+
108
+ **Build**
109
+ - **`build.ts`:** added `external` array to both `Bun.build()` calls covering all optional peer deps (`drizzle-orm`, `typeorm`, `prisma`, `@prisma/client`, `reflect-metadata`, `graphql`, `ioredis`, `express`, `hono`). Without this, `bun run build` failed when any optional dep was absent.
110
+
111
+ **Other**
112
+ - **GraphQL plugin:** `JSON.parse()` on the `variables` field now wrapped in try-catch; previously threw an unhandled exception on malformed JSON.
113
+ - **Session store:** auto-cleanup interval registered on construction; SIGTERM/SIGINT handlers stop it on shutdown (prevents hanging processes).
114
+ - **Rate limit middleware:** SIGTERM/SIGINT cleanup for the cleanup interval — same pattern.
115
+ - **Validator:** removed dead `resultCache` WeakMap that accumulated entries without any code path reading from it.
116
+
117
+ ### Added
118
+
119
+ **Tests**
120
+ - `tests/fixes.test.ts` — 45 integration tests covering all 24 corrected bugs above (JWT blacklist Map behavior, RBAC/Permission auth guards, CacheManager.reset(), prototype chain routing, parallel createMany, MetadataCompiler class identity, lazy ORM imports, GraphQL JSON parse errors, session cleanup, functional route timeout/cache).
121
+ - `tests/cache.test.ts` — 40 tests for `parseTTL`, `MemoryCacheStore` (CRUD, TTL expiry, LRU eviction, pattern deletion), and `CacheManager` (reset, named stores, generateKey, convenience functions).
122
+ - `tests/session.test.ts` — 17 tests for `MemorySessionStore` (CRUD, touch, expiry with real-time wait, multi-session independence).
123
+
124
+ **Total test count: 375 pass, 0 fail** (was 273 before this release).
125
+
126
+ **Benchmarks**
127
+ - `benchmarks/internal.bench.ts` — 14 in-process micro-benchmarks measuring: JWT sign/verify/decode, Map-based blacklist lookup (77 M ops/s), MetadataCompiler cache-miss vs cache-hit (5× faster on hit), Zod `safeParse` valid/invalid, CacheManager get/set, DIContainer singleton resolution, and full Hono stack dispatch (GET simple, GET with param, POST with Zod body).
128
+ - Results saved to `benchmarks/results/internal-2026-06-25.txt`.
129
+
10
130
  ## [0.4.10] - 2026-05-12
11
131
 
12
132
  ### Fixed
@@ -740,7 +860,10 @@ This release brings powerful performance optimization features to Veloce-TS:
740
860
  - CLI tooling
741
861
  - Testing utilities
742
862
 
743
- [Unreleased]: https://github.com/AlfredoMejia3001/veloce-ts/compare/v0.4.0...HEAD
863
+ [Unreleased]: https://github.com/AlfredoMejia3001/veloce-ts/compare/v1.0.0...HEAD
864
+ [1.0.0]: https://github.com/AlfredoMejia3001/veloce-ts/compare/v0.4.18...v1.0.0
865
+ [0.4.18]: https://github.com/AlfredoMejia3001/veloce-ts/compare/v0.4.10...v0.4.18
866
+ [0.4.10]: https://github.com/AlfredoMejia3001/veloce-ts/compare/v0.4.9...v0.4.10
744
867
  [0.4.0]: https://github.com/AlfredoMejia3001/veloce-ts/compare/v0.3.3...v0.4.0
745
868
  [0.3.3]: https://github.com/AlfredoMejia3001/veloce-ts/releases/tag/v0.3.3
746
869
  [0.3.2]: https://github.com/AlfredoMejia3001/veloce-ts/releases/tag/v0.3.2
package/MIGRATION.md ADDED
@@ -0,0 +1,109 @@
1
+ # Migration Guide
2
+
3
+ ## 0.x → 1.0.0
4
+
5
+ Three breaking changes. All have straightforward fixes.
6
+
7
+ ---
8
+
9
+ ### 1. Replace `FastAPITS` with `Veloce`
10
+
11
+ `FastAPITS` is removed. It was deprecated in v0.4.1.
12
+
13
+ ```typescript
14
+ // Before
15
+ import { FastAPITS } from 'veloce-ts';
16
+ const app = new FastAPITS({ title: 'My API' });
17
+
18
+ // After
19
+ import { Veloce } from 'veloce-ts';
20
+ const app = new Veloce({ title: 'My API' });
21
+ ```
22
+
23
+ `VeloceTS` is also valid if you prefer the full name:
24
+
25
+ ```typescript
26
+ import { VeloceTS } from 'veloce-ts';
27
+ const app = new VeloceTS({ title: 'My API' });
28
+ ```
29
+
30
+ ---
31
+
32
+ ### 2. WebSocketPlugin throws on Node.js at startup
33
+
34
+ Previously `WebSocketPlugin` silently returned HTTP 501 on every upgrade request when running on Node.js. In 1.0.0 it throws at `app.usePlugin()` time.
35
+
36
+ **If you run on Bun or Deno** — no change needed. WebSocket works the same.
37
+
38
+ **If you run on Node.js** — remove `WebSocketPlugin` for now. Node.js WebSocket support is not yet implemented. Either:
39
+
40
+ ```typescript
41
+ // Option A: guard by runtime
42
+ const isBun = typeof Bun !== 'undefined';
43
+ if (isBun) {
44
+ app.usePlugin(new WebSocketPlugin({ ... }));
45
+ }
46
+
47
+ // Option B: remove WebSocket until Node.js support lands
48
+ ```
49
+
50
+ ---
51
+
52
+ ### 3. Remove `@InjectDrizzleRepository` usages
53
+
54
+ The decorator was a no-op stub that logged a warning and did nothing. Remove any imports or usages:
55
+
56
+ ```typescript
57
+ // Remove this — it never worked
58
+ import { InjectDrizzleRepository } from 'veloce-ts';
59
+
60
+ @InjectDrizzleRepository() // remove
61
+ userRepo: UserRepository;
62
+ ```
63
+
64
+ Use constructor injection with `@Depends` instead:
65
+
66
+ ```typescript
67
+ import { Controller, Get, Depends } from 'veloce-ts';
68
+ import { UserRepository } from './user.repository';
69
+
70
+ @Controller('/users')
71
+ class UserController {
72
+ @Get('/')
73
+ async list(@Depends(UserRepository) repo: UserRepository) {
74
+ return repo.findMany();
75
+ }
76
+ }
77
+ ```
78
+
79
+ ---
80
+
81
+ ### New in 1.0.0 — no action required
82
+
83
+ These additions are backwards-compatible:
84
+
85
+ - `OAuthPlugin`, `PermissionPlugin`, `SessionPlugin` now importable directly from `'veloce-ts'` (still also available from `'veloce-ts/auth'`)
86
+ - `registerPrisma(app, prismaClient)` — DI helper for Prisma
87
+ - `registerTypeORM(app, dataSource)` — DI helper for TypeORM
88
+
89
+ ```typescript
90
+ import { registerPrisma, registerTypeORM } from 'veloce-ts';
91
+
92
+ // Prisma
93
+ registerPrisma(app, prisma);
94
+
95
+ // TypeORM
96
+ registerTypeORM(app, dataSource);
97
+ ```
98
+
99
+ ---
100
+
101
+ ### Semver from 1.0.0 onwards
102
+
103
+ Veloce-TS follows [Semantic Versioning](https://semver.org/) from this release:
104
+
105
+ - **Patch** (1.0.x) — bug fixes, no API changes
106
+ - **Minor** (1.x.0) — new features, backwards-compatible
107
+ - **Major** (x.0.0) — breaking changes with migration guide
108
+
109
+ Check [CHANGELOG.md](CHANGELOG.md) before upgrading.
package/README.md CHANGED
@@ -83,6 +83,13 @@ Request tracing
83
83
  - Timeout management
84
84
  - Structured logging
85
85
 
86
+ ### 🛡️ **Battle-tested** (v0.4.18)
87
+ Security & correctness audit
88
+ - 375 tests, 0 failures
89
+ - Auth routes secured (RBAC/Permissions)
90
+ - JWT blacklist O(1) Map lookup
91
+ - In-process benchmarks included
92
+
86
93
  </td>
87
94
  </tr>
88
95
  </table>
@@ -236,7 +243,7 @@ app.listen(3000);
236
243
  <summary><b>WebSocket Support</b></summary>
237
244
 
238
245
  ```typescript
239
- import { WebSocket, OnConnect, OnMessage, OnDisconnect } from 'veloce-ts';
246
+ import { WebSocket, OnConnect, OnMessage, OnDisconnect, WebSocketConnection } from 'veloce-ts';
240
247
  import { z } from 'zod';
241
248
 
242
249
  const MessageSchema = z.object({
@@ -489,11 +496,32 @@ app.usePlugin(new OpenAPIPlugin({
489
496
  docsPath: '/docs',
490
497
  }));
491
498
 
492
- // GraphQL support
499
+ // GraphQL support — pass resolver classes via the resolvers option
500
+ import { Resolver, GQLQuery, GQLMutation, Arg } from 'veloce-ts/graphql';
501
+ import { z } from 'zod';
502
+
503
+ @Resolver('user')
504
+ class UserResolver {
505
+ @GQLQuery('getUser')
506
+ async getUser(@Arg('id', z.string()) id: string) {
507
+ return { id, name: 'Alice' };
508
+ }
509
+
510
+ @GQLMutation('createUser')
511
+ async createUser(@Arg('name', z.string()) name: string) {
512
+ return { id: '1', name };
513
+ }
514
+ }
515
+
493
516
  app.usePlugin(new GraphQLPlugin({
494
517
  path: '/graphql',
495
518
  playground: true,
519
+ resolvers: [UserResolver], // pass all @Resolver classes here
496
520
  }));
521
+
522
+ // Alternatively, register via app.include() before usePlugin():
523
+ // app.include(UserResolver);
524
+ // app.usePlugin(new GraphQLPlugin({ playground: true }));
497
525
  ```
498
526
 
499
527
  ## 🌐 Multi-Runtime Support
@@ -520,7 +548,7 @@ These are **known gaps today** so you can choose Veloce-TS with clear expectatio
520
548
 
521
549
  | Area | Limitation |
522
550
  |------|------------|
523
- | **WebSockets on Node.js** | The built-in WebSocket plugin responds with **501** on Node.js. WebSocket upgrades are supported on **Bun** and **Deno**; Node support is not wired up yet (e.g. no `ws`/HTTP upgrade bridge in core). |
551
+ | **WebSockets on Node.js** | `WebSocketPlugin` throws at startup on Node.js with a clear error message directing you to Bun/Deno. WebSocket upgrades are supported on **Bun** and **Deno** only; Node.js support requires a `ws`/HTTP upgrade bridge not yet implemented. |
524
552
  | **GraphQL** | The GraphQL plugin and decorators are **still maturing**. Treat them as **experimental** for production unless you have validated your use case. |
525
553
  | **ORM integrations** | First-class **Drizzle** helpers exist for the DI container (`registerDrizzle`, `@InjectDB`). **Prisma** and **TypeORM** are **not yet** at the same level of documented, built-in integration—use them directly in your services today. |
526
554
  | **Pre-1.0** | APIs may change between minor versions. Check the [CHANGELOG](CHANGELOG.md) before upgrading. |
@@ -534,6 +562,8 @@ Directional priorities—not a release calendar. Items may ship in a different o
534
562
  3. **CLI scaffolding** — Lightweight **code generation** (e.g. controller + route + test skeleton), similar in spirit to Feathers’ `generate service`, kept maintainable and optional.
535
563
  4. **GraphQL** — Improve stability and docs **after** REST, caching, WebSockets-on-Node, and ORM stories are in better shape (lower priority than the items above).
536
564
 
565
+ **Completed in v0.4.18:** Security audit of auth routes, JWT blacklist correctness, MetadataCompiler cache isolation fix, ORM lazy-loading for optional peer deps, 375-test suite, internal micro-benchmarks.
566
+
537
567
  For the latest shipped changes, see [CHANGELOG](CHANGELOG.md). Discussion and proposals: [GitHub Discussions](https://github.com/AlfredoMejia3001/veloce-ts/discussions).
538
568
 
539
569
  ## 📖 Documentation
@@ -1,3 +1,3 @@
1
- var P=Object.create;var{getPrototypeOf:Q,defineProperty:H,getOwnPropertyNames:K,getOwnPropertyDescriptor:U}=Object,L=Object.prototype.hasOwnProperty;function M(x){return this[x]}var V,W,N=(x,z,A)=>{var D=x!=null&&typeof x==="object";if(D){var B=z?V??=new WeakMap:W??=new WeakMap,C=B.get(x);if(C)return C}A=x!=null?P(Q(x)):{};let E=z||!x||!x.__esModule?H(A,"default",{value:x,enumerable:!0}):A;for(let F of K(x))if(!L.call(E,F))H(E,F,{get:M.bind(x,F),enumerable:!0});if(D)B.set(x,E);return E},X=(x)=>{var z=(J??=new WeakMap).get(x),A;if(z)return z;if(z=H({},"__esModule",{value:!0}),x&&typeof x==="object"||typeof x==="function"){for(var D of K(x))if(!L.call(z,D))H(z,D,{get:M.bind(x,D),enumerable:!(A=U(x,D))||A.enumerable})}return J.set(x,z),z},J,R=(x,z)=>()=>(z||x((z={exports:{}}).exports,z),z.exports);var Y=(x)=>x;function Z(x,z){this[x]=Y.bind(null,z)}var $=(x,z)=>{for(var A in z)H(x,A,{get:z[A],enumerable:!0,configurable:!0,set:Z.bind(z,A)})};var T=(x,z)=>()=>(x&&(z=x(x=0)),z);var y={};$(y,{HonoAdapter:()=>O});module.exports=X(y);class O{hono;name="hono";runtime;constructor(x){this.hono=x;this.runtime=j()}listen(x,z){switch(this.runtime){case"bun":return this.listenBun(x,z);case"deno":return this.listenDeno(x,z);case"node":return this.listenNode(x,z);case"workerd":throw Error("Cloudflare Workers do not support listen(). Deploy using wrangler or export the handler with getHandler().");default:throw Error(`Unsupported runtime: ${this.runtime}. FastAPI-TS supports Bun, Node.js, Deno, and Cloudflare Workers.`)}}getHandler(){return this.hono.fetch}getRuntime(){return this.runtime}listenBun(x,z){let A=this.hono,D=Bun.serve({port:x,fetch(B,C){return A.fetch(B,{server:C,upgrade:C.upgrade.bind(C)})},websocket:{open(B){let{manager:C,metadata:E}=B.data??{};if(!C||!E)return;let F=C.handleConnectionBun(B,E);B.data._connection=F},message(B,C){let{manager:E,metadata:F,_connection:G}=B.data??{};if(!E||!F||!G)return;E.handleMessageBun(C,G,F)},close(B,C,E){let{manager:F,metadata:G,_connection:I}=B.data??{};if(!F||!G||!I)return;F.handleDisconnectBun(I,G)},error(B,C){console.error("[WS] Bun WebSocket error:",C)}}});if(z)z();return{port:x,close:async()=>{D.stop()},...D}}listenDeno(x,z){let A=new AbortController;return Deno.serve({port:x,signal:A.signal,onListen:z},this.hono.fetch),{port:x,close:async()=>{A.abort()}}}listenNode(x,z){try{let{serve:A}=(()=>{throw new Error("Cannot require module "+"@hono/node-server");})(),D=A({fetch:this.hono.fetch,port:x},z);return{port:x,close:async()=>{return new Promise((B)=>{D.close(()=>B())})},...D}}catch(A){throw Error("Node.js adapter requires @hono/node-server package. Install it with: npm install @hono/node-server")}}}var j=()=>{if(typeof Bun<"u")return"bun";if(typeof Deno<"u")return"deno";if(typeof navigator<"u"&&navigator.userAgent==="Cloudflare-Workers")return"workerd";if(typeof process<"u"&&process.versions&&process.versions.node)return"node";return"unknown"};f();
1
+ var P=Object.create;var{getPrototypeOf:Q,defineProperty:H,getOwnPropertyNames:K,getOwnPropertyDescriptor:U}=Object,L=Object.prototype.hasOwnProperty;function M(x){return this[x]}var V,W,N=(x,z,A)=>{var D=x!=null&&typeof x==="object";if(D){var B=z?V??=new WeakMap:W??=new WeakMap,C=B.get(x);if(C)return C}A=x!=null?P(Q(x)):{};let E=z||!x||!x.__esModule?H(A,"default",{value:x,enumerable:!0}):A;for(let F of K(x))if(!L.call(E,F))H(E,F,{get:M.bind(x,F),enumerable:!0});if(D)B.set(x,E);return E},X=(x)=>{var z=(J??=new WeakMap).get(x),A;if(z)return z;if(z=H({},"__esModule",{value:!0}),x&&typeof x==="object"||typeof x==="function"){for(var D of K(x))if(!L.call(z,D))H(z,D,{get:M.bind(x,D),enumerable:!(A=U(x,D))||A.enumerable})}return J.set(x,z),z},J,R=(x,z)=>()=>(z||x((z={exports:{}}).exports,z),z.exports);var Y=(x)=>x;function Z(x,z){this[x]=Y.bind(null,z)}var $=(x,z)=>{for(var A in z)H(x,A,{get:z[A],enumerable:!0,configurable:!0,set:Z.bind(z,A)})};var T=(x,z)=>()=>(x&&(z=x(x=0)),z);var y={};$(y,{HonoAdapter:()=>O});module.exports=X(y);class O{hono;name="hono";runtime;constructor(x){this.hono=x;this.runtime=j()}listen(x,z){switch(this.runtime){case"bun":return this.listenBun(x,z);case"deno":return this.listenDeno(x,z);case"node":return this.listenNode(x,z);case"workerd":throw Error("Cloudflare Workers do not support listen(). Deploy using wrangler or export the handler with getHandler().");default:throw Error(`Unsupported runtime: ${this.runtime}. Veloce-TS supports Bun, Node.js, Deno, and Cloudflare Workers.`)}}getHandler(){return this.hono.fetch}getRuntime(){return this.runtime}listenBun(x,z){let A=this.hono,D=Bun.serve({port:x,fetch(B,C){return A.fetch(B,{server:C,upgrade:C.upgrade.bind(C)})},websocket:{open(B){let{manager:C,metadata:E}=B.data??{};if(!C||!E)return;let F=C.handleConnectionBun(B,E);B.data._connection=F},message(B,C){let{manager:E,metadata:F,_connection:G}=B.data??{};if(!E||!F||!G)return;E.handleMessageBun(C,G,F)},close(B,C,E){let{manager:F,metadata:G,_connection:I}=B.data??{};if(!F||!G||!I)return;F.handleDisconnectBun(I,G)},error(B,C){console.error("[WS] Bun WebSocket error:",C)}}});if(z)z();return{port:x,close:async()=>{D.stop()},...D}}listenDeno(x,z){let A=new AbortController;return Deno.serve({port:x,signal:A.signal,onListen:z},this.hono.fetch),{port:x,close:async()=>{A.abort()}}}listenNode(x,z){try{let{serve:A}=(()=>{throw new Error("Cannot require module "+"@hono/node-server");})(),D=A({fetch:this.hono.fetch,port:x},z);return{port:x,close:async()=>{return new Promise((B)=>{D.close(()=>B())})},...D}}catch(A){throw Error("Node.js adapter requires @hono/node-server package. Install it with: npm install @hono/node-server")}}}var j=()=>{if(typeof Bun<"u")return"bun";if(typeof Deno<"u")return"deno";if(typeof navigator<"u"&&navigator.userAgent==="Cloudflare-Workers")return"workerd";if(typeof process<"u"&&process.versions&&process.versions.node)return"node";return"unknown"};f();
2
2
 
3
- //# debugId=8E5D9DB50BF1ED1264756E2164756E21
3
+ //# debugId=17A66C4D10DC90CF64756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["..\\..\\src\\adapters\\hono.ts"],
4
4
  "sourcesContent": [
5
- "/**\r\n * @module veloce-ts/adapters/hono\r\n * @description {@link HonoAdapter}: detecta runtime (Bun/Node/Deno/Workers) y expone `listen` sobre la instancia Hono.\r\n */\r\nimport type { Hono } from 'hono';\r\nimport type { Adapter, ServerInstance } from './base';\r\n\r\n// Type declarations for runtime globals\r\ndeclare const Deno: any;\r\ndeclare const Bun: any;\r\n\r\n/**\r\n * Runtime detection utilities\r\n */\r\nconst detectRuntime = (): 'bun' | 'deno' | 'node' | 'workerd' | 'unknown' => {\r\n // Check for Bun\r\n if (typeof Bun !== 'undefined') {\r\n return 'bun';\r\n }\r\n\r\n // Check for Deno\r\n if (typeof Deno !== 'undefined') {\r\n return 'deno';\r\n }\r\n\r\n // Check for Cloudflare Workers\r\n if (typeof navigator !== 'undefined' && navigator.userAgent === 'Cloudflare-Workers') {\r\n return 'workerd';\r\n }\r\n\r\n // Check for Node.js\r\n if (typeof process !== 'undefined' && process.versions && process.versions.node) {\r\n return 'node';\r\n }\r\n\r\n return 'unknown';\r\n};\r\n\r\n/**\r\n * HonoAdapter - Adapts Hono.js to work across multiple runtimes\r\n * Automatically detects the runtime and uses the appropriate server implementation\r\n */\r\nexport class HonoAdapter implements Adapter {\r\n name = 'hono';\r\n private runtime: ReturnType<typeof detectRuntime>;\r\n\r\n constructor(private hono: Hono) {\r\n this.runtime = detectRuntime();\r\n }\r\n\r\n /**\r\n * Start the server on the specified port\r\n * Automatically uses the appropriate server for the detected runtime\r\n */\r\n listen(port: number, callback?: () => void): ServerInstance {\r\n switch (this.runtime) {\r\n case 'bun':\r\n return this.listenBun(port, callback);\r\n \r\n case 'deno':\r\n return this.listenDeno(port, callback);\r\n \r\n case 'node':\r\n return this.listenNode(port, callback);\r\n \r\n case 'workerd':\r\n throw new Error(\r\n 'Cloudflare Workers do not support listen(). Deploy using wrangler or export the handler with getHandler().'\r\n );\r\n \r\n default:\r\n throw new Error(\r\n `Unsupported runtime: ${this.runtime}. FastAPI-TS supports Bun, Node.js, Deno, and Cloudflare Workers.`\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Get the Hono fetch handler\r\n * This can be used directly in serverless environments or for custom server setups\r\n */\r\n getHandler() {\r\n return this.hono.fetch;\r\n }\r\n\r\n /**\r\n * Get the detected runtime\r\n */\r\n getRuntime(): string {\r\n return this.runtime;\r\n }\r\n\r\n /**\r\n * Start server using Bun's native server\r\n * Passes the Bun server instance as `env` to Hono so WebSocketPlugin\r\n * can call server.upgrade() from within route handlers.\r\n */\r\n private listenBun(port: number, callback?: () => void): ServerInstance {\r\n const hono = this.hono;\r\n const server = Bun.serve({\r\n port,\r\n fetch(req: Request, bunServer: any) {\r\n // Pass the Bun server as `env` so c.env.upgrade() works in handlers,\r\n // and expose the server itself so `getConnInfo` (hono/bun) can read the\r\n // trusted peer IP — needed for IP-based rate limiting that must not\r\n // trust client-supplied X-Forwarded-For headers.\r\n return hono.fetch(req, { server: bunServer, upgrade: bunServer.upgrade.bind(bunServer) });\r\n },\r\n websocket: {\r\n open(ws: any) {\r\n const { manager, metadata } = ws.data ?? {};\r\n if (!manager || !metadata) return;\r\n const connection = manager.handleConnectionBun(ws, metadata);\r\n ws.data._connection = connection;\r\n },\r\n message(ws: any, message: string | Buffer) {\r\n const { manager, metadata, _connection } = ws.data ?? {};\r\n if (!manager || !metadata || !_connection) return;\r\n manager.handleMessageBun(message, _connection, metadata);\r\n },\r\n close(ws: any, code: number, reason: string) {\r\n const { manager, metadata, _connection } = ws.data ?? {};\r\n if (!manager || !metadata || !_connection) return;\r\n manager.handleDisconnectBun(_connection, metadata);\r\n },\r\n error(ws: any, error: Error) {\r\n console.error('[WS] Bun WebSocket error:', error);\r\n },\r\n },\r\n });\r\n\r\n if (callback) {\r\n callback();\r\n }\r\n\r\n return {\r\n port,\r\n close: async () => {\r\n server.stop();\r\n },\r\n ...server\r\n };\r\n }\r\n\r\n /**\r\n * Start server using Deno's native server\r\n */\r\n private listenDeno(port: number, callback?: () => void): ServerInstance {\r\n // Deno.serve returns a promise, so we handle it appropriately\r\n const ac = new AbortController();\r\n \r\n Deno.serve(\r\n {\r\n port,\r\n signal: ac.signal,\r\n onListen: callback\r\n },\r\n this.hono.fetch\r\n );\r\n\r\n // Return an object with a close method for consistency\r\n return {\r\n port,\r\n close: async () => {\r\n ac.abort();\r\n },\r\n };\r\n }\r\n\r\n /**\r\n * Start server using Node.js adapter\r\n * Requires @hono/node-server package\r\n */\r\n private listenNode(port: number, callback?: () => void): ServerInstance {\r\n try {\r\n // Dynamically import @hono/node-server\r\n // This is a peer dependency that users need to install for Node.js support\r\n const { serve } = require('@hono/node-server');\r\n \r\n const server = serve(\r\n {\r\n fetch: this.hono.fetch,\r\n port,\r\n },\r\n callback\r\n );\r\n\r\n return {\r\n port,\r\n close: async () => {\r\n return new Promise<void>((resolve) => {\r\n server.close(() => resolve());\r\n });\r\n },\r\n ...server\r\n };\r\n } catch (error) {\r\n throw new Error(\r\n 'Node.js adapter requires @hono/node-server package. Install it with: npm install @hono/node-server'\r\n );\r\n }\r\n }\r\n}\r\n"
5
+ "/**\r\n * @module veloce-ts/adapters/hono\r\n * @description {@link HonoAdapter}: detecta runtime (Bun/Node/Deno/Workers) y expone `listen` sobre la instancia Hono.\r\n */\r\nimport type { Hono } from 'hono';\r\nimport type { Adapter, ServerInstance } from './base';\r\n\r\n// Type declarations for runtime globals\r\ndeclare const Deno: any;\r\ndeclare const Bun: any;\r\n\r\n/**\r\n * Runtime detection utilities\r\n */\r\nconst detectRuntime = (): 'bun' | 'deno' | 'node' | 'workerd' | 'unknown' => {\r\n // Check for Bun\r\n if (typeof Bun !== 'undefined') {\r\n return 'bun';\r\n }\r\n\r\n // Check for Deno\r\n if (typeof Deno !== 'undefined') {\r\n return 'deno';\r\n }\r\n\r\n // Check for Cloudflare Workers\r\n if (typeof navigator !== 'undefined' && navigator.userAgent === 'Cloudflare-Workers') {\r\n return 'workerd';\r\n }\r\n\r\n // Check for Node.js\r\n if (typeof process !== 'undefined' && process.versions && process.versions.node) {\r\n return 'node';\r\n }\r\n\r\n return 'unknown';\r\n};\r\n\r\n/**\r\n * HonoAdapter - Adapts Hono.js to work across multiple runtimes\r\n * Automatically detects the runtime and uses the appropriate server implementation\r\n */\r\nexport class HonoAdapter implements Adapter {\r\n name = 'hono';\r\n private runtime: ReturnType<typeof detectRuntime>;\r\n\r\n constructor(private hono: Hono) {\r\n this.runtime = detectRuntime();\r\n }\r\n\r\n /**\r\n * Start the server on the specified port\r\n * Automatically uses the appropriate server for the detected runtime\r\n */\r\n listen(port: number, callback?: () => void): ServerInstance {\r\n switch (this.runtime) {\r\n case 'bun':\r\n return this.listenBun(port, callback);\r\n \r\n case 'deno':\r\n return this.listenDeno(port, callback);\r\n \r\n case 'node':\r\n return this.listenNode(port, callback);\r\n \r\n case 'workerd':\r\n throw new Error(\r\n 'Cloudflare Workers do not support listen(). Deploy using wrangler or export the handler with getHandler().'\r\n );\r\n \r\n default:\r\n throw new Error(\r\n `Unsupported runtime: ${this.runtime}. Veloce-TS supports Bun, Node.js, Deno, and Cloudflare Workers.`\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Get the Hono fetch handler\r\n * This can be used directly in serverless environments or for custom server setups\r\n */\r\n getHandler() {\r\n return this.hono.fetch;\r\n }\r\n\r\n /**\r\n * Get the detected runtime\r\n */\r\n getRuntime(): string {\r\n return this.runtime;\r\n }\r\n\r\n /**\r\n * Start server using Bun's native server\r\n * Passes the Bun server instance as `env` to Hono so WebSocketPlugin\r\n * can call server.upgrade() from within route handlers.\r\n */\r\n private listenBun(port: number, callback?: () => void): ServerInstance {\r\n const hono = this.hono;\r\n const server = Bun.serve({\r\n port,\r\n fetch(req: Request, bunServer: any) {\r\n // Pass the Bun server as `env` so c.env.upgrade() works in handlers,\r\n // and expose the server itself so `getConnInfo` (hono/bun) can read the\r\n // trusted peer IP — needed for IP-based rate limiting that must not\r\n // trust client-supplied X-Forwarded-For headers.\r\n return hono.fetch(req, { server: bunServer, upgrade: bunServer.upgrade.bind(bunServer) });\r\n },\r\n websocket: {\r\n open(ws: any) {\r\n const { manager, metadata } = ws.data ?? {};\r\n if (!manager || !metadata) return;\r\n const connection = manager.handleConnectionBun(ws, metadata);\r\n ws.data._connection = connection;\r\n },\r\n message(ws: any, message: string | Buffer) {\r\n const { manager, metadata, _connection } = ws.data ?? {};\r\n if (!manager || !metadata || !_connection) return;\r\n manager.handleMessageBun(message, _connection, metadata);\r\n },\r\n close(ws: any, code: number, reason: string) {\r\n const { manager, metadata, _connection } = ws.data ?? {};\r\n if (!manager || !metadata || !_connection) return;\r\n manager.handleDisconnectBun(_connection, metadata);\r\n },\r\n error(ws: any, error: Error) {\r\n console.error('[WS] Bun WebSocket error:', error);\r\n },\r\n },\r\n });\r\n\r\n if (callback) {\r\n callback();\r\n }\r\n\r\n return {\r\n port,\r\n close: async () => {\r\n server.stop();\r\n },\r\n ...server\r\n };\r\n }\r\n\r\n /**\r\n * Start server using Deno's native server\r\n */\r\n private listenDeno(port: number, callback?: () => void): ServerInstance {\r\n // Deno.serve returns a promise, so we handle it appropriately\r\n const ac = new AbortController();\r\n \r\n Deno.serve(\r\n {\r\n port,\r\n signal: ac.signal,\r\n onListen: callback\r\n },\r\n this.hono.fetch\r\n );\r\n\r\n // Return an object with a close method for consistency\r\n return {\r\n port,\r\n close: async () => {\r\n ac.abort();\r\n },\r\n };\r\n }\r\n\r\n /**\r\n * Start server using Node.js adapter\r\n * Requires @hono/node-server package\r\n */\r\n private listenNode(port: number, callback?: () => void): ServerInstance {\r\n try {\r\n // Dynamically import @hono/node-server\r\n // This is a peer dependency that users need to install for Node.js support\r\n const { serve } = require('@hono/node-server');\r\n \r\n const server = serve(\r\n {\r\n fetch: this.hono.fetch,\r\n port,\r\n },\r\n callback\r\n );\r\n\r\n return {\r\n port,\r\n close: async () => {\r\n return new Promise<void>((resolve) => {\r\n server.close(() => resolve());\r\n });\r\n },\r\n ...server\r\n };\r\n } catch (error) {\r\n throw new Error(\r\n 'Node.js adapter requires @hono/node-server package. Install it with: npm install @hono/node-server'\r\n );\r\n }\r\n }\r\n}\r\n"
6
6
  ],
7
- "mappings": "ihCA0CO,MAAM,CAA+B,CAItB,KAHpB,KAAO,OACC,QAER,WAAW,CAAS,EAAY,CAAZ,YAClB,KAAK,QAAU,EAAc,EAO/B,MAAM,CAAC,EAAc,EAAuC,CAC1D,OAAQ,KAAK,aACN,MACH,OAAO,KAAK,UAAU,EAAM,CAAQ,MAEjC,OACH,OAAO,KAAK,WAAW,EAAM,CAAQ,MAElC,OACH,OAAO,KAAK,WAAW,EAAM,CAAQ,MAElC,UACH,MAAU,MACR,4GACF,UAGA,MAAU,MACR,wBAAwB,KAAK,0EAC/B,GAQN,UAAU,EAAG,CACX,OAAO,KAAK,KAAK,MAMnB,UAAU,EAAW,CACnB,OAAO,KAAK,QAQN,SAAS,CAAC,EAAc,EAAuC,CACrE,IAAM,EAAO,KAAK,KACZ,EAAS,IAAI,MAAM,CACvB,OACA,KAAK,CAAC,EAAc,EAAgB,CAKlC,OAAO,EAAK,MAAM,EAAK,CAAE,OAAQ,EAAW,QAAS,EAAU,QAAQ,KAAK,CAAS,CAAE,CAAC,GAE1F,UAAW,CACT,IAAI,CAAC,EAAS,CACZ,IAAQ,UAAS,YAAa,EAAG,MAAQ,CAAC,EAC1C,GAAI,CAAC,GAAW,CAAC,EAAU,OAC3B,IAAM,EAAa,EAAQ,oBAAoB,EAAI,CAAQ,EAC3D,EAAG,KAAK,YAAc,GAExB,OAAO,CAAC,EAAS,EAA0B,CACzC,IAAQ,UAAS,WAAU,eAAgB,EAAG,MAAQ,CAAC,EACvD,GAAI,CAAC,GAAW,CAAC,GAAY,CAAC,EAAa,OAC3C,EAAQ,iBAAiB,EAAS,EAAa,CAAQ,GAEzD,KAAK,CAAC,EAAS,EAAc,EAAgB,CAC3C,IAAQ,UAAS,WAAU,eAAgB,EAAG,MAAQ,CAAC,EACvD,GAAI,CAAC,GAAW,CAAC,GAAY,CAAC,EAAa,OAC3C,EAAQ,oBAAoB,EAAa,CAAQ,GAEnD,KAAK,CAAC,EAAS,EAAc,CAC3B,QAAQ,MAAM,4BAA6B,CAAK,EAEpD,CACF,CAAC,EAED,GAAI,EACF,EAAS,EAGX,MAAO,CACL,OACA,MAAO,SAAY,CACjB,EAAO,KAAK,MAEX,CACL,EAMM,UAAU,CAAC,EAAc,EAAuC,CAEtE,IAAM,EAAK,IAAI,gBAYf,OAVA,KAAK,MACH,CACE,OACA,OAAQ,EAAG,OACX,SAAU,CACZ,EACA,KAAK,KAAK,KACZ,EAGO,CACL,OACA,MAAO,SAAY,CACjB,EAAG,MAAM,EAEb,EAOM,UAAU,CAAC,EAAc,EAAuC,CACtE,GAAI,CAGF,IAAQ,kFAEF,EAAS,EACb,CACE,MAAO,KAAK,KAAK,MACjB,MACF,EACA,CACF,EAEA,MAAO,CACL,OACA,MAAO,SAAY,CACjB,OAAO,IAAI,QAAc,CAAC,IAAY,CACpC,EAAO,MAAM,IAAM,EAAQ,CAAC,EAC7B,MAEA,CACL,EACA,MAAO,EAAO,CACd,MAAU,MACR,oGACF,GAGN,KA5LM,EAAgB,IAAuD,CAE3E,GAAI,OAAO,IAAQ,IACjB,MAAO,MAIT,GAAI,OAAO,KAAS,IAClB,MAAO,OAIT,GAAI,OAAO,UAAc,KAAe,UAAU,YAAc,qBAC9D,MAAO,UAIT,GAAI,OAAO,QAAY,KAAe,QAAQ,UAAY,QAAQ,SAAS,KACzE,MAAO,OAGT,MAAO",
8
- "debugId": "8E5D9DB50BF1ED1264756E2164756E21",
7
+ "mappings": "ihCA0CO,MAAM,CAA+B,CAItB,KAHpB,KAAO,OACC,QAER,WAAW,CAAS,EAAY,CAAZ,YAClB,KAAK,QAAU,EAAc,EAO/B,MAAM,CAAC,EAAc,EAAuC,CAC1D,OAAQ,KAAK,aACN,MACH,OAAO,KAAK,UAAU,EAAM,CAAQ,MAEjC,OACH,OAAO,KAAK,WAAW,EAAM,CAAQ,MAElC,OACH,OAAO,KAAK,WAAW,EAAM,CAAQ,MAElC,UACH,MAAU,MACR,4GACF,UAGA,MAAU,MACR,wBAAwB,KAAK,yEAC/B,GAQN,UAAU,EAAG,CACX,OAAO,KAAK,KAAK,MAMnB,UAAU,EAAW,CACnB,OAAO,KAAK,QAQN,SAAS,CAAC,EAAc,EAAuC,CACrE,IAAM,EAAO,KAAK,KACZ,EAAS,IAAI,MAAM,CACvB,OACA,KAAK,CAAC,EAAc,EAAgB,CAKlC,OAAO,EAAK,MAAM,EAAK,CAAE,OAAQ,EAAW,QAAS,EAAU,QAAQ,KAAK,CAAS,CAAE,CAAC,GAE1F,UAAW,CACT,IAAI,CAAC,EAAS,CACZ,IAAQ,UAAS,YAAa,EAAG,MAAQ,CAAC,EAC1C,GAAI,CAAC,GAAW,CAAC,EAAU,OAC3B,IAAM,EAAa,EAAQ,oBAAoB,EAAI,CAAQ,EAC3D,EAAG,KAAK,YAAc,GAExB,OAAO,CAAC,EAAS,EAA0B,CACzC,IAAQ,UAAS,WAAU,eAAgB,EAAG,MAAQ,CAAC,EACvD,GAAI,CAAC,GAAW,CAAC,GAAY,CAAC,EAAa,OAC3C,EAAQ,iBAAiB,EAAS,EAAa,CAAQ,GAEzD,KAAK,CAAC,EAAS,EAAc,EAAgB,CAC3C,IAAQ,UAAS,WAAU,eAAgB,EAAG,MAAQ,CAAC,EACvD,GAAI,CAAC,GAAW,CAAC,GAAY,CAAC,EAAa,OAC3C,EAAQ,oBAAoB,EAAa,CAAQ,GAEnD,KAAK,CAAC,EAAS,EAAc,CAC3B,QAAQ,MAAM,4BAA6B,CAAK,EAEpD,CACF,CAAC,EAED,GAAI,EACF,EAAS,EAGX,MAAO,CACL,OACA,MAAO,SAAY,CACjB,EAAO,KAAK,MAEX,CACL,EAMM,UAAU,CAAC,EAAc,EAAuC,CAEtE,IAAM,EAAK,IAAI,gBAYf,OAVA,KAAK,MACH,CACE,OACA,OAAQ,EAAG,OACX,SAAU,CACZ,EACA,KAAK,KAAK,KACZ,EAGO,CACL,OACA,MAAO,SAAY,CACjB,EAAG,MAAM,EAEb,EAOM,UAAU,CAAC,EAAc,EAAuC,CACtE,GAAI,CAGF,IAAQ,kFAEF,EAAS,EACb,CACE,MAAO,KAAK,KAAK,MACjB,MACF,EACA,CACF,EAEA,MAAO,CACL,OACA,MAAO,SAAY,CACjB,OAAO,IAAI,QAAc,CAAC,IAAY,CACpC,EAAO,MAAM,IAAM,EAAQ,CAAC,EAC7B,MAEA,CACL,EACA,MAAO,EAAO,CACd,MAAU,MACR,oGACF,GAGN,KA5LM,EAAgB,IAAuD,CAE3E,GAAI,OAAO,IAAQ,IACjB,MAAO,MAIT,GAAI,OAAO,KAAS,IAClB,MAAO,OAIT,GAAI,OAAO,UAAc,KAAe,UAAU,YAAc,qBAC9D,MAAO,UAIT,GAAI,OAAO,QAAY,KAAe,QAAQ,UAAY,QAAQ,SAAS,KACzE,MAAO,OAGT,MAAO",
8
+ "debugId": "17A66C4D10DC90CF64756E2164756E21",
9
9
  "names": []
10
10
  }