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,762 @@
|
|
|
1
|
+
import { Alepha } from "alepha";
|
|
2
|
+
import { describe, expect, it, vi } from "vitest";
|
|
3
|
+
import type { LoggerInterface } from "../interfaces/LoggerInterface.ts";
|
|
4
|
+
import { EventManager } from "../providers/EventManager.ts";
|
|
5
|
+
|
|
6
|
+
describe("EventManager", () => {
|
|
7
|
+
describe("initialization", () => {
|
|
8
|
+
it("should create EventManager instance", () => {
|
|
9
|
+
const eventManager = new EventManager();
|
|
10
|
+
expect(eventManager).toBeInstanceOf(EventManager);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it("should create EventManager with logger function", () => {
|
|
14
|
+
const mockLogger: LoggerInterface = {
|
|
15
|
+
trace: vi.fn(),
|
|
16
|
+
debug: vi.fn(),
|
|
17
|
+
info: vi.fn(),
|
|
18
|
+
warn: vi.fn(),
|
|
19
|
+
error: vi.fn(),
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const logFn = () => mockLogger;
|
|
23
|
+
const eventManager = new EventManager(logFn);
|
|
24
|
+
|
|
25
|
+
expect(eventManager).toBeInstanceOf(EventManager);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("should be accessible via Alepha.events", () => {
|
|
29
|
+
const alepha = Alepha.create();
|
|
30
|
+
expect(alepha.events).toBeInstanceOf(EventManager);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe("on() - event registration", () => {
|
|
35
|
+
it("should register event handler with callback function", () => {
|
|
36
|
+
const eventManager = new EventManager();
|
|
37
|
+
const callback = vi.fn();
|
|
38
|
+
|
|
39
|
+
const unsubscribe = eventManager.on("echo", callback);
|
|
40
|
+
|
|
41
|
+
expect(typeof unsubscribe).toBe("function");
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it("should register event handler with hook object", () => {
|
|
45
|
+
const eventManager = new EventManager();
|
|
46
|
+
const callback = vi.fn();
|
|
47
|
+
|
|
48
|
+
const unsubscribe = eventManager.on("echo", {
|
|
49
|
+
callback,
|
|
50
|
+
caller: undefined,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
expect(typeof unsubscribe).toBe("function");
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("should register multiple handlers for the same event", () => {
|
|
57
|
+
const eventManager = new EventManager();
|
|
58
|
+
const callback1 = vi.fn();
|
|
59
|
+
const callback2 = vi.fn();
|
|
60
|
+
|
|
61
|
+
eventManager.on("echo", callback1);
|
|
62
|
+
eventManager.on("echo", callback2);
|
|
63
|
+
|
|
64
|
+
// Both handlers should be registered (verified by emit test)
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("should register handlers for different events", () => {
|
|
68
|
+
const eventManager = new EventManager();
|
|
69
|
+
const callback1 = vi.fn();
|
|
70
|
+
const callback2 = vi.fn();
|
|
71
|
+
|
|
72
|
+
eventManager.on("echo", callback1);
|
|
73
|
+
eventManager.on("configure", callback2);
|
|
74
|
+
|
|
75
|
+
// Handlers should be registered separately (verified by emit test)
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
describe("emit() - event execution", () => {
|
|
80
|
+
it("should execute registered callback", async () => {
|
|
81
|
+
const eventManager = new EventManager();
|
|
82
|
+
const callback = vi.fn();
|
|
83
|
+
|
|
84
|
+
eventManager.on("echo", callback);
|
|
85
|
+
await eventManager.emit("echo", { test: "data" });
|
|
86
|
+
|
|
87
|
+
expect(callback).toHaveBeenCalledTimes(1);
|
|
88
|
+
expect(callback).toHaveBeenCalledWith({ test: "data" });
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it("should execute multiple callbacks in order", async () => {
|
|
92
|
+
const eventManager = new EventManager();
|
|
93
|
+
const order: number[] = [];
|
|
94
|
+
|
|
95
|
+
eventManager.on("echo", async () => {
|
|
96
|
+
order.push(1);
|
|
97
|
+
});
|
|
98
|
+
eventManager.on("echo", async () => {
|
|
99
|
+
order.push(2);
|
|
100
|
+
});
|
|
101
|
+
eventManager.on("echo", async () => {
|
|
102
|
+
order.push(3);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
await eventManager.emit("echo", {});
|
|
106
|
+
|
|
107
|
+
expect(order).toEqual([1, 2, 3]);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it("should execute callbacks sequentially (not in parallel)", async () => {
|
|
111
|
+
const eventManager = new EventManager();
|
|
112
|
+
const order: string[] = [];
|
|
113
|
+
|
|
114
|
+
eventManager.on("echo", async () => {
|
|
115
|
+
order.push("1-start");
|
|
116
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
117
|
+
order.push("1-end");
|
|
118
|
+
});
|
|
119
|
+
eventManager.on("echo", async () => {
|
|
120
|
+
order.push("2-start");
|
|
121
|
+
await new Promise((resolve) => setTimeout(resolve, 5));
|
|
122
|
+
order.push("2-end");
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
await eventManager.emit("echo", {});
|
|
126
|
+
|
|
127
|
+
expect(order).toEqual(["1-start", "1-end", "2-start", "2-end"]);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it("should pass payload to all callbacks", async () => {
|
|
131
|
+
const eventManager = new EventManager();
|
|
132
|
+
const callback1 = vi.fn();
|
|
133
|
+
const callback2 = vi.fn();
|
|
134
|
+
const payload = { value: 42, name: "test" };
|
|
135
|
+
|
|
136
|
+
eventManager.on("echo", callback1);
|
|
137
|
+
eventManager.on("echo", callback2);
|
|
138
|
+
|
|
139
|
+
await eventManager.emit("echo", payload);
|
|
140
|
+
|
|
141
|
+
expect(callback1).toHaveBeenCalledWith(payload);
|
|
142
|
+
expect(callback2).toHaveBeenCalledWith(payload);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it("should not execute callbacks for different events", async () => {
|
|
146
|
+
const eventManager = new EventManager();
|
|
147
|
+
const callback1 = vi.fn();
|
|
148
|
+
const callback2 = vi.fn();
|
|
149
|
+
|
|
150
|
+
eventManager.on("echo", callback1);
|
|
151
|
+
eventManager.on("configure", callback2);
|
|
152
|
+
|
|
153
|
+
await eventManager.emit("echo", {});
|
|
154
|
+
|
|
155
|
+
expect(callback1).toHaveBeenCalledTimes(1);
|
|
156
|
+
expect(callback2).not.toHaveBeenCalled();
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it("should handle events with no registered callbacks", async () => {
|
|
160
|
+
const eventManager = new EventManager();
|
|
161
|
+
|
|
162
|
+
// Should not throw
|
|
163
|
+
await expect(eventManager.emit("echo", {})).resolves.toBeUndefined();
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it("should work with Alepha lifecycle events", async () => {
|
|
167
|
+
const alepha = Alepha.create();
|
|
168
|
+
const configureCallback = vi.fn();
|
|
169
|
+
const startCallback = vi.fn();
|
|
170
|
+
const readyCallback = vi.fn();
|
|
171
|
+
|
|
172
|
+
alepha.events.on("configure", configureCallback);
|
|
173
|
+
alepha.events.on("start", startCallback);
|
|
174
|
+
alepha.events.on("ready", readyCallback);
|
|
175
|
+
|
|
176
|
+
await alepha.start();
|
|
177
|
+
|
|
178
|
+
expect(configureCallback).toHaveBeenCalledTimes(1);
|
|
179
|
+
expect(startCallback).toHaveBeenCalledTimes(1);
|
|
180
|
+
expect(readyCallback).toHaveBeenCalledTimes(1);
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
describe("hook priorities", () => {
|
|
185
|
+
it("should execute 'first' priority hooks before others", async () => {
|
|
186
|
+
const eventManager = new EventManager();
|
|
187
|
+
const order: string[] = [];
|
|
188
|
+
|
|
189
|
+
eventManager.on("echo", async () => {
|
|
190
|
+
order.push("normal");
|
|
191
|
+
});
|
|
192
|
+
eventManager.on("echo", {
|
|
193
|
+
callback: async () => {
|
|
194
|
+
order.push("first");
|
|
195
|
+
},
|
|
196
|
+
priority: "first",
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
await eventManager.emit("echo", {});
|
|
200
|
+
|
|
201
|
+
expect(order).toEqual(["first", "normal"]);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
it("should execute 'last' priority hooks after others", async () => {
|
|
205
|
+
const eventManager = new EventManager();
|
|
206
|
+
const order: string[] = [];
|
|
207
|
+
|
|
208
|
+
eventManager.on("echo", async () => {
|
|
209
|
+
order.push("normal");
|
|
210
|
+
});
|
|
211
|
+
eventManager.on("echo", {
|
|
212
|
+
callback: async () => {
|
|
213
|
+
order.push("last");
|
|
214
|
+
},
|
|
215
|
+
priority: "last",
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
await eventManager.emit("echo", {});
|
|
219
|
+
|
|
220
|
+
expect(order).toEqual(["normal", "last"]);
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
it("should handle multiple priority levels correctly", async () => {
|
|
224
|
+
const eventManager = new EventManager();
|
|
225
|
+
const order: string[] = [];
|
|
226
|
+
|
|
227
|
+
eventManager.on("echo", async () => {
|
|
228
|
+
order.push("normal1");
|
|
229
|
+
});
|
|
230
|
+
eventManager.on("echo", {
|
|
231
|
+
callback: async () => {
|
|
232
|
+
order.push("first1");
|
|
233
|
+
},
|
|
234
|
+
priority: "first",
|
|
235
|
+
});
|
|
236
|
+
eventManager.on("echo", {
|
|
237
|
+
callback: async () => {
|
|
238
|
+
order.push("last1");
|
|
239
|
+
},
|
|
240
|
+
priority: "last",
|
|
241
|
+
});
|
|
242
|
+
eventManager.on("echo", async () => {
|
|
243
|
+
order.push("normal2");
|
|
244
|
+
});
|
|
245
|
+
eventManager.on("echo", {
|
|
246
|
+
callback: async () => {
|
|
247
|
+
order.push("first2");
|
|
248
|
+
},
|
|
249
|
+
priority: "first",
|
|
250
|
+
});
|
|
251
|
+
eventManager.on("echo", {
|
|
252
|
+
callback: async () => {
|
|
253
|
+
order.push("last2");
|
|
254
|
+
},
|
|
255
|
+
priority: "last",
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
await eventManager.emit("echo", {});
|
|
259
|
+
|
|
260
|
+
// First hooks are prepended (reverse order of registration)
|
|
261
|
+
// Then normal hooks, then last hooks (in order of registration)
|
|
262
|
+
expect(order[0]).toBe("first2");
|
|
263
|
+
expect(order[1]).toBe("first1");
|
|
264
|
+
expect(order[order.length - 2]).toBe("last1");
|
|
265
|
+
expect(order[order.length - 1]).toBe("last2");
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
it("should insert normal hooks before existing last hooks", async () => {
|
|
269
|
+
const eventManager = new EventManager();
|
|
270
|
+
const order: string[] = [];
|
|
271
|
+
|
|
272
|
+
eventManager.on("echo", {
|
|
273
|
+
callback: async () => {
|
|
274
|
+
order.push("last");
|
|
275
|
+
},
|
|
276
|
+
priority: "last",
|
|
277
|
+
});
|
|
278
|
+
eventManager.on("echo", async () => {
|
|
279
|
+
order.push("normal");
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
await eventManager.emit("echo", {});
|
|
283
|
+
|
|
284
|
+
expect(order).toEqual(["normal", "last"]);
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
describe("reverse execution order", () => {
|
|
289
|
+
it("should execute hooks in reverse order when reverse option is true", async () => {
|
|
290
|
+
const eventManager = new EventManager();
|
|
291
|
+
const order: number[] = [];
|
|
292
|
+
|
|
293
|
+
eventManager.on("echo", async () => {
|
|
294
|
+
order.push(1);
|
|
295
|
+
});
|
|
296
|
+
eventManager.on("echo", async () => {
|
|
297
|
+
order.push(2);
|
|
298
|
+
});
|
|
299
|
+
eventManager.on("echo", async () => {
|
|
300
|
+
order.push(3);
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
await eventManager.emit("echo", {}, { reverse: true });
|
|
304
|
+
|
|
305
|
+
expect(order).toEqual([3, 2, 1]);
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
it("should reverse priorities correctly", async () => {
|
|
309
|
+
const eventManager = new EventManager();
|
|
310
|
+
const order: string[] = [];
|
|
311
|
+
|
|
312
|
+
eventManager.on("echo", {
|
|
313
|
+
callback: async () => {
|
|
314
|
+
order.push("first");
|
|
315
|
+
},
|
|
316
|
+
priority: "first",
|
|
317
|
+
});
|
|
318
|
+
eventManager.on("echo", async () => {
|
|
319
|
+
order.push("normal");
|
|
320
|
+
});
|
|
321
|
+
eventManager.on("echo", {
|
|
322
|
+
callback: async () => {
|
|
323
|
+
order.push("last");
|
|
324
|
+
},
|
|
325
|
+
priority: "last",
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
await eventManager.emit("echo", {}, { reverse: true });
|
|
329
|
+
|
|
330
|
+
// Reversed: last -> normal -> first
|
|
331
|
+
expect(order).toEqual(["last", "normal", "first"]);
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
it("should work with stop lifecycle event", async () => {
|
|
335
|
+
const alepha = Alepha.create();
|
|
336
|
+
const order: string[] = [];
|
|
337
|
+
|
|
338
|
+
alepha.events.on("start", async () => {
|
|
339
|
+
order.push("start-1");
|
|
340
|
+
});
|
|
341
|
+
alepha.events.on("start", async () => {
|
|
342
|
+
order.push("start-2");
|
|
343
|
+
});
|
|
344
|
+
alepha.events.on("stop", async () => {
|
|
345
|
+
order.push("stop-1");
|
|
346
|
+
});
|
|
347
|
+
alepha.events.on("stop", async () => {
|
|
348
|
+
order.push("stop-2");
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
await alepha.start();
|
|
352
|
+
await alepha.stop();
|
|
353
|
+
|
|
354
|
+
// Start should be in order, stop should be reversed
|
|
355
|
+
expect(order).toEqual(["start-1", "start-2", "stop-2", "stop-1"]);
|
|
356
|
+
});
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
describe("error handling", () => {
|
|
360
|
+
it("should throw error when callback throws", async () => {
|
|
361
|
+
const eventManager = new EventManager();
|
|
362
|
+
|
|
363
|
+
eventManager.on("echo", async () => {
|
|
364
|
+
throw new Error("Test error");
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
await expect(eventManager.emit("echo", {})).rejects.toThrow("Test error");
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
it("should stop execution on first error", async () => {
|
|
371
|
+
const eventManager = new EventManager();
|
|
372
|
+
const callback2 = vi.fn();
|
|
373
|
+
|
|
374
|
+
eventManager.on("echo", async () => {
|
|
375
|
+
throw new Error("Test error");
|
|
376
|
+
});
|
|
377
|
+
eventManager.on("echo", callback2);
|
|
378
|
+
|
|
379
|
+
await expect(eventManager.emit("echo", {})).rejects.toThrow();
|
|
380
|
+
expect(callback2).not.toHaveBeenCalled();
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
it("should catch errors when catch option is true", async () => {
|
|
384
|
+
const eventManager = new EventManager();
|
|
385
|
+
const callback2 = vi.fn();
|
|
386
|
+
|
|
387
|
+
eventManager.on("echo", async () => {
|
|
388
|
+
throw new Error("Test error");
|
|
389
|
+
});
|
|
390
|
+
eventManager.on("echo", callback2);
|
|
391
|
+
|
|
392
|
+
await expect(
|
|
393
|
+
eventManager.emit("echo", {}, { catch: true }),
|
|
394
|
+
).resolves.toBeUndefined();
|
|
395
|
+
|
|
396
|
+
// Second callback should still execute
|
|
397
|
+
expect(callback2).toHaveBeenCalledTimes(1);
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
it("should continue executing after caught error", async () => {
|
|
401
|
+
const eventManager = new EventManager();
|
|
402
|
+
const order: number[] = [];
|
|
403
|
+
|
|
404
|
+
eventManager.on("echo", async () => {
|
|
405
|
+
order.push(1);
|
|
406
|
+
throw new Error("Error in 1");
|
|
407
|
+
});
|
|
408
|
+
eventManager.on("echo", async () => {
|
|
409
|
+
order.push(2);
|
|
410
|
+
});
|
|
411
|
+
eventManager.on("echo", async () => {
|
|
412
|
+
order.push(3);
|
|
413
|
+
throw new Error("Error in 3");
|
|
414
|
+
});
|
|
415
|
+
eventManager.on("echo", async () => {
|
|
416
|
+
order.push(4);
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
await eventManager.emit("echo", {}, { catch: true });
|
|
420
|
+
|
|
421
|
+
expect(order).toEqual([1, 2, 3, 4]);
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
it("should provide better error message with log option", async () => {
|
|
425
|
+
const mockLogger: LoggerInterface = {
|
|
426
|
+
trace: vi.fn(),
|
|
427
|
+
debug: vi.fn(),
|
|
428
|
+
info: vi.fn(),
|
|
429
|
+
warn: vi.fn(),
|
|
430
|
+
error: vi.fn(),
|
|
431
|
+
};
|
|
432
|
+
|
|
433
|
+
const eventManager = new EventManager(() => mockLogger);
|
|
434
|
+
|
|
435
|
+
class TestService {}
|
|
436
|
+
|
|
437
|
+
eventManager.on("echo", {
|
|
438
|
+
callback: async () => {
|
|
439
|
+
throw new Error("Test error");
|
|
440
|
+
},
|
|
441
|
+
caller: TestService,
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
await expect(
|
|
445
|
+
eventManager.emit("echo", {}, { log: true }),
|
|
446
|
+
).rejects.toThrow("Failed during 'echo()' hook for service: TestService");
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
it("should log errors when catch and log options are both true", async () => {
|
|
450
|
+
const mockLogger: LoggerInterface = {
|
|
451
|
+
trace: vi.fn(),
|
|
452
|
+
debug: vi.fn(),
|
|
453
|
+
info: vi.fn(),
|
|
454
|
+
warn: vi.fn(),
|
|
455
|
+
error: vi.fn(),
|
|
456
|
+
};
|
|
457
|
+
|
|
458
|
+
const eventManager = new EventManager(() => mockLogger);
|
|
459
|
+
|
|
460
|
+
class TestService {}
|
|
461
|
+
|
|
462
|
+
eventManager.on("echo", {
|
|
463
|
+
callback: async () => {
|
|
464
|
+
throw new Error("Test error");
|
|
465
|
+
},
|
|
466
|
+
caller: TestService,
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
await eventManager.emit("echo", {}, { catch: true, log: true });
|
|
470
|
+
|
|
471
|
+
expect(mockLogger.error).toHaveBeenCalled();
|
|
472
|
+
});
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
describe("logging", () => {
|
|
476
|
+
it("should log trace and debug messages when log option is true", async () => {
|
|
477
|
+
const mockLogger: LoggerInterface = {
|
|
478
|
+
trace: vi.fn(),
|
|
479
|
+
debug: vi.fn(),
|
|
480
|
+
info: vi.fn(),
|
|
481
|
+
warn: vi.fn(),
|
|
482
|
+
error: vi.fn(),
|
|
483
|
+
};
|
|
484
|
+
|
|
485
|
+
const eventManager = new EventManager(() => mockLogger);
|
|
486
|
+
|
|
487
|
+
eventManager.on("echo", async () => {
|
|
488
|
+
// Simple callback
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
await eventManager.emit("echo", {}, { log: true });
|
|
492
|
+
|
|
493
|
+
expect(mockLogger.trace).toHaveBeenCalled();
|
|
494
|
+
expect(mockLogger.debug).toHaveBeenCalled();
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
it("should log execution time for each hook", async () => {
|
|
498
|
+
const mockLogger: LoggerInterface = {
|
|
499
|
+
trace: vi.fn(),
|
|
500
|
+
debug: vi.fn(),
|
|
501
|
+
info: vi.fn(),
|
|
502
|
+
warn: vi.fn(),
|
|
503
|
+
error: vi.fn(),
|
|
504
|
+
};
|
|
505
|
+
|
|
506
|
+
const eventManager = new EventManager(() => mockLogger);
|
|
507
|
+
|
|
508
|
+
class TestService {}
|
|
509
|
+
|
|
510
|
+
eventManager.on("echo", {
|
|
511
|
+
callback: async () => {
|
|
512
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
513
|
+
},
|
|
514
|
+
caller: TestService,
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
await eventManager.emit("echo", {}, { log: true });
|
|
518
|
+
|
|
519
|
+
// Should log the hook execution with timing
|
|
520
|
+
const debugCalls = (mockLogger.debug as any).mock.calls;
|
|
521
|
+
const hasTimingLog = debugCalls.some(
|
|
522
|
+
(call: any[]) => call[0].includes("OK") && call[0].includes("ms"),
|
|
523
|
+
);
|
|
524
|
+
expect(hasTimingLog).toBe(true);
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
it("should log service name from caller", async () => {
|
|
528
|
+
const mockLogger: LoggerInterface = {
|
|
529
|
+
trace: vi.fn(),
|
|
530
|
+
debug: vi.fn(),
|
|
531
|
+
info: vi.fn(),
|
|
532
|
+
warn: vi.fn(),
|
|
533
|
+
error: vi.fn(),
|
|
534
|
+
};
|
|
535
|
+
|
|
536
|
+
const eventManager = new EventManager(() => mockLogger);
|
|
537
|
+
|
|
538
|
+
class MyCustomService {}
|
|
539
|
+
|
|
540
|
+
eventManager.on("echo", {
|
|
541
|
+
callback: async () => {},
|
|
542
|
+
caller: MyCustomService,
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
await eventManager.emit("echo", {}, { log: true });
|
|
546
|
+
|
|
547
|
+
const traceCalls = (mockLogger.trace as any).mock.calls;
|
|
548
|
+
const hasServiceName = traceCalls.some((call: any[]) =>
|
|
549
|
+
call[0].includes("MyCustomService"),
|
|
550
|
+
);
|
|
551
|
+
expect(hasServiceName).toBe(true);
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
it("should log 'unknown' when caller is not provided", async () => {
|
|
555
|
+
const mockLogger: LoggerInterface = {
|
|
556
|
+
trace: vi.fn(),
|
|
557
|
+
debug: vi.fn(),
|
|
558
|
+
info: vi.fn(),
|
|
559
|
+
warn: vi.fn(),
|
|
560
|
+
error: vi.fn(),
|
|
561
|
+
};
|
|
562
|
+
|
|
563
|
+
const eventManager = new EventManager(() => mockLogger);
|
|
564
|
+
|
|
565
|
+
eventManager.on("echo", async () => {});
|
|
566
|
+
|
|
567
|
+
await eventManager.emit("echo", {}, { log: true });
|
|
568
|
+
|
|
569
|
+
const traceCalls = (mockLogger.trace as any).mock.calls;
|
|
570
|
+
const hasUnknown = traceCalls.some((call: any[]) =>
|
|
571
|
+
call[0].includes("unknown"),
|
|
572
|
+
);
|
|
573
|
+
expect(hasUnknown).toBe(true);
|
|
574
|
+
});
|
|
575
|
+
|
|
576
|
+
it("should not log when log option is false", async () => {
|
|
577
|
+
const mockLogger: LoggerInterface = {
|
|
578
|
+
trace: vi.fn(),
|
|
579
|
+
debug: vi.fn(),
|
|
580
|
+
info: vi.fn(),
|
|
581
|
+
warn: vi.fn(),
|
|
582
|
+
error: vi.fn(),
|
|
583
|
+
};
|
|
584
|
+
|
|
585
|
+
const eventManager = new EventManager(() => mockLogger);
|
|
586
|
+
|
|
587
|
+
eventManager.on("echo", async () => {});
|
|
588
|
+
|
|
589
|
+
await eventManager.emit("echo", {});
|
|
590
|
+
|
|
591
|
+
expect(mockLogger.trace).not.toHaveBeenCalled();
|
|
592
|
+
expect(mockLogger.debug).not.toHaveBeenCalled();
|
|
593
|
+
});
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
describe("unsubscribe", () => {
|
|
597
|
+
it("should return unsubscribe function from on()", () => {
|
|
598
|
+
const eventManager = new EventManager();
|
|
599
|
+
const unsubscribe = eventManager.on("echo", async () => {});
|
|
600
|
+
|
|
601
|
+
expect(typeof unsubscribe).toBe("function");
|
|
602
|
+
});
|
|
603
|
+
|
|
604
|
+
it("should remove handler when unsubscribe is called", async () => {
|
|
605
|
+
const eventManager = new EventManager();
|
|
606
|
+
const callback = vi.fn();
|
|
607
|
+
|
|
608
|
+
const unsubscribe = eventManager.on("echo", callback);
|
|
609
|
+
unsubscribe();
|
|
610
|
+
|
|
611
|
+
await eventManager.emit("echo", {});
|
|
612
|
+
|
|
613
|
+
expect(callback).not.toHaveBeenCalled();
|
|
614
|
+
});
|
|
615
|
+
|
|
616
|
+
it("should only remove specific handler", async () => {
|
|
617
|
+
const eventManager = new EventManager();
|
|
618
|
+
const callback1 = vi.fn();
|
|
619
|
+
const callback2 = vi.fn();
|
|
620
|
+
const callback3 = vi.fn();
|
|
621
|
+
|
|
622
|
+
const unsubscribe1 = eventManager.on("echo", callback1);
|
|
623
|
+
eventManager.on("echo", callback2);
|
|
624
|
+
eventManager.on("echo", callback3);
|
|
625
|
+
|
|
626
|
+
unsubscribe1();
|
|
627
|
+
|
|
628
|
+
await eventManager.emit("echo", {});
|
|
629
|
+
|
|
630
|
+
expect(callback1).not.toHaveBeenCalled();
|
|
631
|
+
expect(callback2).toHaveBeenCalledTimes(1);
|
|
632
|
+
expect(callback3).toHaveBeenCalledTimes(1);
|
|
633
|
+
});
|
|
634
|
+
|
|
635
|
+
it("should allow multiple unsubscribe calls safely", async () => {
|
|
636
|
+
const eventManager = new EventManager();
|
|
637
|
+
const callback = vi.fn();
|
|
638
|
+
|
|
639
|
+
const unsubscribe = eventManager.on("echo", callback);
|
|
640
|
+
unsubscribe();
|
|
641
|
+
unsubscribe(); // Should not throw
|
|
642
|
+
|
|
643
|
+
await eventManager.emit("echo", {});
|
|
644
|
+
|
|
645
|
+
expect(callback).not.toHaveBeenCalled();
|
|
646
|
+
});
|
|
647
|
+
|
|
648
|
+
it("should work with different events", async () => {
|
|
649
|
+
const eventManager = new EventManager();
|
|
650
|
+
const callback1 = vi.fn();
|
|
651
|
+
const callback2 = vi.fn();
|
|
652
|
+
|
|
653
|
+
const unsubscribe1 = eventManager.on("echo", callback1);
|
|
654
|
+
eventManager.on("configure", callback2);
|
|
655
|
+
|
|
656
|
+
unsubscribe1();
|
|
657
|
+
|
|
658
|
+
await eventManager.emit("echo", {});
|
|
659
|
+
await eventManager.emit("configure", {} as any);
|
|
660
|
+
|
|
661
|
+
expect(callback1).not.toHaveBeenCalled();
|
|
662
|
+
expect(callback2).toHaveBeenCalledTimes(1);
|
|
663
|
+
});
|
|
664
|
+
});
|
|
665
|
+
|
|
666
|
+
describe("integration with Alepha", () => {
|
|
667
|
+
it("should share EventManager instance across Alepha", () => {
|
|
668
|
+
const alepha = Alepha.create();
|
|
669
|
+
const events1 = alepha.events;
|
|
670
|
+
const events2 = alepha.events;
|
|
671
|
+
|
|
672
|
+
expect(events1).toBe(events2);
|
|
673
|
+
});
|
|
674
|
+
|
|
675
|
+
it("should trigger configure, start, and ready hooks in order", async () => {
|
|
676
|
+
const alepha = Alepha.create();
|
|
677
|
+
const order: string[] = [];
|
|
678
|
+
|
|
679
|
+
alepha.events.on("configure", async () => {
|
|
680
|
+
order.push("configure");
|
|
681
|
+
});
|
|
682
|
+
alepha.events.on("start", async () => {
|
|
683
|
+
order.push("start");
|
|
684
|
+
});
|
|
685
|
+
alepha.events.on("ready", async () => {
|
|
686
|
+
order.push("ready");
|
|
687
|
+
});
|
|
688
|
+
|
|
689
|
+
await alepha.start();
|
|
690
|
+
|
|
691
|
+
expect(order).toEqual(["configure", "start", "ready"]);
|
|
692
|
+
});
|
|
693
|
+
|
|
694
|
+
it("should allow manual event emission", async () => {
|
|
695
|
+
const alepha = Alepha.create();
|
|
696
|
+
const callback = vi.fn();
|
|
697
|
+
|
|
698
|
+
alepha.events.on("echo", callback);
|
|
699
|
+
await alepha.events.emit("echo", { custom: "data" });
|
|
700
|
+
|
|
701
|
+
expect(callback).toHaveBeenCalledWith({ custom: "data" });
|
|
702
|
+
});
|
|
703
|
+
|
|
704
|
+
it("should work with custom hook types via module augmentation", async () => {
|
|
705
|
+
const alepha = Alepha.create();
|
|
706
|
+
const callback = vi.fn();
|
|
707
|
+
|
|
708
|
+
// Using the 'echo' hook which is defined in Hooks interface
|
|
709
|
+
alepha.events.on("echo", callback);
|
|
710
|
+
await alepha.events.emit("echo", { test: true });
|
|
711
|
+
|
|
712
|
+
expect(callback).toHaveBeenCalledWith({ test: true });
|
|
713
|
+
});
|
|
714
|
+
});
|
|
715
|
+
|
|
716
|
+
describe("async behavior", () => {
|
|
717
|
+
it("should wait for async callbacks to complete", async () => {
|
|
718
|
+
const eventManager = new EventManager();
|
|
719
|
+
let completed = false;
|
|
720
|
+
|
|
721
|
+
eventManager.on("echo", async () => {
|
|
722
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
723
|
+
completed = true;
|
|
724
|
+
});
|
|
725
|
+
|
|
726
|
+
await eventManager.emit("echo", {});
|
|
727
|
+
|
|
728
|
+
expect(completed).toBe(true);
|
|
729
|
+
});
|
|
730
|
+
|
|
731
|
+
it("should execute async callbacks sequentially", async () => {
|
|
732
|
+
const eventManager = new EventManager();
|
|
733
|
+
const order: string[] = [];
|
|
734
|
+
|
|
735
|
+
eventManager.on("echo", async () => {
|
|
736
|
+
await new Promise((resolve) => setTimeout(resolve, 30));
|
|
737
|
+
order.push("first");
|
|
738
|
+
});
|
|
739
|
+
eventManager.on("echo", async () => {
|
|
740
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
741
|
+
order.push("second");
|
|
742
|
+
});
|
|
743
|
+
|
|
744
|
+
await eventManager.emit("echo", {});
|
|
745
|
+
|
|
746
|
+
// Second callback should wait for first to complete
|
|
747
|
+
expect(order).toEqual(["first", "second"]);
|
|
748
|
+
});
|
|
749
|
+
|
|
750
|
+
it("should handle Promise rejections as errors", async () => {
|
|
751
|
+
const eventManager = new EventManager();
|
|
752
|
+
|
|
753
|
+
eventManager.on("echo", async () => {
|
|
754
|
+
return Promise.reject(new Error("Async error"));
|
|
755
|
+
});
|
|
756
|
+
|
|
757
|
+
await expect(eventManager.emit("echo", {})).rejects.toThrow(
|
|
758
|
+
"Async error",
|
|
759
|
+
);
|
|
760
|
+
});
|
|
761
|
+
});
|
|
762
|
+
});
|