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
|
@@ -105,12 +105,6 @@ export interface CommandPrimitiveOptions<
|
|
|
105
105
|
*/
|
|
106
106
|
args?: A;
|
|
107
107
|
|
|
108
|
-
/**
|
|
109
|
-
* If false, skip summary message at the end of the command execution.
|
|
110
|
-
* Summary will display only if ({ run }) method calls were made.
|
|
111
|
-
*/
|
|
112
|
-
summary?: boolean;
|
|
113
|
-
|
|
114
108
|
/**
|
|
115
109
|
* Marks this command as the root command.
|
|
116
110
|
* Equivalent to setting name to an empty string "".
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
t,
|
|
15
15
|
} from "alepha";
|
|
16
16
|
import { $logger } from "alepha/logger";
|
|
17
|
+
import { ConsoleColorProvider } from "../../logger/providers/ConsoleColorProvider.ts";
|
|
17
18
|
import { CommandError } from "../errors/CommandError.ts";
|
|
18
19
|
import { Asker } from "../helpers/Asker.ts";
|
|
19
20
|
import { EnvUtils } from "../helpers/EnvUtils.ts";
|
|
@@ -80,6 +81,7 @@ export class CliProvider {
|
|
|
80
81
|
protected readonly env = $env(envSchema);
|
|
81
82
|
protected readonly alepha = $inject(Alepha);
|
|
82
83
|
protected readonly log = $logger();
|
|
84
|
+
protected readonly color = $inject(ConsoleColorProvider);
|
|
83
85
|
protected readonly runner = $inject(Runner);
|
|
84
86
|
protected readonly asker = $inject(Asker);
|
|
85
87
|
protected readonly envUtils = $inject(EnvUtils);
|
|
@@ -235,9 +237,7 @@ export class CliProvider {
|
|
|
235
237
|
await hook.options.handler(args as CommandHandlerArgs<TObject>);
|
|
236
238
|
}
|
|
237
239
|
|
|
238
|
-
|
|
239
|
-
runner.summary();
|
|
240
|
-
}
|
|
240
|
+
runner.end();
|
|
241
241
|
|
|
242
242
|
this.log.debug(`Command '${command.name}' executed successfully.`);
|
|
243
243
|
});
|
|
@@ -708,17 +708,19 @@ export class CliProvider {
|
|
|
708
708
|
|
|
709
709
|
public printHelp(command?: CommandPrimitive<any>): void {
|
|
710
710
|
const cliName = this.name || "cli";
|
|
711
|
+
const c = this.color;
|
|
711
712
|
this.log.info(""); // Newline
|
|
712
713
|
|
|
713
714
|
if (command?.name) {
|
|
714
715
|
// Command-specific help
|
|
715
716
|
const hasChildren = command.hasChildren;
|
|
716
717
|
const argsUsage = hasChildren
|
|
717
|
-
? " <command>"
|
|
718
|
-
: this.
|
|
718
|
+
? ` ${c.set("CYAN", "<command>")}`
|
|
719
|
+
: this.generateColoredArgsUsage(command.options.args);
|
|
719
720
|
const commandPath = this.getCommandPath(command);
|
|
720
|
-
const usage =
|
|
721
|
-
|
|
721
|
+
const usage =
|
|
722
|
+
`${c.set("GREY_LIGHT", cliName)} ${c.set("CYAN", commandPath)}${argsUsage}`.trim();
|
|
723
|
+
this.log.info(`${c.set("WHITE_BOLD", "Usage:")} ${usage}`);
|
|
722
724
|
|
|
723
725
|
if (command.options.description) {
|
|
724
726
|
this.log.info(``);
|
|
@@ -728,7 +730,7 @@ export class CliProvider {
|
|
|
728
730
|
// Show subcommands if this is a parent command
|
|
729
731
|
if (hasChildren) {
|
|
730
732
|
this.log.info("");
|
|
731
|
-
this.log.info("Commands:");
|
|
733
|
+
this.log.info(c.set("WHITE_BOLD", "Commands:"));
|
|
732
734
|
const maxSubCmdLength = this.getMaxChildCmdLength(command.children);
|
|
733
735
|
|
|
734
736
|
for (const child of command.children) {
|
|
@@ -738,14 +740,18 @@ export class CliProvider {
|
|
|
738
740
|
const childArgsUsage = this.generateArgsUsage(child.options.args);
|
|
739
741
|
const cmdStr = [child.name, ...child.aliases].join(", ");
|
|
740
742
|
const fullCmdStr = `${cmdStr}${childArgsUsage}`;
|
|
743
|
+
const coloredCmd = `${c.set("GREY_LIGHT", cliName)} ${c.set("CYAN", command.name)} ${c.set("CYAN", fullCmdStr)}`;
|
|
744
|
+
const padding = " ".repeat(
|
|
745
|
+
Math.max(0, maxSubCmdLength - fullCmdStr.length),
|
|
746
|
+
);
|
|
741
747
|
this.log.info(
|
|
742
|
-
` ${
|
|
748
|
+
` ${coloredCmd}${padding} ${child.options.description ?? ""}`,
|
|
743
749
|
);
|
|
744
750
|
}
|
|
745
751
|
}
|
|
746
752
|
|
|
747
753
|
this.log.info("");
|
|
748
|
-
this.log.info("Flags:");
|
|
754
|
+
this.log.info(c.set("WHITE_BOLD", "Flags:"));
|
|
749
755
|
|
|
750
756
|
const flags = [
|
|
751
757
|
...Object.entries(command.flags.properties).map(([key, value]) => ({
|
|
@@ -778,23 +784,27 @@ export class CliProvider {
|
|
|
778
784
|
const flagStr = (Array.isArray(aliases) ? aliases : [aliases])
|
|
779
785
|
.map((a: string) => (a.length === 1 ? `-${a}` : `--${a}`))
|
|
780
786
|
.join(", ");
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
);
|
|
787
|
+
const coloredFlag = c.set("GREY_LIGHT", flagStr);
|
|
788
|
+
const padding = " ".repeat(Math.max(0, maxFlagLength - flagStr.length));
|
|
789
|
+
this.log.info(` ${coloredFlag}${padding} ${description ?? ""}`);
|
|
784
790
|
}
|
|
785
791
|
|
|
786
792
|
// Show environment variables if defined
|
|
787
793
|
const envVars = Object.entries(command.env.properties);
|
|
788
794
|
if (envVars.length > 0) {
|
|
789
795
|
this.log.info("");
|
|
790
|
-
this.log.info("Env:");
|
|
796
|
+
this.log.info(c.set("WHITE_BOLD", "Env:"));
|
|
791
797
|
const maxEnvLength = Math.max(...envVars.map(([key]) => key.length));
|
|
792
798
|
for (const [key, schema] of envVars) {
|
|
793
799
|
const isOptional = t.schema.isOptional(schema as TSchema);
|
|
794
800
|
const description = (schema as any).description ?? "";
|
|
795
|
-
const optionalStr = isOptional
|
|
801
|
+
const optionalStr = isOptional
|
|
802
|
+
? c.set("GREY_DARK", " (optional)")
|
|
803
|
+
: c.set("RED", " (required)");
|
|
804
|
+
const coloredKey = c.set("CYAN", key);
|
|
805
|
+
const padding = " ".repeat(Math.max(0, maxEnvLength - key.length));
|
|
796
806
|
this.log.info(
|
|
797
|
-
` ${
|
|
807
|
+
` ${coloredKey}${padding} ${description}${optionalStr}`,
|
|
798
808
|
);
|
|
799
809
|
}
|
|
800
810
|
}
|
|
@@ -802,30 +812,34 @@ export class CliProvider {
|
|
|
802
812
|
// general help
|
|
803
813
|
this.log.info(this.description || "Available commands:");
|
|
804
814
|
this.log.info("");
|
|
805
|
-
this.log.info("Commands:");
|
|
815
|
+
this.log.info(c.set("WHITE_BOLD", "Commands:"));
|
|
806
816
|
|
|
807
817
|
// Get top-level commands (commands that are not children of other commands)
|
|
808
818
|
const topLevelCommands = this.getTopLevelCommands();
|
|
809
819
|
const maxCmdLength = this.getMaxCmdLength(topLevelCommands);
|
|
810
820
|
|
|
811
|
-
for (const
|
|
821
|
+
for (const cmd of topLevelCommands) {
|
|
812
822
|
// skip root command and hooks in list
|
|
813
|
-
if (
|
|
823
|
+
if (cmd.name === "" || cmd.options.hide) {
|
|
814
824
|
continue;
|
|
815
825
|
}
|
|
816
826
|
|
|
817
|
-
const cmdStr = [
|
|
818
|
-
const argsUsage =
|
|
827
|
+
const cmdStr = [cmd.name, ...cmd.aliases].join(", ");
|
|
828
|
+
const argsUsage = cmd.hasChildren
|
|
819
829
|
? " <command>"
|
|
820
|
-
: this.generateArgsUsage(
|
|
830
|
+
: this.generateArgsUsage(cmd.options.args);
|
|
821
831
|
const fullCmdStr = `${cmdStr}${argsUsage}`;
|
|
832
|
+
const coloredCmd = `${c.set("GREY_LIGHT", cliName)} ${c.set("CYAN", fullCmdStr)}`;
|
|
833
|
+
const padding = " ".repeat(
|
|
834
|
+
Math.max(0, maxCmdLength - fullCmdStr.length),
|
|
835
|
+
);
|
|
822
836
|
this.log.info(
|
|
823
|
-
` ${
|
|
837
|
+
` ${coloredCmd}${padding} ${cmd.options.description ?? ""}`,
|
|
824
838
|
);
|
|
825
839
|
}
|
|
826
840
|
|
|
827
841
|
this.log.info("");
|
|
828
|
-
this.log.info("Flags:");
|
|
842
|
+
this.log.info(c.set("WHITE_BOLD", "Flags:"));
|
|
829
843
|
|
|
830
844
|
// In general help, also show root command flags
|
|
831
845
|
const rootCommand = this.commands.find((cmd) => cmd.name === "");
|
|
@@ -851,14 +865,48 @@ export class CliProvider {
|
|
|
851
865
|
const flagStr = aliases
|
|
852
866
|
.map((a) => (a.length === 1 ? `-${a}` : `--${a}`))
|
|
853
867
|
.join(", ");
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
);
|
|
868
|
+
const coloredFlag = c.set("GREY_LIGHT", flagStr);
|
|
869
|
+
const padding = " ".repeat(Math.max(0, maxFlagLength - flagStr.length));
|
|
870
|
+
this.log.info(` ${coloredFlag}${padding} ${description ?? ""}`);
|
|
857
871
|
}
|
|
858
872
|
}
|
|
859
873
|
this.log.info(""); // Newline
|
|
860
874
|
}
|
|
861
875
|
|
|
876
|
+
/**
|
|
877
|
+
* Generate colored args usage string for help display.
|
|
878
|
+
*/
|
|
879
|
+
protected generateColoredArgsUsage(schema?: TSchema): string {
|
|
880
|
+
if (!schema) {
|
|
881
|
+
return "";
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
const c = this.color;
|
|
885
|
+
|
|
886
|
+
if (t.schema.isOptional(schema)) {
|
|
887
|
+
const typeName = this.getTypeName(schema);
|
|
888
|
+
const key = "title" in schema ? (schema as any).title : "arg1";
|
|
889
|
+
return ` ${c.set("GREY_DARK", `[${key}${typeName}]`)}`;
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
if (t.schema.isTuple(schema) && schema.items) {
|
|
893
|
+
const items = schema.items;
|
|
894
|
+
const args = items.map((item, index) => {
|
|
895
|
+
const argName = `arg${index + 1}`;
|
|
896
|
+
const typeName = this.getTypeName(item);
|
|
897
|
+
if (t.schema.isOptional(item)) {
|
|
898
|
+
return c.set("GREY_DARK", `[${argName}${typeName}]`);
|
|
899
|
+
}
|
|
900
|
+
return c.set("CYAN", `<${argName}${typeName}>`);
|
|
901
|
+
});
|
|
902
|
+
return ` ${args.join(" ")}`;
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
const typeName = this.getTypeName(schema);
|
|
906
|
+
const key = "title" in schema ? (schema as any).title : "arg1";
|
|
907
|
+
return ` ${c.set("CYAN", `<${key}${typeName}>`)}`;
|
|
908
|
+
}
|
|
909
|
+
|
|
862
910
|
/**
|
|
863
911
|
* Get the full command path (e.g., "deploy vercel" for a child command).
|
|
864
912
|
*/
|
package/src/core/Alepha.ts
CHANGED
|
@@ -165,6 +165,13 @@ export class Alepha {
|
|
|
165
165
|
...state.env,
|
|
166
166
|
...process.env,
|
|
167
167
|
};
|
|
168
|
+
|
|
169
|
+
// remove empty env variables
|
|
170
|
+
for (const key in state.env) {
|
|
171
|
+
if (state.env[key] === "") {
|
|
172
|
+
delete (state.env as any)[key];
|
|
173
|
+
}
|
|
174
|
+
}
|
|
168
175
|
}
|
|
169
176
|
|
|
170
177
|
// force production mode when building with vite
|
|
@@ -482,9 +489,17 @@ export class Alepha {
|
|
|
482
489
|
|
|
483
490
|
const target = this.store.get("alepha.target");
|
|
484
491
|
if (target) {
|
|
492
|
+
this.modules = [];
|
|
485
493
|
this.registry = new Map();
|
|
486
494
|
this.primitiveRegistry = new Map();
|
|
495
|
+
this.pendingInstantiations = [];
|
|
496
|
+
this.substitutions = new Map();
|
|
497
|
+
this.events.clear();
|
|
498
|
+
delete (target as any)[MODULE];
|
|
487
499
|
this.with(target);
|
|
500
|
+
for (const [key] of this.substitutions.entries()) {
|
|
501
|
+
this.inject(key);
|
|
502
|
+
}
|
|
488
503
|
}
|
|
489
504
|
|
|
490
505
|
this.locked = true;
|
|
@@ -868,6 +883,15 @@ export class Alepha {
|
|
|
868
883
|
> = {};
|
|
869
884
|
|
|
870
885
|
for (const [provide, { parents }] of this.registry.entries()) {
|
|
886
|
+
if (provide.name === "") {
|
|
887
|
+
// ignore anonymous classes
|
|
888
|
+
continue;
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
if (Module.is(provide)) {
|
|
892
|
+
continue;
|
|
893
|
+
}
|
|
894
|
+
|
|
871
895
|
graph[provide.name] = {
|
|
872
896
|
from: parents.filter((it) => !!it).map((it) => it.name),
|
|
873
897
|
};
|
|
@@ -891,6 +915,27 @@ export class Alepha {
|
|
|
891
915
|
return graph;
|
|
892
916
|
}
|
|
893
917
|
|
|
918
|
+
public dump(): AlephaDump {
|
|
919
|
+
const env: Record<string, AlephaDumpEnvVariable> = {};
|
|
920
|
+
for (const [schema] of this.cacheEnv.entries()) {
|
|
921
|
+
const ref = schema as any;
|
|
922
|
+
for (const [key, value] of Object.entries(ref.properties)) {
|
|
923
|
+
const prop = value as any;
|
|
924
|
+
env[key] = {
|
|
925
|
+
description: prop.description,
|
|
926
|
+
default: prop.default,
|
|
927
|
+
required: ref.required?.includes(key) ?? undefined,
|
|
928
|
+
enum: prop.enum ? ([...prop.enum] as Array<string>) : undefined,
|
|
929
|
+
};
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
return {
|
|
934
|
+
env,
|
|
935
|
+
providers: this.graph(),
|
|
936
|
+
};
|
|
937
|
+
}
|
|
938
|
+
|
|
894
939
|
public services<T extends object>(base: Service<T>): Array<T> {
|
|
895
940
|
const list: Array<T> = [];
|
|
896
941
|
for (const [key, value] of this.registry.entries()) {
|
|
@@ -995,6 +1040,20 @@ export interface Hook<T extends keyof Hooks = any> {
|
|
|
995
1040
|
|
|
996
1041
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
997
1042
|
|
|
1043
|
+
export interface AlephaDump {
|
|
1044
|
+
env: Record<string, AlephaDumpEnvVariable>;
|
|
1045
|
+
providers: Record<string, { from: string[]; as?: string[]; module?: string }>;
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
export interface AlephaDumpEnvVariable {
|
|
1049
|
+
description: string;
|
|
1050
|
+
default?: string;
|
|
1051
|
+
required?: boolean;
|
|
1052
|
+
enum?: Array<string>;
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
// ---------------------------------------------------------------------------------------------------------------------
|
|
1056
|
+
|
|
998
1057
|
/**
|
|
999
1058
|
* This is how we store services in the Alepha container.
|
|
1000
1059
|
*/
|
|
@@ -1049,6 +1108,34 @@ export interface State {
|
|
|
1049
1108
|
|
|
1050
1109
|
/**
|
|
1051
1110
|
* If defined, the Alepha container will only register this service and its dependencies.
|
|
1111
|
+
*
|
|
1112
|
+
* @example
|
|
1113
|
+
* ```ts
|
|
1114
|
+
* class MigrateCmd {
|
|
1115
|
+
* db = $inject(DatabaseProvider);
|
|
1116
|
+
* alepha = $inject(Alepha);
|
|
1117
|
+
* env = $env(
|
|
1118
|
+
* t.object({
|
|
1119
|
+
* MIGRATE: t.optional(t.boolean()),
|
|
1120
|
+
* }),
|
|
1121
|
+
* );
|
|
1122
|
+
*
|
|
1123
|
+
* constructor() {
|
|
1124
|
+
* if (this.env.MIGRATE) {
|
|
1125
|
+
* this.alepha.set("alepha.target", MigrateCmd);
|
|
1126
|
+
* }
|
|
1127
|
+
* }
|
|
1128
|
+
*
|
|
1129
|
+
* ready = $hook({
|
|
1130
|
+
* on: "ready",
|
|
1131
|
+
* handler: async () => {
|
|
1132
|
+
* if (this.env.MIGRATE) {
|
|
1133
|
+
* await this.db.migrate();
|
|
1134
|
+
* }
|
|
1135
|
+
* },
|
|
1136
|
+
* });
|
|
1137
|
+
* }
|
|
1138
|
+
* ```
|
|
1052
1139
|
*/
|
|
1053
1140
|
"alepha.target"?: Service;
|
|
1054
1141
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Alepha } from "alepha";
|
|
2
|
+
import { describe, it } from "vitest";
|
|
3
|
+
|
|
4
|
+
describe("alepha.events.emit", () => {
|
|
5
|
+
it("should handle errors with catch option", async ({ expect }) => {
|
|
6
|
+
const alepha = Alepha.create();
|
|
7
|
+
|
|
8
|
+
alepha.events.on("echo", () => {
|
|
9
|
+
throw new Error("Error in echo");
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
await alepha.start();
|
|
13
|
+
|
|
14
|
+
await expect(() => alepha.events.emit("echo", {})).rejects.toThrowError(
|
|
15
|
+
"Error in echo",
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
expect(await alepha.events.emit("echo", {}, { catch: true })).toEqual(
|
|
19
|
+
undefined,
|
|
20
|
+
);
|
|
21
|
+
});
|
|
22
|
+
});
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { $inject, Alepha } from "alepha";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
|
|
4
|
+
describe("Alepha#graph", () => {
|
|
5
|
+
it("should generate dependency graph", async () => {
|
|
6
|
+
class A {
|
|
7
|
+
value = "a";
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
class B {
|
|
11
|
+
a = $inject(A);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
class C {
|
|
15
|
+
a = $inject(A);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
class M {
|
|
19
|
+
b = $inject(B);
|
|
20
|
+
c = $inject(C);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
class A3X {
|
|
24
|
+
value = "a3bis";
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
class A3 {
|
|
28
|
+
deps = $inject(A3X);
|
|
29
|
+
value = "a2";
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
class X {
|
|
33
|
+
value = "x";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
class X2 {
|
|
37
|
+
value = "x2";
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const a = Alepha.create();
|
|
41
|
+
|
|
42
|
+
a.with({
|
|
43
|
+
provide: A,
|
|
44
|
+
use: A3,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
a.with({
|
|
48
|
+
provide: X,
|
|
49
|
+
use: X2,
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
a.with(M);
|
|
53
|
+
|
|
54
|
+
await a.start();
|
|
55
|
+
|
|
56
|
+
expect(a.graph()).toEqual({
|
|
57
|
+
B: { from: ["M"] },
|
|
58
|
+
C: { from: ["M"] },
|
|
59
|
+
M: { from: ["Alepha"] },
|
|
60
|
+
A3X: { from: ["A3"] },
|
|
61
|
+
A3: { from: ["B", "C", "Alepha"], as: ["A"] },
|
|
62
|
+
X2: { from: ["Alepha"], as: ["X"] },
|
|
63
|
+
AlsProvider: {
|
|
64
|
+
from: ["StateManager", "Alepha"],
|
|
65
|
+
module: "alepha.core",
|
|
66
|
+
},
|
|
67
|
+
EventManager: {
|
|
68
|
+
from: ["StateManager", "Alepha"],
|
|
69
|
+
module: "alepha.core",
|
|
70
|
+
},
|
|
71
|
+
StateManager: {
|
|
72
|
+
from: ["Alepha"],
|
|
73
|
+
module: "alepha.core",
|
|
74
|
+
},
|
|
75
|
+
Json: {
|
|
76
|
+
from: ["JsonSchemaCodec"],
|
|
77
|
+
module: "alepha.core",
|
|
78
|
+
},
|
|
79
|
+
JsonSchemaCodec: {
|
|
80
|
+
from: ["StateManager", "CodecManager"],
|
|
81
|
+
module: "alepha.core",
|
|
82
|
+
},
|
|
83
|
+
CodecManager: {
|
|
84
|
+
from: ["Alepha"],
|
|
85
|
+
module: "alepha.core",
|
|
86
|
+
},
|
|
87
|
+
SchemaValidator: {
|
|
88
|
+
from: ["CodecManager"],
|
|
89
|
+
module: "alepha.core",
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { $inject, Alepha } from "alepha";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
|
|
4
|
+
class A {}
|
|
5
|
+
|
|
6
|
+
class B {}
|
|
7
|
+
|
|
8
|
+
class C {
|
|
9
|
+
a = $inject(A);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
class D {
|
|
13
|
+
alepha = $inject(Alepha);
|
|
14
|
+
constructor() {
|
|
15
|
+
if (this.alepha.has(A)) {
|
|
16
|
+
this.alepha.with(B);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
describe("Alepha#has", () => {
|
|
22
|
+
it("should check if service is registered", () => {
|
|
23
|
+
const container = new Alepha();
|
|
24
|
+
expect(container.has(A)).toBe(false);
|
|
25
|
+
expect(container.has(B)).toBe(false);
|
|
26
|
+
expect(container.has(C)).toBe(false);
|
|
27
|
+
container.with(C);
|
|
28
|
+
expect(container.has(A)).toBe(true);
|
|
29
|
+
expect(container.has(B)).toBe(false);
|
|
30
|
+
expect(container.has(C)).toBe(true);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it("should check service dependencies", () => {
|
|
34
|
+
const container = new Alepha().with(D);
|
|
35
|
+
expect(container.has(D)).toBe(true);
|
|
36
|
+
expect(container.has(B)).toBe(false);
|
|
37
|
+
const container2 = new Alepha().with(D).with(A);
|
|
38
|
+
expect(container2.has(D)).toBe(true);
|
|
39
|
+
expect(container2.has(B)).toBe(false);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { Alepha } from "alepha";
|
|
3
|
+
import { describe, expect, it } from "vitest";
|
|
4
|
+
|
|
5
|
+
describe("Alepha#inject", () => {
|
|
6
|
+
it("should handle transient lifetime", ({ expect }) => {
|
|
7
|
+
class Logger {
|
|
8
|
+
id = randomUUID();
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const alepha = new Alepha();
|
|
12
|
+
|
|
13
|
+
expect(alepha.inject(Logger, { lifetime: "transient" }).id).not.toBe(
|
|
14
|
+
alepha.inject(Logger, { lifetime: "transient" }).id,
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
const log = alepha.inject(Logger);
|
|
18
|
+
|
|
19
|
+
expect(log.id).toBe(alepha.inject(Logger).id);
|
|
20
|
+
|
|
21
|
+
expect(alepha.inject(Logger, { lifetime: "transient" }).id).not.toBe(
|
|
22
|
+
log.id,
|
|
23
|
+
);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("should handle transient lifetime with substitution", ({ expect }) => {
|
|
27
|
+
class BaseLogger {
|
|
28
|
+
print(msg: string): string {
|
|
29
|
+
return msg;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
class EmojiLogger extends BaseLogger {
|
|
34
|
+
print(msg: string): string {
|
|
35
|
+
return `${msg}π`;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const alepha = new Alepha().with({
|
|
40
|
+
provide: BaseLogger,
|
|
41
|
+
use: EmojiLogger,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const log = alepha.inject(BaseLogger, { lifetime: "transient" });
|
|
45
|
+
|
|
46
|
+
expect(log).toBeInstanceOf(EmojiLogger);
|
|
47
|
+
expect(log.print("Hello")).toBe("Helloπ");
|
|
48
|
+
|
|
49
|
+
expect(alepha.has(BaseLogger)).toBe(true);
|
|
50
|
+
|
|
51
|
+
// no trace of EmojiLogger in Alepha
|
|
52
|
+
expect(alepha.has(EmojiLogger)).toBe(false);
|
|
53
|
+
expect(alepha.has(BaseLogger, { inSubstitutions: false })).toBe(false);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("should handle scoped lifetime", ({ expect }) => {
|
|
57
|
+
class Request {
|
|
58
|
+
id = randomUUID();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const alepha = new Alepha();
|
|
62
|
+
|
|
63
|
+
const base = alepha.inject(Request, { lifetime: "scoped" });
|
|
64
|
+
|
|
65
|
+
expect(alepha.inject(Request, { lifetime: "scoped" }).id).toBe(base.id);
|
|
66
|
+
|
|
67
|
+
alepha.context.run(() => {
|
|
68
|
+
expect(alepha.inject(Request, { lifetime: "scoped" }).id).not.toBe(
|
|
69
|
+
base.id,
|
|
70
|
+
);
|
|
71
|
+
expect(alepha.inject(Request, { lifetime: "scoped" }).id).toBe(
|
|
72
|
+
alepha.inject(Request, { lifetime: "scoped" }).id,
|
|
73
|
+
);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("should pass constructor args correctly", () => {
|
|
78
|
+
class Logger {
|
|
79
|
+
constructor(public a: string) {}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const alepha = new Alepha();
|
|
83
|
+
|
|
84
|
+
expect(alepha.inject(Logger, { args: ["a"] }).a).toBe("a");
|
|
85
|
+
expect(alepha.inject(Logger).a).toBe("a");
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it("should inject Alepha instance itself", () => {
|
|
89
|
+
const alepha = new Alepha();
|
|
90
|
+
|
|
91
|
+
expect(alepha.inject(Alepha)).toBe(alepha);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { $inject, Alepha, TooLateSubstitutionError } from "alepha";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
|
|
4
|
+
describe("Alepha#with", () => {
|
|
5
|
+
it("should allow substitution", () => {
|
|
6
|
+
class A {
|
|
7
|
+
value = "a";
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
class M {
|
|
11
|
+
a = $inject(A);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
expect(
|
|
15
|
+
Alepha.create()
|
|
16
|
+
.with({
|
|
17
|
+
provide: A,
|
|
18
|
+
use: class extends A {
|
|
19
|
+
value = "z";
|
|
20
|
+
},
|
|
21
|
+
})
|
|
22
|
+
.inject(M).a.value,
|
|
23
|
+
).toBe("z");
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
class A {
|
|
27
|
+
a = "a";
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
class B {
|
|
31
|
+
a = "b";
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
class C {
|
|
35
|
+
a = "c";
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
class M {
|
|
39
|
+
a = $inject(A);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
it("should allow optional substitution", () => {
|
|
43
|
+
const T1 = Alepha.create().with(M);
|
|
44
|
+
expect(T1.inject(M).a.a).toBe("a");
|
|
45
|
+
|
|
46
|
+
const T2 = Alepha.create().with({
|
|
47
|
+
provide: A,
|
|
48
|
+
use: B,
|
|
49
|
+
});
|
|
50
|
+
expect(T2.inject(M).a.a).toBe("b");
|
|
51
|
+
|
|
52
|
+
const T3 = Alepha.create();
|
|
53
|
+
T3.with({
|
|
54
|
+
provide: A,
|
|
55
|
+
use: C,
|
|
56
|
+
optional: true,
|
|
57
|
+
});
|
|
58
|
+
expect(T3.inject(M).a.a).toBe("c");
|
|
59
|
+
|
|
60
|
+
const T4 = Alepha.create();
|
|
61
|
+
T4.with(M);
|
|
62
|
+
T4.with({
|
|
63
|
+
provide: A,
|
|
64
|
+
use: C,
|
|
65
|
+
optional: true,
|
|
66
|
+
});
|
|
67
|
+
expect(T1.inject(M).a.a).toBe("a");
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it("should reject substitution of already registered service", () => {
|
|
71
|
+
const T5 = Alepha.create();
|
|
72
|
+
T5.with(M);
|
|
73
|
+
expect(() =>
|
|
74
|
+
T5.with({
|
|
75
|
+
provide: A,
|
|
76
|
+
use: C,
|
|
77
|
+
optional: false, // should throw, because the default is already set
|
|
78
|
+
}),
|
|
79
|
+
).toThrow(TooLateSubstitutionError);
|
|
80
|
+
});
|
|
81
|
+
});
|