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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/api/notifications/entities/notifications.ts","../../../src/api/notifications/schemas/notificationCreateSchema.ts","../../../src/api/notifications/schemas/notificationQuerySchema.ts","../../../src/api/notifications/primitives/$notification.ts","../../../src/api/notifications/services/NotificationSenderService.ts","../../../src/api/notifications/services/NotificationService.ts","../../../src/api/notifications/controllers/NotificationController.ts","../../../src/api/notifications/jobs/NotificationJobs.ts","../../../src/api/notifications/queues/NotificationQueues.ts","../../../src/api/notifications/schemas/notificationContactPreferencesSchema.ts","../../../src/api/notifications/index.ts"],"sourcesContent":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/orm/schemas/insertSchema.ts","../../../src/orm/schemas/updateSchema.ts","../../../src/orm/primitives/$entity.ts","../../../src/orm/constants/PG_SYMBOLS.ts","../../../src/orm/helpers/pgAttr.ts","../../../src/orm/providers/drivers/NodePostgresProvider.ts","../../../src/orm/providers/drivers/NodeSqliteProvider.ts","../../../src/orm/index.ts","../../../src/api/notifications/entities/notifications.ts","../../../src/api/notifications/schemas/notificationCreateSchema.ts","../../../src/api/notifications/schemas/notificationQuerySchema.ts","../../../src/api/notifications/primitives/$notification.ts","../../../src/api/notifications/services/NotificationSenderService.ts","../../../src/api/notifications/services/NotificationService.ts","../../../src/api/notifications/controllers/AdminNotificationController.ts","../../../src/api/notifications/jobs/NotificationJobs.ts","../../../src/api/notifications/queues/NotificationQueues.ts","../../../src/api/notifications/schemas/notificationContactPreferencesSchema.ts","../../../src/api/notifications/index.ts"],"sourcesContent":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { $env, $inject, $module, Alepha, AlephaError, KIND, Primitive, createPrimitive, t } from "alepha";
|
|
2
|
-
import { $entity, $repository, pageQuerySchema, pg } from "alepha/orm";
|
|
3
2
|
import { $action } from "alepha/server";
|
|
3
|
+
import { $entity, $repository, db, pageQuerySchema } from "alepha/orm";
|
|
4
4
|
import { $batch } from "alepha/batch";
|
|
5
5
|
import { DateTimeProvider } from "alepha/datetime";
|
|
6
6
|
import { $logger } from "alepha/logger";
|
|
@@ -12,10 +12,10 @@ import { SmsProvider } from "alepha/sms";
|
|
|
12
12
|
const notifications = $entity({
|
|
13
13
|
name: "notifications",
|
|
14
14
|
schema: t.object({
|
|
15
|
-
id:
|
|
16
|
-
version:
|
|
17
|
-
createdAt:
|
|
18
|
-
updatedAt:
|
|
15
|
+
id: db.primaryKey(t.uuid()),
|
|
16
|
+
version: db.version(),
|
|
17
|
+
createdAt: db.createdAt(),
|
|
18
|
+
updatedAt: db.updatedAt(),
|
|
19
19
|
type: t.enum(["email", "sms"]),
|
|
20
20
|
template: t.text(),
|
|
21
21
|
category: t.optional(t.text({ description: "For grouping related notifications (e.g., 'authentication', 'marketing'). Contact can filter notifications by category." })),
|
|
@@ -333,10 +333,10 @@ var NotificationService = class {
|
|
|
333
333
|
};
|
|
334
334
|
|
|
335
335
|
//#endregion
|
|
336
|
-
//#region ../../src/api/notifications/controllers/
|
|
337
|
-
var
|
|
336
|
+
//#region ../../src/api/notifications/controllers/AdminNotificationController.ts
|
|
337
|
+
var AdminNotificationController = class {
|
|
338
338
|
url = "/notifications";
|
|
339
|
-
group = "notifications";
|
|
339
|
+
group = "admin:notifications";
|
|
340
340
|
notificationService = $inject(NotificationService);
|
|
341
341
|
/**
|
|
342
342
|
* Find notifications with pagination and filtering.
|
|
@@ -347,7 +347,7 @@ var NotificationController = class {
|
|
|
347
347
|
description: "Find notifications with pagination and filtering",
|
|
348
348
|
schema: {
|
|
349
349
|
query: notificationQuerySchema,
|
|
350
|
-
response:
|
|
350
|
+
response: t.page(notifications.schema)
|
|
351
351
|
},
|
|
352
352
|
handler: ({ query }) => this.notificationService.findNotifications(query)
|
|
353
353
|
});
|
|
@@ -380,7 +380,7 @@ const AlephaApiNotifications = $module({
|
|
|
380
380
|
name: "alepha.api.notifications",
|
|
381
381
|
primitives: [$notification],
|
|
382
382
|
services: [
|
|
383
|
-
|
|
383
|
+
AdminNotificationController,
|
|
384
384
|
NotificationService,
|
|
385
385
|
NotificationSenderService,
|
|
386
386
|
NotificationQueues,
|
|
@@ -388,10 +388,10 @@ const AlephaApiNotifications = $module({
|
|
|
388
388
|
],
|
|
389
389
|
register: (alepha) => {
|
|
390
390
|
if (alepha.parseEnv(notificationServiceEnvSchema).NOTIFICATION_QUEUE) alepha.with(NotificationQueues);
|
|
391
|
-
alepha.with(
|
|
391
|
+
alepha.with(AdminNotificationController).with(NotificationService).with(NotificationSenderService).with(NotificationJobs);
|
|
392
392
|
}
|
|
393
393
|
});
|
|
394
394
|
|
|
395
395
|
//#endregion
|
|
396
|
-
export { $notification,
|
|
396
|
+
export { $notification, AdminNotificationController, AlephaApiNotifications, NotificationJobs, NotificationPrimitive, NotificationQueues, NotificationSenderService, NotificationService, notificationContactPreferencesSchema, notificationCreateSchema, notificationQuerySchema, notificationServiceEnvSchema, notifications };
|
|
397
397
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["notifications"],"sources":["../../../src/api/notifications/entities/notifications.ts","../../../src/api/notifications/schemas/notificationQuerySchema.ts","../../../src/api/notifications/primitives/$notification.ts","../../../src/api/notifications/services/NotificationSenderService.ts","../../../src/api/notifications/queues/NotificationQueues.ts","../../../src/api/notifications/schemas/notificationCreateSchema.ts","../../../src/api/notifications/services/NotificationService.ts","../../../src/api/notifications/controllers/NotificationController.ts","../../../src/api/notifications/jobs/NotificationJobs.ts","../../../src/api/notifications/schemas/notificationContactPreferencesSchema.ts","../../../src/api/notifications/index.ts"],"sourcesContent":["import { type Static, t } from \"alepha\";\nimport { $entity, pg } from \"alepha/orm\";\n\nexport const notifications = $entity({\n name: \"notifications\",\n schema: t.object({\n id: pg.primaryKey(t.uuid()),\n\n version: pg.version(),\n\n createdAt: pg.createdAt(),\n\n updatedAt: pg.updatedAt(),\n\n // -----------------------------------------------------------------------------------------------------------------\n\n type: t.enum([\"email\", \"sms\"]),\n\n template: t.text(), // e.g. 'resetPassword'\n\n category: t.optional(\n t.text({\n description:\n \"For grouping related notifications (e.g., 'authentication', 'marketing'). Contact can filter notifications by category.\",\n }),\n ),\n\n critical: t.optional(\n t.boolean({\n description:\n \"Prioritize delivery of this notification. Set to true for important system alerts.\",\n }),\n ),\n\n sensitive: t.optional(\n t.boolean({\n description:\n \"Message won't be logged or stored in plain text. Set to true when notification contains passwords or codes.\",\n }),\n ),\n\n // -----------------------------------------------------------------------------------------------------------------\n\n contact: t.text(), // e.g. email address or phone number or user ID or whatever\n\n variables: t.optional(t.record(t.text(), t.any())),\n\n scheduledAt: t.optional(\n t.datetime({\n description:\n \"When set, the notification will be sent at or after this date/time.\",\n }),\n ),\n\n // -----------------------------------------------------------------------------------------------------------------\n\n sentAt: t.optional(t.datetime()),\n\n error: t.optional(\n t.object({\n at: t.datetime(),\n name: t.text(),\n message: t.text({ size: \"rich\" }),\n }),\n ),\n\n // TODO: retryCount, lastRetryAt, etc.\n }),\n});\n\nexport type NotificationEntity = Static<typeof notifications.schema>;\n","import type { Static } from \"alepha\";\nimport { t } from \"alepha\";\nimport { pageQuerySchema } from \"alepha/orm\";\n\nexport const notificationQuerySchema = t.extend(pageQuerySchema, {\n type: t.optional(t.enum([\"email\", \"sms\"])),\n template: t.optional(t.string()),\n contact: t.optional(t.string()),\n category: t.optional(t.string()),\n status: t.optional(t.enum([\"pending\", \"sent\", \"failed\"])),\n});\n\nexport type NotificationQuery = Static<typeof notificationQuerySchema>;\n","import {\n $inject,\n createPrimitive,\n KIND,\n Primitive,\n type Static,\n type StaticEncode,\n type TObject,\n} from \"alepha\";\nimport { NotificationService } from \"../services/NotificationService.ts\";\n\n/**\n * Creates a notification primitive for managing email/SMS notification templates.\n *\n * Provides type-safe, reusable notification templates with multi-language support,\n * variable substitution, and categorization for different notification channels.\n *\n * @example\n * ```ts\n * class NotificationTemplates {\n * welcomeEmail = $notification({\n * name: \"welcome-email\",\n * category: \"onboarding\",\n * schema: t.object({ username: t.text(), activationLink: t.text() }),\n * email: {\n * subject: \"Welcome to our platform!\",\n * body: (vars) => `Hello ${vars.username}, click: ${vars.activationLink}`\n * }\n * });\n *\n * async sendWelcome(user: User) {\n * await this.welcomeEmail.push({\n * variables: { username: user.name, activationLink: generateLink() },\n * contact: user.email\n * });\n * }\n * }\n * ```\n */\nexport const $notification = <T extends TObject>(\n options: NotificationPrimitiveOptions<T>,\n) => createPrimitive(NotificationPrimitive<T>, options);\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface NotificationPrimitiveOptions<T extends TObject>\n extends NotificationMessage<T> {\n name?: string;\n description?: string;\n category?: string;\n critical?: boolean;\n sensitive?: boolean;\n translations?: {\n // e.g., \"en\", \"fr\", even \"en-US\"\n [lang: string]: NotificationMessage<T>;\n };\n schema: T;\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport class NotificationPrimitive<T extends TObject> extends Primitive<\n NotificationPrimitiveOptions<T>\n> {\n protected readonly notificationService = $inject(NotificationService);\n\n public get name() {\n return this.options.name ?? `${this.config.propertyKey}`;\n }\n\n public async push(options: NotificationPushOptions<T>) {\n if (this.options.email) {\n await this.notificationService.createNotification({\n ...options,\n type: \"email\",\n template: this.name,\n });\n }\n }\n\n public configure(options: Partial<NotificationPrimitiveOptions<T>>) {\n Object.assign(this.options, options);\n }\n}\n\n$notification[KIND] = NotificationPrimitive;\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface NotificationPushOptions<T extends TObject> {\n variables: StaticEncode<T>;\n contact: string;\n}\n\nexport interface NotificationMessage<T extends TObject> {\n email?: {\n subject: string;\n body: string | ((variables: Static<T>) => string);\n };\n sms?: {\n message: string | ((variables: Static<T>) => string);\n };\n}\n","import { $inject, Alepha, AlephaError } from \"alepha\";\nimport { DateTimeProvider } from \"alepha/datetime\";\nimport { EmailProvider } from \"alepha/email\";\nimport { $logger } from \"alepha/logger\";\nimport { $repository } from \"alepha/orm\";\nimport { SmsProvider } from \"alepha/sms\";\nimport {\n type NotificationEntity,\n notifications,\n} from \"../entities/notifications.ts\";\nimport { $notification } from \"../primitives/$notification.ts\";\n\nexport class NotificationSenderService {\n protected readonly alepha = $inject(Alepha);\n protected readonly log = $logger();\n protected readonly notificationRepository = $repository(notifications);\n protected readonly dateTimeProvider = $inject(DateTimeProvider);\n protected readonly emailProvider = $inject(EmailProvider);\n protected readonly smsProvider = $inject(SmsProvider);\n\n public async send(notificationId: string | NotificationEntity) {\n this.log.trace(\"Sending notification\", {\n notificationId:\n typeof notificationId === \"string\" ? notificationId : notificationId.id,\n });\n\n const notification =\n typeof notificationId === \"string\"\n ? await this.notificationRepository.findById(notificationId)\n : notificationId;\n\n if (notification.sentAt) {\n this.log.debug(\"Notification already sent\", {\n notificationId: notification.id,\n sentAt: notification.sentAt,\n });\n return;\n }\n\n this.log.debug(\"Processing notification\", {\n id: notification.id,\n type: notification.type,\n template: notification.template,\n contact: notification.contact,\n });\n\n try {\n if (notification.type === \"email\") {\n await this.emailProvider.send(this.renderEmail(notification));\n notification.sentAt = this.dateTimeProvider.nowISOString();\n this.log.info(\"Email notification sent\", {\n id: notification.id,\n template: notification.template,\n contact: notification.contact,\n });\n }\n if (notification.type === \"sms\") {\n await this.smsProvider.send(this.renderSms(notification));\n notification.sentAt = this.dateTimeProvider.nowISOString();\n this.log.info(\"SMS notification sent\", {\n id: notification.id,\n template: notification.template,\n contact: notification.contact,\n });\n }\n } catch (e) {\n this.log.error(\"Failed to send notification\", {\n id: notification.id,\n type: notification.type,\n template: notification.template,\n contact: notification.contact,\n error: e,\n });\n if (e instanceof Error) {\n notification.error = {\n at: this.dateTimeProvider.nowISOString(),\n name: e.name,\n message: e.message,\n };\n }\n } finally {\n await this.notificationRepository.save(notification);\n }\n }\n\n public renderSms(notification: NotificationEntity) {\n this.log.trace(\"Rendering SMS notification\", {\n id: notification.id,\n template: notification.template,\n });\n\n const { variables, contact, template } = this.load(notification);\n\n const sms = template.options.sms;\n if (!sms) {\n this.log.error(\"Notification template has no SMS defined\", {\n id: notification.id,\n template: notification.template,\n });\n throw new AlephaError(\n `Notification template ${notification.template} has no sms defined`,\n );\n }\n\n this.log.debug(\"Rendering SMS\", {\n template: notification.template,\n contact,\n });\n\n const message =\n typeof sms.message === \"function\"\n ? sms.message(variables as any)\n : sms.message;\n\n return {\n to: contact,\n message,\n };\n }\n\n public renderEmail(notification: NotificationEntity) {\n this.log.trace(\"Rendering email notification\", {\n id: notification.id,\n template: notification.template,\n });\n\n const { variables, contact, template } = this.load(notification);\n\n const email = template.options.email;\n if (!email) {\n this.log.error(\"Notification template has no email defined\", {\n id: notification.id,\n template: notification.template,\n });\n throw new AlephaError(\n `Notification template ${notification.template} has no email defined`,\n );\n }\n\n this.log.debug(\"Rendering email\", {\n template: notification.template,\n contact,\n subject: email.subject,\n });\n\n const subject = email.subject;\n\n const body =\n typeof email.body === \"function\"\n ? email.body(variables as any)\n : email.body;\n\n return {\n to: contact,\n subject,\n body,\n };\n }\n\n protected load(notification: NotificationEntity) {\n const variables = notification.variables || {};\n const contact = notification.contact;\n const template = this.alepha\n .primitives($notification)\n .find((it) => it.name === notification.template);\n\n if (!template) {\n this.log.error(\"Notification template not found\", {\n id: notification.id,\n template: notification.template,\n });\n throw new AlephaError(\n `No notification template found for ${notification.template}`,\n );\n }\n\n return {\n template,\n variables,\n contact,\n };\n }\n}\n","import { $inject, t } from \"alepha\";\nimport { $queue } from \"alepha/queue\";\nimport { NotificationSenderService } from \"../services/NotificationSenderService.ts\";\n\nexport class NotificationQueues {\n protected readonly notificationSenderService = $inject(\n NotificationSenderService,\n );\n\n public readonly processNotification = $queue({\n description: \"Queue for processing notifications\",\n schema: t.object({\n notificationId: t.string({ format: \"uuid\" }),\n }),\n handler: async (message) => {\n await this.notificationSenderService.send(message.payload.notificationId);\n },\n });\n}\n","import { type Static, t } from \"alepha\";\nimport { notifications } from \"../entities/notifications.ts\";\n\nexport const notificationCreateSchema = t.pick(notifications.schema, [\n \"type\",\n \"contact\",\n \"template\",\n \"variables\",\n]);\n\nexport type NotificationCreate = Static<typeof notificationCreateSchema>;\n","import { $env, $inject, Alepha, type Static, t } from \"alepha\";\nimport { $batch } from \"alepha/batch\";\nimport { DateTimeProvider } from \"alepha/datetime\";\nimport { $logger } from \"alepha/logger\";\nimport { $repository, type Page } from \"alepha/orm\";\nimport {\n type NotificationEntity,\n notifications,\n} from \"../entities/notifications.ts\";\nimport { NotificationQueues } from \"../queues/NotificationQueues.ts\";\nimport {\n type NotificationCreate,\n notificationCreateSchema,\n} from \"../schemas/notificationCreateSchema.ts\";\nimport type { NotificationQuery } from \"../schemas/notificationQuerySchema.ts\";\nimport { NotificationSenderService } from \"./NotificationSenderService.ts\";\n\nexport const notificationServiceEnvSchema = t.object({\n NOTIFICATION_QUEUE: t.optional(\n t.boolean({\n description:\n \"If true, notifications will be queued instead of sent immediately\",\n }),\n ),\n});\n\ndeclare module \"alepha\" {\n interface Env extends Partial<Static<typeof notificationServiceEnvSchema>> {}\n}\n\nexport class NotificationService {\n protected readonly alepha = $inject(Alepha);\n protected readonly log = $logger();\n protected readonly env = $env(notificationServiceEnvSchema);\n protected readonly notificationRepository = $repository(notifications);\n protected readonly dateTimeProvider = $inject(DateTimeProvider);\n protected readonly notificationSenderService = $inject(\n NotificationSenderService,\n );\n\n public readonly notificationBatch = $batch({\n maxSize: 100,\n maxDuration: [15, \"seconds\"],\n schema: notificationCreateSchema,\n handler: async (notifications: NotificationCreate[]) => {\n this.log.debug(\"Processing notification batch\", {\n size: notifications.length,\n templates: [...new Set(notifications.map((n) => n.template))],\n });\n\n const entities =\n await this.notificationRepository.createMany(notifications);\n\n await this.alepha\n .inject(NotificationQueues)\n .processNotification.push(\n ...entities.map((it) => ({ notificationId: it.id })),\n );\n\n this.log.info(\"Notification batch queued\", {\n count: entities.length,\n ids: entities.map((it) => it.id),\n });\n },\n });\n\n public async findNotificationById(id: string) {\n this.log.trace(\"Finding notification by ID\", { id });\n return this.notificationRepository.findOne({ where: { id } });\n }\n\n public async findNotifications(\n q: NotificationQuery = {},\n ): Promise<Page<NotificationEntity>> {\n this.log.trace(\"Finding notifications\", { query: q });\n q.sort ??= \"-createdAt\";\n\n const where = this.notificationRepository.createQueryWhere();\n\n if (q.type) {\n where.type = { eq: q.type };\n }\n\n if (q.template) {\n where.template = { like: `%${q.template}%` };\n }\n\n if (q.contact) {\n where.contact = { like: `%${q.contact}%` };\n }\n\n if (q.category) {\n where.category = { eq: q.category };\n }\n\n if (q.status) {\n if (q.status === \"sent\") {\n where.sentAt = { isNotNull: true };\n where.error = { isNull: true };\n } else if (q.status === \"failed\") {\n where.error = { isNotNull: true };\n } else if (q.status === \"pending\") {\n where.sentAt = { isNull: true };\n where.error = { isNull: true };\n }\n }\n\n return this.notificationRepository.paginate(q, { where }, { count: true });\n }\n\n /**\n * Create a new notification.\n */\n public async createNotification(entry: NotificationCreate): Promise<void> {\n this.log.trace(\"Creating notification\", {\n template: entry.template,\n type: entry.type,\n contact: entry.contact,\n });\n\n if (\n this.env.NOTIFICATION_QUEUE !== true ||\n this.alepha.isServerless() ||\n this.alepha.isTest()\n ) {\n this.log.debug(\"Sending notification immediately\", {\n template: entry.template,\n type: entry.type,\n contact: entry.contact,\n });\n const notification = await this.notificationRepository.create(entry);\n await this.notificationSenderService.send(notification);\n return;\n }\n\n this.log.debug(\"Queuing notification to batch\", {\n template: entry.template,\n type: entry.type,\n contact: entry.contact,\n });\n\n this.notificationBatch.push(entry).catch((e) => {\n this.log.error(\"Failed to push notification to batch\", {\n template: entry.template,\n type: entry.type,\n contact: entry.contact,\n error: e,\n });\n });\n }\n}\n","import { $inject } from \"alepha\";\nimport { pg } from \"alepha/orm\";\nimport { $action } from \"alepha/server\";\nimport { notifications } from \"../entities/notifications.ts\";\nimport { notificationQuerySchema } from \"../schemas/notificationQuerySchema.ts\";\nimport { NotificationService } from \"../services/NotificationService.ts\";\n\nexport class NotificationController {\n protected readonly url = \"/notifications\";\n protected readonly group = \"notifications\";\n protected readonly notificationService = $inject(NotificationService);\n\n /**\n * Find notifications with pagination and filtering.\n */\n public readonly findNotifications = $action({\n path: this.url,\n group: this.group,\n description: \"Find notifications with pagination and filtering\",\n schema: {\n query: notificationQuerySchema,\n response: pg.page(notifications.schema),\n },\n handler: ({ query }) => this.notificationService.findNotifications(query),\n });\n}\n","export class NotificationJobs {\n // - retry (lost, failed) notifications\n // - purge old notifications\n}\n","import { type Static, t } from \"alepha\";\n\nexport const notificationContactPreferencesSchema = t.object({\n language: t.optional(t.text()),\n exclude: t.array(t.text()),\n});\n\nexport type NotificationContactPreferences = Static<\n typeof notificationContactPreferencesSchema\n>;\n","import { $module } from \"alepha\";\nimport { NotificationController } from \"./controllers/NotificationController.ts\";\nimport { NotificationJobs } from \"./jobs/NotificationJobs.ts\";\nimport { $notification } from \"./primitives/$notification.ts\";\nimport { NotificationQueues } from \"./queues/NotificationQueues.ts\";\nimport { NotificationSenderService } from \"./services/NotificationSenderService.ts\";\nimport {\n NotificationService,\n notificationServiceEnvSchema,\n} from \"./services/NotificationService.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./controllers/NotificationController.ts\";\nexport * from \"./entities/notifications.ts\";\nexport * from \"./jobs/NotificationJobs.ts\";\nexport * from \"./primitives/$notification.ts\";\nexport * from \"./queues/NotificationQueues.ts\";\nexport * from \"./schemas/notificationContactPreferencesSchema.ts\";\nexport * from \"./schemas/notificationCreateSchema.ts\";\nexport * from \"./schemas/notificationQuerySchema.ts\";\nexport * from \"./services/NotificationSenderService.ts\";\nexport * from \"./services/NotificationService.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Provides notification management API endpoints for Alepha applications.\n *\n * This module includes notification sending, retrieval, status tracking,\n * and user notification preferences management.\n *\n * Requires `AlephaSms` module to be loaded for SMS notifications.\n *\n * @module alepha.api.notifications\n */\nexport const AlephaApiNotifications = $module({\n name: \"alepha.api.notifications\",\n primitives: [$notification],\n services: [\n NotificationController,\n NotificationService,\n NotificationSenderService,\n NotificationQueues,\n NotificationJobs,\n ],\n register: (alepha) => {\n const env = alepha.parseEnv(notificationServiceEnvSchema);\n if (env.NOTIFICATION_QUEUE) {\n alepha.with(NotificationQueues);\n }\n\n alepha\n .with(NotificationController)\n .with(NotificationService)\n .with(NotificationSenderService)\n .with(NotificationJobs);\n },\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["notifications"],"sources":["../../../src/api/notifications/entities/notifications.ts","../../../src/api/notifications/schemas/notificationQuerySchema.ts","../../../src/api/notifications/primitives/$notification.ts","../../../src/api/notifications/services/NotificationSenderService.ts","../../../src/api/notifications/queues/NotificationQueues.ts","../../../src/api/notifications/schemas/notificationCreateSchema.ts","../../../src/api/notifications/services/NotificationService.ts","../../../src/api/notifications/controllers/AdminNotificationController.ts","../../../src/api/notifications/jobs/NotificationJobs.ts","../../../src/api/notifications/schemas/notificationContactPreferencesSchema.ts","../../../src/api/notifications/index.ts"],"sourcesContent":["import { type Static, t } from \"alepha\";\nimport { $entity, db } from \"alepha/orm\";\n\nexport const notifications = $entity({\n name: \"notifications\",\n schema: t.object({\n id: db.primaryKey(t.uuid()),\n\n version: db.version(),\n\n createdAt: db.createdAt(),\n\n updatedAt: db.updatedAt(),\n\n // -----------------------------------------------------------------------------------------------------------------\n\n type: t.enum([\"email\", \"sms\"]),\n\n template: t.text(), // e.g. 'resetPassword'\n\n category: t.optional(\n t.text({\n description:\n \"For grouping related notifications (e.g., 'authentication', 'marketing'). Contact can filter notifications by category.\",\n }),\n ),\n\n critical: t.optional(\n t.boolean({\n description:\n \"Prioritize delivery of this notification. Set to true for important system alerts.\",\n }),\n ),\n\n sensitive: t.optional(\n t.boolean({\n description:\n \"Message won't be logged or stored in plain text. Set to true when notification contains passwords or codes.\",\n }),\n ),\n\n // -----------------------------------------------------------------------------------------------------------------\n\n contact: t.text(), // e.g. email address or phone number or user ID or whatever\n\n variables: t.optional(t.record(t.text(), t.any())),\n\n scheduledAt: t.optional(\n t.datetime({\n description:\n \"When set, the notification will be sent at or after this date/time.\",\n }),\n ),\n\n // -----------------------------------------------------------------------------------------------------------------\n\n sentAt: t.optional(t.datetime()),\n\n error: t.optional(\n t.object({\n at: t.datetime(),\n name: t.text(),\n message: t.text({ size: \"rich\" }),\n }),\n ),\n\n // TODO: retryCount, lastRetryAt, etc.\n }),\n});\n\nexport type NotificationEntity = Static<typeof notifications.schema>;\n","import type { Static } from \"alepha\";\nimport { t } from \"alepha\";\nimport { pageQuerySchema } from \"alepha/orm\";\n\nexport const notificationQuerySchema = t.extend(pageQuerySchema, {\n type: t.optional(t.enum([\"email\", \"sms\"])),\n template: t.optional(t.string()),\n contact: t.optional(t.string()),\n category: t.optional(t.string()),\n status: t.optional(t.enum([\"pending\", \"sent\", \"failed\"])),\n});\n\nexport type NotificationQuery = Static<typeof notificationQuerySchema>;\n","import {\n $inject,\n createPrimitive,\n KIND,\n Primitive,\n type Static,\n type StaticEncode,\n type TObject,\n} from \"alepha\";\nimport { NotificationService } from \"../services/NotificationService.ts\";\n\n/**\n * Creates a notification primitive for managing email/SMS notification templates.\n *\n * Provides type-safe, reusable notification templates with multi-language support,\n * variable substitution, and categorization for different notification channels.\n *\n * @example\n * ```ts\n * class NotificationTemplates {\n * welcomeEmail = $notification({\n * name: \"welcome-email\",\n * category: \"onboarding\",\n * schema: t.object({ username: t.text(), activationLink: t.text() }),\n * email: {\n * subject: \"Welcome to our platform!\",\n * body: (vars) => `Hello ${vars.username}, click: ${vars.activationLink}`\n * }\n * });\n *\n * async sendWelcome(user: User) {\n * await this.welcomeEmail.push({\n * variables: { username: user.name, activationLink: generateLink() },\n * contact: user.email\n * });\n * }\n * }\n * ```\n */\nexport const $notification = <T extends TObject>(\n options: NotificationPrimitiveOptions<T>,\n) => createPrimitive(NotificationPrimitive<T>, options);\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface NotificationPrimitiveOptions<T extends TObject>\n extends NotificationMessage<T> {\n name?: string;\n description?: string;\n category?: string;\n critical?: boolean;\n sensitive?: boolean;\n translations?: {\n // e.g., \"en\", \"fr\", even \"en-US\"\n [lang: string]: NotificationMessage<T>;\n };\n schema: T;\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport class NotificationPrimitive<T extends TObject> extends Primitive<\n NotificationPrimitiveOptions<T>\n> {\n protected readonly notificationService = $inject(NotificationService);\n\n public get name() {\n return this.options.name ?? `${this.config.propertyKey}`;\n }\n\n public async push(options: NotificationPushOptions<T>) {\n if (this.options.email) {\n await this.notificationService.createNotification({\n ...options,\n type: \"email\",\n template: this.name,\n });\n }\n }\n\n public configure(options: Partial<NotificationPrimitiveOptions<T>>) {\n Object.assign(this.options, options);\n }\n}\n\n$notification[KIND] = NotificationPrimitive;\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface NotificationPushOptions<T extends TObject> {\n variables: StaticEncode<T>;\n contact: string;\n}\n\nexport interface NotificationMessage<T extends TObject> {\n email?: {\n subject: string;\n body: string | ((variables: Static<T>) => string);\n };\n sms?: {\n message: string | ((variables: Static<T>) => string);\n };\n}\n","import { $inject, Alepha, AlephaError } from \"alepha\";\nimport { DateTimeProvider } from \"alepha/datetime\";\nimport { EmailProvider } from \"alepha/email\";\nimport { $logger } from \"alepha/logger\";\nimport { $repository } from \"alepha/orm\";\nimport { SmsProvider } from \"alepha/sms\";\nimport {\n type NotificationEntity,\n notifications,\n} from \"../entities/notifications.ts\";\nimport { $notification } from \"../primitives/$notification.ts\";\n\nexport class NotificationSenderService {\n protected readonly alepha = $inject(Alepha);\n protected readonly log = $logger();\n protected readonly notificationRepository = $repository(notifications);\n protected readonly dateTimeProvider = $inject(DateTimeProvider);\n protected readonly emailProvider = $inject(EmailProvider);\n protected readonly smsProvider = $inject(SmsProvider);\n\n public async send(notificationId: string | NotificationEntity) {\n this.log.trace(\"Sending notification\", {\n notificationId:\n typeof notificationId === \"string\" ? notificationId : notificationId.id,\n });\n\n const notification =\n typeof notificationId === \"string\"\n ? await this.notificationRepository.findById(notificationId)\n : notificationId;\n\n if (notification.sentAt) {\n this.log.debug(\"Notification already sent\", {\n notificationId: notification.id,\n sentAt: notification.sentAt,\n });\n return;\n }\n\n this.log.debug(\"Processing notification\", {\n id: notification.id,\n type: notification.type,\n template: notification.template,\n contact: notification.contact,\n });\n\n try {\n if (notification.type === \"email\") {\n await this.emailProvider.send(this.renderEmail(notification));\n notification.sentAt = this.dateTimeProvider.nowISOString();\n this.log.info(\"Email notification sent\", {\n id: notification.id,\n template: notification.template,\n contact: notification.contact,\n });\n }\n if (notification.type === \"sms\") {\n await this.smsProvider.send(this.renderSms(notification));\n notification.sentAt = this.dateTimeProvider.nowISOString();\n this.log.info(\"SMS notification sent\", {\n id: notification.id,\n template: notification.template,\n contact: notification.contact,\n });\n }\n } catch (e) {\n this.log.error(\"Failed to send notification\", {\n id: notification.id,\n type: notification.type,\n template: notification.template,\n contact: notification.contact,\n error: e,\n });\n if (e instanceof Error) {\n notification.error = {\n at: this.dateTimeProvider.nowISOString(),\n name: e.name,\n message: e.message,\n };\n }\n } finally {\n await this.notificationRepository.save(notification);\n }\n }\n\n public renderSms(notification: NotificationEntity) {\n this.log.trace(\"Rendering SMS notification\", {\n id: notification.id,\n template: notification.template,\n });\n\n const { variables, contact, template } = this.load(notification);\n\n const sms = template.options.sms;\n if (!sms) {\n this.log.error(\"Notification template has no SMS defined\", {\n id: notification.id,\n template: notification.template,\n });\n throw new AlephaError(\n `Notification template ${notification.template} has no sms defined`,\n );\n }\n\n this.log.debug(\"Rendering SMS\", {\n template: notification.template,\n contact,\n });\n\n const message =\n typeof sms.message === \"function\"\n ? sms.message(variables as any)\n : sms.message;\n\n return {\n to: contact,\n message,\n };\n }\n\n public renderEmail(notification: NotificationEntity) {\n this.log.trace(\"Rendering email notification\", {\n id: notification.id,\n template: notification.template,\n });\n\n const { variables, contact, template } = this.load(notification);\n\n const email = template.options.email;\n if (!email) {\n this.log.error(\"Notification template has no email defined\", {\n id: notification.id,\n template: notification.template,\n });\n throw new AlephaError(\n `Notification template ${notification.template} has no email defined`,\n );\n }\n\n this.log.debug(\"Rendering email\", {\n template: notification.template,\n contact,\n subject: email.subject,\n });\n\n const subject = email.subject;\n\n const body =\n typeof email.body === \"function\"\n ? email.body(variables as any)\n : email.body;\n\n return {\n to: contact,\n subject,\n body,\n };\n }\n\n protected load(notification: NotificationEntity) {\n const variables = notification.variables || {};\n const contact = notification.contact;\n const template = this.alepha\n .primitives($notification)\n .find((it) => it.name === notification.template);\n\n if (!template) {\n this.log.error(\"Notification template not found\", {\n id: notification.id,\n template: notification.template,\n });\n throw new AlephaError(\n `No notification template found for ${notification.template}`,\n );\n }\n\n return {\n template,\n variables,\n contact,\n };\n }\n}\n","import { $inject, t } from \"alepha\";\nimport { $queue } from \"alepha/queue\";\nimport { NotificationSenderService } from \"../services/NotificationSenderService.ts\";\n\nexport class NotificationQueues {\n protected readonly notificationSenderService = $inject(\n NotificationSenderService,\n );\n\n public readonly processNotification = $queue({\n description: \"Queue for processing notifications\",\n schema: t.object({\n notificationId: t.string({ format: \"uuid\" }),\n }),\n handler: async (message) => {\n await this.notificationSenderService.send(message.payload.notificationId);\n },\n });\n}\n","import { type Static, t } from \"alepha\";\nimport { notifications } from \"../entities/notifications.ts\";\n\nexport const notificationCreateSchema = t.pick(notifications.schema, [\n \"type\",\n \"contact\",\n \"template\",\n \"variables\",\n]);\n\nexport type NotificationCreate = Static<typeof notificationCreateSchema>;\n","import { $env, $inject, Alepha, type Static, t } from \"alepha\";\nimport { $batch } from \"alepha/batch\";\nimport { DateTimeProvider } from \"alepha/datetime\";\nimport { $logger } from \"alepha/logger\";\nimport { $repository, type Page } from \"alepha/orm\";\nimport {\n type NotificationEntity,\n notifications,\n} from \"../entities/notifications.ts\";\nimport { NotificationQueues } from \"../queues/NotificationQueues.ts\";\nimport {\n type NotificationCreate,\n notificationCreateSchema,\n} from \"../schemas/notificationCreateSchema.ts\";\nimport type { NotificationQuery } from \"../schemas/notificationQuerySchema.ts\";\nimport { NotificationSenderService } from \"./NotificationSenderService.ts\";\n\nexport const notificationServiceEnvSchema = t.object({\n NOTIFICATION_QUEUE: t.optional(\n t.boolean({\n description:\n \"If true, notifications will be queued instead of sent immediately\",\n }),\n ),\n});\n\ndeclare module \"alepha\" {\n interface Env extends Partial<Static<typeof notificationServiceEnvSchema>> {}\n}\n\nexport class NotificationService {\n protected readonly alepha = $inject(Alepha);\n protected readonly log = $logger();\n protected readonly env = $env(notificationServiceEnvSchema);\n protected readonly notificationRepository = $repository(notifications);\n protected readonly dateTimeProvider = $inject(DateTimeProvider);\n protected readonly notificationSenderService = $inject(\n NotificationSenderService,\n );\n\n public readonly notificationBatch = $batch({\n maxSize: 100,\n maxDuration: [15, \"seconds\"],\n schema: notificationCreateSchema,\n handler: async (notifications: NotificationCreate[]) => {\n this.log.debug(\"Processing notification batch\", {\n size: notifications.length,\n templates: [...new Set(notifications.map((n) => n.template))],\n });\n\n const entities =\n await this.notificationRepository.createMany(notifications);\n\n await this.alepha\n .inject(NotificationQueues)\n .processNotification.push(\n ...entities.map((it) => ({ notificationId: it.id })),\n );\n\n this.log.info(\"Notification batch queued\", {\n count: entities.length,\n ids: entities.map((it) => it.id),\n });\n },\n });\n\n public async findNotificationById(id: string) {\n this.log.trace(\"Finding notification by ID\", { id });\n return this.notificationRepository.findOne({ where: { id } });\n }\n\n public async findNotifications(\n q: NotificationQuery = {},\n ): Promise<Page<NotificationEntity>> {\n this.log.trace(\"Finding notifications\", { query: q });\n q.sort ??= \"-createdAt\";\n\n const where = this.notificationRepository.createQueryWhere();\n\n if (q.type) {\n where.type = { eq: q.type };\n }\n\n if (q.template) {\n where.template = { like: `%${q.template}%` };\n }\n\n if (q.contact) {\n where.contact = { like: `%${q.contact}%` };\n }\n\n if (q.category) {\n where.category = { eq: q.category };\n }\n\n if (q.status) {\n if (q.status === \"sent\") {\n where.sentAt = { isNotNull: true };\n where.error = { isNull: true };\n } else if (q.status === \"failed\") {\n where.error = { isNotNull: true };\n } else if (q.status === \"pending\") {\n where.sentAt = { isNull: true };\n where.error = { isNull: true };\n }\n }\n\n return this.notificationRepository.paginate(q, { where }, { count: true });\n }\n\n /**\n * Create a new notification.\n */\n public async createNotification(entry: NotificationCreate): Promise<void> {\n this.log.trace(\"Creating notification\", {\n template: entry.template,\n type: entry.type,\n contact: entry.contact,\n });\n\n if (\n this.env.NOTIFICATION_QUEUE !== true ||\n this.alepha.isServerless() ||\n this.alepha.isTest()\n ) {\n this.log.debug(\"Sending notification immediately\", {\n template: entry.template,\n type: entry.type,\n contact: entry.contact,\n });\n const notification = await this.notificationRepository.create(entry);\n await this.notificationSenderService.send(notification);\n return;\n }\n\n this.log.debug(\"Queuing notification to batch\", {\n template: entry.template,\n type: entry.type,\n contact: entry.contact,\n });\n\n this.notificationBatch.push(entry).catch((e) => {\n this.log.error(\"Failed to push notification to batch\", {\n template: entry.template,\n type: entry.type,\n contact: entry.contact,\n error: e,\n });\n });\n }\n}\n","import { $inject, t } from \"alepha\";\nimport { $action } from \"alepha/server\";\nimport { notifications } from \"../entities/notifications.ts\";\nimport { notificationQuerySchema } from \"../schemas/notificationQuerySchema.ts\";\nimport { NotificationService } from \"../services/NotificationService.ts\";\n\nexport class AdminNotificationController {\n protected readonly url = \"/notifications\";\n protected readonly group = \"admin:notifications\";\n protected readonly notificationService = $inject(NotificationService);\n\n /**\n * Find notifications with pagination and filtering.\n */\n public readonly findNotifications = $action({\n path: this.url,\n group: this.group,\n description: \"Find notifications with pagination and filtering\",\n schema: {\n query: notificationQuerySchema,\n response: t.page(notifications.schema),\n },\n handler: ({ query }) => this.notificationService.findNotifications(query),\n });\n}\n","export class NotificationJobs {\n // - retry (lost, failed) notifications\n // - purge old notifications\n}\n","import { type Static, t } from \"alepha\";\n\nexport const notificationContactPreferencesSchema = t.object({\n language: t.optional(t.text()),\n exclude: t.array(t.text()),\n});\n\nexport type NotificationContactPreferences = Static<\n typeof notificationContactPreferencesSchema\n>;\n","import { $module } from \"alepha\";\nimport { AdminNotificationController } from \"./controllers/AdminNotificationController.ts\";\nimport { NotificationJobs } from \"./jobs/NotificationJobs.ts\";\nimport { $notification } from \"./primitives/$notification.ts\";\nimport { NotificationQueues } from \"./queues/NotificationQueues.ts\";\nimport { NotificationSenderService } from \"./services/NotificationSenderService.ts\";\nimport {\n NotificationService,\n notificationServiceEnvSchema,\n} from \"./services/NotificationService.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./controllers/AdminNotificationController.ts\";\nexport * from \"./entities/notifications.ts\";\nexport * from \"./jobs/NotificationJobs.ts\";\nexport * from \"./primitives/$notification.ts\";\nexport * from \"./queues/NotificationQueues.ts\";\nexport * from \"./schemas/notificationContactPreferencesSchema.ts\";\nexport * from \"./schemas/notificationCreateSchema.ts\";\nexport * from \"./schemas/notificationQuerySchema.ts\";\nexport * from \"./services/NotificationSenderService.ts\";\nexport * from \"./services/NotificationService.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Provides notification management API endpoints for Alepha applications.\n *\n * This module includes notification sending, retrieval, status tracking,\n * and user notification preferences management.\n *\n * Requires `AlephaSms` module to be loaded for SMS notifications.\n *\n * @module alepha.api.notifications\n */\nexport const AlephaApiNotifications = $module({\n name: \"alepha.api.notifications\",\n primitives: [$notification],\n services: [\n AdminNotificationController,\n NotificationService,\n NotificationSenderService,\n NotificationQueues,\n NotificationJobs,\n ],\n register: (alepha) => {\n const env = alepha.parseEnv(notificationServiceEnvSchema);\n if (env.NOTIFICATION_QUEUE) {\n alepha.with(NotificationQueues);\n }\n\n alepha\n .with(AdminNotificationController)\n .with(NotificationService)\n .with(NotificationSenderService)\n .with(NotificationJobs);\n },\n});\n"],"mappings":"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"}
|
|
@@ -1,6 +1,164 @@
|
|
|
1
1
|
import { $module, t } from "alepha";
|
|
2
|
-
import { $entity,
|
|
2
|
+
import { $entity, db } from "alepha/orm";
|
|
3
3
|
|
|
4
|
+
//#region ../../src/api/parameters/schemas/activateConfigBodySchema.ts
|
|
5
|
+
/**
|
|
6
|
+
* Activate config body schema.
|
|
7
|
+
*/
|
|
8
|
+
const activateConfigBodySchema = t.object({
|
|
9
|
+
version: t.integer({ description: "Version number to activate" }),
|
|
10
|
+
creatorId: t.optional(t.uuid()),
|
|
11
|
+
creatorName: t.optional(t.text())
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region ../../src/api/parameters/schemas/checkScheduledResponseSchema.ts
|
|
16
|
+
/**
|
|
17
|
+
* Check scheduled response schema.
|
|
18
|
+
*/
|
|
19
|
+
const checkScheduledResponseSchema = t.object({ message: t.text() });
|
|
20
|
+
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region ../../src/api/parameters/schemas/parameterStatusSchema.ts
|
|
23
|
+
/**
|
|
24
|
+
* Parameter status enum schema.
|
|
25
|
+
*/
|
|
26
|
+
const parameterStatusSchema = t.enum([
|
|
27
|
+
"expired",
|
|
28
|
+
"current",
|
|
29
|
+
"next",
|
|
30
|
+
"future"
|
|
31
|
+
]);
|
|
32
|
+
|
|
33
|
+
//#endregion
|
|
34
|
+
//#region ../../src/api/parameters/schemas/parameterResponseSchema.ts
|
|
35
|
+
/**
|
|
36
|
+
* Parameter response schema for API responses.
|
|
37
|
+
*/
|
|
38
|
+
const parameterResponseSchema = t.object({
|
|
39
|
+
id: t.uuid(),
|
|
40
|
+
createdAt: t.datetime(),
|
|
41
|
+
updatedAt: t.datetime(),
|
|
42
|
+
name: t.text(),
|
|
43
|
+
content: t.json(),
|
|
44
|
+
schemaHash: t.text(),
|
|
45
|
+
status: parameterStatusSchema,
|
|
46
|
+
activationDate: t.datetime(),
|
|
47
|
+
expiredAt: t.optional(t.datetime()),
|
|
48
|
+
version: t.integer(),
|
|
49
|
+
changeDescription: t.optional(t.text()),
|
|
50
|
+
tags: t.optional(t.array(t.text())),
|
|
51
|
+
creatorId: t.optional(t.uuid()),
|
|
52
|
+
creatorName: t.optional(t.text()),
|
|
53
|
+
previousContent: t.optional(t.json()),
|
|
54
|
+
migrationLog: t.optional(t.text())
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region ../../src/api/parameters/schemas/configCurrentResponseSchema.ts
|
|
59
|
+
/**
|
|
60
|
+
* Current config response schema.
|
|
61
|
+
*/
|
|
62
|
+
const configCurrentResponseSchema = t.object({
|
|
63
|
+
current: t.optional(parameterResponseSchema),
|
|
64
|
+
next: t.optional(parameterResponseSchema),
|
|
65
|
+
defaultValue: t.optional(t.json()),
|
|
66
|
+
currentValue: t.optional(t.json()),
|
|
67
|
+
schema: t.optional(t.json())
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
//#endregion
|
|
71
|
+
//#region ../../src/api/parameters/schemas/configHistoryResponseSchema.ts
|
|
72
|
+
/**
|
|
73
|
+
* Config history response schema.
|
|
74
|
+
*/
|
|
75
|
+
const configHistoryResponseSchema = t.object({ versions: t.array(parameterResponseSchema) });
|
|
76
|
+
|
|
77
|
+
//#endregion
|
|
78
|
+
//#region ../../src/api/parameters/schemas/configNameParamSchema.ts
|
|
79
|
+
/**
|
|
80
|
+
* Config name param schema.
|
|
81
|
+
*/
|
|
82
|
+
const configNameParamSchema = t.object({ name: t.text({ description: "Configuration name (e.g., app.features.flags)" }) });
|
|
83
|
+
|
|
84
|
+
//#endregion
|
|
85
|
+
//#region ../../src/api/parameters/schemas/configNamesResponseSchema.ts
|
|
86
|
+
/**
|
|
87
|
+
* Config names list response schema.
|
|
88
|
+
*/
|
|
89
|
+
const configNamesResponseSchema = t.object({ names: t.array(t.text()) });
|
|
90
|
+
|
|
91
|
+
//#endregion
|
|
92
|
+
//#region ../../src/api/parameters/schemas/configsByStatusResponseSchema.ts
|
|
93
|
+
/**
|
|
94
|
+
* Configs by status response schema.
|
|
95
|
+
*/
|
|
96
|
+
const configsByStatusResponseSchema = t.object({ configs: t.array(parameterResponseSchema) });
|
|
97
|
+
|
|
98
|
+
//#endregion
|
|
99
|
+
//#region ../../src/api/parameters/schemas/configTreeNodeSchema.ts
|
|
100
|
+
/**
|
|
101
|
+
* Tree node schema for configuration tree navigation.
|
|
102
|
+
*/
|
|
103
|
+
const configTreeNodeSchema = t.object({
|
|
104
|
+
name: t.text(),
|
|
105
|
+
path: t.text(),
|
|
106
|
+
isLeaf: t.boolean(),
|
|
107
|
+
children: t.array(t.any())
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
//#endregion
|
|
111
|
+
//#region ../../src/api/parameters/schemas/configVersionParamSchema.ts
|
|
112
|
+
/**
|
|
113
|
+
* Config name and version param schema.
|
|
114
|
+
*/
|
|
115
|
+
const configVersionParamSchema = t.object({
|
|
116
|
+
name: t.text(),
|
|
117
|
+
version: t.integer()
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
//#endregion
|
|
121
|
+
//#region ../../src/api/parameters/schemas/configVersionResponseSchema.ts
|
|
122
|
+
/**
|
|
123
|
+
* Config version response schema.
|
|
124
|
+
*/
|
|
125
|
+
const configVersionResponseSchema = t.object({ config: t.optional(parameterResponseSchema) });
|
|
126
|
+
|
|
127
|
+
//#endregion
|
|
128
|
+
//#region ../../src/api/parameters/schemas/createConfigVersionBodySchema.ts
|
|
129
|
+
/**
|
|
130
|
+
* Create config version body schema.
|
|
131
|
+
*/
|
|
132
|
+
const createConfigVersionBodySchema = t.object({
|
|
133
|
+
content: t.json({ description: "New configuration content" }),
|
|
134
|
+
schemaHash: t.text({ description: "Hash of the schema for migration detection" }),
|
|
135
|
+
activationDate: t.optional(t.datetime({ description: "When to activate (default: now)" })),
|
|
136
|
+
changeDescription: t.optional(t.text({ description: "Description of changes" })),
|
|
137
|
+
tags: t.optional(t.array(t.text())),
|
|
138
|
+
creatorId: t.optional(t.uuid()),
|
|
139
|
+
creatorName: t.optional(t.text())
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
//#endregion
|
|
143
|
+
//#region ../../src/api/parameters/schemas/rollbackConfigBodySchema.ts
|
|
144
|
+
/**
|
|
145
|
+
* Rollback config body schema.
|
|
146
|
+
*/
|
|
147
|
+
const rollbackConfigBodySchema = t.object({
|
|
148
|
+
targetVersion: t.integer({ description: "Version number to rollback to" }),
|
|
149
|
+
changeDescription: t.optional(t.text()),
|
|
150
|
+
creatorId: t.optional(t.uuid()),
|
|
151
|
+
creatorName: t.optional(t.text())
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
//#endregion
|
|
155
|
+
//#region ../../src/api/parameters/schemas/statusParamSchema.ts
|
|
156
|
+
/**
|
|
157
|
+
* Status param schema.
|
|
158
|
+
*/
|
|
159
|
+
const statusParamSchema = t.object({ status: parameterStatusSchema });
|
|
160
|
+
|
|
161
|
+
//#endregion
|
|
4
162
|
//#region ../../src/api/parameters/entities/parameters.ts
|
|
5
163
|
/**
|
|
6
164
|
* Configuration parameter entity for versioned configuration management.
|
|
@@ -14,18 +172,13 @@ import { $entity, pg } from "alepha/orm";
|
|
|
14
172
|
const parameters = $entity({
|
|
15
173
|
name: "parameters",
|
|
16
174
|
schema: t.object({
|
|
17
|
-
id:
|
|
18
|
-
createdAt:
|
|
19
|
-
updatedAt:
|
|
175
|
+
id: db.primaryKey(t.uuid()),
|
|
176
|
+
createdAt: db.createdAt(),
|
|
177
|
+
updatedAt: db.updatedAt(),
|
|
20
178
|
name: t.text(),
|
|
21
179
|
content: t.json(),
|
|
22
180
|
schemaHash: t.text(),
|
|
23
|
-
status:
|
|
24
|
-
"expired",
|
|
25
|
-
"current",
|
|
26
|
-
"next",
|
|
27
|
-
"future"
|
|
28
|
-
]), "future"),
|
|
181
|
+
status: db.default(parameterStatusSchema, "future"),
|
|
29
182
|
activationDate: t.datetime(),
|
|
30
183
|
expiredAt: t.optional(t.datetime()),
|
|
31
184
|
version: t.integer(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.browser.js","names":[],"sources":["../../../src/api/parameters/entities/parameters.ts","../../../src/api/parameters/index.browser.ts"],"sourcesContent":["import { type Static, t } from \"alepha\";\nimport { $entity, pg } from \"alepha/orm\";\n\n/**\n * Parameter status values.\n *\n * - EXPIRED: Past version, no longer active\n * - CURRENT: Currently active version\n * - NEXT: Scheduled to become active (closest future date)\n * - FUTURE: Scheduled for activation after NEXT\n */\nexport type ParameterStatus = \"expired\" | \"current\" | \"next\" | \"future\";\n\n/**\n * Configuration parameter entity for versioned configuration management.\n *\n * Stores all versions of configuration parameters with:\n * - Automatic status management (expired, current, next, future)\n * - Schema versioning for migrations\n * - Activation scheduling\n * - Audit trail (creator info)\n */\nexport const parameters = $entity({\n name: \"parameters\",\n schema: t.object({\n id: pg.primaryKey(t.uuid()),\n createdAt: pg.createdAt(),\n updatedAt: pg.updatedAt(),\n\n /**\n * Configuration name using dot notation for tree hierarchy.\n * Examples: \"app.features\", \"app.pricing.tiers\", \"system.limits\"\n */\n name: t.text(),\n\n /**\n * The configuration content as JSON.\n */\n content: t.json(),\n\n /**\n * Schema version hash for detecting schema changes.\n * Used for auto-migration when schema evolves.\n */\n schemaHash: t.text(),\n\n /**\n * Current status of this parameter version.\n */\n status: pg.default(\n t.enum([\"expired\", \"current\", \"next\", \"future\"]),\n \"future\",\n ),\n\n /**\n * When this version should become active.\n * Default is immediate (now).\n */\n activationDate: t.datetime(),\n\n /**\n * When this version was deactivated (became expired).\n * Null if still active or scheduled.\n */\n expiredAt: t.optional(t.datetime()),\n\n /**\n * Version number for this configuration.\n * Auto-incremented per config name.\n */\n version: t.integer(),\n\n /**\n * Optional description of changes in this version.\n */\n changeDescription: t.optional(t.text()),\n\n /**\n * Optional tags for filtering/categorization.\n */\n tags: t.optional(t.array(t.text())),\n\n /**\n * Creator user ID (if available).\n */\n creatorId: t.optional(t.uuid()),\n\n /**\n * Creator display name for audit trail.\n */\n creatorName: t.optional(t.text()),\n\n /**\n * Previous content before this change (for rollback reference).\n */\n previousContent: t.optional(t.json()),\n\n /**\n * Migration log if schema changed.\n */\n migrationLog: t.optional(t.text()),\n }),\n indexes: [\n { columns: [\"name\", \"status\"] },\n { columns: [\"name\", \"activationDate\"] },\n { columns: [\"name\", \"version\"], unique: true },\n { columns: [\"status\"] },\n { columns: [\"activationDate\"] },\n ],\n});\n\nexport type Parameter = Static<typeof parameters.schema>;\nexport type ParameterInsert = Omit<Parameter, \"id\" | \"createdAt\" | \"updatedAt\">;\n","import { $module } from \"alepha\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./entities/parameters.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport const AlephaApiParameters = $module({\n name: \"alepha.api.parameters\",\n services: [],\n});\n"],"mappings":";;;;;;;;;;;;;AAsBA,MAAa,aAAa,QAAQ;CAChC,MAAM;CACN,QAAQ,EAAE,OAAO;EACf,IAAI,GAAG,WAAW,EAAE,MAAM,CAAC;EAC3B,WAAW,GAAG,WAAW;EACzB,WAAW,GAAG,WAAW;EAMzB,MAAM,EAAE,MAAM;EAKd,SAAS,EAAE,MAAM;EAMjB,YAAY,EAAE,MAAM;EAKpB,QAAQ,GAAG,QACT,EAAE,KAAK;GAAC;GAAW;GAAW;GAAQ;GAAS,CAAC,EAChD,SACD;EAMD,gBAAgB,EAAE,UAAU;EAM5B,WAAW,EAAE,SAAS,EAAE,UAAU,CAAC;EAMnC,SAAS,EAAE,SAAS;EAKpB,mBAAmB,EAAE,SAAS,EAAE,MAAM,CAAC;EAKvC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;EAKnC,WAAW,EAAE,SAAS,EAAE,MAAM,CAAC;EAK/B,aAAa,EAAE,SAAS,EAAE,MAAM,CAAC;EAKjC,iBAAiB,EAAE,SAAS,EAAE,MAAM,CAAC;EAKrC,cAAc,EAAE,SAAS,EAAE,MAAM,CAAC;EACnC,CAAC;CACF,SAAS;EACP,EAAE,SAAS,CAAC,QAAQ,SAAS,EAAE;EAC/B,EAAE,SAAS,CAAC,QAAQ,iBAAiB,EAAE;EACvC;GAAE,SAAS,CAAC,QAAQ,UAAU;GAAE,QAAQ;GAAM;EAC9C,EAAE,SAAS,CAAC,SAAS,EAAE;EACvB,EAAE,SAAS,CAAC,iBAAiB,EAAE;EAChC;CACF,CAAC;;;;ACrGF,MAAa,sBAAsB,QAAQ;CACzC,MAAM;CACN,UAAU,EAAE;CACb,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.browser.js","names":[],"sources":["../../../src/api/parameters/schemas/activateConfigBodySchema.ts","../../../src/api/parameters/schemas/checkScheduledResponseSchema.ts","../../../src/api/parameters/schemas/parameterStatusSchema.ts","../../../src/api/parameters/schemas/parameterResponseSchema.ts","../../../src/api/parameters/schemas/configCurrentResponseSchema.ts","../../../src/api/parameters/schemas/configHistoryResponseSchema.ts","../../../src/api/parameters/schemas/configNameParamSchema.ts","../../../src/api/parameters/schemas/configNamesResponseSchema.ts","../../../src/api/parameters/schemas/configsByStatusResponseSchema.ts","../../../src/api/parameters/schemas/configTreeNodeSchema.ts","../../../src/api/parameters/schemas/configVersionParamSchema.ts","../../../src/api/parameters/schemas/configVersionResponseSchema.ts","../../../src/api/parameters/schemas/createConfigVersionBodySchema.ts","../../../src/api/parameters/schemas/rollbackConfigBodySchema.ts","../../../src/api/parameters/schemas/statusParamSchema.ts","../../../src/api/parameters/entities/parameters.ts","../../../src/api/parameters/index.browser.ts"],"sourcesContent":["import { type Static, t } from \"alepha\";\n\n/**\n * Activate config body schema.\n */\nexport const activateConfigBodySchema = t.object({\n version: t.integer({ description: \"Version number to activate\" }),\n creatorId: t.optional(t.uuid()),\n creatorName: t.optional(t.text()),\n});\n\nexport type ActivateConfigBody = Static<typeof activateConfigBodySchema>;\n","import { t } from \"alepha\";\n\n/**\n * Check scheduled response schema.\n */\nexport const checkScheduledResponseSchema = t.object({\n message: t.text(),\n});\n","import { type Static, t } from \"alepha\";\n\n/**\n * Parameter status enum schema.\n */\nexport const parameterStatusSchema = t.enum([\n \"expired\",\n \"current\",\n \"next\",\n \"future\",\n]);\n\nexport type ParameterStatus = Static<typeof parameterStatusSchema>;\n","import { type Static, t } from \"alepha\";\nimport { parameterStatusSchema } from \"./parameterStatusSchema.ts\";\n\n/**\n * Parameter response schema for API responses.\n */\nexport const parameterResponseSchema = t.object({\n id: t.uuid(),\n createdAt: t.datetime(),\n updatedAt: t.datetime(),\n name: t.text(),\n content: t.json(),\n schemaHash: t.text(),\n status: parameterStatusSchema,\n activationDate: t.datetime(),\n expiredAt: t.optional(t.datetime()),\n version: t.integer(),\n changeDescription: t.optional(t.text()),\n tags: t.optional(t.array(t.text())),\n creatorId: t.optional(t.uuid()),\n creatorName: t.optional(t.text()),\n previousContent: t.optional(t.json()),\n migrationLog: t.optional(t.text()),\n});\n\nexport type ParameterResponse = Static<typeof parameterResponseSchema>;\n","import { t } from \"alepha\";\nimport { parameterResponseSchema } from \"./parameterResponseSchema.ts\";\n\n/**\n * Current config response schema.\n */\nexport const configCurrentResponseSchema = t.object({\n current: t.optional(parameterResponseSchema),\n next: t.optional(parameterResponseSchema),\n defaultValue: t.optional(t.json()),\n currentValue: t.optional(t.json()),\n schema: t.optional(t.json()),\n});\n","import { t } from \"alepha\";\nimport { parameterResponseSchema } from \"./parameterResponseSchema.ts\";\n\n/**\n * Config history response schema.\n */\nexport const configHistoryResponseSchema = t.object({\n versions: t.array(parameterResponseSchema),\n});\n","import { t } from \"alepha\";\n\n/**\n * Config name param schema.\n */\nexport const configNameParamSchema = t.object({\n name: t.text({\n description: \"Configuration name (e.g., app.features.flags)\",\n }),\n});\n","import { t } from \"alepha\";\n\n/**\n * Config names list response schema.\n */\nexport const configNamesResponseSchema = t.object({\n names: t.array(t.text()),\n});\n","import { t } from \"alepha\";\nimport { parameterResponseSchema } from \"./parameterResponseSchema.ts\";\n\n/**\n * Configs by status response schema.\n */\nexport const configsByStatusResponseSchema = t.object({\n configs: t.array(parameterResponseSchema),\n});\n","import { type Static, t } from \"alepha\";\n\n/**\n * Tree node schema for configuration tree navigation.\n */\nexport const configTreeNodeSchema = t.object({\n name: t.text(),\n path: t.text(),\n isLeaf: t.boolean(),\n children: t.array(t.any()),\n});\n\nexport type ConfigTreeNode = Static<typeof configTreeNodeSchema>;\n","import { t } from \"alepha\";\n\n/**\n * Config name and version param schema.\n */\nexport const configVersionParamSchema = t.object({\n name: t.text(),\n version: t.integer(),\n});\n","import { t } from \"alepha\";\nimport { parameterResponseSchema } from \"./parameterResponseSchema.ts\";\n\n/**\n * Config version response schema.\n */\nexport const configVersionResponseSchema = t.object({\n config: t.optional(parameterResponseSchema),\n});\n","import { type Static, t } from \"alepha\";\n\n/**\n * Create config version body schema.\n */\nexport const createConfigVersionBodySchema = t.object({\n content: t.json({ description: \"New configuration content\" }),\n schemaHash: t.text({\n description: \"Hash of the schema for migration detection\",\n }),\n activationDate: t.optional(\n t.datetime({ description: \"When to activate (default: now)\" }),\n ),\n changeDescription: t.optional(\n t.text({ description: \"Description of changes\" }),\n ),\n tags: t.optional(t.array(t.text())),\n creatorId: t.optional(t.uuid()),\n creatorName: t.optional(t.text()),\n});\n\nexport type CreateConfigVersionBody = Static<\n typeof createConfigVersionBodySchema\n>;\n","import { type Static, t } from \"alepha\";\n\n/**\n * Rollback config body schema.\n */\nexport const rollbackConfigBodySchema = t.object({\n targetVersion: t.integer({\n description: \"Version number to rollback to\",\n }),\n changeDescription: t.optional(t.text()),\n creatorId: t.optional(t.uuid()),\n creatorName: t.optional(t.text()),\n});\n\nexport type RollbackConfigBody = Static<typeof rollbackConfigBodySchema>;\n","import { t } from \"alepha\";\nimport { parameterStatusSchema } from \"./parameterStatusSchema.ts\";\n\n/**\n * Status param schema.\n */\nexport const statusParamSchema = t.object({\n status: parameterStatusSchema,\n});\n","import { type Static, t } from \"alepha\";\nimport { $entity, db } from \"alepha/orm\";\nimport { parameterStatusSchema } from \"../schemas/index.ts\";\n\nexport type { ParameterStatus } from \"../schemas/index.ts\";\n\n/**\n * Configuration parameter entity for versioned configuration management.\n *\n * Stores all versions of configuration parameters with:\n * - Automatic status management (expired, current, next, future)\n * - Schema versioning for migrations\n * - Activation scheduling\n * - Audit trail (creator info)\n */\nexport const parameters = $entity({\n name: \"parameters\",\n schema: t.object({\n id: db.primaryKey(t.uuid()),\n createdAt: db.createdAt(),\n updatedAt: db.updatedAt(),\n\n /**\n * Configuration name using dot notation for tree hierarchy.\n * Examples: \"app.features\", \"app.pricing.tiers\", \"system.limits\"\n */\n name: t.text(),\n\n /**\n * The configuration content as JSON.\n */\n content: t.json(),\n\n /**\n * Schema version hash for detecting schema changes.\n * Used for auto-migration when schema evolves.\n */\n schemaHash: t.text(),\n\n /**\n * Current status of this parameter version.\n */\n status: db.default(parameterStatusSchema, \"future\"),\n\n /**\n * When this version should become active.\n * Default is immediate (now).\n */\n activationDate: t.datetime(),\n\n /**\n * When this version was deactivated (became expired).\n * Null if still active or scheduled.\n */\n expiredAt: t.optional(t.datetime()),\n\n /**\n * Version number for this configuration.\n * Auto-incremented per config name.\n */\n version: t.integer(),\n\n /**\n * Optional description of changes in this version.\n */\n changeDescription: t.optional(t.text()),\n\n /**\n * Optional tags for filtering/categorization.\n */\n tags: t.optional(t.array(t.text())),\n\n /**\n * Creator user ID (if available).\n */\n creatorId: t.optional(t.uuid()),\n\n /**\n * Creator display name for audit trail.\n */\n creatorName: t.optional(t.text()),\n\n /**\n * Previous content before this change (for rollback reference).\n */\n previousContent: t.optional(t.json()),\n\n /**\n * Migration log if schema changed.\n */\n migrationLog: t.optional(t.text()),\n }),\n indexes: [\n { columns: [\"name\", \"status\"] },\n { columns: [\"name\", \"activationDate\"] },\n { columns: [\"name\", \"version\"], unique: true },\n { columns: [\"status\"] },\n { columns: [\"activationDate\"] },\n ],\n});\n\nexport type Parameter = Static<typeof parameters.schema>;\nexport type ParameterInsert = Omit<Parameter, \"id\" | \"createdAt\" | \"updatedAt\">;\n","import { $module } from \"alepha\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./entities/parameters.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport const AlephaApiParameters = $module({\n name: \"alepha.api.parameters\",\n services: [],\n});\n"],"mappings":"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"}
|