alepha 0.14.1 → 0.14.3
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 +3 -3
- 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 +784 -784
- 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 +57 -57
- 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 +165 -165
- 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 +583 -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 +281 -276
- 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 +778 -764
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +831 -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 +125 -125
- 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/batch/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/cache/core/index.js.map +1 -1
- package/dist/cli/index.d.ts +249 -218
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +951 -821
- package/dist/cli/index.js.map +1 -1
- package/dist/command/index.d.ts +40 -0
- package/dist/command/index.d.ts.map +1 -1
- package/dist/command/index.js +97 -17
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js +14 -18
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +29 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +21 -24
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +21 -24
- package/dist/core/index.native.js.map +1 -1
- package/dist/datetime/index.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/lock/redis/index.js.map +1 -1
- package/dist/logger/index.js.map +1 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/orm/index.browser.js +26 -5
- package/dist/orm/index.browser.js.map +1 -1
- package/dist/orm/index.d.ts +146 -121
- package/dist/orm/index.d.ts.map +1 -1
- package/dist/orm/index.js +49 -24
- package/dist/orm/index.js.map +1 -1
- package/dist/redis/index.js.map +1 -1
- package/dist/retry/index.js.map +1 -1
- package/dist/router/index.js.map +1 -1
- package/dist/scheduler/index.d.ts +6 -6
- package/dist/scheduler/index.js.map +1 -1
- package/dist/security/index.d.ts +29 -29
- 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.js.map +1 -1
- package/dist/server/compress/index.d.ts.map +1 -1
- package/dist/server/compress/index.js +2 -0
- package/dist/server/compress/index.js.map +1 -1
- package/dist/server/cookies/index.browser.js.map +1 -1
- package/dist/server/cookies/index.js.map +1 -1
- package/dist/server/core/index.browser.js.map +1 -1
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js +1 -1
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/health/index.d.ts +17 -17
- package/dist/server/helmet/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/multipart/index.js.map +1 -1
- package/dist/server/rate-limit/index.js.map +1 -1
- package/dist/server/security/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 +8 -3
- package/dist/server/swagger/index.js.map +1 -1
- package/dist/thread/index.js.map +1 -1
- package/dist/topic/core/index.js.map +1 -1
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +12 -4
- package/dist/vite/index.js.map +1 -1
- package/dist/websocket/index.browser.js.map +1 -1
- package/dist/websocket/index.js.map +1 -1
- 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 +13 -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 +54 -16
- package/src/cli/apps/AlephaPackageBuilderCli.ts +2 -1
- package/src/cli/assets/appRouterTs.ts +1 -1
- package/src/cli/commands/{ViteCommands.ts → build.ts} +2 -105
- package/src/cli/commands/clean.ts +14 -0
- package/src/cli/commands/{DrizzleCommands.ts → db.ts} +10 -117
- package/src/cli/commands/{DeployCommands.ts → deploy.ts} +1 -1
- package/src/cli/commands/dev.ts +69 -0
- package/src/cli/commands/format.ts +17 -0
- package/src/cli/commands/gen/changelog.spec.ts +315 -0
- package/src/cli/commands/{ChangelogCommands.ts → gen/changelog.ts} +16 -31
- package/src/cli/commands/gen/openapi.ts +71 -0
- package/src/cli/commands/gen.ts +18 -0
- package/src/cli/commands/{CoreCommands.ts → init.ts} +4 -40
- package/src/cli/commands/lint.ts +17 -0
- package/src/cli/commands/root.ts +41 -0
- package/src/cli/commands/run.ts +24 -0
- package/src/cli/commands/test.ts +42 -0
- package/src/cli/commands/typecheck.ts +24 -0
- package/src/cli/commands/{VerifyCommands.ts → verify.ts} +1 -13
- package/src/cli/defineConfig.ts +10 -1
- package/src/cli/index.ts +17 -7
- package/src/cli/services/AlephaCliUtils.ts +71 -32
- 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/primitives/$command.spec.ts +1588 -0
- package/src/command/providers/CliProvider.ts +74 -24
- package/src/core/Alepha.ts +52 -4
- 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/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/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.browser.ts +1 -1
- package/src/orm/index.ts +10 -6
- 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/{PostgresTypeProvider.ts → DatabaseTypeProvider.ts} +25 -3
- 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 +378 -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 +942 -0
- package/src/server/compress/providers/ServerCompressProvider.spec.ts +31 -0
- package/src/server/compress/providers/ServerCompressProvider.ts +2 -0
- 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/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 +3 -1
- 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/swagger/__tests__/ui.spec.ts +52 -0
- package/src/server/swagger/primitives/$swagger.spec.ts +193 -0
- package/src/server/swagger/providers/ServerSwaggerProvider.ts +18 -8
- 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/plugins/viteAlephaDev.ts +16 -4
- 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/commands/BiomeCommands.ts +0 -29
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { $inject, t } from "alepha";
|
|
2
|
+
import { $command } from "alepha/command";
|
|
3
|
+
import { AlephaCliUtils } from "../services/AlephaCliUtils.ts";
|
|
4
|
+
|
|
5
|
+
export class TestCommand {
|
|
6
|
+
protected readonly utils = $inject(AlephaCliUtils);
|
|
7
|
+
|
|
8
|
+
public readonly test = $command({
|
|
9
|
+
name: "test",
|
|
10
|
+
description: "Run tests using Vitest",
|
|
11
|
+
flags: t.object({
|
|
12
|
+
config: t.optional(
|
|
13
|
+
t.string({
|
|
14
|
+
description: "Path to Vitest config file",
|
|
15
|
+
alias: "c",
|
|
16
|
+
}),
|
|
17
|
+
),
|
|
18
|
+
}),
|
|
19
|
+
env: t.object({
|
|
20
|
+
VITEST_ARGS: t.optional(
|
|
21
|
+
t.string({
|
|
22
|
+
default: "",
|
|
23
|
+
description:
|
|
24
|
+
"Additional arguments to pass to Vitest. E.g., --coverage",
|
|
25
|
+
}),
|
|
26
|
+
),
|
|
27
|
+
}),
|
|
28
|
+
handler: async ({ root, flags, env }) => {
|
|
29
|
+
await this.utils.ensureConfig(root, {
|
|
30
|
+
tsconfigJson: true,
|
|
31
|
+
viteConfigTs: true,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Ensure vitest is installed before running
|
|
35
|
+
await this.utils.ensureDependency(root, "vitest");
|
|
36
|
+
|
|
37
|
+
const config = flags.config ? `--config=${flags.config}` : "";
|
|
38
|
+
|
|
39
|
+
await this.utils.exec(`vitest run ${config} ${env.VITEST_ARGS}`);
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { $inject } from "alepha";
|
|
2
|
+
import { $command } from "alepha/command";
|
|
3
|
+
import { $logger } from "alepha/logger";
|
|
4
|
+
import { AlephaCliUtils } from "../services/AlephaCliUtils.ts";
|
|
5
|
+
|
|
6
|
+
export class TypecheckCommand {
|
|
7
|
+
protected readonly utils = $inject(AlephaCliUtils);
|
|
8
|
+
protected readonly log = $logger();
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Run TypeScript type checking across the codebase with no emit.
|
|
12
|
+
*/
|
|
13
|
+
public readonly typecheck = $command({
|
|
14
|
+
name: "typecheck",
|
|
15
|
+
aliases: ["tc"],
|
|
16
|
+
description: "Check TypeScript types across the codebase",
|
|
17
|
+
handler: async ({ root }) => {
|
|
18
|
+
this.log.info("Starting TypeScript type checking...");
|
|
19
|
+
await this.utils.ensureDependency(root, "typescript");
|
|
20
|
+
await this.utils.exec("tsc --noEmit");
|
|
21
|
+
this.log.info("TypeScript type checking completed successfully.");
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
}
|
|
@@ -2,7 +2,7 @@ import { $inject } from "alepha";
|
|
|
2
2
|
import { $command } from "alepha/command";
|
|
3
3
|
import { AlephaCliUtils } from "../services/AlephaCliUtils.ts";
|
|
4
4
|
|
|
5
|
-
export class
|
|
5
|
+
export class VerifyCommand {
|
|
6
6
|
protected readonly utils = $inject(AlephaCliUtils);
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -44,16 +44,4 @@ export class VerifyCommands {
|
|
|
44
44
|
await run("alepha clean");
|
|
45
45
|
},
|
|
46
46
|
});
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Run TypeScript type checking across the codebase with no emit.
|
|
50
|
-
*/
|
|
51
|
-
public readonly typecheck = $command({
|
|
52
|
-
name: "typecheck",
|
|
53
|
-
description: "Check TypeScript types across the codebase",
|
|
54
|
-
handler: async ({ root }) => {
|
|
55
|
-
await this.utils.ensureDependency(root, "typescript");
|
|
56
|
-
await this.utils.exec("tsc --noEmit");
|
|
57
|
-
},
|
|
58
|
-
});
|
|
59
47
|
}
|
package/src/cli/defineConfig.ts
CHANGED
|
@@ -3,13 +3,22 @@ import type { CommandPrimitive } from "alepha/command";
|
|
|
3
3
|
|
|
4
4
|
export type AlephaCliConfig = (alepha: Alepha) => {
|
|
5
5
|
commands?: Record<string, CommandPrimitive>;
|
|
6
|
+
services?: Array<any>;
|
|
6
7
|
};
|
|
7
8
|
|
|
8
9
|
export const defineConfig = (config: AlephaCliConfig) => {
|
|
9
10
|
return (alepha: Alepha) => {
|
|
10
|
-
const { commands } = config(alepha);
|
|
11
|
+
const { commands, services = [] } = config(alepha);
|
|
12
|
+
for (const it of services) {
|
|
13
|
+
alepha.with(it);
|
|
14
|
+
}
|
|
11
15
|
return {
|
|
12
16
|
...commands,
|
|
13
17
|
};
|
|
14
18
|
};
|
|
15
19
|
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @alias defineConfig
|
|
23
|
+
*/
|
|
24
|
+
export const defineAlephaConfig = defineConfig;
|
package/src/cli/index.ts
CHANGED
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
export * from "./apps/AlephaCli.ts";
|
|
2
2
|
export * from "./apps/AlephaPackageBuilderCli.ts";
|
|
3
|
-
export * from "./
|
|
4
|
-
export * from "./commands/
|
|
5
|
-
export * from "./commands/
|
|
6
|
-
export * from "./commands/
|
|
7
|
-
export * from "./commands/
|
|
8
|
-
export * from "./commands/
|
|
9
|
-
export * from "./commands/
|
|
3
|
+
export * from "./atoms/changelogOptions.ts";
|
|
4
|
+
export * from "./commands/build.ts";
|
|
5
|
+
export * from "./commands/clean.ts";
|
|
6
|
+
export * from "./commands/db.ts";
|
|
7
|
+
export * from "./commands/deploy.ts";
|
|
8
|
+
export * from "./commands/dev.ts";
|
|
9
|
+
export * from "./commands/format.ts";
|
|
10
|
+
export * from "./commands/gen/changelog.ts";
|
|
11
|
+
export * from "./commands/gen/openapi.ts";
|
|
12
|
+
export * from "./commands/init.ts";
|
|
13
|
+
export * from "./commands/lint.ts";
|
|
14
|
+
export * from "./commands/root.ts";
|
|
15
|
+
export * from "./commands/run.ts";
|
|
16
|
+
export * from "./commands/test.ts";
|
|
17
|
+
export * from "./commands/typecheck.ts";
|
|
18
|
+
export * from "./commands/verify.ts";
|
|
10
19
|
export * from "./defineConfig.ts";
|
|
11
20
|
export * from "./services/AlephaCliUtils.ts";
|
|
21
|
+
export * from "./services/GitMessageParser.ts";
|
|
12
22
|
export * from "./version.ts";
|
|
@@ -6,7 +6,6 @@ import { EnvUtils, type RunnerMethod } from "alepha/command";
|
|
|
6
6
|
import { FileSystemProvider } from "alepha/file";
|
|
7
7
|
import { $logger } from "alepha/logger";
|
|
8
8
|
import { boot } from "alepha/vite";
|
|
9
|
-
import { tsImport } from "tsx/esm/api";
|
|
10
9
|
import { appRouterTs } from "../assets/appRouterTs.ts";
|
|
11
10
|
import { biomeJson } from "../assets/biomeJson.ts";
|
|
12
11
|
import { dummySpecTs } from "../assets/dummySpecTs.ts";
|
|
@@ -32,6 +31,7 @@ export class AlephaCliUtils {
|
|
|
32
31
|
protected readonly log = $logger();
|
|
33
32
|
protected readonly fs = $inject(FileSystemProvider);
|
|
34
33
|
protected readonly envUtils = $inject(EnvUtils);
|
|
34
|
+
protected readonly alepha = $inject(Alepha);
|
|
35
35
|
|
|
36
36
|
/**
|
|
37
37
|
* Execute a command using npx with inherited stdio.
|
|
@@ -142,6 +142,40 @@ export class AlephaCliUtils {
|
|
|
142
142
|
// Package Manager & Project Setup
|
|
143
143
|
// ===================================================================================================================
|
|
144
144
|
|
|
145
|
+
public async removeFiles(root: string, files: string[]): Promise<void> {
|
|
146
|
+
await Promise.all(
|
|
147
|
+
files.map((file) =>
|
|
148
|
+
this.fs.rm(join(root, file), { force: true, recursive: true }),
|
|
149
|
+
),
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
public async removeYarn(root: string): Promise<void> {
|
|
154
|
+
await this.removeFiles(root, [".yarn", ".yarnrc.yml", ".yarn"]);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
public async removePnpm(root: string): Promise<void> {
|
|
158
|
+
await this.removeFiles(root, ["pnpm-lock.yaml", "pnpm-workspace.yaml"]);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
public async removeNpm(root: string): Promise<void> {
|
|
162
|
+
await this.removeFiles(root, ["package-lock.json"]);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
public async removeBun(root: string): Promise<void> {
|
|
166
|
+
await this.removeFiles(root, ["bun.lockb"]);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
public async removeAllPmFilesExcept(
|
|
170
|
+
root: string,
|
|
171
|
+
except: string,
|
|
172
|
+
): Promise<void> {
|
|
173
|
+
if (except !== "yarn") await this.removeYarn(root);
|
|
174
|
+
if (except !== "pnpm") await this.removePnpm(root);
|
|
175
|
+
if (except !== "npm") await this.removeNpm(root);
|
|
176
|
+
if (except !== "bun") await this.removeBun(root);
|
|
177
|
+
}
|
|
178
|
+
|
|
145
179
|
/**
|
|
146
180
|
* Ensure Yarn is configured in the project directory.
|
|
147
181
|
*
|
|
@@ -157,25 +191,19 @@ export class AlephaCliUtils {
|
|
|
157
191
|
false,
|
|
158
192
|
);
|
|
159
193
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
194
|
+
await this.removeAllPmFilesExcept(root, "yarn");
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
public async ensureBun(root: string): Promise<void> {
|
|
198
|
+
await this.removeAllPmFilesExcept(root, "bun");
|
|
163
199
|
}
|
|
164
200
|
|
|
165
201
|
public async ensurePnpm(root: string): Promise<void> {
|
|
166
|
-
|
|
167
|
-
await this.fs.rm(join(root, "package-lock.json"), { force: true });
|
|
168
|
-
await this.fs.rm(join(root, "yarn.lock"), { force: true });
|
|
169
|
-
await this.fs.rm(join(root, ".yarn"), { force: true, recursive: true });
|
|
170
|
-
await this.fs.rm(join(root, ".yarnrc.yml"), { force: true });
|
|
202
|
+
await this.removeAllPmFilesExcept(root, "pnpm");
|
|
171
203
|
}
|
|
172
204
|
|
|
173
205
|
public async ensureNpm(root: string): Promise<void> {
|
|
174
|
-
|
|
175
|
-
await this.fs.rm(join(root, "pnpm-lock.yaml"), { force: true });
|
|
176
|
-
await this.fs.rm(join(root, "yarn.lock"), { force: true });
|
|
177
|
-
await this.fs.rm(join(root, ".yarn"), { force: true, recursive: true });
|
|
178
|
-
await this.fs.rm(join(root, ".yarnrc.yml"), { force: true });
|
|
206
|
+
await this.removeAllPmFilesExcept(root, "npm");
|
|
179
207
|
}
|
|
180
208
|
|
|
181
209
|
/**
|
|
@@ -436,9 +464,10 @@ export class AlephaCliUtils {
|
|
|
436
464
|
process.env.ALEPHA_CLI_IMPORT = "true";
|
|
437
465
|
|
|
438
466
|
const entry = await boot.getServerEntry(rootDir, explicitEntry);
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
467
|
+
|
|
468
|
+
delete (global as any).__alepha;
|
|
469
|
+
|
|
470
|
+
const mod = await import(entry);
|
|
442
471
|
|
|
443
472
|
this.log.debug(`Load entry: ${entry}`);
|
|
444
473
|
|
|
@@ -523,6 +552,9 @@ ${models.map((it: string) => `export const ${it} = models["${it}"];`).join("\n")
|
|
|
523
552
|
if (flags?.bun) {
|
|
524
553
|
return "bun";
|
|
525
554
|
}
|
|
555
|
+
if (this.alepha.isBun()) {
|
|
556
|
+
return "bun";
|
|
557
|
+
}
|
|
526
558
|
if (await this.checkFileExists(root, "yarn.lock", true)) {
|
|
527
559
|
return "yarn";
|
|
528
560
|
}
|
|
@@ -659,6 +691,27 @@ ${models.map((it: string) => `export const ${it} = models["${it}"];`).join("\n")
|
|
|
659
691
|
return this.hasDependency(root, "expo");
|
|
660
692
|
}
|
|
661
693
|
|
|
694
|
+
async getInstallCommand(root: string, packageName: string, dev = true) {
|
|
695
|
+
const pm = await this.getPackageManager(root);
|
|
696
|
+
let cmd: string;
|
|
697
|
+
|
|
698
|
+
switch (pm) {
|
|
699
|
+
case "yarn":
|
|
700
|
+
cmd = `yarn add ${dev ? "-D" : ""} ${packageName}`;
|
|
701
|
+
break;
|
|
702
|
+
case "pnpm":
|
|
703
|
+
cmd = `pnpm add ${dev ? "-D" : ""} ${packageName}`;
|
|
704
|
+
break;
|
|
705
|
+
case "bun":
|
|
706
|
+
cmd = `bun add ${dev ? "-d" : ""} ${packageName}`;
|
|
707
|
+
break;
|
|
708
|
+
default:
|
|
709
|
+
cmd = `npm install ${dev ? "--save-dev" : ""} ${packageName}`;
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
return cmd.replace(/\s+/g, " ").trim();
|
|
713
|
+
}
|
|
714
|
+
|
|
662
715
|
/**
|
|
663
716
|
* Install a dependency if it's missing from the project.
|
|
664
717
|
*
|
|
@@ -677,21 +730,7 @@ ${models.map((it: string) => `export const ${it} = models["${it}"];`).join("\n")
|
|
|
677
730
|
return;
|
|
678
731
|
}
|
|
679
732
|
|
|
680
|
-
const
|
|
681
|
-
let cmd: string;
|
|
682
|
-
|
|
683
|
-
switch (pm) {
|
|
684
|
-
case "yarn":
|
|
685
|
-
cmd = `yarn add ${dev ? "-D" : ""} ${packageName}`;
|
|
686
|
-
break;
|
|
687
|
-
case "pnpm":
|
|
688
|
-
cmd = `pnpm add ${dev ? "-D" : ""} ${packageName}`;
|
|
689
|
-
break;
|
|
690
|
-
default:
|
|
691
|
-
cmd = `npm install ${dev ? "--save-dev" : ""} ${packageName}`;
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
cmd = cmd.replace(/\s+/g, " ").trim();
|
|
733
|
+
const cmd = await this.getInstallCommand(root, packageName, dev);
|
|
695
734
|
|
|
696
735
|
if (options.run) {
|
|
697
736
|
// if it's during a Runner flow, just use the runner's run method
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
type ChangelogOptions,
|
|
4
4
|
DEFAULT_IGNORE,
|
|
5
5
|
} from "../atoms/changelogOptions.ts";
|
|
6
|
-
import type { Commit } from "../commands/
|
|
6
|
+
import type { Commit } from "../commands/gen/changelog.ts";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Service for parsing git commit messages into structured format.
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { Alepha, AlephaError, t } from "alepha";
|
|
2
|
+
import {
|
|
3
|
+
LogDestinationProvider,
|
|
4
|
+
MemoryDestinationProvider,
|
|
5
|
+
} from "alepha/logger";
|
|
6
|
+
import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
|
|
7
|
+
import { Asker } from "../index.ts";
|
|
8
|
+
|
|
9
|
+
describe("Asker", () => {
|
|
10
|
+
let alepha: Alepha;
|
|
11
|
+
let asker: Asker;
|
|
12
|
+
let mockLogger: MemoryDestinationProvider;
|
|
13
|
+
|
|
14
|
+
const mockPromptInterface = (answers: string[]) => {
|
|
15
|
+
const question = vi.fn();
|
|
16
|
+
for (const answer of answers) {
|
|
17
|
+
question.mockResolvedValueOnce(answer);
|
|
18
|
+
}
|
|
19
|
+
const close = vi.fn();
|
|
20
|
+
|
|
21
|
+
vi.spyOn(
|
|
22
|
+
asker as unknown as { createPromptInterface: () => any },
|
|
23
|
+
"createPromptInterface",
|
|
24
|
+
).mockReturnValue({
|
|
25
|
+
question,
|
|
26
|
+
close,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
return { question, close };
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
beforeEach(() => {
|
|
33
|
+
alepha = Alepha.create({
|
|
34
|
+
env: {
|
|
35
|
+
LOG_LEVEL: "info",
|
|
36
|
+
},
|
|
37
|
+
})
|
|
38
|
+
.with({
|
|
39
|
+
provide: LogDestinationProvider,
|
|
40
|
+
use: MemoryDestinationProvider,
|
|
41
|
+
})
|
|
42
|
+
.with(Asker);
|
|
43
|
+
|
|
44
|
+
asker = alepha.inject(Asker);
|
|
45
|
+
mockLogger = alepha.inject(MemoryDestinationProvider);
|
|
46
|
+
mockLogger.clear();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
afterEach(() => {
|
|
50
|
+
vi.restoreAllMocks();
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test("returns trimmed string when no schema is provided", async () => {
|
|
54
|
+
const { question, close } = mockPromptInterface([" hello world "]);
|
|
55
|
+
|
|
56
|
+
const result = await asker.ask("What is your name?");
|
|
57
|
+
|
|
58
|
+
expect(result).toBe("hello world");
|
|
59
|
+
expect(question).toHaveBeenCalledTimes(1);
|
|
60
|
+
expect(question).toHaveBeenCalledWith("What is your name?\n> ");
|
|
61
|
+
expect(close).toHaveBeenCalledTimes(1);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test("retries until schema validation passes", async () => {
|
|
65
|
+
const { question, close } = mockPromptInterface(["abc", "41"]);
|
|
66
|
+
|
|
67
|
+
const result = await asker.ask("Enter a number", {
|
|
68
|
+
schema: t.number(),
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
expect(result).toBe(41);
|
|
72
|
+
expect(question).toHaveBeenCalledTimes(2);
|
|
73
|
+
expect(close).toHaveBeenCalledTimes(1);
|
|
74
|
+
expect(mockLogger.logs.some((log) => log.level === "ERROR")).toBe(true);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test("uses schema defaults when the user provides an empty answer", async () => {
|
|
78
|
+
const { question, close } = mockPromptInterface([""]);
|
|
79
|
+
|
|
80
|
+
const result = await asker.ask("What is your favorite color?", {
|
|
81
|
+
schema: t.text({ default: "blue" }),
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
expect(result).toBe("blue");
|
|
85
|
+
expect(question).toHaveBeenCalledTimes(1);
|
|
86
|
+
expect(close).toHaveBeenCalledTimes(1);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test("retries when custom validation throws an AlephaError", async () => {
|
|
90
|
+
const { question, close } = mockPromptInterface(["wrong", "right"]);
|
|
91
|
+
|
|
92
|
+
const result = await asker.ask("Provide the secret", {
|
|
93
|
+
schema: t.text(),
|
|
94
|
+
validate: (value) => {
|
|
95
|
+
if (value !== "right") {
|
|
96
|
+
throw new AlephaError("Invalid secret");
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
expect(result).toBe("right");
|
|
102
|
+
expect(question).toHaveBeenCalledTimes(2);
|
|
103
|
+
expect(close).toHaveBeenCalledTimes(1);
|
|
104
|
+
|
|
105
|
+
const errorLogs = mockLogger.logs.filter((log) => log.level === "ERROR");
|
|
106
|
+
expect(errorLogs).toHaveLength(1);
|
|
107
|
+
expect(errorLogs[0].message).toContain("Invalid secret");
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
test("propagates unexpected errors without logging", async () => {
|
|
111
|
+
const { question, close } = mockPromptInterface(["value"]);
|
|
112
|
+
const unexpectedError = new Error("boom");
|
|
113
|
+
|
|
114
|
+
await expect(
|
|
115
|
+
asker.ask("Trigger failure", {
|
|
116
|
+
schema: t.text(),
|
|
117
|
+
validate: () => {
|
|
118
|
+
throw unexpectedError;
|
|
119
|
+
},
|
|
120
|
+
}),
|
|
121
|
+
).rejects.toBe(unexpectedError);
|
|
122
|
+
|
|
123
|
+
expect(question).toHaveBeenCalledTimes(1);
|
|
124
|
+
expect(close).toHaveBeenCalledTimes(1);
|
|
125
|
+
expect(mockLogger.logs.some((log) => log.level === "ERROR")).toBe(false);
|
|
126
|
+
});
|
|
127
|
+
});
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { Alepha } from "alepha";
|
|
2
|
+
import {
|
|
3
|
+
LogDestinationProvider,
|
|
4
|
+
MemoryDestinationProvider,
|
|
5
|
+
} from "alepha/logger";
|
|
6
|
+
import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
|
|
7
|
+
import { Runner } from "../index.ts";
|
|
8
|
+
|
|
9
|
+
describe("Runner", () => {
|
|
10
|
+
let mockLogger: MemoryDestinationProvider;
|
|
11
|
+
let runner: Runner;
|
|
12
|
+
|
|
13
|
+
beforeEach(async () => {
|
|
14
|
+
const alepha = Alepha.create({
|
|
15
|
+
env: {
|
|
16
|
+
LOG_LEVEL: "info",
|
|
17
|
+
},
|
|
18
|
+
}).with({
|
|
19
|
+
provide: LogDestinationProvider,
|
|
20
|
+
use: MemoryDestinationProvider,
|
|
21
|
+
});
|
|
22
|
+
// Create a new MockLogger and Runner for each test to ensure isolation
|
|
23
|
+
runner = alepha.inject(Runner);
|
|
24
|
+
mockLogger = alepha.inject(MemoryDestinationProvider);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
afterEach(() => {
|
|
28
|
+
vi.clearAllMocks();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test("should execute a single shell command via run.sh", async () => {
|
|
32
|
+
await runner.run(`echo "hello"`);
|
|
33
|
+
|
|
34
|
+
expect(mockLogger.logs).toHaveLength(2);
|
|
35
|
+
const startLog = mockLogger.logs[0];
|
|
36
|
+
const finishLog = mockLogger.logs[1];
|
|
37
|
+
|
|
38
|
+
expect(startLog.message).toBe("Starting 'echo \"hello\"' ...");
|
|
39
|
+
expect(startLog.level).toBe("INFO");
|
|
40
|
+
|
|
41
|
+
expect(finishLog.message).toMatch(
|
|
42
|
+
/^Finished 'echo "hello"' after \d+\.\ds$/,
|
|
43
|
+
);
|
|
44
|
+
expect(finishLog.level).toBe("INFO");
|
|
45
|
+
|
|
46
|
+
const timers = (runner as any).timers;
|
|
47
|
+
expect(timers).toHaveLength(1);
|
|
48
|
+
expect(timers[0].name).toBe('echo "hello"');
|
|
49
|
+
expect(timers[0].duration).toMatch(/^\d+\.\ds$/);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test("should execute a single shell command via run(sh`...`)", async () => {
|
|
53
|
+
await runner.run(`echo "world"`);
|
|
54
|
+
expect(mockLogger.logs[0].message).toBe("Starting 'echo \"world\"' ...");
|
|
55
|
+
expect(mockLogger.logs).toHaveLength(2);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test("should execute a single function task via run.fn", async () => {
|
|
59
|
+
const mockFn = vi.fn();
|
|
60
|
+
await runner.run("my-test-function", mockFn);
|
|
61
|
+
|
|
62
|
+
expect(mockFn).toHaveBeenCalledOnce();
|
|
63
|
+
expect(mockLogger.logs).toHaveLength(2);
|
|
64
|
+
expect(mockLogger.logs[0].message).toBe("Starting 'my-test-function' ...");
|
|
65
|
+
expect(mockLogger.logs[1].message).toMatch(
|
|
66
|
+
/^Finished 'my-test-function' after \d+\.\ds$/,
|
|
67
|
+
);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test("should execute a single function task via run(fn(...))", async () => {
|
|
71
|
+
const mockFn = vi.fn();
|
|
72
|
+
await runner.run("another-function", mockFn);
|
|
73
|
+
expect(mockFn).toHaveBeenCalledOnce();
|
|
74
|
+
expect(mockLogger.logs).toHaveLength(2);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test("should execute an array of tasks in parallel", async () => {
|
|
78
|
+
const fn1 = vi.fn(() => new Promise((res) => setTimeout(res, 20)));
|
|
79
|
+
const fn2 = vi.fn(() => new Promise((res) => setTimeout(res, 20)));
|
|
80
|
+
|
|
81
|
+
await runner.run([
|
|
82
|
+
`echo "parallel sh"`,
|
|
83
|
+
{ name: "parallel fn 1", handler: fn1 },
|
|
84
|
+
{ name: "parallel fn 2", handler: fn2 },
|
|
85
|
+
]);
|
|
86
|
+
|
|
87
|
+
expect(fn1).toHaveBeenCalledOnce();
|
|
88
|
+
expect(fn2).toHaveBeenCalledOnce();
|
|
89
|
+
expect(mockLogger.logs).toHaveLength(6); // 3 start, 3 finish logs
|
|
90
|
+
expect((runner as any).timers).toHaveLength(3);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
test("should throw and log an error for a failing shell command", async () => {
|
|
94
|
+
await expect(runner.run(`exit 1`)).rejects.toThrow("Task 'exit 1' failed");
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test("should throw and log an error for a failing function task", async () => {
|
|
98
|
+
const error = new Error("Function failed!");
|
|
99
|
+
const failingFn = () => {
|
|
100
|
+
throw error;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
await expect(runner.run("failing-task", failingFn)).rejects.toThrow(
|
|
104
|
+
"Task 'failing-task' failed",
|
|
105
|
+
);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
test("summary() should print a formatted table of executed tasks", async () => {
|
|
109
|
+
await runner.run(`echo "Task 1"`);
|
|
110
|
+
await runner.run("A slightly longer task name", () => {});
|
|
111
|
+
|
|
112
|
+
runner.summary();
|
|
113
|
+
|
|
114
|
+
const logs = mockLogger.logs
|
|
115
|
+
.slice(4)
|
|
116
|
+
.map((l) => l.message)
|
|
117
|
+
.join("\n");
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
test("summary() should not print a table if no tasks were run", () => {
|
|
121
|
+
runner.summary();
|
|
122
|
+
|
|
123
|
+
const logs = mockLogger.logs.map((l) => l.message);
|
|
124
|
+
expect(logs.length).toBe(0);
|
|
125
|
+
});
|
|
126
|
+
});
|