alepha 0.14.2 → 0.14.4
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/README.md +1 -1
- package/dist/api/audits/index.browser.js +5 -5
- package/dist/api/audits/index.browser.js.map +1 -1
- package/dist/api/audits/index.d.ts +706 -785
- package/dist/api/audits/index.d.ts.map +1 -1
- package/dist/api/audits/index.js +13 -13
- package/dist/api/audits/index.js.map +1 -1
- package/dist/api/files/index.browser.js +5 -5
- package/dist/api/files/index.browser.js.map +1 -1
- package/dist/api/files/index.d.ts +58 -137
- package/dist/api/files/index.d.ts.map +1 -1
- package/dist/api/files/index.js +71 -71
- package/dist/api/files/index.js.map +1 -1
- package/dist/api/jobs/index.browser.js +5 -5
- package/dist/api/jobs/index.browser.js.map +1 -1
- package/dist/api/jobs/index.d.ts +29 -108
- package/dist/api/jobs/index.d.ts.map +1 -1
- package/dist/api/jobs/index.js +10 -10
- package/dist/api/jobs/index.js.map +1 -1
- package/dist/api/notifications/index.browser.js +10 -10
- package/dist/api/notifications/index.browser.js.map +1 -1
- package/dist/api/notifications/index.d.ts +504 -171
- package/dist/api/notifications/index.d.ts.map +1 -1
- package/dist/api/notifications/index.js +12 -12
- package/dist/api/notifications/index.js.map +1 -1
- package/dist/api/parameters/index.browser.js +163 -10
- package/dist/api/parameters/index.browser.js.map +1 -1
- package/dist/api/parameters/index.d.ts +277 -351
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/parameters/index.js +196 -91
- package/dist/api/parameters/index.js.map +1 -1
- package/dist/api/users/index.browser.js +19 -19
- package/dist/api/users/index.browser.js.map +1 -1
- package/dist/api/users/index.d.ts +787 -852
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +827 -596
- package/dist/api/users/index.js.map +1 -1
- package/dist/api/verifications/index.browser.js +6 -6
- package/dist/api/verifications/index.browser.js.map +1 -1
- package/dist/api/verifications/index.d.ts +128 -128
- package/dist/api/verifications/index.d.ts.map +1 -1
- package/dist/api/verifications/index.js +6 -6
- package/dist/api/verifications/index.js.map +1 -1
- package/dist/bin/index.d.ts +1 -2
- package/dist/bin/index.js +0 -1
- package/dist/bin/index.js.map +1 -1
- package/dist/cli/index.d.ts +252 -131
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +595 -395
- package/dist/cli/index.js.map +1 -1
- package/dist/command/index.d.ts +46 -11
- package/dist/command/index.d.ts.map +1 -1
- package/dist/command/index.js +99 -19
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js +40 -22
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +45 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +40 -22
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +40 -22
- package/dist/core/index.native.js.map +1 -1
- package/dist/fake/index.js +195 -168
- package/dist/fake/index.js.map +1 -1
- package/dist/file/index.d.ts +8 -0
- package/dist/file/index.d.ts.map +1 -1
- package/dist/file/index.js +3 -0
- package/dist/file/index.js.map +1 -1
- package/dist/logger/index.d.ts +1 -1
- package/dist/logger/index.d.ts.map +1 -1
- package/dist/logger/index.js +12 -2
- package/dist/logger/index.js.map +1 -1
- package/dist/mcp/index.js +1 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/orm/index.d.ts +59 -195
- package/dist/orm/index.d.ts.map +1 -1
- package/dist/orm/index.js +201 -430
- package/dist/orm/index.js.map +1 -1
- package/dist/security/index.d.ts +1 -1
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +1 -1
- package/dist/security/index.js.map +1 -1
- package/dist/server/auth/index.d.ts +171 -155
- package/dist/server/auth/index.d.ts.map +1 -1
- package/dist/server/auth/index.js +0 -1
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/cache/index.d.ts +12 -0
- package/dist/server/cache/index.d.ts.map +1 -1
- package/dist/server/cache/index.js +55 -2
- package/dist/server/cache/index.js.map +1 -1
- package/dist/server/compress/index.d.ts +6 -0
- package/dist/server/compress/index.d.ts.map +1 -1
- package/dist/server/compress/index.js +38 -1
- package/dist/server/compress/index.js.map +1 -1
- package/dist/server/core/index.browser.js +2 -2
- package/dist/server/core/index.browser.js.map +1 -1
- package/dist/server/core/index.d.ts +10 -10
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js +7 -4
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/links/index.browser.js +22 -6
- package/dist/server/links/index.browser.js.map +1 -1
- package/dist/server/links/index.d.ts +46 -44
- package/dist/server/links/index.d.ts.map +1 -1
- package/dist/server/links/index.js +24 -41
- package/dist/server/links/index.js.map +1 -1
- package/dist/server/static/index.d.ts.map +1 -1
- package/dist/server/static/index.js +4 -0
- package/dist/server/static/index.js.map +1 -1
- package/dist/server/swagger/index.d.ts +2 -1
- package/dist/server/swagger/index.d.ts.map +1 -1
- package/dist/server/swagger/index.js +9 -5
- package/dist/server/swagger/index.js.map +1 -1
- package/dist/vite/index.d.ts +101 -106
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +574 -503
- package/dist/vite/index.js.map +1 -1
- package/dist/websocket/index.d.ts +7 -7
- package/package.json +7 -7
- package/src/api/audits/controllers/{AuditController.ts → AdminAuditController.ts} +5 -6
- package/src/api/audits/entities/audits.ts +5 -5
- package/src/api/audits/index.browser.ts +1 -1
- package/src/api/audits/index.ts +3 -3
- package/src/api/audits/primitives/$audit.spec.ts +276 -0
- package/src/api/audits/services/AuditService.spec.ts +495 -0
- package/src/api/files/__tests__/$bucket.spec.ts +91 -0
- package/src/api/files/controllers/AdminFileStatsController.spec.ts +166 -0
- package/src/api/files/controllers/{StorageStatsController.ts → AdminFileStatsController.ts} +2 -2
- package/src/api/files/controllers/FileController.spec.ts +558 -0
- package/src/api/files/controllers/FileController.ts +4 -5
- package/src/api/files/entities/files.ts +5 -5
- package/src/api/files/index.browser.ts +1 -1
- package/src/api/files/index.ts +4 -4
- package/src/api/files/jobs/FileJobs.spec.ts +52 -0
- package/src/api/files/services/FileService.spec.ts +109 -0
- package/src/api/jobs/__tests__/JobController.spec.ts +343 -0
- package/src/api/jobs/controllers/{JobController.ts → AdminJobController.ts} +2 -2
- package/src/api/jobs/entities/jobExecutions.ts +5 -5
- package/src/api/jobs/index.ts +3 -3
- package/src/api/jobs/primitives/$job.spec.ts +476 -0
- package/src/api/notifications/controllers/{NotificationController.ts → AdminNotificationController.ts} +4 -5
- package/src/api/notifications/entities/notifications.ts +5 -5
- package/src/api/notifications/index.browser.ts +1 -1
- package/src/api/notifications/index.ts +4 -4
- package/src/api/parameters/controllers/{ConfigController.ts → AdminConfigController.ts} +46 -107
- package/src/api/parameters/entities/parameters.ts +7 -17
- package/src/api/parameters/index.ts +3 -3
- package/src/api/parameters/primitives/$config.spec.ts +356 -0
- package/src/api/parameters/schemas/activateConfigBodySchema.ts +12 -0
- package/src/api/parameters/schemas/checkScheduledResponseSchema.ts +8 -0
- package/src/api/parameters/schemas/configCurrentResponseSchema.ts +13 -0
- package/src/api/parameters/schemas/configHistoryResponseSchema.ts +9 -0
- package/src/api/parameters/schemas/configNameParamSchema.ts +10 -0
- package/src/api/parameters/schemas/configNamesResponseSchema.ts +8 -0
- package/src/api/parameters/schemas/configTreeNodeSchema.ts +13 -0
- package/src/api/parameters/schemas/configVersionParamSchema.ts +9 -0
- package/src/api/parameters/schemas/configVersionResponseSchema.ts +9 -0
- package/src/api/parameters/schemas/configsByStatusResponseSchema.ts +9 -0
- package/src/api/parameters/schemas/createConfigVersionBodySchema.ts +24 -0
- package/src/api/parameters/schemas/index.ts +15 -0
- package/src/api/parameters/schemas/parameterResponseSchema.ts +26 -0
- package/src/api/parameters/schemas/parameterStatusSchema.ts +13 -0
- package/src/api/parameters/schemas/rollbackConfigBodySchema.ts +15 -0
- package/src/api/parameters/schemas/statusParamSchema.ts +9 -0
- package/src/api/users/__tests__/EmailVerification.spec.ts +369 -0
- package/src/api/users/__tests__/PasswordReset.spec.ts +550 -0
- package/src/api/users/controllers/AdminIdentityController.spec.ts +365 -0
- package/src/api/users/controllers/{IdentityController.ts → AdminIdentityController.ts} +3 -4
- package/src/api/users/controllers/AdminSessionController.spec.ts +274 -0
- package/src/api/users/controllers/{SessionController.ts → AdminSessionController.ts} +3 -4
- package/src/api/users/controllers/AdminUserController.spec.ts +372 -0
- package/src/api/users/controllers/AdminUserController.ts +116 -0
- package/src/api/users/controllers/UserController.ts +4 -107
- package/src/api/users/controllers/UserRealmController.ts +3 -0
- package/src/api/users/entities/identities.ts +6 -6
- package/src/api/users/entities/sessions.ts +6 -6
- package/src/api/users/entities/users.ts +9 -9
- package/src/api/users/index.ts +9 -6
- package/src/api/users/primitives/$userRealm.ts +13 -8
- package/src/api/users/services/CredentialService.spec.ts +509 -0
- package/src/api/users/services/CredentialService.ts +46 -0
- package/src/api/users/services/IdentityService.ts +15 -0
- package/src/api/users/services/RegistrationService.spec.ts +630 -0
- package/src/api/users/services/RegistrationService.ts +18 -0
- package/src/api/users/services/SessionService.spec.ts +301 -0
- package/src/api/users/services/SessionService.ts +110 -1
- package/src/api/users/services/UserService.ts +67 -2
- package/src/api/verifications/__tests__/CodeVerification.spec.ts +318 -0
- package/src/api/verifications/__tests__/LinkVerification.spec.ts +279 -0
- package/src/api/verifications/entities/verifications.ts +6 -6
- package/src/api/verifications/jobs/VerificationJobs.spec.ts +50 -0
- package/src/batch/__tests__/startup-buffering.spec.ts +458 -0
- package/src/batch/primitives/$batch.spec.ts +766 -0
- package/src/batch/providers/BatchProvider.spec.ts +786 -0
- package/src/bin/index.ts +0 -1
- package/src/bucket/__tests__/shared.ts +194 -0
- package/src/bucket/primitives/$bucket.spec.ts +104 -0
- package/src/bucket/providers/FileStorageProvider.spec.ts +13 -0
- package/src/bucket/providers/LocalFileStorageProvider.spec.ts +77 -0
- package/src/bucket/providers/MemoryFileStorageProvider.spec.ts +82 -0
- package/src/cache/core/__tests__/shared.ts +377 -0
- package/src/cache/core/primitives/$cache.spec.ts +111 -0
- package/src/cache/redis/__tests__/cache-redis.spec.ts +70 -0
- package/src/cli/apps/AlephaCli.ts +25 -6
- package/src/cli/atoms/buildOptions.ts +88 -0
- package/src/cli/commands/build.ts +32 -69
- package/src/cli/commands/db.ts +0 -4
- package/src/cli/commands/dev.ts +34 -10
- package/src/cli/commands/gen/changelog.spec.ts +315 -0
- package/src/cli/commands/{changelog.ts → gen/changelog.ts} +9 -9
- package/src/cli/commands/gen/env.ts +53 -0
- package/src/cli/commands/gen/openapi.ts +71 -0
- package/src/cli/commands/gen/resource.ts +15 -0
- package/src/cli/commands/gen.ts +24 -0
- package/src/cli/commands/init.ts +2 -1
- package/src/cli/commands/root.ts +12 -3
- package/src/cli/commands/test.ts +0 -1
- package/src/cli/commands/typecheck.ts +5 -0
- package/src/cli/commands/verify.ts +1 -1
- package/src/cli/defineConfig.ts +49 -7
- package/src/cli/index.ts +2 -2
- package/src/cli/services/AlephaCliUtils.ts +105 -55
- package/src/cli/services/GitMessageParser.ts +1 -1
- package/src/command/helpers/Asker.spec.ts +127 -0
- package/src/command/helpers/Runner.spec.ts +126 -0
- package/src/command/helpers/Runner.ts +1 -1
- package/src/command/primitives/$command.spec.ts +1588 -0
- package/src/command/primitives/$command.ts +0 -6
- package/src/command/providers/CliProvider.ts +75 -27
- package/src/core/Alepha.ts +87 -0
- package/src/core/__tests__/Alepha-emit.spec.ts +22 -0
- package/src/core/__tests__/Alepha-graph.spec.ts +93 -0
- package/src/core/__tests__/Alepha-has.spec.ts +41 -0
- package/src/core/__tests__/Alepha-inject.spec.ts +93 -0
- package/src/core/__tests__/Alepha-register.spec.ts +81 -0
- package/src/core/__tests__/Alepha-start.spec.ts +176 -0
- package/src/core/__tests__/Alepha-with.spec.ts +14 -0
- package/src/core/__tests__/TypeBox-usecases.spec.ts +35 -0
- package/src/core/__tests__/TypeBoxLocale.spec.ts +15 -0
- package/src/core/__tests__/descriptor.spec.ts +34 -0
- package/src/core/__tests__/fixtures/A.ts +5 -0
- package/src/core/__tests__/pagination.spec.ts +77 -0
- package/src/core/helpers/jsonSchemaToTypeBox.ts +2 -2
- package/src/core/primitives/$atom.spec.ts +43 -0
- package/src/core/primitives/$hook.spec.ts +130 -0
- package/src/core/primitives/$inject.spec.ts +175 -0
- package/src/core/primitives/$module.spec.ts +115 -0
- package/src/core/providers/CodecManager.spec.ts +740 -0
- package/src/core/providers/EventManager.spec.ts +762 -0
- package/src/core/providers/EventManager.ts +4 -0
- package/src/core/providers/StateManager.spec.ts +365 -0
- package/src/core/providers/TypeProvider.spec.ts +1607 -0
- package/src/core/providers/TypeProvider.ts +20 -26
- package/src/datetime/primitives/$interval.spec.ts +103 -0
- package/src/datetime/providers/DateTimeProvider.spec.ts +86 -0
- package/src/email/primitives/$email.spec.ts +175 -0
- package/src/email/providers/LocalEmailProvider.spec.ts +341 -0
- package/src/fake/__tests__/keyName.example.ts +40 -0
- package/src/fake/__tests__/keyName.spec.ts +152 -0
- package/src/fake/__tests__/module.example.ts +32 -0
- package/src/fake/providers/FakeProvider.spec.ts +438 -0
- package/src/file/providers/FileSystemProvider.ts +8 -0
- package/src/file/providers/NodeFileSystemProvider.spec.ts +418 -0
- package/src/file/providers/NodeFileSystemProvider.ts +5 -0
- package/src/file/services/FileDetector.spec.ts +591 -0
- package/src/lock/core/__tests__/shared.ts +190 -0
- package/src/lock/core/providers/MemoryLockProvider.spec.ts +25 -0
- package/src/lock/redis/providers/RedisLockProvider.spec.ts +25 -0
- package/src/logger/__tests__/SimpleFormatterProvider.spec.ts +109 -0
- package/src/logger/index.ts +15 -3
- package/src/logger/primitives/$logger.spec.ts +108 -0
- package/src/logger/services/Logger.spec.ts +295 -0
- package/src/mcp/__tests__/errors.spec.ts +175 -0
- package/src/mcp/__tests__/integration.spec.ts +450 -0
- package/src/mcp/helpers/jsonrpc.spec.ts +380 -0
- package/src/mcp/primitives/$prompt.spec.ts +468 -0
- package/src/mcp/primitives/$resource.spec.ts +390 -0
- package/src/mcp/primitives/$tool.spec.ts +406 -0
- package/src/mcp/providers/McpServerProvider.spec.ts +797 -0
- package/src/mcp/transports/StdioMcpTransport.ts +1 -1
- package/src/orm/__tests__/$repository-crud.spec.ts +276 -0
- package/src/orm/__tests__/$repository-hooks.spec.ts +325 -0
- package/src/orm/__tests__/$repository-orderBy.spec.ts +128 -0
- package/src/orm/__tests__/$repository-pagination-sort.spec.ts +149 -0
- package/src/orm/__tests__/$repository-save.spec.ts +37 -0
- package/src/orm/__tests__/ModelBuilder-integration.spec.ts +490 -0
- package/src/orm/__tests__/ModelBuilder-types.spec.ts +186 -0
- package/src/orm/__tests__/PostgresProvider.spec.ts +46 -0
- package/src/orm/__tests__/delete-returning.spec.ts +256 -0
- package/src/orm/__tests__/deletedAt.spec.ts +80 -0
- package/src/orm/__tests__/enums.spec.ts +315 -0
- package/src/orm/__tests__/execute.spec.ts +72 -0
- package/src/orm/__tests__/fixtures/bigEntitySchema.ts +65 -0
- package/src/orm/__tests__/fixtures/userEntitySchema.ts +27 -0
- package/src/orm/__tests__/joins.spec.ts +1114 -0
- package/src/orm/__tests__/page.spec.ts +287 -0
- package/src/orm/__tests__/primaryKey.spec.ts +87 -0
- package/src/orm/__tests__/query-date-encoding.spec.ts +402 -0
- package/src/orm/__tests__/ref-auto-onDelete.spec.ts +156 -0
- package/src/orm/__tests__/references.spec.ts +102 -0
- package/src/orm/__tests__/security.spec.ts +710 -0
- package/src/orm/__tests__/sqlite.spec.ts +111 -0
- package/src/orm/__tests__/string-operators.spec.ts +429 -0
- package/src/orm/__tests__/timestamps.spec.ts +388 -0
- package/src/orm/__tests__/validation.spec.ts +183 -0
- package/src/orm/__tests__/version.spec.ts +64 -0
- package/src/orm/helpers/parseQueryString.spec.ts +196 -0
- package/src/orm/index.ts +2 -8
- package/src/orm/primitives/$repository.spec.ts +137 -0
- package/src/orm/primitives/$sequence.spec.ts +29 -0
- package/src/orm/primitives/$transaction.spec.ts +82 -0
- package/src/orm/providers/drivers/BunPostgresProvider.ts +3 -3
- package/src/orm/providers/drivers/BunSqliteProvider.ts +1 -1
- package/src/orm/providers/drivers/CloudflareD1Provider.ts +1 -1
- package/src/orm/providers/drivers/DatabaseProvider.ts +1 -1
- package/src/orm/providers/drivers/NodePostgresProvider.ts +3 -3
- package/src/orm/providers/drivers/NodeSqliteProvider.ts +1 -1
- package/src/orm/providers/drivers/PglitePostgresProvider.ts +2 -2
- package/src/orm/services/ModelBuilder.spec.ts +575 -0
- package/src/orm/services/Repository.spec.ts +137 -0
- package/src/queue/core/__tests__/shared.ts +143 -0
- package/src/queue/core/providers/MemoryQueueProvider.spec.ts +23 -0
- package/src/queue/core/providers/WorkerProvider.spec.ts +394 -0
- package/src/queue/redis/providers/RedisQueueProvider.spec.ts +23 -0
- package/src/redis/__tests__/redis.spec.ts +58 -0
- package/src/retry/primitives/$retry.spec.ts +234 -0
- package/src/retry/providers/RetryProvider.spec.ts +438 -0
- package/src/router/__tests__/match.spec.ts +252 -0
- package/src/router/providers/RouterProvider.spec.ts +197 -0
- package/src/scheduler/__tests__/$scheduler-cron.spec.ts +25 -0
- package/src/scheduler/__tests__/$scheduler-interval.spec.ts +25 -0
- package/src/scheduler/__tests__/shared.ts +77 -0
- package/src/security/__tests__/bug-1-wildcard-after-start.spec.ts +229 -0
- package/src/security/__tests__/bug-2-password-validation.spec.ts +245 -0
- package/src/security/__tests__/bug-3-regex-vulnerability.spec.ts +407 -0
- package/src/security/__tests__/bug-4-oauth2-validation.spec.ts +439 -0
- package/src/security/__tests__/multi-layer-permissions.spec.ts +522 -0
- package/src/security/primitives/$permission.spec.ts +30 -0
- package/src/security/primitives/$permission.ts +2 -2
- package/src/security/primitives/$realm.spec.ts +101 -0
- package/src/security/primitives/$role.spec.ts +52 -0
- package/src/security/primitives/$serviceAccount.spec.ts +61 -0
- package/src/security/providers/SecurityProvider.spec.ts +350 -0
- package/src/server/auth/providers/ServerAuthProvider.ts +0 -2
- package/src/server/cache/providers/ServerCacheProvider.spec.ts +1125 -0
- package/src/server/cache/providers/ServerCacheProvider.ts +94 -9
- package/src/server/compress/providers/ServerCompressProvider.spec.ts +31 -0
- package/src/server/compress/providers/ServerCompressProvider.ts +63 -2
- package/src/server/cookies/providers/ServerCookiesProvider.spec.ts +253 -0
- package/src/server/core/__tests__/ServerRouterProvider-getRoutes.spec.ts +334 -0
- package/src/server/core/__tests__/ServerRouterProvider-requestId.spec.ts +129 -0
- package/src/server/core/helpers/ServerReply.ts +2 -2
- package/src/server/core/primitives/$action.spec.ts +191 -0
- package/src/server/core/primitives/$route.spec.ts +65 -0
- package/src/server/core/providers/ServerBodyParserProvider.spec.ts +93 -0
- package/src/server/core/providers/ServerLoggerProvider.spec.ts +100 -0
- package/src/server/core/providers/ServerProvider.ts +14 -2
- package/src/server/core/services/HttpClient.spec.ts +123 -0
- package/src/server/core/services/UserAgentParser.spec.ts +111 -0
- package/src/server/cors/providers/ServerCorsProvider.spec.ts +481 -0
- package/src/server/health/providers/ServerHealthProvider.spec.ts +22 -0
- package/src/server/helmet/providers/ServerHelmetProvider.spec.ts +105 -0
- package/src/server/links/__tests__/$action.spec.ts +238 -0
- package/src/server/links/__tests__/fixtures/CrudApp.ts +122 -0
- package/src/server/links/__tests__/requestId.spec.ts +120 -0
- package/src/server/links/primitives/$remote.spec.ts +228 -0
- package/src/server/links/providers/LinkProvider.spec.ts +54 -0
- package/src/server/links/providers/LinkProvider.ts +49 -3
- package/src/server/links/providers/ServerLinksProvider.ts +1 -53
- package/src/server/links/schemas/apiLinksResponseSchema.ts +7 -0
- package/src/server/metrics/providers/ServerMetricsProvider.spec.ts +25 -0
- package/src/server/multipart/providers/ServerMultipartProvider.spec.ts +528 -0
- package/src/server/proxy/primitives/$proxy.spec.ts +87 -0
- package/src/server/rate-limit/__tests__/ActionRateLimit.spec.ts +211 -0
- package/src/server/rate-limit/providers/ServerRateLimitProvider.spec.ts +344 -0
- package/src/server/security/__tests__/BasicAuth.spec.ts +684 -0
- package/src/server/security/__tests__/ServerSecurityProvider-realm.spec.ts +388 -0
- package/src/server/security/providers/ServerSecurityProvider.spec.ts +123 -0
- package/src/server/static/primitives/$serve.spec.ts +193 -0
- package/src/server/static/providers/ServerStaticProvider.ts +10 -0
- package/src/server/swagger/__tests__/ui.spec.ts +52 -0
- package/src/server/swagger/primitives/$swagger.spec.ts +193 -0
- package/src/server/swagger/providers/ServerSwaggerProvider.ts +19 -12
- package/src/sms/primitives/$sms.spec.ts +165 -0
- package/src/sms/providers/LocalSmsProvider.spec.ts +224 -0
- package/src/sms/providers/MemorySmsProvider.spec.ts +193 -0
- package/src/thread/primitives/$thread.spec.ts +186 -0
- package/src/topic/core/__tests__/shared.ts +144 -0
- package/src/topic/core/providers/MemoryTopicProvider.spec.ts +23 -0
- package/src/topic/redis/providers/RedisTopicProvider.spec.ts +23 -0
- package/src/vite/helpers/importViteReact.ts +13 -0
- package/src/vite/index.ts +1 -21
- package/src/vite/plugins/viteAlephaDev.ts +32 -5
- package/src/vite/plugins/viteAlephaSsrPreload.ts +222 -0
- package/src/vite/tasks/buildClient.ts +11 -0
- package/src/vite/tasks/buildServer.ts +47 -3
- package/src/vite/tasks/devServer.ts +69 -0
- package/src/vite/tasks/index.ts +2 -1
- package/src/vite/tasks/runAlepha.ts +7 -1
- package/src/websocket/__tests__/$websocket-new.spec.ts +195 -0
- package/src/websocket/primitives/$channel.spec.ts +30 -0
- package/src/cli/assets/viteConfigTs.ts +0 -14
- package/src/cli/commands/run.ts +0 -24
- package/src/vite/plugins/viteAlepha.ts +0 -37
- package/src/vite/plugins/viteAlephaBuild.ts +0 -281
|
@@ -0,0 +1,740 @@
|
|
|
1
|
+
import { $inject, Alepha, CodecManager, TypeBoxError, t } from "alepha";
|
|
2
|
+
import type { TSchema } from "typebox";
|
|
3
|
+
import { describe, expect, it } from "vitest";
|
|
4
|
+
import { JsonSchemaCodec } from "../providers/JsonSchemaCodec.ts";
|
|
5
|
+
import { SchemaCodec } from "../providers/SchemaCodec.ts";
|
|
6
|
+
|
|
7
|
+
describe("CodecManager", () => {
|
|
8
|
+
describe("initialization", () => {
|
|
9
|
+
it("should initialize with JSON codec as default", () => {
|
|
10
|
+
const alepha = Alepha.create();
|
|
11
|
+
const codecManager = alepha.codec;
|
|
12
|
+
|
|
13
|
+
expect(codecManager).toBeInstanceOf(CodecManager);
|
|
14
|
+
expect(codecManager.default).toBe("json");
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it("should get JSON codec by default", () => {
|
|
18
|
+
const alepha = Alepha.create();
|
|
19
|
+
const codecManager = alepha.codec;
|
|
20
|
+
const jsonCodec = codecManager.getCodec("json");
|
|
21
|
+
|
|
22
|
+
expect(jsonCodec).toBeInstanceOf(JsonSchemaCodec);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
describe("codec registration", () => {
|
|
27
|
+
it("should register custom codec", () => {
|
|
28
|
+
class CustomCodec extends SchemaCodec {
|
|
29
|
+
public encodeToString(schema: TSchema, value: any): string {
|
|
30
|
+
return `custom:${JSON.stringify(value)}`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
public encodeToBinary(schema: TSchema, value: any): Uint8Array {
|
|
34
|
+
const str = this.encodeToString(schema, value);
|
|
35
|
+
return new TextEncoder().encode(str);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public decode<T>(schema: TSchema, value: unknown): T {
|
|
39
|
+
return value as T;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const alepha = Alepha.create();
|
|
44
|
+
const codecManager = alepha.codec;
|
|
45
|
+
const customCodec = new CustomCodec();
|
|
46
|
+
|
|
47
|
+
codecManager.register("custom", customCodec);
|
|
48
|
+
|
|
49
|
+
const retrieved = codecManager.getCodec("custom");
|
|
50
|
+
expect(retrieved).toBe(customCodec);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("should throw error when codec not found", () => {
|
|
54
|
+
const alepha = Alepha.create();
|
|
55
|
+
const codecManager = alepha.codec;
|
|
56
|
+
|
|
57
|
+
expect(() => codecManager.getCodec("nonexistent")).toThrow(
|
|
58
|
+
'Codec "nonexistent" not found. Available codecs: json',
|
|
59
|
+
);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("should list available codecs in error message", () => {
|
|
63
|
+
class MockCodec extends SchemaCodec {
|
|
64
|
+
public encodeToString(): string {
|
|
65
|
+
return "";
|
|
66
|
+
}
|
|
67
|
+
public encodeToBinary(): Uint8Array {
|
|
68
|
+
return new Uint8Array();
|
|
69
|
+
}
|
|
70
|
+
public decode<T>(schema: TSchema, value: unknown): T {
|
|
71
|
+
return value as T;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const alepha = Alepha.create();
|
|
76
|
+
const codecManager = alepha.codec;
|
|
77
|
+
codecManager.register("mock", new MockCodec());
|
|
78
|
+
|
|
79
|
+
expect(() => codecManager.getCodec("missing")).toThrow(
|
|
80
|
+
'Codec "missing" not found. Available codecs: json, mock',
|
|
81
|
+
);
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
describe("encoding - object format", () => {
|
|
86
|
+
it("should encode to object by default", () => {
|
|
87
|
+
const alepha = Alepha.create();
|
|
88
|
+
const codecManager = alepha.codec;
|
|
89
|
+
|
|
90
|
+
const schema = t.object({
|
|
91
|
+
name: t.text(),
|
|
92
|
+
age: t.integer(),
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
const result = codecManager.encode(schema, {
|
|
96
|
+
name: "John",
|
|
97
|
+
age: 30,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
expect(result).toEqual({ name: "John", age: 30 });
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it("should encode nested objects", () => {
|
|
104
|
+
const alepha = Alepha.create();
|
|
105
|
+
const codecManager = alepha.codec;
|
|
106
|
+
|
|
107
|
+
const schema = t.object({
|
|
108
|
+
user: t.object({
|
|
109
|
+
name: t.text(),
|
|
110
|
+
address: t.object({
|
|
111
|
+
city: t.text(),
|
|
112
|
+
zip: t.text(),
|
|
113
|
+
}),
|
|
114
|
+
}),
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
const result = codecManager.encode(schema, {
|
|
118
|
+
user: {
|
|
119
|
+
name: "John",
|
|
120
|
+
address: {
|
|
121
|
+
city: "NYC",
|
|
122
|
+
zip: "10001",
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
expect(result).toEqual({
|
|
128
|
+
user: {
|
|
129
|
+
name: "John",
|
|
130
|
+
address: {
|
|
131
|
+
city: "NYC",
|
|
132
|
+
zip: "10001",
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it("should encode arrays", () => {
|
|
139
|
+
const alepha = Alepha.create();
|
|
140
|
+
const codecManager = alepha.codec;
|
|
141
|
+
|
|
142
|
+
const schema = t.object({
|
|
143
|
+
items: t.array(t.text()),
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
const result = codecManager.encode(schema, {
|
|
147
|
+
items: ["a", "b", "c"],
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
expect(result).toEqual({ items: ["a", "b", "c"] });
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it("should transform values according to schema", () => {
|
|
154
|
+
const alepha = Alepha.create();
|
|
155
|
+
const codecManager = alepha.codec;
|
|
156
|
+
|
|
157
|
+
const schema = t.object({
|
|
158
|
+
value: t.text(),
|
|
159
|
+
flag: t.boolean(),
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
const result = codecManager.encode(schema, { value: "test", flag: true });
|
|
163
|
+
|
|
164
|
+
expect(result).toEqual({ value: "test", flag: true });
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it("should keep bigint string as-is", () => {
|
|
168
|
+
const alepha = Alepha.create();
|
|
169
|
+
const codecManager = alepha.codec;
|
|
170
|
+
|
|
171
|
+
const schema = t.object({
|
|
172
|
+
bigNum: t.bigint(),
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
const result = codecManager.encode(schema, { bigNum: "123456789" });
|
|
176
|
+
|
|
177
|
+
expect(result.bigNum).toBe("123456789");
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it("should handle optional fields", () => {
|
|
181
|
+
const alepha = Alepha.create();
|
|
182
|
+
const codecManager = alepha.codec;
|
|
183
|
+
|
|
184
|
+
const schema = t.object({
|
|
185
|
+
required: t.text(),
|
|
186
|
+
optional: t.optional(t.text()),
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
const result = codecManager.encode(schema, { required: "value" });
|
|
190
|
+
|
|
191
|
+
expect(result).toEqual({ required: "value" });
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
describe("encoding - string format", () => {
|
|
196
|
+
it("should encode to JSON string with 'as: string' option", () => {
|
|
197
|
+
const alepha = Alepha.create();
|
|
198
|
+
const codecManager = alepha.codec;
|
|
199
|
+
|
|
200
|
+
const schema = t.object({
|
|
201
|
+
name: t.text(),
|
|
202
|
+
age: t.integer(),
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
const result = codecManager.encode(
|
|
206
|
+
schema,
|
|
207
|
+
{ name: "John", age: 30 },
|
|
208
|
+
{ as: "string" },
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
expect(typeof result).toBe("string");
|
|
212
|
+
expect(result).toBe('{"name":"John","age":30}');
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
it("should encode complex objects to JSON string", () => {
|
|
216
|
+
const alepha = Alepha.create();
|
|
217
|
+
const codecManager = alepha.codec;
|
|
218
|
+
|
|
219
|
+
const schema = t.object({
|
|
220
|
+
items: t.array(
|
|
221
|
+
t.object({
|
|
222
|
+
id: t.integer(),
|
|
223
|
+
name: t.text(),
|
|
224
|
+
}),
|
|
225
|
+
),
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
const result = codecManager.encode(
|
|
229
|
+
schema,
|
|
230
|
+
{
|
|
231
|
+
items: [
|
|
232
|
+
{ id: 1, name: "Item 1" },
|
|
233
|
+
{ id: 2, name: "Item 2" },
|
|
234
|
+
],
|
|
235
|
+
},
|
|
236
|
+
{ as: "string" },
|
|
237
|
+
);
|
|
238
|
+
|
|
239
|
+
expect(result).toBe(
|
|
240
|
+
'{"items":[{"id":1,"name":"Item 1"},{"id":2,"name":"Item 2"}]}',
|
|
241
|
+
);
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
describe("encoding - binary format", () => {
|
|
246
|
+
it("should encode to Uint8Array with 'as: binary' option", () => {
|
|
247
|
+
const alepha = Alepha.create();
|
|
248
|
+
const codecManager = alepha.codec;
|
|
249
|
+
|
|
250
|
+
const schema = t.object({
|
|
251
|
+
name: t.text(),
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
const result = codecManager.encode(
|
|
255
|
+
schema,
|
|
256
|
+
{ name: "John" },
|
|
257
|
+
{ as: "binary" },
|
|
258
|
+
);
|
|
259
|
+
|
|
260
|
+
expect(result).toBeInstanceOf(Uint8Array);
|
|
261
|
+
|
|
262
|
+
const decoded = new TextDecoder().decode(result);
|
|
263
|
+
expect(decoded).toBe('{"name":"John"}');
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
it("should encode and decode binary roundtrip", () => {
|
|
267
|
+
const alepha = Alepha.create();
|
|
268
|
+
const codecManager = alepha.codec;
|
|
269
|
+
|
|
270
|
+
const schema = t.object({
|
|
271
|
+
name: t.text(),
|
|
272
|
+
count: t.integer(),
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
const original = { name: "Test", count: 42 };
|
|
276
|
+
const binary = codecManager.encode(schema, original, { as: "binary" });
|
|
277
|
+
const decoded = codecManager.decode(schema, binary);
|
|
278
|
+
|
|
279
|
+
expect(decoded).toEqual(original);
|
|
280
|
+
});
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
describe("custom encoder option", () => {
|
|
284
|
+
it("should use custom encoder when specified", () => {
|
|
285
|
+
class CustomCodec extends SchemaCodec {
|
|
286
|
+
public encodeToString(_schema: TSchema, value: any): string {
|
|
287
|
+
return `CUSTOM:${JSON.stringify(value)}`;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
public encodeToBinary(): Uint8Array {
|
|
291
|
+
return new Uint8Array();
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
public decode<T>(_schema: TSchema, value: unknown): T {
|
|
295
|
+
return value as T;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
const alepha = Alepha.create();
|
|
300
|
+
const codecManager = alepha.codec;
|
|
301
|
+
codecManager.register("custom", new CustomCodec());
|
|
302
|
+
|
|
303
|
+
const schema = t.object({ value: t.text() });
|
|
304
|
+
const result = codecManager.encode(
|
|
305
|
+
schema,
|
|
306
|
+
{ value: "test" },
|
|
307
|
+
{ encoder: "custom", as: "string" },
|
|
308
|
+
);
|
|
309
|
+
|
|
310
|
+
expect(result).toBe('CUSTOM:{"value":"test"}');
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
it("should throw error when custom encoder not found", () => {
|
|
314
|
+
const alepha = Alepha.create();
|
|
315
|
+
const codecManager = alepha.codec;
|
|
316
|
+
|
|
317
|
+
const schema = t.object({ value: t.text() });
|
|
318
|
+
|
|
319
|
+
expect(() =>
|
|
320
|
+
codecManager.encode(schema, { value: "test" }, { encoder: "missing" }),
|
|
321
|
+
).toThrow('Codec "missing" not found');
|
|
322
|
+
});
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
describe("decoding", () => {
|
|
326
|
+
it("should decode object", () => {
|
|
327
|
+
const alepha = Alepha.create();
|
|
328
|
+
const codecManager = alepha.codec;
|
|
329
|
+
|
|
330
|
+
const schema = t.object({
|
|
331
|
+
name: t.text(),
|
|
332
|
+
age: t.integer(),
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
const result = codecManager.decode(schema, {
|
|
336
|
+
name: "John",
|
|
337
|
+
age: 30,
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
expect(result).toEqual({ name: "John", age: 30 });
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
it("should decode JSON string", () => {
|
|
344
|
+
const alepha = Alepha.create();
|
|
345
|
+
const codecManager = alepha.codec;
|
|
346
|
+
|
|
347
|
+
const schema = t.object({
|
|
348
|
+
name: t.text(),
|
|
349
|
+
age: t.integer(),
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
const result = codecManager.decode(schema, '{"name":"John","age":30}');
|
|
353
|
+
|
|
354
|
+
expect(result).toEqual({ name: "John", age: 30 });
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
it("should decode Uint8Array", () => {
|
|
358
|
+
const alepha = Alepha.create();
|
|
359
|
+
const codecManager = alepha.codec;
|
|
360
|
+
|
|
361
|
+
const schema = t.object({
|
|
362
|
+
name: t.text(),
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
const binary = new TextEncoder().encode('{"name":"John"}');
|
|
366
|
+
const result = codecManager.decode(schema, binary);
|
|
367
|
+
|
|
368
|
+
expect(result).toEqual({ name: "John" });
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
it("should decode numbers correctly", () => {
|
|
372
|
+
const alepha = Alepha.create();
|
|
373
|
+
const codecManager = alepha.codec;
|
|
374
|
+
|
|
375
|
+
const schema = t.object({
|
|
376
|
+
count: t.integer(),
|
|
377
|
+
price: t.number(),
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
const result = codecManager.decode(schema, {
|
|
381
|
+
count: 42,
|
|
382
|
+
price: 19.99,
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
expect(result.count).toBe(42);
|
|
386
|
+
expect(result.price).toBe(19.99);
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
it("should decode string to string (bigint format)", () => {
|
|
390
|
+
const alepha = Alepha.create();
|
|
391
|
+
const codecManager = alepha.codec;
|
|
392
|
+
|
|
393
|
+
const schema = t.object({
|
|
394
|
+
bigNum: t.bigint(),
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
const result = codecManager.decode(schema, { bigNum: "123456789" });
|
|
398
|
+
|
|
399
|
+
expect(result.bigNum).toBe("123456789");
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
it("should apply default values during validation", () => {
|
|
403
|
+
const alepha = Alepha.create();
|
|
404
|
+
const codecManager = alepha.codec;
|
|
405
|
+
|
|
406
|
+
const schema = t.object({
|
|
407
|
+
name: t.text(),
|
|
408
|
+
role: t.text({ default: "user" }),
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
const decoded = codecManager.decode(schema, { name: "John" });
|
|
412
|
+
const result = codecManager.validate(schema, decoded);
|
|
413
|
+
|
|
414
|
+
expect(result).toEqual({ name: "John", role: "user" });
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
it("should trim strings when trim option is set during validation", () => {
|
|
418
|
+
const alepha = Alepha.create();
|
|
419
|
+
const codecManager = alepha.codec;
|
|
420
|
+
|
|
421
|
+
const schema = t.object({
|
|
422
|
+
name: t.text({ trim: true }),
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
const decoded = codecManager.decode(schema, { name: " John " });
|
|
426
|
+
const result = codecManager.validate(schema, decoded);
|
|
427
|
+
|
|
428
|
+
expect(result.name).toBe("John");
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
it("should convert null to undefined for non-nullable fields during validation", () => {
|
|
432
|
+
const alepha = Alepha.create();
|
|
433
|
+
const codecManager = alepha.codec;
|
|
434
|
+
|
|
435
|
+
const schema = t.object({
|
|
436
|
+
required: t.text(),
|
|
437
|
+
optional: t.optional(t.text()),
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
const decoded = codecManager.decode(schema, {
|
|
441
|
+
required: "value",
|
|
442
|
+
optional: null,
|
|
443
|
+
});
|
|
444
|
+
const result = codecManager.validate(schema, decoded);
|
|
445
|
+
|
|
446
|
+
expect(result).toEqual({ required: "value" });
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
it("should validate and throw error on invalid data", () => {
|
|
450
|
+
const alepha = Alepha.create();
|
|
451
|
+
const codecManager = alepha.codec;
|
|
452
|
+
|
|
453
|
+
const schema = t.object({
|
|
454
|
+
age: t.integer(),
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
expect(() =>
|
|
458
|
+
codecManager.decode(schema, { age: "not a number" }),
|
|
459
|
+
).toThrow(TypeBoxError);
|
|
460
|
+
});
|
|
461
|
+
|
|
462
|
+
it("should decode arrays", () => {
|
|
463
|
+
const alepha = Alepha.create();
|
|
464
|
+
const codecManager = alepha.codec;
|
|
465
|
+
|
|
466
|
+
const schema = t.object({
|
|
467
|
+
items: t.array(
|
|
468
|
+
t.object({
|
|
469
|
+
id: t.integer(),
|
|
470
|
+
name: t.text(),
|
|
471
|
+
}),
|
|
472
|
+
),
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
const result = codecManager.decode(schema, {
|
|
476
|
+
items: [
|
|
477
|
+
{ id: 1, name: "Item 1" },
|
|
478
|
+
{ id: 2, name: "Item 2" },
|
|
479
|
+
],
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
expect(result.items).toHaveLength(2);
|
|
483
|
+
expect(result.items[0]).toEqual({ id: 1, name: "Item 1" });
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
it("should use custom decoder when specified", () => {
|
|
487
|
+
class CustomCodec extends SchemaCodec {
|
|
488
|
+
public encodeToString(): string {
|
|
489
|
+
return "";
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
public encodeToBinary(): Uint8Array {
|
|
493
|
+
return new Uint8Array();
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
public decode<T>(_schema: TSchema, value: unknown): T {
|
|
497
|
+
// Custom decoding logic: prefix all strings with "DECODED:"
|
|
498
|
+
if (typeof value === "object" && value !== null) {
|
|
499
|
+
const result: any = {};
|
|
500
|
+
const obj = value as Record<string, any>;
|
|
501
|
+
for (const key in obj) {
|
|
502
|
+
if (typeof obj[key] === "string") {
|
|
503
|
+
result[key] = `DECODED:${obj[key]}`;
|
|
504
|
+
} else {
|
|
505
|
+
result[key] = obj[key];
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
return result as T;
|
|
509
|
+
}
|
|
510
|
+
return value as T;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
const alepha = Alepha.create();
|
|
515
|
+
const codecManager = alepha.codec;
|
|
516
|
+
codecManager.register("custom", new CustomCodec());
|
|
517
|
+
|
|
518
|
+
const schema = t.object({ value: t.text() });
|
|
519
|
+
const result = codecManager.decode(
|
|
520
|
+
schema,
|
|
521
|
+
{ value: "test" },
|
|
522
|
+
{ encoder: "custom" },
|
|
523
|
+
);
|
|
524
|
+
|
|
525
|
+
expect(result.value).toBe("DECODED:test");
|
|
526
|
+
});
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
describe("roundtrip encoding/decoding", () => {
|
|
530
|
+
it("should handle roundtrip for complex objects", () => {
|
|
531
|
+
const alepha = Alepha.create();
|
|
532
|
+
const codecManager = alepha.codec;
|
|
533
|
+
|
|
534
|
+
const schema = t.object({
|
|
535
|
+
user: t.object({
|
|
536
|
+
id: t.integer(),
|
|
537
|
+
name: t.text(),
|
|
538
|
+
email: t.text(),
|
|
539
|
+
active: t.boolean(),
|
|
540
|
+
}),
|
|
541
|
+
tags: t.array(t.text()),
|
|
542
|
+
count: t.bigint(),
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
const original = {
|
|
546
|
+
user: {
|
|
547
|
+
id: 1,
|
|
548
|
+
name: "John Doe",
|
|
549
|
+
email: "john@example.com",
|
|
550
|
+
active: true,
|
|
551
|
+
},
|
|
552
|
+
tags: ["typescript", "testing"],
|
|
553
|
+
count: "999999999999",
|
|
554
|
+
};
|
|
555
|
+
|
|
556
|
+
// Encode to string
|
|
557
|
+
const encoded = codecManager.encode(schema, original, { as: "string" });
|
|
558
|
+
|
|
559
|
+
// Decode back
|
|
560
|
+
const decoded = codecManager.decode(schema, encoded);
|
|
561
|
+
|
|
562
|
+
expect(decoded.user.id).toBe(original.user.id);
|
|
563
|
+
expect(decoded.user.name).toBe(original.user.name);
|
|
564
|
+
expect(decoded.user.email).toBe(original.user.email);
|
|
565
|
+
expect(decoded.user.active).toBe(original.user.active);
|
|
566
|
+
expect(decoded.tags).toEqual(original.tags);
|
|
567
|
+
expect(decoded.count).toBe(original.count);
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
it("should handle roundtrip with binary format", () => {
|
|
571
|
+
const alepha = Alepha.create();
|
|
572
|
+
const codecManager = alepha.codec;
|
|
573
|
+
|
|
574
|
+
const schema = t.object({
|
|
575
|
+
data: t.text(),
|
|
576
|
+
value: t.integer(),
|
|
577
|
+
});
|
|
578
|
+
|
|
579
|
+
const original = { data: "test", value: 42 };
|
|
580
|
+
|
|
581
|
+
const binary = codecManager.encode(schema, original, { as: "binary" });
|
|
582
|
+
const decoded = codecManager.decode(schema, binary);
|
|
583
|
+
|
|
584
|
+
expect(decoded).toEqual(original);
|
|
585
|
+
});
|
|
586
|
+
});
|
|
587
|
+
|
|
588
|
+
describe("integration with Alepha container", () => {
|
|
589
|
+
it("should inject CodecManager via $inject", () => {
|
|
590
|
+
class TestService {
|
|
591
|
+
codec = $inject(CodecManager);
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
const alepha = Alepha.create();
|
|
595
|
+
const service = alepha.inject(TestService);
|
|
596
|
+
|
|
597
|
+
expect(service.codec).toBeInstanceOf(CodecManager);
|
|
598
|
+
expect(service.codec).toBe(alepha.codec);
|
|
599
|
+
});
|
|
600
|
+
|
|
601
|
+
it("should use same CodecManager instance across services", () => {
|
|
602
|
+
class Service1 {
|
|
603
|
+
codec = $inject(CodecManager);
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
class Service2 {
|
|
607
|
+
codec = $inject(CodecManager);
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
const alepha = Alepha.create();
|
|
611
|
+
const s1 = alepha.inject(Service1);
|
|
612
|
+
const s2 = alepha.inject(Service2);
|
|
613
|
+
|
|
614
|
+
expect(s1.codec).toBe(s2.codec);
|
|
615
|
+
});
|
|
616
|
+
|
|
617
|
+
it("should register custom codec in service", () => {
|
|
618
|
+
class CustomCodec extends SchemaCodec {
|
|
619
|
+
public encodeToString(): string {
|
|
620
|
+
return "custom";
|
|
621
|
+
}
|
|
622
|
+
public encodeToBinary(): Uint8Array {
|
|
623
|
+
return new Uint8Array();
|
|
624
|
+
}
|
|
625
|
+
public decode<T>(_schema: TSchema, value: unknown): T {
|
|
626
|
+
return value as T;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
class ConfigService {
|
|
631
|
+
codec = $inject(CodecManager);
|
|
632
|
+
|
|
633
|
+
constructor() {
|
|
634
|
+
this.codec.register("custom", new CustomCodec());
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
const alepha = Alepha.create();
|
|
639
|
+
alepha.inject(ConfigService);
|
|
640
|
+
|
|
641
|
+
const codecManager = alepha.codec;
|
|
642
|
+
const customCodec = codecManager.getCodec("custom");
|
|
643
|
+
|
|
644
|
+
expect(customCodec).toBeInstanceOf(CustomCodec);
|
|
645
|
+
});
|
|
646
|
+
});
|
|
647
|
+
|
|
648
|
+
describe("JsonSchemaCodec specifics", () => {
|
|
649
|
+
it("should handle null values correctly during validation", () => {
|
|
650
|
+
const alepha = Alepha.create();
|
|
651
|
+
const codecManager = alepha.codec;
|
|
652
|
+
|
|
653
|
+
const schema = t.object({
|
|
654
|
+
nullable: t.nullable(t.text()),
|
|
655
|
+
optional: t.optional(t.text()),
|
|
656
|
+
});
|
|
657
|
+
|
|
658
|
+
const decoded = codecManager.decode(schema, {
|
|
659
|
+
nullable: null,
|
|
660
|
+
optional: null,
|
|
661
|
+
});
|
|
662
|
+
const result = codecManager.validate(schema, decoded);
|
|
663
|
+
|
|
664
|
+
expect(result.nullable).toBeNull();
|
|
665
|
+
expect(result.optional).toBeUndefined();
|
|
666
|
+
});
|
|
667
|
+
|
|
668
|
+
it("should handle array preprocessing during validation", () => {
|
|
669
|
+
const alepha = Alepha.create();
|
|
670
|
+
const codecManager = alepha.codec;
|
|
671
|
+
|
|
672
|
+
const schema = t.object({
|
|
673
|
+
items: t.array(t.text({ trim: true })),
|
|
674
|
+
});
|
|
675
|
+
|
|
676
|
+
const decoded = codecManager.decode(schema, {
|
|
677
|
+
items: [" a ", " b ", " c "],
|
|
678
|
+
});
|
|
679
|
+
const result = codecManager.validate(schema, decoded);
|
|
680
|
+
|
|
681
|
+
expect(result.items).toEqual(["a", "b", "c"]);
|
|
682
|
+
});
|
|
683
|
+
|
|
684
|
+
it("should remove undefined values from objects during validation", () => {
|
|
685
|
+
const alepha = Alepha.create();
|
|
686
|
+
const codecManager = alepha.codec;
|
|
687
|
+
|
|
688
|
+
const schema = t.object({
|
|
689
|
+
a: t.text(),
|
|
690
|
+
b: t.optional(t.text()),
|
|
691
|
+
});
|
|
692
|
+
|
|
693
|
+
const decoded = codecManager.decode(schema, {
|
|
694
|
+
a: "value",
|
|
695
|
+
b: undefined,
|
|
696
|
+
});
|
|
697
|
+
const result = codecManager.validate(schema, decoded);
|
|
698
|
+
|
|
699
|
+
expect(result).toEqual({ a: "value" });
|
|
700
|
+
expect("b" in result).toBe(false);
|
|
701
|
+
});
|
|
702
|
+
});
|
|
703
|
+
|
|
704
|
+
describe("error handling", () => {
|
|
705
|
+
it("should throw TypeBoxError on encoding validation failure", () => {
|
|
706
|
+
const alepha = Alepha.create();
|
|
707
|
+
const codecManager = alepha.codec;
|
|
708
|
+
|
|
709
|
+
const schema = t.object({
|
|
710
|
+
age: t.integer({ minimum: 0, maximum: 150 }),
|
|
711
|
+
});
|
|
712
|
+
|
|
713
|
+
expect(() => codecManager.encode(schema, { age: 200 })).toThrow(
|
|
714
|
+
TypeBoxError,
|
|
715
|
+
);
|
|
716
|
+
});
|
|
717
|
+
|
|
718
|
+
it("should throw TypeBoxError when validating invalid decoded data", () => {
|
|
719
|
+
const alepha = Alepha.create();
|
|
720
|
+
const codecManager = alepha.codec;
|
|
721
|
+
|
|
722
|
+
const schema = t.object({
|
|
723
|
+
email: t.text({ format: "email" }),
|
|
724
|
+
});
|
|
725
|
+
|
|
726
|
+
expect(() =>
|
|
727
|
+
codecManager.decode(schema, { email: "not-an-email" }),
|
|
728
|
+
).toThrow(TypeBoxError);
|
|
729
|
+
});
|
|
730
|
+
|
|
731
|
+
it("should throw error on invalid JSON string", () => {
|
|
732
|
+
const alepha = Alepha.create();
|
|
733
|
+
const codecManager = alepha.codec;
|
|
734
|
+
|
|
735
|
+
const schema = t.object({ value: t.text() });
|
|
736
|
+
|
|
737
|
+
expect(() => codecManager.decode(schema, "{ invalid json }")).toThrow();
|
|
738
|
+
});
|
|
739
|
+
});
|
|
740
|
+
});
|