alepha 0.13.6 → 0.13.8
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 +5 -2
- package/assets/swagger-ui/swagger-ui-bundle.js +1 -1
- package/assets/swagger-ui/swagger-ui-standalone-preset.js +1 -1
- package/assets/swagger-ui/swagger-ui.css +1 -1
- package/dist/api/audits/index.browser.js +116 -0
- package/dist/api/audits/index.browser.js.map +1 -0
- package/dist/api/audits/index.d.ts +1194 -0
- package/dist/api/audits/index.js +674 -0
- package/dist/api/audits/index.js.map +1 -0
- package/dist/{api-files → api/files}/index.browser.js +5 -5
- package/dist/api/files/index.browser.js.map +1 -0
- package/dist/{api-files → api/files}/index.d.ts +16 -9
- package/dist/{api-files → api/files}/index.js +10 -10
- package/dist/api/files/index.js.map +1 -0
- package/dist/{api-jobs → api/jobs}/index.browser.js +5 -5
- package/dist/api/jobs/index.browser.js.map +1 -0
- package/dist/{api-jobs → api/jobs}/index.d.ts +35 -35
- package/dist/{api-jobs → api/jobs}/index.js +9 -9
- package/dist/api/jobs/index.js.map +1 -0
- package/dist/{api-notifications → api/notifications}/index.browser.js +11 -11
- package/dist/api/notifications/index.browser.js.map +1 -0
- package/dist/api/notifications/index.d.ts +327 -0
- package/dist/{api-notifications → api/notifications}/index.js +11 -11
- package/dist/api/notifications/index.js.map +1 -0
- package/dist/api/parameters/index.browser.js +60 -0
- package/dist/api/parameters/index.browser.js.map +1 -0
- package/dist/api/parameters/index.d.ts +761 -0
- package/dist/api/parameters/index.js +877 -0
- package/dist/api/parameters/index.js.map +1 -0
- package/dist/{api-users → api/users}/index.browser.js +6 -6
- package/dist/api/users/index.browser.js.map +1 -0
- package/dist/{api-users → api/users}/index.d.ts +259 -247
- package/dist/{api-users → api/users}/index.js +125 -112
- package/dist/api/users/index.js.map +1 -0
- package/dist/{api-verifications → api/verifications}/index.browser.js +5 -5
- package/dist/api/verifications/index.browser.js.map +1 -0
- package/dist/api/verifications/index.d.ts +248 -0
- package/dist/{api-verifications → api/verifications}/index.js +13 -12
- package/dist/api/verifications/index.js.map +1 -0
- package/dist/bin/index.js +1 -0
- package/dist/bin/index.js.map +1 -1
- package/dist/cache/{index.d.ts → core/index.d.ts} +4 -4
- package/dist/cache/{index.js → core/index.js} +5 -5
- package/dist/cache/core/index.js.map +1 -0
- package/dist/{cache-redis → cache/redis}/index.d.ts +2 -2
- package/dist/{cache-redis → cache/redis}/index.js +2 -2
- package/dist/cache/redis/index.js.map +1 -0
- package/dist/cli/index.d.ts +71 -9
- package/dist/cli/index.js +280 -79
- package/dist/cli/index.js.map +1 -1
- package/dist/command/index.d.ts +63 -2
- package/dist/command/index.js +30 -3
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js +241 -61
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +170 -90
- package/dist/core/index.js +264 -67
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +248 -65
- package/dist/core/index.native.js.map +1 -1
- package/dist/email/index.js +15 -10554
- package/dist/email/index.js.map +1 -1
- package/dist/lock/{index.d.ts → core/index.d.ts} +5 -5
- package/dist/lock/{index.js → core/index.js} +5 -5
- package/dist/lock/core/index.js.map +1 -0
- package/dist/{lock-redis → lock/redis}/index.d.ts +2 -2
- package/dist/{lock-redis → lock/redis}/index.js +2 -2
- package/dist/lock/redis/index.js.map +1 -0
- package/dist/logger/index.d.ts +4 -4
- package/dist/logger/index.js +77 -72
- package/dist/logger/index.js.map +1 -1
- package/dist/orm/index.d.ts +5 -1
- package/dist/orm/index.js +24 -7
- package/dist/orm/index.js.map +1 -1
- package/dist/queue/core/index.d.ts +548 -0
- package/dist/queue/core/index.js +391 -0
- package/dist/queue/core/index.js.map +1 -0
- package/dist/queue/redis/index.d.ts +28 -0
- package/dist/queue/redis/index.js +43 -0
- package/dist/queue/redis/index.js.map +1 -0
- package/dist/scheduler/index.d.ts +7 -7
- package/dist/scheduler/index.js +1 -393
- package/dist/scheduler/index.js.map +1 -1
- package/dist/security/index.d.ts +1 -1
- package/dist/security/index.js +2 -1413
- package/dist/security/index.js.map +1 -1
- package/dist/{server-auth → server/auth}/index.browser.js +6 -6
- package/dist/server/auth/index.browser.js.map +1 -0
- package/dist/{server-auth → server/auth}/index.d.ts +175 -164
- package/dist/server/auth/index.js +742 -0
- package/dist/server/auth/index.js.map +1 -0
- package/dist/{server-cache → server/cache}/index.d.ts +2 -2
- package/dist/{server-cache → server/cache}/index.js +2 -2
- package/dist/server/cache/index.js.map +1 -0
- package/dist/{server-compress → server/compress}/index.d.ts +2 -2
- package/dist/{server-compress → server/compress}/index.js +2 -2
- package/dist/server/compress/index.js.map +1 -0
- package/dist/{server-cookies → server/cookies}/index.browser.js +3 -3
- package/dist/server/cookies/index.browser.js.map +1 -0
- package/dist/{server-cookies → server/cookies}/index.d.ts +4 -4
- package/dist/{server-cookies → server/cookies}/index.js +9 -5
- package/dist/server/cookies/index.js.map +1 -0
- package/dist/server/{index.browser.js → core/index.browser.js} +14 -14
- package/dist/server/core/index.browser.js.map +1 -0
- package/dist/server/{index.d.ts → core/index.d.ts} +46 -37
- package/dist/server/{index.js → core/index.js} +47 -33
- package/dist/server/core/index.js.map +1 -0
- package/dist/{server-cors → server/cors}/index.d.ts +3 -3
- package/dist/{server-cors → server/cors}/index.js +3 -3
- package/dist/server/cors/index.js.map +1 -0
- package/dist/{server-health → server/health}/index.d.ts +3 -3
- package/dist/{server-health → server/health}/index.js +3 -3
- package/dist/server/health/index.js.map +1 -0
- package/dist/{server-helmet → server/helmet}/index.d.ts +2 -2
- package/dist/{server-helmet → server/helmet}/index.js +2 -2
- package/dist/server/helmet/index.js.map +1 -0
- package/dist/{server-links → server/links}/index.browser.js +5 -5
- package/dist/server/links/index.browser.js.map +1 -0
- package/dist/{server-links → server/links}/index.d.ts +40 -40
- package/dist/{server-links → server/links}/index.js +7 -7
- package/dist/server/links/index.js.map +1 -0
- package/dist/{server-metrics → server/metrics}/index.d.ts +2 -2
- package/dist/server/metrics/index.js +74 -0
- package/dist/server/metrics/index.js.map +1 -0
- package/dist/{server-multipart → server/multipart}/index.d.ts +2 -2
- package/dist/{server-multipart → server/multipart}/index.js +2 -2
- package/dist/server/multipart/index.js.map +1 -0
- package/dist/{server-proxy → server/proxy}/index.d.ts +3 -3
- package/dist/{server-proxy → server/proxy}/index.js +3 -3
- package/dist/server/proxy/index.js.map +1 -0
- package/dist/{server-rate-limit → server/rate-limit}/index.d.ts +4 -4
- package/dist/{server-rate-limit → server/rate-limit}/index.js +4 -4
- package/dist/server/rate-limit/index.js.map +1 -0
- package/dist/{server-security → server/security}/index.browser.js +1 -1
- package/dist/server/security/index.browser.js.map +1 -0
- package/dist/{server-security → server/security}/index.d.ts +4 -4
- package/dist/{server-security → server/security}/index.js +4 -4
- package/dist/server/security/index.js.map +1 -0
- package/dist/{server-static → server/static}/index.d.ts +3 -3
- package/dist/{server-static → server/static}/index.js +3 -3
- package/dist/server/static/index.js.map +1 -0
- package/dist/{server-swagger → server/swagger}/index.d.ts +3 -3
- package/dist/{server-swagger → server/swagger}/index.js +4 -4
- package/dist/server/swagger/index.js.map +1 -0
- package/dist/thread/index.js +2 -2
- package/dist/thread/index.js.map +1 -1
- package/dist/topic/{index.d.ts → core/index.d.ts} +6 -6
- package/dist/topic/{index.js → core/index.js} +6 -6
- package/dist/topic/core/index.js.map +1 -0
- package/dist/{topic-redis → topic/redis}/index.d.ts +2 -2
- package/dist/{topic-redis → topic/redis}/index.js +2 -2
- package/dist/topic/redis/index.js.map +1 -0
- package/dist/vite/index.d.ts +13 -2
- package/dist/vite/index.js +114 -50
- package/dist/vite/index.js.map +1 -1
- package/dist/websocket/index.browser.js +3 -3
- package/dist/websocket/index.browser.js.map +1 -1
- package/dist/websocket/index.js +4 -4
- package/dist/websocket/index.js.map +1 -1
- package/package.json +160 -156
- package/src/api/audits/controllers/AuditController.ts +186 -0
- package/src/api/audits/entities/audits.ts +132 -0
- package/src/api/audits/index.browser.ts +18 -0
- package/src/api/audits/index.ts +58 -0
- package/src/api/audits/primitives/$audit.ts +159 -0
- package/src/api/audits/schemas/auditQuerySchema.ts +23 -0
- package/src/api/audits/schemas/auditResourceSchema.ts +9 -0
- package/src/api/audits/schemas/createAuditSchema.ts +27 -0
- package/src/api/audits/services/AuditService.ts +412 -0
- package/src/{api-files → api/files}/index.ts +1 -0
- package/src/api/parameters/controllers/ConfigController.ts +324 -0
- package/src/api/parameters/entities/parameters.ts +113 -0
- package/src/api/parameters/index.ts +60 -0
- package/src/api/parameters/primitives/$config.ts +351 -0
- package/src/api/parameters/schedulers/ConfigActivationScheduler.ts +30 -0
- package/src/api/parameters/services/ConfigStore.ts +491 -0
- package/src/{api-users → api/users}/atoms/realmAuthSettingsAtom.ts +19 -0
- package/src/{api-users → api/users}/controllers/UserRealmController.ts +0 -2
- package/src/{api-users → api/users}/index.ts +2 -0
- package/src/{api-users → api/users}/primitives/$userRealm.ts +18 -3
- package/src/{api-users → api/users}/providers/UserRealmProvider.ts +12 -10
- package/src/{api-users → api/users}/services/RegistrationService.ts +2 -1
- package/src/{api-users → api/users}/services/SessionService.ts +4 -0
- package/src/{api-users → api/users}/services/UserService.ts +3 -0
- package/src/{api-verifications → api/verifications}/index.ts +9 -1
- package/src/bin/index.ts +1 -0
- package/src/cli/apps/AlephaPackageBuilderCli.ts +73 -48
- package/src/cli/assets/appRouterTs.ts +1 -1
- package/src/cli/assets/biomeJson.ts +2 -2
- package/src/cli/assets/dummySpecTs.ts +7 -0
- package/src/cli/assets/editorconfig.ts +13 -0
- package/src/cli/assets/indexHtml.ts +1 -1
- package/src/cli/assets/mainBrowserTs.ts +1 -1
- package/src/cli/assets/mainTs.ts +14 -0
- package/src/cli/assets/viteConfigTs.ts +1 -1
- package/src/cli/commands/BiomeCommands.ts +2 -0
- package/src/cli/commands/CoreCommands.ts +38 -15
- package/src/cli/commands/VerifyCommands.ts +6 -2
- package/src/cli/commands/ViteCommands.ts +28 -18
- package/src/cli/services/AlephaCliUtils.ts +243 -37
- package/src/command/helpers/Asker.ts +0 -1
- package/src/command/primitives/$command.ts +67 -0
- package/src/command/providers/CliProvider.ts +39 -8
- package/src/core/Alepha.ts +40 -30
- package/src/core/helpers/jsonSchemaToTypeBox.ts +307 -0
- package/src/core/index.shared.ts +1 -0
- package/src/core/index.ts +30 -3
- package/src/core/providers/EventManager.ts +1 -1
- package/src/core/providers/SchemaValidator.ts +1 -1
- package/src/core/providers/StateManager.ts +23 -12
- package/src/core/providers/TypeProvider.ts +26 -34
- package/src/logger/index.ts +8 -6
- package/src/logger/primitives/$logger.ts +1 -1
- package/src/logger/providers/{SimpleFormatterProvider.ts → PrettyFormatterProvider.ts} +10 -1
- package/src/orm/index.ts +6 -0
- package/src/orm/services/PgRelationManager.ts +2 -2
- package/src/orm/services/PostgresModelBuilder.ts +11 -7
- package/src/orm/services/Repository.ts +16 -7
- package/src/orm/services/SqliteModelBuilder.ts +10 -0
- package/src/queue/{index.ts → core/index.ts} +2 -3
- package/src/queue/{primitives → core/primitives}/$queue.ts +17 -162
- package/src/queue/core/providers/MemoryQueueProvider.ts +19 -0
- package/src/queue/core/providers/QueueProvider.ts +23 -0
- package/src/queue/core/providers/WorkerProvider.ts +244 -0
- package/src/queue/redis/providers/RedisQueueProvider.ts +31 -0
- package/src/{server-auth → server/auth}/primitives/$auth.ts +7 -0
- package/src/{server-auth → server/auth}/providers/ServerAuthProvider.ts +51 -8
- package/src/{server-cookies → server/cookies}/index.ts +2 -1
- package/src/server/{index.ts → core/index.ts} +7 -0
- package/src/server/{primitives → core/primitives}/$action.ts +10 -1
- package/src/server/{providers → core/providers}/ServerBodyParserProvider.ts +11 -5
- package/src/server/{providers → core/providers}/ServerRouterProvider.ts +13 -7
- package/src/{server-rate-limit → server/rate-limit}/index.ts +1 -1
- package/src/{server-swagger → server/swagger}/providers/ServerSwaggerProvider.ts +1 -0
- package/src/thread/primitives/$thread.ts +2 -2
- package/src/vite/index.ts +0 -2
- package/src/vite/tasks/buildServer.ts +3 -4
- package/src/vite/tasks/copyAssets.ts +32 -8
- package/src/vite/tasks/generateCloudflare.ts +35 -19
- package/src/vite/tasks/generateDocker.ts +18 -4
- package/src/vite/tasks/generateSitemap.ts +5 -7
- package/src/vite/tasks/generateVercel.ts +76 -41
- package/src/vite/tasks/runAlepha.ts +16 -1
- package/src/websocket/providers/NodeWebSocketServerProvider.ts +3 -11
- package/src/websocket/services/WebSocketClient.ts +3 -3
- package/dist/api-files/index.browser.js.map +0 -1
- package/dist/api-files/index.js.map +0 -1
- package/dist/api-jobs/index.browser.js.map +0 -1
- package/dist/api-jobs/index.js.map +0 -1
- package/dist/api-notifications/index.browser.js.map +0 -1
- package/dist/api-notifications/index.d.ts +0 -327
- package/dist/api-notifications/index.js.map +0 -1
- package/dist/api-parameters/index.browser.js +0 -29
- package/dist/api-parameters/index.browser.js.map +0 -1
- package/dist/api-parameters/index.d.ts +0 -83
- package/dist/api-parameters/index.js +0 -63
- package/dist/api-parameters/index.js.map +0 -1
- package/dist/api-users/index.browser.js.map +0 -1
- package/dist/api-users/index.js.map +0 -1
- package/dist/api-verifications/index.browser.js.map +0 -1
- package/dist/api-verifications/index.d.ts +0 -229
- package/dist/api-verifications/index.js.map +0 -1
- package/dist/cache/index.js.map +0 -1
- package/dist/cache-redis/index.js.map +0 -1
- package/dist/cli/dist-BlfFtOk2.js +0 -2770
- package/dist/cli/dist-BlfFtOk2.js.map +0 -1
- package/dist/lock/index.js.map +0 -1
- package/dist/lock-redis/index.js.map +0 -1
- package/dist/queue/index.d.ts +0 -1265
- package/dist/queue/index.js +0 -1037
- package/dist/queue/index.js.map +0 -1
- package/dist/queue-redis/index.d.ts +0 -82
- package/dist/queue-redis/index.js +0 -872
- package/dist/queue-redis/index.js.map +0 -1
- package/dist/server/index.browser.js.map +0 -1
- package/dist/server/index.js.map +0 -1
- package/dist/server-auth/index.browser.js.map +0 -1
- package/dist/server-auth/index.js +0 -1943
- package/dist/server-auth/index.js.map +0 -1
- package/dist/server-cache/index.js.map +0 -1
- package/dist/server-compress/index.js.map +0 -1
- package/dist/server-cookies/index.browser.js.map +0 -1
- package/dist/server-cookies/index.js.map +0 -1
- package/dist/server-cors/index.js.map +0 -1
- package/dist/server-health/index.js.map +0 -1
- package/dist/server-helmet/index.js.map +0 -1
- package/dist/server-links/index.browser.js.map +0 -1
- package/dist/server-links/index.js.map +0 -1
- package/dist/server-metrics/index.js +0 -4532
- package/dist/server-metrics/index.js.map +0 -1
- package/dist/server-multipart/index.js.map +0 -1
- package/dist/server-proxy/index.js.map +0 -1
- package/dist/server-rate-limit/index.js.map +0 -1
- package/dist/server-security/index.browser.js.map +0 -1
- package/dist/server-security/index.js.map +0 -1
- package/dist/server-static/index.js.map +0 -1
- package/dist/server-swagger/index.js.map +0 -1
- package/dist/topic/index.js.map +0 -1
- package/dist/topic-redis/index.js.map +0 -1
- package/src/api-parameters/controllers/ParameterController.ts +0 -45
- package/src/api-parameters/entities/parameters.ts +0 -30
- package/src/api-parameters/index.ts +0 -21
- package/src/api-parameters/primitives/$config.ts +0 -79
- package/src/api-parameters/services/ParameterStore.ts +0 -23
- package/src/queue/interfaces/QueueJob.ts +0 -459
- package/src/queue/providers/MemoryQueueProvider.ts +0 -850
- package/src/queue/providers/QueueProvider.ts +0 -319
- package/src/queue/providers/WorkerProvider.ts +0 -344
- package/src/queue-redis/providers/RedisQueueProvider.ts +0 -1209
- /package/src/{api-files → api/files}/controllers/FileController.ts +0 -0
- /package/src/{api-files → api/files}/controllers/StorageStatsController.ts +0 -0
- /package/src/{api-files → api/files}/entities/files.ts +0 -0
- /package/src/{api-files → api/files}/index.browser.ts +0 -0
- /package/src/{api-files → api/files}/jobs/FileJobs.ts +0 -0
- /package/src/{api-files → api/files}/schemas/fileQuerySchema.ts +0 -0
- /package/src/{api-files → api/files}/schemas/fileResourceSchema.ts +0 -0
- /package/src/{api-files → api/files}/schemas/storageStatsSchema.ts +0 -0
- /package/src/{api-files → api/files}/services/FileService.ts +0 -0
- /package/src/{api-jobs → api/jobs}/controllers/JobController.ts +0 -0
- /package/src/{api-jobs → api/jobs}/entities/jobExecutions.ts +0 -0
- /package/src/{api-jobs → api/jobs}/index.browser.ts +0 -0
- /package/src/{api-jobs → api/jobs}/index.ts +0 -0
- /package/src/{api-jobs → api/jobs}/primitives/$job.ts +0 -0
- /package/src/{api-jobs → api/jobs}/providers/JobProvider.ts +0 -0
- /package/src/{api-jobs → api/jobs}/schemas/jobExecutionQuerySchema.ts +0 -0
- /package/src/{api-jobs → api/jobs}/schemas/jobExecutionResourceSchema.ts +0 -0
- /package/src/{api-jobs → api/jobs}/schemas/triggerJobSchema.ts +0 -0
- /package/src/{api-jobs → api/jobs}/services/JobService.ts +0 -0
- /package/src/{api-notifications → api/notifications}/controllers/NotificationController.ts +0 -0
- /package/src/{api-notifications → api/notifications}/entities/notifications.ts +0 -0
- /package/src/{api-notifications → api/notifications}/index.browser.ts +0 -0
- /package/src/{api-notifications → api/notifications}/index.ts +0 -0
- /package/src/{api-notifications → api/notifications}/jobs/NotificationJobs.ts +0 -0
- /package/src/{api-notifications → api/notifications}/primitives/$notification.ts +0 -0
- /package/src/{api-notifications → api/notifications}/queues/NotificationQueues.ts +0 -0
- /package/src/{api-notifications → api/notifications}/schemas/notificationContactPreferencesSchema.ts +0 -0
- /package/src/{api-notifications → api/notifications}/schemas/notificationContactSchema.ts +0 -0
- /package/src/{api-notifications → api/notifications}/schemas/notificationCreateSchema.ts +0 -0
- /package/src/{api-notifications → api/notifications}/schemas/notificationQuerySchema.ts +0 -0
- /package/src/{api-notifications → api/notifications}/services/NotificationSenderService.ts +0 -0
- /package/src/{api-notifications → api/notifications}/services/NotificationService.ts +0 -0
- /package/src/{api-parameters → api/parameters}/index.browser.ts +0 -0
- /package/src/{api-users → api/users}/controllers/IdentityController.ts +0 -0
- /package/src/{api-users → api/users}/controllers/SessionController.ts +0 -0
- /package/src/{api-users → api/users}/controllers/UserController.ts +0 -0
- /package/src/{api-users → api/users}/entities/identities.ts +0 -0
- /package/src/{api-users → api/users}/entities/sessions.ts +0 -0
- /package/src/{api-users → api/users}/entities/users.ts +0 -0
- /package/src/{api-users → api/users}/index.browser.ts +0 -0
- /package/src/{api-users → api/users}/notifications/UserNotifications.ts +0 -0
- /package/src/{api-users → api/users}/schemas/completePasswordResetRequestSchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/completeRegistrationRequestSchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/createUserSchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/identityQuerySchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/identityResourceSchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/loginSchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/passwordResetIntentResponseSchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/registerQuerySchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/registerRequestSchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/registerResponseSchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/registerSchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/registrationIntentResponseSchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/resetPasswordSchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/sessionQuerySchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/sessionResourceSchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/updateUserSchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/userQuerySchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/userRealmConfigSchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/userResourceSchema.ts +0 -0
- /package/src/{api-users → api/users}/services/CredentialService.ts +0 -0
- /package/src/{api-users → api/users}/services/IdentityService.ts +0 -0
- /package/src/{api-users → api/users}/services/SessionCrudService.ts +0 -0
- /package/src/{api-verifications → api/verifications}/controllers/VerificationController.ts +0 -0
- /package/src/{api-verifications → api/verifications}/entities/verifications.ts +0 -0
- /package/src/{api-verifications → api/verifications}/index.browser.ts +0 -0
- /package/src/{api-verifications → api/verifications}/jobs/VerificationJobs.ts +0 -0
- /package/src/{api-verifications → api/verifications}/parameters/VerificationParameters.ts +0 -0
- /package/src/{api-verifications → api/verifications}/schemas/requestVerificationCodeResponseSchema.ts +0 -0
- /package/src/{api-verifications → api/verifications}/schemas/validateVerificationCodeResponseSchema.ts +0 -0
- /package/src/{api-verifications → api/verifications}/schemas/verificationSettingsSchema.ts +0 -0
- /package/src/{api-verifications → api/verifications}/schemas/verificationTypeEnumSchema.ts +0 -0
- /package/src/{api-verifications → api/verifications}/services/VerificationService.ts +0 -0
- /package/src/cache/{errors → core/errors}/CacheError.ts +0 -0
- /package/src/cache/{index.ts → core/index.ts} +0 -0
- /package/src/cache/{primitives → core/primitives}/$cache.ts +0 -0
- /package/src/cache/{providers → core/providers}/CacheProvider.ts +0 -0
- /package/src/cache/{providers → core/providers}/MemoryCacheProvider.ts +0 -0
- /package/src/{cache-redis → cache/redis}/index.ts +0 -0
- /package/src/{cache-redis → cache/redis}/providers/RedisCacheProvider.ts +0 -0
- /package/src/lock/{index.ts → core/index.ts} +0 -0
- /package/src/lock/{primitives → core/primitives}/$lock.ts +0 -0
- /package/src/lock/{providers → core/providers}/LockProvider.ts +0 -0
- /package/src/lock/{providers → core/providers}/LockTopicProvider.ts +0 -0
- /package/src/lock/{providers → core/providers}/MemoryLockProvider.ts +0 -0
- /package/src/{lock-redis → lock/redis}/index.ts +0 -0
- /package/src/{lock-redis → lock/redis}/providers/RedisLockProvider.ts +0 -0
- /package/src/queue/{primitives → core/primitives}/$consumer.ts +0 -0
- /package/src/{queue-redis → queue/redis}/index.ts +0 -0
- /package/src/{server-auth → server/auth}/constants/routes.ts +0 -0
- /package/src/{server-auth → server/auth}/index.browser.ts +0 -0
- /package/src/{server-auth → server/auth}/index.shared.ts +0 -0
- /package/src/{server-auth → server/auth}/index.ts +0 -0
- /package/src/{server-auth → server/auth}/primitives/$authApple.ts +0 -0
- /package/src/{server-auth → server/auth}/primitives/$authCredentials.ts +0 -0
- /package/src/{server-auth → server/auth}/primitives/$authGithub.ts +0 -0
- /package/src/{server-auth → server/auth}/primitives/$authGoogle.ts +0 -0
- /package/src/{server-auth → server/auth}/schemas/authenticationProviderSchema.ts +0 -0
- /package/src/{server-auth → server/auth}/schemas/tokenResponseSchema.ts +0 -0
- /package/src/{server-auth → server/auth}/schemas/tokensSchema.ts +0 -0
- /package/src/{server-auth → server/auth}/schemas/userinfoResponseSchema.ts +0 -0
- /package/src/{server-cache → server/cache}/index.ts +0 -0
- /package/src/{server-cache → server/cache}/providers/ServerCacheProvider.ts +0 -0
- /package/src/{server-compress → server/compress}/index.ts +0 -0
- /package/src/{server-compress → server/compress}/providers/ServerCompressProvider.ts +0 -0
- /package/src/{server-cookies → server/cookies}/index.browser.ts +0 -0
- /package/src/{server-cookies → server/cookies}/primitives/$cookie.browser.ts +0 -0
- /package/src/{server-cookies → server/cookies}/primitives/$cookie.ts +0 -0
- /package/src/{server-cookies → server/cookies}/providers/ServerCookiesProvider.ts +0 -0
- /package/src/{server-cookies → server/cookies}/services/CookieParser.ts +0 -0
- /package/src/server/{constants → core/constants}/routeMethods.ts +0 -0
- /package/src/server/{errors → core/errors}/BadRequestError.ts +0 -0
- /package/src/server/{errors → core/errors}/ConflictError.ts +0 -0
- /package/src/server/{errors → core/errors}/ForbiddenError.ts +0 -0
- /package/src/server/{errors → core/errors}/HttpError.ts +0 -0
- /package/src/server/{errors → core/errors}/NotFoundError.ts +0 -0
- /package/src/server/{errors → core/errors}/UnauthorizedError.ts +0 -0
- /package/src/server/{errors → core/errors}/ValidationError.ts +0 -0
- /package/src/server/{helpers → core/helpers}/ServerReply.ts +0 -0
- /package/src/server/{helpers → core/helpers}/isMultipart.ts +0 -0
- /package/src/server/{index.browser.ts → core/index.browser.ts} +0 -0
- /package/src/server/{index.shared.ts → core/index.shared.ts} +0 -0
- /package/src/server/{interfaces → core/interfaces}/ServerRequest.ts +0 -0
- /package/src/server/{primitives → core/primitives}/$route.ts +0 -0
- /package/src/server/{providers → core/providers}/BunHttpServerProvider.ts +0 -0
- /package/src/server/{providers → core/providers}/NodeHttpServerProvider.ts +0 -0
- /package/src/server/{providers → core/providers}/ServerLoggerProvider.ts +0 -0
- /package/src/server/{providers → core/providers}/ServerNotReadyProvider.ts +0 -0
- /package/src/server/{providers → core/providers}/ServerProvider.ts +0 -0
- /package/src/server/{providers → core/providers}/ServerTimingProvider.ts +0 -0
- /package/src/server/{schemas → core/schemas}/errorSchema.ts +0 -0
- /package/src/server/{schemas → core/schemas}/okSchema.ts +0 -0
- /package/src/server/{services → core/services}/HttpClient.ts +0 -0
- /package/src/server/{services → core/services}/ServerRequestParser.ts +0 -0
- /package/src/server/{services → core/services}/UserAgentParser.ts +0 -0
- /package/src/{server-cors → server/cors}/index.ts +0 -0
- /package/src/{server-cors → server/cors}/primitives/$cors.ts +0 -0
- /package/src/{server-cors → server/cors}/providers/ServerCorsProvider.ts +0 -0
- /package/src/{server-health → server/health}/index.ts +0 -0
- /package/src/{server-health → server/health}/providers/ServerHealthProvider.ts +0 -0
- /package/src/{server-health → server/health}/schemas/healthSchema.ts +0 -0
- /package/src/{server-helmet → server/helmet}/index.ts +0 -0
- /package/src/{server-helmet → server/helmet}/providers/ServerHelmetProvider.ts +0 -0
- /package/src/{server-links → server/links}/index.browser.ts +0 -0
- /package/src/{server-links → server/links}/index.ts +0 -0
- /package/src/{server-links → server/links}/primitives/$client.ts +0 -0
- /package/src/{server-links → server/links}/primitives/$remote.ts +0 -0
- /package/src/{server-links → server/links}/providers/LinkProvider.ts +0 -0
- /package/src/{server-links → server/links}/providers/RemotePrimitiveProvider.ts +0 -0
- /package/src/{server-links → server/links}/providers/ServerLinksProvider.ts +0 -0
- /package/src/{server-links → server/links}/schemas/apiLinksResponseSchema.ts +0 -0
- /package/src/{server-metrics → server/metrics}/index.ts +0 -0
- /package/src/{server-metrics → server/metrics}/providers/ServerMetricsProvider.ts +0 -0
- /package/src/{server-multipart → server/multipart}/index.ts +0 -0
- /package/src/{server-multipart → server/multipart}/providers/ServerMultipartProvider.ts +0 -0
- /package/src/{server-proxy → server/proxy}/index.ts +0 -0
- /package/src/{server-proxy → server/proxy}/primitives/$proxy.ts +0 -0
- /package/src/{server-proxy → server/proxy}/providers/ServerProxyProvider.ts +0 -0
- /package/src/{server-rate-limit → server/rate-limit}/primitives/$rateLimit.ts +0 -0
- /package/src/{server-rate-limit → server/rate-limit}/providers/ServerRateLimitProvider.ts +0 -0
- /package/src/{server-security → server/security}/index.browser.ts +0 -0
- /package/src/{server-security → server/security}/index.ts +0 -0
- /package/src/{server-security → server/security}/primitives/$basicAuth.ts +0 -0
- /package/src/{server-security → server/security}/providers/ServerBasicAuthProvider.ts +0 -0
- /package/src/{server-security → server/security}/providers/ServerSecurityProvider.ts +0 -0
- /package/src/{server-static → server/static}/index.ts +0 -0
- /package/src/{server-static → server/static}/primitives/$serve.ts +0 -0
- /package/src/{server-static → server/static}/providers/ServerStaticProvider.ts +0 -0
- /package/src/{server-swagger → server/swagger}/index.ts +0 -0
- /package/src/{server-swagger → server/swagger}/primitives/$swagger.ts +0 -0
- /package/src/topic/{errors → core/errors}/TopicTimeoutError.ts +0 -0
- /package/src/topic/{index.ts → core/index.ts} +0 -0
- /package/src/topic/{primitives → core/primitives}/$subscriber.ts +0 -0
- /package/src/topic/{primitives → core/primitives}/$topic.ts +0 -0
- /package/src/topic/{providers → core/providers}/MemoryTopicProvider.ts +0 -0
- /package/src/topic/{providers → core/providers}/TopicProvider.ts +0 -0
- /package/src/{topic-redis → topic/redis}/index.ts +0 -0
- /package/src/{topic-redis → topic/redis}/providers/RedisTopicProvider.ts +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["contextData: Partial<CreateAudit>","stats: AuditStats","t","definition: AuditTypeDefinition"],"sources":["../../../src/api/audits/entities/audits.ts","../../../src/api/audits/schemas/auditQuerySchema.ts","../../../src/api/audits/schemas/auditResourceSchema.ts","../../../src/api/audits/schemas/createAuditSchema.ts","../../../src/api/audits/services/AuditService.ts","../../../src/api/audits/controllers/AuditController.ts","../../../src/api/audits/primitives/$audit.ts","../../../src/api/audits/index.ts"],"sourcesContent":["import type { Static } from \"alepha\";\nimport { t } from \"alepha\";\nimport { $entity, pg } from \"alepha/orm\";\n\n/**\n * Audit severity levels for categorizing events.\n */\nexport const auditSeveritySchema = t.enum([\"info\", \"warning\", \"critical\"], {\n default: \"info\",\n description: \"Severity level of the audit event\",\n});\n\nexport type AuditSeverity = Static<typeof auditSeveritySchema>;\n\n/**\n * Audit log entity for tracking important system events.\n *\n * Stores comprehensive audit information including:\n * - Who performed the action (userId, userRealm)\n * - What happened (type, action, resource)\n * - When it happened (createdAt)\n * - Context and details (metadata, ipAddress, userAgent)\n */\nexport const audits = $entity({\n name: \"audits\",\n schema: t.object({\n id: pg.primaryKey(t.bigint()),\n createdAt: pg.createdAt(),\n\n /**\n * Audit event type (e.g., \"auth\", \"user\", \"payment\", \"system\").\n * Used for categorizing and filtering audit events.\n */\n type: t.text({\n description: \"Audit event type (e.g., auth, user, payment, system)\",\n }),\n\n /**\n * Specific action performed (e.g., \"login\", \"logout\", \"create\", \"update\", \"delete\").\n */\n action: t.text({\n description: \"Specific action performed (e.g., login, create, update)\",\n }),\n\n /**\n * Severity level of the event.\n */\n severity: pg.default(auditSeveritySchema, \"info\"),\n\n /**\n * User ID who performed the action (null for system events).\n */\n userId: t.optional(t.uuid()),\n\n /**\n * User realm for multi-tenant support.\n */\n userRealm: t.optional(t.text()),\n\n /**\n * User email at the time of the event (denormalized for history).\n */\n userEmail: t.optional(t.email()),\n\n /**\n * Resource type affected (e.g., \"user\", \"order\", \"file\").\n */\n resourceType: t.optional(t.text()),\n\n /**\n * Resource ID affected.\n */\n resourceId: t.optional(t.text()),\n\n /**\n * Human-readable description of the event.\n */\n description: t.optional(t.text()),\n\n /**\n * Additional metadata/context as JSON.\n */\n metadata: t.optional(t.json()),\n\n /**\n * Client IP address.\n */\n ipAddress: t.optional(t.text()),\n\n /**\n * Client user agent.\n */\n userAgent: t.optional(t.text()),\n\n /**\n * Session ID if applicable.\n */\n sessionId: t.optional(t.uuid()),\n\n /**\n * Request ID for correlation.\n */\n requestId: t.optional(t.text()),\n\n /**\n * Whether the action was successful.\n */\n success: pg.default(t.boolean(), true),\n\n /**\n * Error message if the action failed.\n */\n errorMessage: t.optional(t.text()),\n }),\n indexes: [\n \"createdAt\",\n \"type\",\n \"action\",\n \"userId\",\n \"userRealm\",\n \"resourceType\",\n \"resourceId\",\n \"severity\",\n { columns: [\"type\", \"action\"] },\n { columns: [\"userId\", \"createdAt\"] },\n { columns: [\"userRealm\", \"createdAt\"] },\n ],\n});\n\nexport const auditEntitySchema = audits.schema;\nexport const auditEntityInsertSchema = audits.insertSchema;\nexport type AuditEntity = Static<typeof audits.schema>;\n","import type { Static } from \"alepha\";\nimport { t } from \"alepha\";\nimport { pageQuerySchema } from \"alepha/orm\";\nimport { auditSeveritySchema } from \"../entities/audits.ts\";\n\n/**\n * Query schema for searching and filtering audit logs.\n */\nexport const auditQuerySchema = t.extend(pageQuerySchema, {\n type: t.optional(t.text({ description: \"Filter by audit type\" })),\n action: t.optional(t.text({ description: \"Filter by action\" })),\n severity: t.optional(auditSeveritySchema),\n userId: t.optional(t.uuid({ description: \"Filter by user ID\" })),\n userRealm: t.optional(t.text({ description: \"Filter by user realm\" })),\n resourceType: t.optional(t.text({ description: \"Filter by resource type\" })),\n resourceId: t.optional(t.text({ description: \"Filter by resource ID\" })),\n success: t.optional(t.boolean({ description: \"Filter by success status\" })),\n from: t.optional(t.datetime({ description: \"Start date filter\" })),\n to: t.optional(t.datetime({ description: \"End date filter\" })),\n search: t.optional(t.text({ description: \"Search in description\" })),\n});\n\nexport type AuditQuery = Static<typeof auditQuerySchema>;\n","import type { Static } from \"alepha\";\nimport { audits } from \"../entities/audits.ts\";\n\n/**\n * Resource schema for audit log responses.\n */\nexport const auditResourceSchema = audits.schema;\n\nexport type AuditResource = Static<typeof auditResourceSchema>;\n","import type { Static } from \"alepha\";\nimport { t } from \"alepha\";\nimport { auditSeveritySchema } from \"../entities/audits.ts\";\n\n/**\n * Schema for creating a new audit log entry.\n */\nexport const createAuditSchema = t.object({\n type: t.text({ description: \"Audit event type\" }),\n action: t.text({ description: \"Specific action performed\" }),\n severity: t.optional(auditSeveritySchema),\n userId: t.optional(t.uuid()),\n userRealm: t.optional(t.text()),\n userEmail: t.optional(t.email()),\n resourceType: t.optional(t.text()),\n resourceId: t.optional(t.text()),\n description: t.optional(t.text()),\n metadata: t.optional(t.json()),\n ipAddress: t.optional(t.text()),\n userAgent: t.optional(t.text()),\n sessionId: t.optional(t.uuid()),\n requestId: t.optional(t.text()),\n success: t.optional(t.boolean()),\n errorMessage: t.optional(t.text()),\n});\n\nexport type CreateAudit = Static<typeof createAuditSchema>;\n","import { $inject, Alepha } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport { $repository, type Page } from \"alepha/orm\";\nimport type { ServerRequest } from \"alepha/server\";\nimport {\n type AuditEntity,\n type AuditSeverity,\n audits,\n} from \"../entities/audits.ts\";\nimport type { AuditQuery } from \"../schemas/auditQuerySchema.ts\";\nimport type { CreateAudit } from \"../schemas/createAuditSchema.ts\";\n\n/**\n * Registered audit type definition.\n */\nexport interface AuditTypeDefinition {\n type: string;\n description?: string;\n actions: string[];\n}\n\n/**\n * Service for managing audit logs.\n *\n * Provides methods for:\n * - Creating audit entries\n * - Querying audit history\n * - Aggregating audit statistics\n * - Managing registered audit types\n */\nexport class AuditService {\n protected readonly alepha = $inject(Alepha);\n protected readonly log = $logger();\n protected readonly repo = $repository(audits);\n\n /**\n * Registry of audit types and their allowed actions.\n */\n protected readonly auditTypes = new Map<string, AuditTypeDefinition>();\n\n /**\n * Register an audit type with its allowed actions.\n */\n public registerType(definition: AuditTypeDefinition): void {\n this.auditTypes.set(definition.type, definition);\n this.log.debug(\"Audit type registered\", {\n type: definition.type,\n actions: definition.actions,\n });\n }\n\n /**\n * Get all registered audit types.\n */\n public getRegisteredTypes(): AuditTypeDefinition[] {\n return Array.from(this.auditTypes.values());\n }\n\n /**\n * Get current request context if available.\n */\n protected getRequestContext(): ServerRequest | undefined {\n return this.alepha.context.get<ServerRequest>(\"request\");\n }\n\n /**\n * Create a new audit log entry.\n * Automatically populates ipAddress, userAgent, and requestId from the current request context.\n */\n public async create(data: CreateAudit): Promise<AuditEntity> {\n const request = this.getRequestContext();\n\n // Auto-populate from request context if not provided\n const contextData: Partial<CreateAudit> = {};\n\n if (request) {\n if (!data.ipAddress && request.ip) {\n contextData.ipAddress = request.ip;\n }\n if (!data.userAgent && request.headers[\"user-agent\"]) {\n contextData.userAgent = request.headers[\"user-agent\"];\n }\n if (!data.requestId && request.requestId) {\n contextData.requestId = request.requestId;\n }\n // Check for session in metadata\n if (!data.sessionId && request.metadata?.sessionId) {\n contextData.sessionId = request.metadata.sessionId;\n }\n // Extract user from request.user (set by ServerSecurityProvider)\n const user = request.user;\n if (user) {\n if (!data.userId && user.id) {\n contextData.userId = user.id;\n }\n if (!data.userEmail && user.email) {\n contextData.userEmail = user.email;\n }\n if (!data.userRealm && user.realm) {\n contextData.userRealm = user.realm;\n }\n }\n }\n\n this.log.trace(\"Creating audit entry\", {\n type: data.type,\n action: data.action,\n userId: data.userId ?? contextData.userId,\n });\n\n const entry = await this.repo.create({\n ...contextData,\n ...data,\n severity: data.severity ?? \"info\",\n success: data.success ?? true,\n });\n\n this.log.debug(\"Audit entry created\", {\n id: entry.id,\n type: data.type,\n action: data.action,\n });\n\n return entry;\n }\n\n /**\n * Record an audit event (convenience method).\n */\n public async record(\n type: string,\n action: string,\n options: Omit<CreateAudit, \"type\" | \"action\"> = {},\n ): Promise<AuditEntity> {\n return this.create({ type, action, ...options });\n }\n\n /**\n * Record an authentication event.\n */\n public async recordAuth(\n action:\n | \"login\"\n | \"logout\"\n | \"login_failed\"\n | \"token_refresh\"\n | \"mfa_setup\"\n | \"mfa_verify\",\n options: Omit<CreateAudit, \"type\" | \"action\"> = {},\n ): Promise<AuditEntity> {\n return this.create({\n type: \"auth\",\n action,\n severity: action === \"login_failed\" ? \"warning\" : \"info\",\n ...options,\n });\n }\n\n /**\n * Record a user management event.\n */\n public async recordUser(\n action:\n | \"create\"\n | \"update\"\n | \"delete\"\n | \"enable\"\n | \"disable\"\n | \"role_change\",\n options: Omit<CreateAudit, \"type\" | \"action\"> = {},\n ): Promise<AuditEntity> {\n return this.create({\n type: \"user\",\n action,\n resourceType: \"user\",\n ...options,\n });\n }\n\n /**\n * Record a data access event.\n */\n public async recordAccess(\n action: \"view\" | \"export\" | \"download\",\n options: Omit<CreateAudit, \"type\" | \"action\"> = {},\n ): Promise<AuditEntity> {\n return this.create({ type: \"access\", action, ...options });\n }\n\n /**\n * Record a security event.\n */\n public async recordSecurity(\n action:\n | \"permission_denied\"\n | \"suspicious_activity\"\n | \"rate_limited\"\n | \"blocked\",\n options: Omit<CreateAudit, \"type\" | \"action\"> = {},\n ): Promise<AuditEntity> {\n return this.create({\n type: \"security\",\n action,\n severity: \"warning\",\n ...options,\n });\n }\n\n /**\n * Record a system event.\n */\n public async recordSystem(\n action: \"startup\" | \"shutdown\" | \"config_change\" | \"maintenance\" | \"error\",\n options: Omit<CreateAudit, \"type\" | \"action\"> = {},\n ): Promise<AuditEntity> {\n return this.create({\n type: \"system\",\n action,\n severity: action === \"error\" ? \"critical\" : \"info\",\n ...options,\n });\n }\n\n /**\n * Find audit entries with filtering and pagination.\n */\n public async find(query: AuditQuery = {}): Promise<Page<AuditEntity>> {\n this.log.trace(\"Finding audit entries\", { query });\n\n query.sort ??= \"-createdAt\";\n\n const where = this.repo.createQueryWhere();\n\n if (query.type) {\n where.type = { eq: query.type };\n }\n\n if (query.action) {\n where.action = { eq: query.action };\n }\n\n if (query.severity) {\n where.severity = { eq: query.severity };\n }\n\n if (query.userId) {\n where.userId = { eq: query.userId };\n }\n\n if (query.userRealm) {\n where.userRealm = { eq: query.userRealm };\n }\n\n if (query.resourceType) {\n where.resourceType = { eq: query.resourceType };\n }\n\n if (query.resourceId) {\n where.resourceId = { eq: query.resourceId };\n }\n\n if (query.success !== undefined) {\n where.success = { eq: query.success };\n }\n\n if (query.from) {\n where.createdAt = { ...(where.createdAt as object), gte: query.from };\n }\n\n if (query.to) {\n where.createdAt = { ...(where.createdAt as object), lte: query.to };\n }\n\n if (query.search) {\n where.description = { like: `%${query.search}%` };\n }\n\n const result = await this.repo.paginate(query, { where }, { count: true });\n\n this.log.debug(\"Audit entries found\", {\n count: result.content.length,\n total: result.page.totalElements,\n });\n\n return result;\n }\n\n /**\n * Get audit entry by ID.\n */\n public async getById(id: string): Promise<AuditEntity> {\n return this.repo.findById(id);\n }\n\n /**\n * Get audit entries for a specific user.\n */\n public async findByUser(\n userId: string,\n query: Omit<AuditQuery, \"userId\"> = {},\n ): Promise<Page<AuditEntity>> {\n return this.find({ ...query, userId });\n }\n\n /**\n * Get audit entries for a specific resource.\n */\n public async findByResource(\n resourceType: string,\n resourceId: string,\n query: Omit<AuditQuery, \"resourceType\" | \"resourceId\"> = {},\n ): Promise<Page<AuditEntity>> {\n return this.find({ ...query, resourceType, resourceId });\n }\n\n /**\n * Get audit statistics for a time period.\n */\n public async getStats(\n options: { from?: Date; to?: Date; userRealm?: string } = {},\n ): Promise<AuditStats> {\n this.log.trace(\"Getting audit stats\", options);\n\n const where = this.repo.createQueryWhere();\n\n if (options.from) {\n where.createdAt = { gte: options.from.toISOString() };\n }\n\n if (options.to) {\n where.createdAt = {\n ...(where.createdAt as object),\n lte: options.to.toISOString(),\n };\n }\n\n if (options.userRealm) {\n where.userRealm = { eq: options.userRealm };\n }\n\n const all = await this.repo.findMany({ where });\n\n const stats: AuditStats = {\n total: all.length,\n byType: {},\n bySeverity: { info: 0, warning: 0, critical: 0 },\n successRate: 0,\n recentFailures: [],\n };\n\n let successCount = 0;\n\n for (const entry of all) {\n // Count by type\n stats.byType[entry.type] = (stats.byType[entry.type] || 0) + 1;\n\n // Count by severity\n const severity = entry.severity as AuditSeverity;\n stats.bySeverity[severity]++;\n\n // Count successes\n if (entry.success) {\n successCount++;\n }\n }\n\n stats.successRate = stats.total > 0 ? successCount / stats.total : 1;\n\n // Get recent failures\n const failures = all\n .filter((e) => !e.success)\n .sort(\n (a, b) =>\n new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(),\n )\n .slice(0, 10);\n\n stats.recentFailures = failures;\n\n return stats;\n }\n\n /**\n * Delete old audit entries (for retention policy).\n */\n public async deleteOlderThan(date: Date): Promise<number> {\n this.log.info(\"Deleting old audit entries\", { olderThan: date });\n\n const old = await this.repo.findMany({\n where: { createdAt: { lt: date.toISOString() } },\n });\n\n for (const entry of old) {\n await this.repo.deleteById(entry.id);\n }\n\n this.log.info(\"Old audit entries deleted\", { count: old.length });\n\n return old.length;\n }\n}\n\n/**\n * Audit statistics summary.\n */\nexport interface AuditStats {\n total: number;\n byType: Record<string, number>;\n bySeverity: Record<AuditSeverity, number>;\n successRate: number;\n recentFailures: AuditEntity[];\n}\n","import { $inject, t } from \"alepha\";\nimport { pg } from \"alepha/orm\";\nimport { $action } from \"alepha/server\";\nimport { auditQuerySchema } from \"../schemas/auditQuerySchema.ts\";\nimport { auditResourceSchema } from \"../schemas/auditResourceSchema.ts\";\nimport { createAuditSchema } from \"../schemas/createAuditSchema.ts\";\nimport { AuditService } from \"../services/AuditService.ts\";\n\n/**\n * REST API controller for audit log management.\n *\n * Provides endpoints for:\n * - Querying audit logs with filtering\n * - Creating audit entries\n * - Getting audit statistics\n * - Viewing registered audit types\n */\nexport class AuditController {\n protected readonly url = \"/audits\";\n protected readonly group = \"audits\";\n protected readonly auditService = $inject(AuditService);\n\n /**\n * Find audit entries with filtering and pagination.\n */\n public readonly findAudits = $action({\n path: this.url,\n group: this.group,\n description: \"Find audit entries with filtering and pagination\",\n schema: {\n query: auditQuerySchema,\n response: pg.page(auditResourceSchema),\n },\n handler: ({ query }) => this.auditService.find(query),\n });\n\n /**\n * Get a single audit entry by ID.\n */\n public readonly getAudit = $action({\n path: `${this.url}/:id`,\n group: this.group,\n description: \"Get a single audit entry by ID\",\n schema: {\n params: t.object({\n id: t.text(),\n }),\n response: auditResourceSchema,\n },\n handler: ({ params }) => this.auditService.getById(params.id),\n });\n\n /**\n * Create a new audit entry.\n */\n public readonly createAudit = $action({\n method: \"POST\",\n path: this.url,\n group: this.group,\n description: \"Create a new audit entry\",\n schema: {\n body: createAuditSchema,\n response: auditResourceSchema,\n },\n handler: ({ body }) => this.auditService.create(body),\n });\n\n /**\n * Get audit entries for a specific user.\n */\n public readonly findByUser = $action({\n path: `${this.url}/user/:userId`,\n group: this.group,\n description: \"Get audit entries for a specific user\",\n schema: {\n params: t.object({\n userId: t.uuid(),\n }),\n query: t.omit(auditQuerySchema, [\"userId\"]),\n response: pg.page(auditResourceSchema),\n },\n handler: ({ params, query }) =>\n this.auditService.findByUser(params.userId, query),\n });\n\n /**\n * Get audit entries for a specific resource.\n */\n public readonly findByResource = $action({\n path: `${this.url}/resource/:resourceType/:resourceId`,\n group: this.group,\n description: \"Get audit entries for a specific resource\",\n schema: {\n params: t.object({\n resourceType: t.text(),\n resourceId: t.text(),\n }),\n query: t.omit(auditQuerySchema, [\"resourceType\", \"resourceId\"]),\n response: pg.page(auditResourceSchema),\n },\n handler: ({ params, query }) =>\n this.auditService.findByResource(\n params.resourceType,\n params.resourceId,\n query,\n ),\n });\n\n /**\n * Get audit statistics.\n */\n public readonly getStats = $action({\n path: `${this.url}/stats`,\n group: this.group,\n description: \"Get audit statistics for a time period\",\n schema: {\n query: t.object({\n from: t.optional(t.datetime()),\n to: t.optional(t.datetime()),\n userRealm: t.optional(t.text()),\n }),\n response: t.object({\n total: t.integer(),\n byType: t.record(t.text(), t.integer()),\n bySeverity: t.object({\n info: t.integer(),\n warning: t.integer(),\n critical: t.integer(),\n }),\n successRate: t.number(),\n recentFailures: t.array(auditResourceSchema),\n }),\n },\n handler: ({ query }) =>\n this.auditService.getStats({\n from: query.from ? new Date(query.from) : undefined,\n to: query.to ? new Date(query.to) : undefined,\n userRealm: query.userRealm,\n }),\n });\n\n /**\n * Get registered audit types.\n */\n public readonly getTypes = $action({\n path: `${this.url}/types`,\n group: this.group,\n description: \"Get all registered audit types\",\n schema: {\n response: t.array(\n t.object({\n type: t.text(),\n description: t.optional(t.text()),\n actions: t.array(t.text()),\n }),\n ),\n },\n handler: () => this.auditService.getRegisteredTypes(),\n });\n\n /**\n * Get distinct values for filters.\n */\n public readonly getFilterOptions = $action({\n path: `${this.url}/filters`,\n group: this.group,\n description: \"Get distinct values for audit filters\",\n schema: {\n response: t.object({\n types: t.array(t.text()),\n actions: t.array(t.text()),\n resourceTypes: t.array(t.text()),\n userRealms: t.array(t.text()),\n }),\n },\n handler: async () => {\n const types = this.auditService.getRegisteredTypes();\n return {\n types: types.map((t) => t.type),\n actions: types.flatMap((t) => t.actions),\n resourceTypes: [\"user\", \"session\", \"file\", \"order\", \"payment\"],\n userRealms: [\"default\"],\n };\n },\n });\n}\n","import { $inject, createPrimitive, KIND, Primitive } from \"alepha\";\nimport {\n AuditService,\n type AuditTypeDefinition,\n} from \"../services/AuditService.ts\";\n\n/**\n * Options for creating an audit type primitive.\n */\nexport interface AuditPrimitiveOptions {\n /**\n * Unique audit type identifier (e.g., \"auth\", \"payment\", \"order\").\n */\n type: string;\n\n /**\n * Human-readable description of this audit type.\n */\n description?: string;\n\n /**\n * List of allowed actions for this audit type.\n */\n actions: string[];\n}\n\n/**\n * Audit type primitive for registering domain-specific audit events.\n *\n * Provides a type-safe way to define and log audit events within a specific domain.\n *\n * @example\n * ```ts\n * class PaymentAudits {\n * audit = $audit({\n * type: \"payment\",\n * description: \"Payment-related audit events\",\n * actions: [\"create\", \"refund\", \"cancel\", \"dispute\"],\n * });\n *\n * async logPaymentCreated(paymentId: string, userId: string, amount: number) {\n * await this.audit.log(\"create\", {\n * userId,\n * resourceType: \"payment\",\n * resourceId: paymentId,\n * description: `Payment of ${amount} created`,\n * metadata: { amount },\n * });\n * }\n * }\n * ```\n */\nexport class AuditPrimitive extends Primitive<AuditPrimitiveOptions> {\n protected readonly auditService = $inject(AuditService);\n\n /**\n * The audit type identifier.\n */\n public get type(): string {\n return this.options.type;\n }\n\n /**\n * The audit type description.\n */\n public get description(): string | undefined {\n return this.options.description;\n }\n\n /**\n * The allowed actions for this audit type.\n */\n public get actions(): string[] {\n return this.options.actions;\n }\n\n /**\n * Log an audit event for this type.\n */\n public async log(\n action: string,\n options: AuditLogOptions = {},\n ): Promise<void> {\n await this.auditService.record(this.options.type, action, options);\n }\n\n /**\n * Log a successful audit event.\n */\n public async logSuccess(\n action: string,\n options: Omit<AuditLogOptions, \"success\"> = {},\n ): Promise<void> {\n await this.log(action, { ...options, success: true });\n }\n\n /**\n * Log a failed audit event.\n */\n public async logFailure(\n action: string,\n errorMessage: string,\n options: Omit<AuditLogOptions, \"success\" | \"errorMessage\"> = {},\n ): Promise<void> {\n await this.log(action, { ...options, success: false, errorMessage });\n }\n\n /**\n * Called during initialization to register this audit type.\n */\n protected onInit(): void {\n const definition: AuditTypeDefinition = {\n type: this.options.type,\n description: this.options.description,\n actions: this.options.actions,\n };\n this.auditService.registerType(definition);\n }\n}\n\n/**\n * Options for logging an audit event.\n */\nexport interface AuditLogOptions {\n severity?: \"info\" | \"warning\" | \"critical\";\n userId?: string;\n userRealm?: string;\n userEmail?: string;\n resourceType?: string;\n resourceId?: string;\n description?: string;\n metadata?: Record<string, unknown>;\n ipAddress?: string;\n userAgent?: string;\n sessionId?: string;\n requestId?: string;\n success?: boolean;\n errorMessage?: string;\n}\n\n/**\n * Create an audit type primitive.\n *\n * @example\n * ```ts\n * class OrderAudits {\n * audit = $audit({\n * type: \"order\",\n * description: \"Order management events\",\n * actions: [\"create\", \"update\", \"cancel\", \"fulfill\", \"ship\"],\n * });\n * }\n * ```\n */\nexport const $audit = (options: AuditPrimitiveOptions) => {\n return createPrimitive(AuditPrimitive, options);\n};\n\n$audit[KIND] = AuditPrimitive;\n","import { $module } from \"alepha\";\nimport { AuditController } from \"./controllers/AuditController.ts\";\nimport { AuditService } from \"./services/AuditService.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./controllers/AuditController.ts\";\nexport * from \"./entities/audits.ts\";\nexport * from \"./primitives/$audit.ts\";\nexport * from \"./schemas/auditQuerySchema.ts\";\nexport * from \"./schemas/auditResourceSchema.ts\";\nexport * from \"./schemas/createAuditSchema.ts\";\nexport * from \"./services/AuditService.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Provides audit logging API endpoints for Alepha applications.\n *\n * This module includes:\n * - Audit log CRUD operations\n * - Filtering and searching audit events\n * - Audit statistics and analytics\n * - `$audit` primitive for domain-specific audit types\n *\n * @module alepha.api.audits\n *\n * @example\n * ```ts\n * // In your app module\n * import { AlephaApiAudits } from \"alepha/api/audits\";\n *\n * const App = $module({\n * name: \"app\",\n * services: [AlephaApiAudits, ...],\n * });\n *\n * // Create domain-specific audit types\n * class PaymentAudits {\n * audit = $audit({\n * type: \"payment\",\n * actions: [\"create\", \"refund\", \"cancel\"],\n * });\n *\n * async onPaymentCreated(paymentId: string, userId: string) {\n * await this.audit.log(\"create\", {\n * userId,\n * resourceType: \"payment\",\n * resourceId: paymentId,\n * });\n * }\n * }\n * ```\n */\nexport const AlephaApiAudits = $module({\n name: \"alepha.api.audits\",\n services: [AuditService, AuditController],\n});\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { $module, t } from "alepha";
|
|
2
2
|
import { $entity, pageQuerySchema, pg } from "alepha/orm";
|
|
3
3
|
|
|
4
|
-
//#region ../../src/api
|
|
4
|
+
//#region ../../src/api/files/entities/files.ts
|
|
5
5
|
const files = $entity({
|
|
6
6
|
name: "files",
|
|
7
7
|
schema: t.object({
|
|
@@ -32,7 +32,7 @@ const files = $entity({
|
|
|
32
32
|
});
|
|
33
33
|
|
|
34
34
|
//#endregion
|
|
35
|
-
//#region ../../src/api
|
|
35
|
+
//#region ../../src/api/files/schemas/fileQuerySchema.ts
|
|
36
36
|
const fileQuerySchema = t.extend(pageQuerySchema, {
|
|
37
37
|
bucket: t.optional(t.string()),
|
|
38
38
|
tags: t.optional(t.array(t.string())),
|
|
@@ -44,14 +44,14 @@ const fileQuerySchema = t.extend(pageQuerySchema, {
|
|
|
44
44
|
});
|
|
45
45
|
|
|
46
46
|
//#endregion
|
|
47
|
-
//#region ../../src/api
|
|
47
|
+
//#region ../../src/api/files/schemas/fileResourceSchema.ts
|
|
48
48
|
const fileResourceSchema = t.extend(files.schema, {}, {
|
|
49
49
|
title: "FileResource",
|
|
50
50
|
description: "A file resource representing a file stored in the system."
|
|
51
51
|
});
|
|
52
52
|
|
|
53
53
|
//#endregion
|
|
54
|
-
//#region ../../src/api
|
|
54
|
+
//#region ../../src/api/files/schemas/storageStatsSchema.ts
|
|
55
55
|
const bucketStatsSchema = t.object({
|
|
56
56
|
bucket: t.string(),
|
|
57
57
|
totalSize: t.number(),
|
|
@@ -69,7 +69,7 @@ const storageStatsSchema = t.object({
|
|
|
69
69
|
});
|
|
70
70
|
|
|
71
71
|
//#endregion
|
|
72
|
-
//#region ../../src/api
|
|
72
|
+
//#region ../../src/api/files/index.browser.ts
|
|
73
73
|
const AlephaApiFiles = $module({
|
|
74
74
|
name: "alepha.api.files",
|
|
75
75
|
services: []
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.browser.js","names":[],"sources":["../../../src/api/files/entities/files.ts","../../../src/api/files/schemas/fileQuerySchema.ts","../../../src/api/files/schemas/fileResourceSchema.ts","../../../src/api/files/schemas/storageStatsSchema.ts","../../../src/api/files/index.browser.ts"],"sourcesContent":["import { type Static, t } from \"alepha\";\nimport { $entity, pg } from \"alepha/orm\";\n\nexport const files = $entity({\n name: \"files\",\n schema: t.object({\n id: pg.primaryKey(t.uuid()),\n version: pg.version(),\n createdAt: pg.createdAt(),\n updatedAt: pg.updatedAt(),\n blobId: t.text(),\n creator: t.optional(t.uuid()),\n creatorRealm: t.optional(t.string()),\n creatorName: t.optional(t.string()),\n bucket: t.text(),\n expirationDate: t.optional(t.datetime()),\n name: t.text(),\n size: t.number(),\n mimeType: t.string(),\n tags: t.optional(t.array(t.text())),\n checksum: t.optional(t.string()),\n }),\n indexes: [\n \"expirationDate\",\n \"bucket\",\n \"creator\",\n \"createdAt\",\n \"mimeType\",\n {\n columns: [\"bucket\", \"createdAt\"],\n },\n ],\n});\n\nexport type FileEntity = Static<typeof files.schema>;\n","import type { Static } from \"alepha\";\nimport { t } from \"alepha\";\nimport { pageQuerySchema } from \"alepha/orm\";\n\nexport const fileQuerySchema = t.extend(pageQuerySchema, {\n bucket: t.optional(t.string()),\n tags: t.optional(t.array(t.string())),\n name: t.optional(t.string()),\n mimeType: t.optional(t.string()),\n creator: t.optional(t.uuid()),\n createdAfter: t.optional(t.datetime()),\n createdBefore: t.optional(t.datetime()),\n});\n\nexport type FileQuery = Static<typeof fileQuerySchema>;\n","import { type Static, t } from \"alepha\";\nimport { files } from \"../entities/files.ts\";\n\nexport const fileResourceSchema = t.extend(\n files.schema,\n {},\n {\n title: \"FileResource\",\n description: \"A file resource representing a file stored in the system.\",\n },\n);\n\nexport type FileResource = Static<typeof fileResourceSchema>;\n","import type { Static } from \"alepha\";\nimport { t } from \"alepha\";\n\nexport const bucketStatsSchema = t.object({\n bucket: t.string(),\n totalSize: t.number(),\n fileCount: t.number(),\n});\n\nexport const mimeTypeStatsSchema = t.object({\n mimeType: t.string(),\n fileCount: t.number(),\n});\n\nexport const storageStatsSchema = t.object({\n totalSize: t.number(),\n totalFiles: t.number(),\n byBucket: t.array(bucketStatsSchema),\n byMimeType: t.array(mimeTypeStatsSchema),\n});\n\nexport type BucketStats = Static<typeof bucketStatsSchema>;\nexport type MimeTypeStats = Static<typeof mimeTypeStatsSchema>;\nexport type StorageStats = Static<typeof storageStatsSchema>;\n","import { $module } from \"alepha\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport type * from \"./controllers/FileController.ts\";\nexport type * from \"./controllers/StorageStatsController.ts\";\nexport * from \"./entities/files.ts\";\nexport * from \"./schemas/fileQuerySchema.ts\";\nexport * from \"./schemas/fileResourceSchema.ts\";\nexport * from \"./schemas/storageStatsSchema.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport const AlephaApiFiles = $module({\n name: \"alepha.api.files\",\n services: [],\n});\n"],"mappings":";;;;AAGA,MAAa,QAAQ,QAAQ;CAC3B,MAAM;CACN,QAAQ,EAAE,OAAO;EACf,IAAI,GAAG,WAAW,EAAE,MAAM,CAAC;EAC3B,SAAS,GAAG,SAAS;EACrB,WAAW,GAAG,WAAW;EACzB,WAAW,GAAG,WAAW;EACzB,QAAQ,EAAE,MAAM;EAChB,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC;EAC7B,cAAc,EAAE,SAAS,EAAE,QAAQ,CAAC;EACpC,aAAa,EAAE,SAAS,EAAE,QAAQ,CAAC;EACnC,QAAQ,EAAE,MAAM;EAChB,gBAAgB,EAAE,SAAS,EAAE,UAAU,CAAC;EACxC,MAAM,EAAE,MAAM;EACd,MAAM,EAAE,QAAQ;EAChB,UAAU,EAAE,QAAQ;EACpB,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;EACnC,UAAU,EAAE,SAAS,EAAE,QAAQ,CAAC;EACjC,CAAC;CACF,SAAS;EACP;EACA;EACA;EACA;EACA;EACA,EACE,SAAS,CAAC,UAAU,YAAY,EACjC;EACF;CACF,CAAC;;;;AC5BF,MAAa,kBAAkB,EAAE,OAAO,iBAAiB;CACvD,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC;CAC9B,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;CACrC,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC;CAC5B,UAAU,EAAE,SAAS,EAAE,QAAQ,CAAC;CAChC,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC;CAC7B,cAAc,EAAE,SAAS,EAAE,UAAU,CAAC;CACtC,eAAe,EAAE,SAAS,EAAE,UAAU,CAAC;CACxC,CAAC;;;;ACTF,MAAa,qBAAqB,EAAE,OAClC,MAAM,QACN,EAAE,EACF;CACE,OAAO;CACP,aAAa;CACd,CACF;;;;ACPD,MAAa,oBAAoB,EAAE,OAAO;CACxC,QAAQ,EAAE,QAAQ;CAClB,WAAW,EAAE,QAAQ;CACrB,WAAW,EAAE,QAAQ;CACtB,CAAC;AAEF,MAAa,sBAAsB,EAAE,OAAO;CAC1C,UAAU,EAAE,QAAQ;CACpB,WAAW,EAAE,QAAQ;CACtB,CAAC;AAEF,MAAa,qBAAqB,EAAE,OAAO;CACzC,WAAW,EAAE,QAAQ;CACrB,YAAY,EAAE,QAAQ;CACtB,UAAU,EAAE,MAAM,kBAAkB;CACpC,YAAY,EAAE,MAAM,oBAAoB;CACzC,CAAC;;;;ACNF,MAAa,iBAAiB,QAAQ;CACpC,MAAM;CACN,UAAU,EAAE;CACb,CAAC"}
|
|
@@ -8,6 +8,7 @@ import { Ok } from "alepha/server";
|
|
|
8
8
|
import { DateTime, DateTimeProvider, DurationLike } from "alepha/datetime";
|
|
9
9
|
import * as alepha_logger0 from "alepha/logger";
|
|
10
10
|
import "alepha/server/security";
|
|
11
|
+
import * as alepha_scheduler0 from "alepha/scheduler";
|
|
11
12
|
import { UserAccountToken } from "alepha/security";
|
|
12
13
|
import { BuildExtraConfigColumns, SQL } from "drizzle-orm";
|
|
13
14
|
import { PgColumnBuilderBase, PgSequenceOptions, PgTableExtraConfigValue, UpdateDeleteAction } from "drizzle-orm/pg-core";
|
|
@@ -17,7 +18,7 @@ import "drizzle-orm/postgres-js";
|
|
|
17
18
|
import "postgres";
|
|
18
19
|
import "drizzle-orm/sqlite-core";
|
|
19
20
|
|
|
20
|
-
//#region ../../src/api
|
|
21
|
+
//#region ../../src/api/files/entities/files.d.ts
|
|
21
22
|
declare const files: alepha_orm64.EntityPrimitive<alepha160.TObject<{
|
|
22
23
|
id: alepha_orm64.PgAttr<alepha_orm64.PgAttr<alepha160.TString, typeof alepha_orm64.PG_PRIMARY_KEY>, typeof alepha_orm64.PG_DEFAULT>;
|
|
23
24
|
version: alepha_orm64.PgAttr<alepha_orm64.PgAttr<alepha160.TInteger, typeof alepha_orm64.PG_VERSION>, typeof alepha_orm64.PG_DEFAULT>;
|
|
@@ -37,7 +38,7 @@ declare const files: alepha_orm64.EntityPrimitive<alepha160.TObject<{
|
|
|
37
38
|
}>>;
|
|
38
39
|
type FileEntity = Static<typeof files.schema>;
|
|
39
40
|
//#endregion
|
|
40
|
-
//#region ../../src/api
|
|
41
|
+
//#region ../../src/api/files/schemas/fileQuerySchema.d.ts
|
|
41
42
|
declare const fileQuerySchema: alepha160.TObject<{
|
|
42
43
|
page: alepha160.TOptional<alepha160.TInteger>;
|
|
43
44
|
size: alepha160.TOptional<alepha160.TInteger>;
|
|
@@ -377,7 +378,7 @@ declare module "alepha" {
|
|
|
377
378
|
}
|
|
378
379
|
}
|
|
379
380
|
//#endregion
|
|
380
|
-
//#region ../../src/api
|
|
381
|
+
//#region ../../src/api/files/schemas/fileResourceSchema.d.ts
|
|
381
382
|
declare const fileResourceSchema: alepha160.TObject<{
|
|
382
383
|
id: PgAttr<PgAttr<alepha160.TString, typeof PG_PRIMARY_KEY>, typeof PG_DEFAULT>;
|
|
383
384
|
version: PgAttr<PgAttr<alepha160.TInteger, typeof PG_VERSION>, typeof PG_DEFAULT>;
|
|
@@ -397,7 +398,7 @@ declare const fileResourceSchema: alepha160.TObject<{
|
|
|
397
398
|
}>;
|
|
398
399
|
type FileResource = Static<typeof fileResourceSchema>;
|
|
399
400
|
//#endregion
|
|
400
|
-
//#region ../../src/api
|
|
401
|
+
//#region ../../src/api/files/schemas/storageStatsSchema.d.ts
|
|
401
402
|
declare const bucketStatsSchema: alepha160.TObject<{
|
|
402
403
|
bucket: alepha160.TString;
|
|
403
404
|
totalSize: alepha160.TNumber;
|
|
@@ -424,7 +425,7 @@ type BucketStats = Static<typeof bucketStatsSchema>;
|
|
|
424
425
|
type MimeTypeStats = Static<typeof mimeTypeStatsSchema>;
|
|
425
426
|
type StorageStats = Static<typeof storageStatsSchema>;
|
|
426
427
|
//#endregion
|
|
427
|
-
//#region ../../src/api
|
|
428
|
+
//#region ../../src/api/files/services/FileService.d.ts
|
|
428
429
|
declare class FileService {
|
|
429
430
|
protected readonly alepha: Alepha;
|
|
430
431
|
protected readonly log: alepha_logger0.Logger;
|
|
@@ -568,7 +569,7 @@ declare class FileService {
|
|
|
568
569
|
entityToResource(entity: FileEntity): FileResource;
|
|
569
570
|
}
|
|
570
571
|
//#endregion
|
|
571
|
-
//#region ../../src/api
|
|
572
|
+
//#region ../../src/api/files/controllers/FileController.d.ts
|
|
572
573
|
/**
|
|
573
574
|
* REST API controller for file management operations.
|
|
574
575
|
* Provides endpoints for uploading, downloading, listing, and deleting files.
|
|
@@ -701,7 +702,7 @@ declare class FileController {
|
|
|
701
702
|
}>;
|
|
702
703
|
}
|
|
703
704
|
//#endregion
|
|
704
|
-
//#region ../../src/api
|
|
705
|
+
//#region ../../src/api/files/controllers/StorageStatsController.d.ts
|
|
705
706
|
/**
|
|
706
707
|
* REST API controller for storage analytics and statistics.
|
|
707
708
|
* Provides endpoints for viewing storage usage metrics.
|
|
@@ -732,7 +733,13 @@ declare class StorageStatsController {
|
|
|
732
733
|
}>;
|
|
733
734
|
}
|
|
734
735
|
//#endregion
|
|
735
|
-
//#region ../../src/api
|
|
736
|
+
//#region ../../src/api/files/jobs/FileJobs.d.ts
|
|
737
|
+
declare class FileJobs {
|
|
738
|
+
protected readonly fileService: FileService;
|
|
739
|
+
readonly purgeFiles: alepha_scheduler0.SchedulerPrimitive;
|
|
740
|
+
}
|
|
741
|
+
//#endregion
|
|
742
|
+
//#region ../../src/api/files/index.d.ts
|
|
736
743
|
declare module "alepha/bucket" {
|
|
737
744
|
interface BucketFileOptions {
|
|
738
745
|
/**
|
|
@@ -765,5 +772,5 @@ declare module "alepha/bucket" {
|
|
|
765
772
|
*/
|
|
766
773
|
declare const AlephaApiFiles: alepha160.Service<alepha160.Module>;
|
|
767
774
|
//#endregion
|
|
768
|
-
export { AlephaApiFiles, BucketStats, FileController, FileEntity, FileService, MimeTypeStats, StorageStats, StorageStatsController, bucketStatsSchema, files, mimeTypeStatsSchema, storageStatsSchema };
|
|
775
|
+
export { AlephaApiFiles, BucketStats, FileController, FileEntity, FileJobs, FileService, MimeTypeStats, StorageStats, StorageStatsController, bucketStatsSchema, files, mimeTypeStatsSchema, storageStatsSchema };
|
|
769
776
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -10,7 +10,7 @@ import { $logger } from "alepha/logger";
|
|
|
10
10
|
import "alepha/server/security";
|
|
11
11
|
import { $scheduler } from "alepha/scheduler";
|
|
12
12
|
|
|
13
|
-
//#region ../../src/api
|
|
13
|
+
//#region ../../src/api/files/schemas/fileQuerySchema.ts
|
|
14
14
|
const fileQuerySchema = t.extend(pageQuerySchema, {
|
|
15
15
|
bucket: t.optional(t.string()),
|
|
16
16
|
tags: t.optional(t.array(t.string())),
|
|
@@ -22,7 +22,7 @@ const fileQuerySchema = t.extend(pageQuerySchema, {
|
|
|
22
22
|
});
|
|
23
23
|
|
|
24
24
|
//#endregion
|
|
25
|
-
//#region ../../src/api
|
|
25
|
+
//#region ../../src/api/files/entities/files.ts
|
|
26
26
|
const files = $entity({
|
|
27
27
|
name: "files",
|
|
28
28
|
schema: t.object({
|
|
@@ -53,14 +53,14 @@ const files = $entity({
|
|
|
53
53
|
});
|
|
54
54
|
|
|
55
55
|
//#endregion
|
|
56
|
-
//#region ../../src/api
|
|
56
|
+
//#region ../../src/api/files/schemas/fileResourceSchema.ts
|
|
57
57
|
const fileResourceSchema = t.extend(files.schema, {}, {
|
|
58
58
|
title: "FileResource",
|
|
59
59
|
description: "A file resource representing a file stored in the system."
|
|
60
60
|
});
|
|
61
61
|
|
|
62
62
|
//#endregion
|
|
63
|
-
//#region ../../src/api
|
|
63
|
+
//#region ../../src/api/files/services/FileService.ts
|
|
64
64
|
var FileService = class {
|
|
65
65
|
alepha = $inject(Alepha);
|
|
66
66
|
log = $logger();
|
|
@@ -322,7 +322,7 @@ var FileService = class {
|
|
|
322
322
|
};
|
|
323
323
|
|
|
324
324
|
//#endregion
|
|
325
|
-
//#region ../../src/api
|
|
325
|
+
//#region ../../src/api/files/controllers/FileController.ts
|
|
326
326
|
/**
|
|
327
327
|
* REST API controller for file management operations.
|
|
328
328
|
* Provides endpoints for uploading, downloading, listing, and deleting files.
|
|
@@ -430,7 +430,7 @@ var FileController = class {
|
|
|
430
430
|
};
|
|
431
431
|
|
|
432
432
|
//#endregion
|
|
433
|
-
//#region ../../src/api
|
|
433
|
+
//#region ../../src/api/files/schemas/storageStatsSchema.ts
|
|
434
434
|
const bucketStatsSchema = t.object({
|
|
435
435
|
bucket: t.string(),
|
|
436
436
|
totalSize: t.number(),
|
|
@@ -448,7 +448,7 @@ const storageStatsSchema = t.object({
|
|
|
448
448
|
});
|
|
449
449
|
|
|
450
450
|
//#endregion
|
|
451
|
-
//#region ../../src/api
|
|
451
|
+
//#region ../../src/api/files/controllers/StorageStatsController.ts
|
|
452
452
|
/**
|
|
453
453
|
* REST API controller for storage analytics and statistics.
|
|
454
454
|
* Provides endpoints for viewing storage usage metrics.
|
|
@@ -472,7 +472,7 @@ var StorageStatsController = class {
|
|
|
472
472
|
};
|
|
473
473
|
|
|
474
474
|
//#endregion
|
|
475
|
-
//#region ../../src/api
|
|
475
|
+
//#region ../../src/api/files/jobs/FileJobs.ts
|
|
476
476
|
var FileJobs = class {
|
|
477
477
|
fileService = $inject(FileService);
|
|
478
478
|
purgeFiles = $scheduler({
|
|
@@ -486,7 +486,7 @@ var FileJobs = class {
|
|
|
486
486
|
};
|
|
487
487
|
|
|
488
488
|
//#endregion
|
|
489
|
-
//#region ../../src/api
|
|
489
|
+
//#region ../../src/api/files/index.ts
|
|
490
490
|
/**
|
|
491
491
|
* Provides file management API endpoints for Alepha applications.
|
|
492
492
|
*
|
|
@@ -509,5 +509,5 @@ const AlephaApiFiles = $module({
|
|
|
509
509
|
});
|
|
510
510
|
|
|
511
511
|
//#endregion
|
|
512
|
-
export { AlephaApiFiles, FileController, FileService, StorageStatsController, bucketStatsSchema, files, mimeTypeStatsSchema, storageStatsSchema };
|
|
512
|
+
export { AlephaApiFiles, FileController, FileJobs, FileService, StorageStatsController, bucketStatsSchema, files, mimeTypeStatsSchema, storageStatsSchema };
|
|
513
513
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["expirationDate: string | undefined","updateData: Partial<FileEntity>","files"],"sources":["../../../src/api/files/schemas/fileQuerySchema.ts","../../../src/api/files/entities/files.ts","../../../src/api/files/schemas/fileResourceSchema.ts","../../../src/api/files/services/FileService.ts","../../../src/api/files/controllers/FileController.ts","../../../src/api/files/schemas/storageStatsSchema.ts","../../../src/api/files/controllers/StorageStatsController.ts","../../../src/api/files/jobs/FileJobs.ts","../../../src/api/files/index.ts"],"sourcesContent":["import type { Static } from \"alepha\";\nimport { t } from \"alepha\";\nimport { pageQuerySchema } from \"alepha/orm\";\n\nexport const fileQuerySchema = t.extend(pageQuerySchema, {\n bucket: t.optional(t.string()),\n tags: t.optional(t.array(t.string())),\n name: t.optional(t.string()),\n mimeType: t.optional(t.string()),\n creator: t.optional(t.uuid()),\n createdAfter: t.optional(t.datetime()),\n createdBefore: t.optional(t.datetime()),\n});\n\nexport type FileQuery = Static<typeof fileQuerySchema>;\n","import { type Static, t } from \"alepha\";\nimport { $entity, pg } from \"alepha/orm\";\n\nexport const files = $entity({\n name: \"files\",\n schema: t.object({\n id: pg.primaryKey(t.uuid()),\n version: pg.version(),\n createdAt: pg.createdAt(),\n updatedAt: pg.updatedAt(),\n blobId: t.text(),\n creator: t.optional(t.uuid()),\n creatorRealm: t.optional(t.string()),\n creatorName: t.optional(t.string()),\n bucket: t.text(),\n expirationDate: t.optional(t.datetime()),\n name: t.text(),\n size: t.number(),\n mimeType: t.string(),\n tags: t.optional(t.array(t.text())),\n checksum: t.optional(t.string()),\n }),\n indexes: [\n \"expirationDate\",\n \"bucket\",\n \"creator\",\n \"createdAt\",\n \"mimeType\",\n {\n columns: [\"bucket\", \"createdAt\"],\n },\n ],\n});\n\nexport type FileEntity = Static<typeof files.schema>;\n","import { type Static, t } from \"alepha\";\nimport { files } from \"../entities/files.ts\";\n\nexport const fileResourceSchema = t.extend(\n files.schema,\n {},\n {\n title: \"FileResource\",\n description: \"A file resource representing a file stored in the system.\",\n },\n);\n\nexport type FileResource = Static<typeof fileResourceSchema>;\n","import { createHash } from \"node:crypto\";\nimport { $hook, $inject, Alepha, type FileLike } from \"alepha\";\nimport {\n $bucket,\n type BucketPrimitive,\n FileNotFoundError,\n} from \"alepha/bucket\";\nimport {\n type DateTime,\n DateTimeProvider,\n type DurationLike,\n} from \"alepha/datetime\";\nimport { $logger } from \"alepha/logger\";\nimport { $repository, type Page } from \"alepha/orm\";\nimport type { UserAccountToken } from \"alepha/security\";\nimport type { Ok } from \"alepha/server\";\nimport { NotFoundError } from \"alepha/server\";\nimport { type FileEntity, files } from \"../entities/files.ts\";\nimport type { FileQuery } from \"../schemas/fileQuerySchema.ts\";\nimport type { FileResource } from \"../schemas/fileResourceSchema.ts\";\nimport type { StorageStats } from \"../schemas/storageStatsSchema.ts\";\n\nexport class FileService {\n protected readonly alepha = $inject(Alepha);\n protected readonly log = $logger();\n protected readonly fileRepository = $repository(files);\n protected readonly dateTimeProvider = $inject(DateTimeProvider);\n protected readonly defaultBucket = $bucket({ name: \"default\" });\n\n protected onUploadFile = $hook({\n on: \"bucket:file:uploaded\",\n handler: async ({ file, bucket, options, id }) => {\n if (options.persist === false) {\n return;\n }\n\n const checksum = await this.calculateChecksum(file);\n\n await this.fileRepository.create({\n blobId: id,\n mimeType: file.type,\n name: file.name,\n size: file.size,\n creator: options.user?.id,\n creatorRealm: options.user?.realm,\n expirationDate: this.getExpirationDate(options.ttl),\n bucket: bucket.name,\n checksum,\n });\n },\n });\n\n protected onDeleteBucketFile = $hook({\n on: \"bucket:file:deleted\",\n handler: async ({ bucket, id }) => {\n await this.fileRepository.deleteMany({\n blobId: { eq: id },\n bucket: { eq: bucket.name },\n });\n },\n });\n\n // -------------------------------------------------------------------------------------------------------------------\n\n /**\n * Calculates SHA-256 checksum of a file.\n *\n * @param file - The file to calculate checksum for\n * @returns Hexadecimal string representation of the SHA-256 hash\n * @protected\n */\n protected async calculateChecksum(file: FileLike): Promise<string> {\n const buffer = await file.arrayBuffer();\n const hash = createHash(\"sha256\");\n hash.update(Buffer.from(buffer));\n return hash.digest(\"hex\");\n }\n\n /**\n * Gets a bucket primitive by name.\n *\n * @param bucketName - The name of the bucket to retrieve (defaults to \"default\")\n * @returns The bucket primitive\n * @throws {NotFoundError} If the bucket is not found\n */\n public bucket(bucketName: string = this.defaultBucket.name): BucketPrimitive {\n const bucket = this.alepha\n .primitives($bucket)\n .find((it) => it.name === bucketName);\n\n if (!bucket) {\n throw new NotFoundError(`Bucket '${bucketName}' not found.`);\n }\n\n return bucket;\n }\n\n // -------------------------------------------------------------------------------------------------------------------\n\n /**\n * Finds files matching the given query criteria with pagination support.\n * Supports filtering by bucket, tags, name, mimeType, creator, and date range.\n *\n * @param q - Query parameters including bucket, tags, name, mimeType, creator, date range, pagination, and sorting\n * @returns Paginated list of file entities\n */\n public async findFiles(q: FileQuery = {}): Promise<Page<FileEntity>> {\n q.sort ??= \"-createdAt\";\n\n const where = this.fileRepository.createQueryWhere();\n\n if (q.bucket) {\n where.bucket = { eq: q.bucket };\n }\n\n if (q.tags) {\n where.tags = { arrayContains: q.tags };\n }\n\n if (q.name) {\n where.name = { ilike: `%${q.name}%` };\n }\n\n if (q.mimeType) {\n where.mimeType = { eq: q.mimeType };\n }\n\n if (q.creator) {\n where.creator = { eq: q.creator };\n }\n\n if (q.createdAfter && q.createdBefore) {\n where.createdAt = {\n gte: q.createdAfter,\n lte: q.createdBefore,\n };\n } else if (q.createdAfter) {\n where.createdAt = { gte: q.createdAfter };\n } else if (q.createdBefore) {\n where.createdAt = { lte: q.createdBefore };\n }\n\n return await this.fileRepository\n .paginate(q, { where }, { count: true })\n .then((page) => {\n return {\n ...page,\n content: page.content.map((it) => this.entityToResource(it)),\n };\n });\n }\n\n /**\n * Finds files that have expired based on their expiration date.\n * Limited to 1000 files per call to prevent memory issues.\n *\n * @returns Array of expired file entities\n */\n public async findExpiredFiles(): Promise<FileEntity[]> {\n return await this.fileRepository.findMany({\n limit: 1000,\n where: {\n expirationDate: { lte: this.dateTimeProvider.nowISOString() },\n },\n });\n }\n\n /**\n * Calculates an expiration date based on a TTL (time to live) duration.\n *\n * @param ttl - Duration like \"1 day\", \"2 hours\", etc.\n * @returns DateTime representation of the expiration date, or undefined if no TTL provided\n * @protected\n */\n protected getExpirationDate(ttl?: DurationLike): string | undefined {\n return ttl\n ? this.dateTimeProvider\n .now()\n .add(this.dateTimeProvider.duration(ttl))\n .toISOString()\n : undefined;\n }\n\n /**\n * Uploads a file to a bucket and creates a database record with metadata.\n * Automatically calculates and stores the file checksum (SHA-256).\n *\n * @param file - The file to upload\n * @param options - Upload options including bucket, expiration, user, and tags\n * @param options.bucket - Target bucket name (defaults to \"default\")\n * @param options.expirationDate - When the file should expire\n * @param options.user - User performing the upload (for audit trail)\n * @param options.tags - Tags to associate with the file\n * @returns The created file entity with all metadata\n * @throws {NotFoundError} If the specified bucket doesn't exist\n */\n public async uploadFile(\n file: FileLike,\n options: {\n expirationDate?: string | DateTime;\n bucket?: string;\n user?: UserAccountToken;\n tags?: string[];\n } = {},\n ): Promise<FileEntity> {\n const bucket = this.bucket(options.bucket);\n\n const checksum = await this.calculateChecksum(file);\n const blobId = await bucket.upload(file, { persist: false });\n\n let expirationDate: string | undefined;\n if (options.expirationDate) {\n expirationDate = this.dateTimeProvider\n .of(options.expirationDate)\n .toISOString();\n } else if (bucket.options.ttl) {\n expirationDate = this.getExpirationDate(bucket.options.ttl);\n }\n\n return await this.fileRepository.create({\n blobId: blobId,\n mimeType: file.type,\n name: file.name,\n size: file.size,\n creator: options.user?.id,\n creatorRealm: options.user?.realm,\n creatorName: options.user?.name,\n expirationDate,\n bucket: bucket.name,\n tags: options.tags,\n checksum,\n });\n }\n\n /**\n * Streams a file from storage by its database ID.\n *\n * @param id - The database ID (UUID) of the file to stream\n * @returns The file object ready for streaming/downloading\n * @throws {NotFoundError} If the file doesn't exist in the database\n * @throws {FileNotFoundError} If the file exists in database but not in storage\n */\n public async streamFile(id: string): Promise<FileLike> {\n const entity = await this.getFileById(id);\n const bucket = this.bucket(entity.bucket);\n\n return await bucket.download(entity.blobId);\n }\n\n /**\n * Updates file metadata (name, tags, expiration date).\n * Does not modify the actual file content in storage.\n *\n * @param id - The database ID (UUID) of the file to update\n * @param data - Partial file data to update\n * @param data.name - New file name\n * @param data.tags - New tags array\n * @param data.expirationDate - New expiration date\n * @returns The updated file entity\n * @throws {NotFoundError} If the file doesn't exist in the database\n */\n public async updateFile(\n id: string,\n data: {\n name?: string;\n tags?: string[];\n expirationDate?: DateTime | string;\n },\n ): Promise<FileEntity> {\n const file = await this.getFileById(id);\n\n const updateData: Partial<FileEntity> = {};\n\n if (data.name !== undefined) {\n updateData.name = data.name;\n }\n\n if (data.tags !== undefined) {\n updateData.tags = data.tags;\n }\n\n if (data.expirationDate !== undefined) {\n updateData.expirationDate = this.dateTimeProvider\n .of(data.expirationDate)\n .toISOString();\n }\n\n return await this.fileRepository.updateById(file.id, updateData);\n }\n\n /**\n * Deletes a file from both storage and database.\n * Handles cases where file is already deleted from storage gracefully.\n * Always ensures database record is removed even if storage deletion fails.\n *\n * @param id - The database ID (UUID) of the file to delete\n * @returns Success response with the deleted file ID\n * @throws {NotFoundError} If the file doesn't exist in the database\n */\n public async deleteFile(id: string): Promise<Ok> {\n const file = await this.getFileById(id);\n const bucket = this.bucket(file.bucket);\n\n // Always delete the database record\n await this.fileRepository.deleteById(file.id);\n\n try {\n await bucket.delete(file.blobId, true);\n } catch (e) {\n if (e instanceof FileNotFoundError) {\n // File is already deleted in the bucket, this is okay\n this.log.debug(\n `File ${file.blobId} not found in bucket ${bucket.name}, cleaning up database record`,\n );\n } else {\n // Other errors (permission, network, etc.) - log but continue to clean up database\n this.log.warn(\n `Failed to delete file ${file.blobId} from bucket ${bucket.name}`,\n e,\n );\n }\n }\n\n return { ok: true, id: String(file.id) };\n }\n\n /**\n * Retrieves a file entity by its ID.\n * If already an entity object, returns it as-is (convenience method).\n *\n * @param id - Either a UUID string or an existing FileEntity object\n * @returns The file entity\n * @throws {NotFoundError} If the file doesn't exist in the database\n */\n public async getFileById(id: string | FileEntity): Promise<FileEntity> {\n if (typeof id === \"object\") {\n return id;\n }\n\n return await this.fileRepository.findById(id);\n }\n\n /**\n * Gets storage statistics including total size, file count, and breakdowns by bucket and MIME type.\n *\n * @returns Storage statistics with aggregated data\n */\n public async getStorageStats(): Promise<StorageStats> {\n const allFiles = await this.fileRepository.findMany({});\n\n const totalSize = allFiles.reduce((sum, file) => sum + file.size, 0);\n const totalFiles = allFiles.length;\n\n // Group by bucket\n const bucketMap = new Map<\n string,\n { totalSize: number; fileCount: number }\n >();\n for (const file of allFiles) {\n const existing = bucketMap.get(file.bucket) || {\n totalSize: 0,\n fileCount: 0,\n };\n existing.totalSize += file.size;\n existing.fileCount += 1;\n bucketMap.set(file.bucket, existing);\n }\n\n // Group by MIME type\n const mimeTypeMap = new Map<string, number>();\n for (const file of allFiles) {\n const existing = mimeTypeMap.get(file.mimeType) || 0;\n mimeTypeMap.set(file.mimeType, existing + 1);\n }\n\n return {\n totalSize,\n totalFiles,\n byBucket: Array.from(bucketMap.entries()).map(([bucket, stats]) => ({\n bucket,\n totalSize: stats.totalSize,\n fileCount: stats.fileCount,\n })),\n byMimeType: Array.from(mimeTypeMap.entries()).map(\n ([mimeType, fileCount]) => ({\n mimeType,\n fileCount,\n }),\n ),\n };\n }\n\n /**\n * Converts a file entity to a file resource (API response format).\n * Currently a pass-through, but allows for future transformation logic.\n *\n * @param entity - The file entity to convert\n * @returns The file resource for API responses\n */\n public entityToResource(entity: FileEntity): FileResource {\n return entity;\n }\n}\n","import { $inject, t } from \"alepha\";\nimport { pg } from \"alepha/orm\";\nimport { $action, okSchema } from \"alepha/server\";\nimport { fileQuerySchema } from \"../schemas/fileQuerySchema.ts\";\nimport { fileResourceSchema } from \"../schemas/fileResourceSchema.ts\";\nimport { FileService } from \"../services/FileService.ts\";\n\n/**\n * REST API controller for file management operations.\n * Provides endpoints for uploading, downloading, listing, and deleting files.\n */\nexport class FileController {\n protected readonly url = \"/files\";\n protected readonly group = \"files\";\n protected readonly fileService = $inject(FileService);\n\n /**\n * GET /files - Lists files with optional filtering and pagination.\n * Supports filtering by bucket and tags.\n */\n public readonly findFiles = $action({\n path: this.url,\n group: this.group,\n description: \"List files with filtering and pagination\",\n schema: {\n query: fileQuerySchema,\n response: pg.page(fileResourceSchema),\n },\n handler: ({ query }) => this.fileService.findFiles(query),\n });\n\n /**\n * DELETE /files/:id - Deletes a file from both storage and database.\n * Removes the file from the bucket and cleans up the database record.\n */\n public readonly deleteFile = $action({\n method: \"DELETE\",\n path: `${this.url}/:id`,\n group: this.group,\n description: \"Delete a file\",\n schema: {\n params: t.object({\n id: t.uuid(),\n }),\n response: okSchema,\n },\n handler: ({ params }) => this.fileService.deleteFile(params.id),\n });\n\n /**\n * POST /files - Uploads a new file to storage.\n * Creates a database record with metadata and calculates checksum.\n * Optionally specify bucket and expiration date.\n */\n public readonly uploadFile = $action({\n path: this.url,\n group: this.group,\n description: \"Upload a new file\",\n schema: {\n body: t.object({\n file: t.file(),\n }),\n query: t.object({\n expirationDate: t.optional(t.datetime()),\n bucket: t.optional(t.string()),\n }),\n response: fileResourceSchema,\n },\n handler: async ({ body, user, query }) =>\n this.fileService.uploadFile(body.file, {\n user,\n ...query,\n }),\n });\n\n /**\n * PATCH /files/:id - Updates file metadata.\n * Allows updating name, tags, and expiration date without modifying file content.\n */\n public readonly updateFile = $action({\n method: \"PATCH\",\n path: `${this.url}/:id`,\n group: this.group,\n description: \"Update file metadata\",\n schema: {\n params: t.object({\n id: t.uuid(),\n }),\n body: t.object({\n name: t.optional(t.string()),\n tags: t.optional(t.array(t.string())),\n expirationDate: t.optional(t.datetime()),\n }),\n response: fileResourceSchema,\n },\n handler: ({ params, body }) => this.fileService.updateFile(params.id, body),\n });\n\n /**\n * GET /files/:id - Streams/downloads a file by its ID.\n * Returns the file content with appropriate Content-Type header.\n * Cached with ETag support for 1 year (immutable).\n */\n public readonly streamFile = $action({\n path: `${this.url}/:id`,\n group: this.group,\n description: \"Download a file\",\n cache: {\n etag: true,\n control: {\n public: true,\n maxAge: [1, \"year\"],\n immutable: true,\n },\n },\n schema: {\n params: t.object({\n id: t.uuid(),\n }),\n response: t.file(),\n },\n handler: async ({ params }) => {\n return await this.fileService.streamFile(params.id);\n },\n });\n}\n","import type { Static } from \"alepha\";\nimport { t } from \"alepha\";\n\nexport const bucketStatsSchema = t.object({\n bucket: t.string(),\n totalSize: t.number(),\n fileCount: t.number(),\n});\n\nexport const mimeTypeStatsSchema = t.object({\n mimeType: t.string(),\n fileCount: t.number(),\n});\n\nexport const storageStatsSchema = t.object({\n totalSize: t.number(),\n totalFiles: t.number(),\n byBucket: t.array(bucketStatsSchema),\n byMimeType: t.array(mimeTypeStatsSchema),\n});\n\nexport type BucketStats = Static<typeof bucketStatsSchema>;\nexport type MimeTypeStats = Static<typeof mimeTypeStatsSchema>;\nexport type StorageStats = Static<typeof storageStatsSchema>;\n","import \"alepha/server/security\";\nimport { $inject } from \"alepha\";\nimport { $action } from \"alepha/server\";\nimport { storageStatsSchema } from \"../schemas/storageStatsSchema.ts\";\nimport { FileService } from \"../services/FileService.ts\";\n\n/**\n * REST API controller for storage analytics and statistics.\n * Provides endpoints for viewing storage usage metrics.\n */\nexport class StorageStatsController {\n protected readonly url = \"/files/stats\";\n protected readonly group = \"files\";\n protected readonly fileService = $inject(FileService);\n\n /**\n * GET /files/stats - Gets storage statistics.\n * Returns aggregated data including total size, file count,\n * and breakdowns by bucket and MIME type.\n */\n public readonly getStats = $action({\n path: this.url,\n group: this.group,\n description: \"Get storage statistics\",\n schema: {\n response: storageStatsSchema,\n },\n handler: () => this.fileService.getStorageStats(),\n });\n}\n","import { $inject } from \"alepha\";\nimport { $scheduler } from \"alepha/scheduler\";\nimport { FileService } from \"../services/FileService.ts\";\n\nexport class FileJobs {\n protected readonly fileService = $inject(FileService);\n\n public readonly purgeFiles = $scheduler({\n description: \"Purge files that are marked for deletion\",\n cron: \"*/15 * * * *\", // Every 15 minutes\n handler: async () => {\n const files = await this.fileService.findExpiredFiles();\n\n await Promise.all(\n files.map((file) => this.fileService.deleteFile(file.id)),\n );\n },\n });\n}\n","import { $module } from \"alepha\";\nimport { AlephaBucket } from \"alepha/bucket\";\nimport type { DurationLike } from \"alepha/datetime\";\nimport type { UserAccountToken } from \"alepha/security\";\nimport { AlephaServerCache } from \"alepha/server/cache\";\nimport { AlephaServerMultipart } from \"alepha/server/multipart\";\nimport { FileController } from \"./controllers/FileController.ts\";\nimport { StorageStatsController } from \"./controllers/StorageStatsController.ts\";\nimport { FileJobs } from \"./jobs/FileJobs.ts\";\nimport { FileService } from \"./services/FileService.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./controllers/FileController.ts\";\nexport * from \"./controllers/StorageStatsController.ts\";\nexport * from \"./entities/files.ts\";\nexport * from \"./jobs/FileJobs.ts\";\nexport * from \"./schemas/storageStatsSchema.ts\";\nexport * from \"./services/FileService.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\ndeclare module \"alepha/bucket\" {\n interface BucketFileOptions {\n /**\n * Time to live for the files in the bucket.\n */\n ttl?: DurationLike;\n\n /**\n * Tags for the bucket.\n */\n tags?: string[];\n\n /**\n * User performing the operation.\n */\n user?: UserAccountToken;\n\n /**\n * Whether to persist the file metadata in the database.\n *\n * @default true\n */\n persist?: boolean;\n }\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Provides file management API endpoints for Alepha applications.\n *\n * This module includes file upload, download, storage management,\n * and file metadata operations.\n *\n * @module alepha.api.files\n */\nexport const AlephaApiFiles = $module({\n name: \"alepha.api.files\",\n services: [FileController, StorageStatsController, FileJobs, FileService],\n register: (alepha) => {\n alepha\n .with(AlephaBucket)\n .with(AlephaServerCache)\n .with(AlephaServerMultipart)\n .with(FileController)\n .with(StorageStatsController)\n .with(FileJobs);\n },\n});\n"],"mappings":";;;;;;;;;;;;;AAIA,MAAa,kBAAkB,EAAE,OAAO,iBAAiB;CACvD,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC;CAC9B,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;CACrC,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC;CAC5B,UAAU,EAAE,SAAS,EAAE,QAAQ,CAAC;CAChC,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC;CAC7B,cAAc,EAAE,SAAS,EAAE,UAAU,CAAC;CACtC,eAAe,EAAE,SAAS,EAAE,UAAU,CAAC;CACxC,CAAC;;;;ACTF,MAAa,QAAQ,QAAQ;CAC3B,MAAM;CACN,QAAQ,EAAE,OAAO;EACf,IAAI,GAAG,WAAW,EAAE,MAAM,CAAC;EAC3B,SAAS,GAAG,SAAS;EACrB,WAAW,GAAG,WAAW;EACzB,WAAW,GAAG,WAAW;EACzB,QAAQ,EAAE,MAAM;EAChB,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC;EAC7B,cAAc,EAAE,SAAS,EAAE,QAAQ,CAAC;EACpC,aAAa,EAAE,SAAS,EAAE,QAAQ,CAAC;EACnC,QAAQ,EAAE,MAAM;EAChB,gBAAgB,EAAE,SAAS,EAAE,UAAU,CAAC;EACxC,MAAM,EAAE,MAAM;EACd,MAAM,EAAE,QAAQ;EAChB,UAAU,EAAE,QAAQ;EACpB,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;EACnC,UAAU,EAAE,SAAS,EAAE,QAAQ,CAAC;EACjC,CAAC;CACF,SAAS;EACP;EACA;EACA;EACA;EACA;EACA,EACE,SAAS,CAAC,UAAU,YAAY,EACjC;EACF;CACF,CAAC;;;;AC7BF,MAAa,qBAAqB,EAAE,OAClC,MAAM,QACN,EAAE,EACF;CACE,OAAO;CACP,aAAa;CACd,CACF;;;;ACYD,IAAa,cAAb,MAAyB;CACvB,AAAmB,SAAS,QAAQ,OAAO;CAC3C,AAAmB,MAAM,SAAS;CAClC,AAAmB,iBAAiB,YAAY,MAAM;CACtD,AAAmB,mBAAmB,QAAQ,iBAAiB;CAC/D,AAAmB,gBAAgB,QAAQ,EAAE,MAAM,WAAW,CAAC;CAE/D,AAAU,eAAe,MAAM;EAC7B,IAAI;EACJ,SAAS,OAAO,EAAE,MAAM,QAAQ,SAAS,SAAS;AAChD,OAAI,QAAQ,YAAY,MACtB;GAGF,MAAM,WAAW,MAAM,KAAK,kBAAkB,KAAK;AAEnD,SAAM,KAAK,eAAe,OAAO;IAC/B,QAAQ;IACR,UAAU,KAAK;IACf,MAAM,KAAK;IACX,MAAM,KAAK;IACX,SAAS,QAAQ,MAAM;IACvB,cAAc,QAAQ,MAAM;IAC5B,gBAAgB,KAAK,kBAAkB,QAAQ,IAAI;IACnD,QAAQ,OAAO;IACf;IACD,CAAC;;EAEL,CAAC;CAEF,AAAU,qBAAqB,MAAM;EACnC,IAAI;EACJ,SAAS,OAAO,EAAE,QAAQ,SAAS;AACjC,SAAM,KAAK,eAAe,WAAW;IACnC,QAAQ,EAAE,IAAI,IAAI;IAClB,QAAQ,EAAE,IAAI,OAAO,MAAM;IAC5B,CAAC;;EAEL,CAAC;;;;;;;;CAWF,MAAgB,kBAAkB,MAAiC;EACjE,MAAM,SAAS,MAAM,KAAK,aAAa;EACvC,MAAM,OAAO,WAAW,SAAS;AACjC,OAAK,OAAO,OAAO,KAAK,OAAO,CAAC;AAChC,SAAO,KAAK,OAAO,MAAM;;;;;;;;;CAU3B,AAAO,OAAO,aAAqB,KAAK,cAAc,MAAuB;EAC3E,MAAM,SAAS,KAAK,OACjB,WAAW,QAAQ,CACnB,MAAM,OAAO,GAAG,SAAS,WAAW;AAEvC,MAAI,CAAC,OACH,OAAM,IAAI,cAAc,WAAW,WAAW,cAAc;AAG9D,SAAO;;;;;;;;;CAYT,MAAa,UAAU,IAAe,EAAE,EAA6B;AACnE,IAAE,SAAS;EAEX,MAAM,QAAQ,KAAK,eAAe,kBAAkB;AAEpD,MAAI,EAAE,OACJ,OAAM,SAAS,EAAE,IAAI,EAAE,QAAQ;AAGjC,MAAI,EAAE,KACJ,OAAM,OAAO,EAAE,eAAe,EAAE,MAAM;AAGxC,MAAI,EAAE,KACJ,OAAM,OAAO,EAAE,OAAO,IAAI,EAAE,KAAK,IAAI;AAGvC,MAAI,EAAE,SACJ,OAAM,WAAW,EAAE,IAAI,EAAE,UAAU;AAGrC,MAAI,EAAE,QACJ,OAAM,UAAU,EAAE,IAAI,EAAE,SAAS;AAGnC,MAAI,EAAE,gBAAgB,EAAE,cACtB,OAAM,YAAY;GAChB,KAAK,EAAE;GACP,KAAK,EAAE;GACR;WACQ,EAAE,aACX,OAAM,YAAY,EAAE,KAAK,EAAE,cAAc;WAChC,EAAE,cACX,OAAM,YAAY,EAAE,KAAK,EAAE,eAAe;AAG5C,SAAO,MAAM,KAAK,eACf,SAAS,GAAG,EAAE,OAAO,EAAE,EAAE,OAAO,MAAM,CAAC,CACvC,MAAM,SAAS;AACd,UAAO;IACL,GAAG;IACH,SAAS,KAAK,QAAQ,KAAK,OAAO,KAAK,iBAAiB,GAAG,CAAC;IAC7D;IACD;;;;;;;;CASN,MAAa,mBAA0C;AACrD,SAAO,MAAM,KAAK,eAAe,SAAS;GACxC,OAAO;GACP,OAAO,EACL,gBAAgB,EAAE,KAAK,KAAK,iBAAiB,cAAc,EAAE,EAC9D;GACF,CAAC;;;;;;;;;CAUJ,AAAU,kBAAkB,KAAwC;AAClE,SAAO,MACH,KAAK,iBACF,KAAK,CACL,IAAI,KAAK,iBAAiB,SAAS,IAAI,CAAC,CACxC,aAAa,GAChB;;;;;;;;;;;;;;;CAgBN,MAAa,WACX,MACA,UAKI,EAAE,EACe;EACrB,MAAM,SAAS,KAAK,OAAO,QAAQ,OAAO;EAE1C,MAAM,WAAW,MAAM,KAAK,kBAAkB,KAAK;EACnD,MAAM,SAAS,MAAM,OAAO,OAAO,MAAM,EAAE,SAAS,OAAO,CAAC;EAE5D,IAAIA;AACJ,MAAI,QAAQ,eACV,kBAAiB,KAAK,iBACnB,GAAG,QAAQ,eAAe,CAC1B,aAAa;WACP,OAAO,QAAQ,IACxB,kBAAiB,KAAK,kBAAkB,OAAO,QAAQ,IAAI;AAG7D,SAAO,MAAM,KAAK,eAAe,OAAO;GAC9B;GACR,UAAU,KAAK;GACf,MAAM,KAAK;GACX,MAAM,KAAK;GACX,SAAS,QAAQ,MAAM;GACvB,cAAc,QAAQ,MAAM;GAC5B,aAAa,QAAQ,MAAM;GAC3B;GACA,QAAQ,OAAO;GACf,MAAM,QAAQ;GACd;GACD,CAAC;;;;;;;;;;CAWJ,MAAa,WAAW,IAA+B;EACrD,MAAM,SAAS,MAAM,KAAK,YAAY,GAAG;AAGzC,SAAO,MAFQ,KAAK,OAAO,OAAO,OAAO,CAErB,SAAS,OAAO,OAAO;;;;;;;;;;;;;;CAe7C,MAAa,WACX,IACA,MAKqB;EACrB,MAAM,OAAO,MAAM,KAAK,YAAY,GAAG;EAEvC,MAAMC,aAAkC,EAAE;AAE1C,MAAI,KAAK,SAAS,OAChB,YAAW,OAAO,KAAK;AAGzB,MAAI,KAAK,SAAS,OAChB,YAAW,OAAO,KAAK;AAGzB,MAAI,KAAK,mBAAmB,OAC1B,YAAW,iBAAiB,KAAK,iBAC9B,GAAG,KAAK,eAAe,CACvB,aAAa;AAGlB,SAAO,MAAM,KAAK,eAAe,WAAW,KAAK,IAAI,WAAW;;;;;;;;;;;CAYlE,MAAa,WAAW,IAAyB;EAC/C,MAAM,OAAO,MAAM,KAAK,YAAY,GAAG;EACvC,MAAM,SAAS,KAAK,OAAO,KAAK,OAAO;AAGvC,QAAM,KAAK,eAAe,WAAW,KAAK,GAAG;AAE7C,MAAI;AACF,SAAM,OAAO,OAAO,KAAK,QAAQ,KAAK;WAC/B,GAAG;AACV,OAAI,aAAa,kBAEf,MAAK,IAAI,MACP,QAAQ,KAAK,OAAO,uBAAuB,OAAO,KAAK,+BACxD;OAGD,MAAK,IAAI,KACP,yBAAyB,KAAK,OAAO,eAAe,OAAO,QAC3D,EACD;;AAIL,SAAO;GAAE,IAAI;GAAM,IAAI,OAAO,KAAK,GAAG;GAAE;;;;;;;;;;CAW1C,MAAa,YAAY,IAA8C;AACrE,MAAI,OAAO,OAAO,SAChB,QAAO;AAGT,SAAO,MAAM,KAAK,eAAe,SAAS,GAAG;;;;;;;CAQ/C,MAAa,kBAAyC;EACpD,MAAM,WAAW,MAAM,KAAK,eAAe,SAAS,EAAE,CAAC;EAEvD,MAAM,YAAY,SAAS,QAAQ,KAAK,SAAS,MAAM,KAAK,MAAM,EAAE;EACpE,MAAM,aAAa,SAAS;EAG5B,MAAM,4BAAY,IAAI,KAGnB;AACH,OAAK,MAAM,QAAQ,UAAU;GAC3B,MAAM,WAAW,UAAU,IAAI,KAAK,OAAO,IAAI;IAC7C,WAAW;IACX,WAAW;IACZ;AACD,YAAS,aAAa,KAAK;AAC3B,YAAS,aAAa;AACtB,aAAU,IAAI,KAAK,QAAQ,SAAS;;EAItC,MAAM,8BAAc,IAAI,KAAqB;AAC7C,OAAK,MAAM,QAAQ,UAAU;GAC3B,MAAM,WAAW,YAAY,IAAI,KAAK,SAAS,IAAI;AACnD,eAAY,IAAI,KAAK,UAAU,WAAW,EAAE;;AAG9C,SAAO;GACL;GACA;GACA,UAAU,MAAM,KAAK,UAAU,SAAS,CAAC,CAAC,KAAK,CAAC,QAAQ,YAAY;IAClE;IACA,WAAW,MAAM;IACjB,WAAW,MAAM;IAClB,EAAE;GACH,YAAY,MAAM,KAAK,YAAY,SAAS,CAAC,CAAC,KAC3C,CAAC,UAAU,gBAAgB;IAC1B;IACA;IACD,EACF;GACF;;;;;;;;;CAUH,AAAO,iBAAiB,QAAkC;AACxD,SAAO;;;;;;;;;;ACrYX,IAAa,iBAAb,MAA4B;CAC1B,AAAmB,MAAM;CACzB,AAAmB,QAAQ;CAC3B,AAAmB,cAAc,QAAQ,YAAY;;;;;CAMrD,AAAgB,YAAY,QAAQ;EAClC,MAAM,KAAK;EACX,OAAO,KAAK;EACZ,aAAa;EACb,QAAQ;GACN,OAAO;GACP,UAAU,GAAG,KAAK,mBAAmB;GACtC;EACD,UAAU,EAAE,YAAY,KAAK,YAAY,UAAU,MAAM;EAC1D,CAAC;;;;;CAMF,AAAgB,aAAa,QAAQ;EACnC,QAAQ;EACR,MAAM,GAAG,KAAK,IAAI;EAClB,OAAO,KAAK;EACZ,aAAa;EACb,QAAQ;GACN,QAAQ,EAAE,OAAO,EACf,IAAI,EAAE,MAAM,EACb,CAAC;GACF,UAAU;GACX;EACD,UAAU,EAAE,aAAa,KAAK,YAAY,WAAW,OAAO,GAAG;EAChE,CAAC;;;;;;CAOF,AAAgB,aAAa,QAAQ;EACnC,MAAM,KAAK;EACX,OAAO,KAAK;EACZ,aAAa;EACb,QAAQ;GACN,MAAM,EAAE,OAAO,EACb,MAAM,EAAE,MAAM,EACf,CAAC;GACF,OAAO,EAAE,OAAO;IACd,gBAAgB,EAAE,SAAS,EAAE,UAAU,CAAC;IACxC,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC;IAC/B,CAAC;GACF,UAAU;GACX;EACD,SAAS,OAAO,EAAE,MAAM,MAAM,YAC5B,KAAK,YAAY,WAAW,KAAK,MAAM;GACrC;GACA,GAAG;GACJ,CAAC;EACL,CAAC;;;;;CAMF,AAAgB,aAAa,QAAQ;EACnC,QAAQ;EACR,MAAM,GAAG,KAAK,IAAI;EAClB,OAAO,KAAK;EACZ,aAAa;EACb,QAAQ;GACN,QAAQ,EAAE,OAAO,EACf,IAAI,EAAE,MAAM,EACb,CAAC;GACF,MAAM,EAAE,OAAO;IACb,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC;IAC5B,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IACrC,gBAAgB,EAAE,SAAS,EAAE,UAAU,CAAC;IACzC,CAAC;GACF,UAAU;GACX;EACD,UAAU,EAAE,QAAQ,WAAW,KAAK,YAAY,WAAW,OAAO,IAAI,KAAK;EAC5E,CAAC;;;;;;CAOF,AAAgB,aAAa,QAAQ;EACnC,MAAM,GAAG,KAAK,IAAI;EAClB,OAAO,KAAK;EACZ,aAAa;EACb,OAAO;GACL,MAAM;GACN,SAAS;IACP,QAAQ;IACR,QAAQ,CAAC,GAAG,OAAO;IACnB,WAAW;IACZ;GACF;EACD,QAAQ;GACN,QAAQ,EAAE,OAAO,EACf,IAAI,EAAE,MAAM,EACb,CAAC;GACF,UAAU,EAAE,MAAM;GACnB;EACD,SAAS,OAAO,EAAE,aAAa;AAC7B,UAAO,MAAM,KAAK,YAAY,WAAW,OAAO,GAAG;;EAEtD,CAAC;;;;;ACzHJ,MAAa,oBAAoB,EAAE,OAAO;CACxC,QAAQ,EAAE,QAAQ;CAClB,WAAW,EAAE,QAAQ;CACrB,WAAW,EAAE,QAAQ;CACtB,CAAC;AAEF,MAAa,sBAAsB,EAAE,OAAO;CAC1C,UAAU,EAAE,QAAQ;CACpB,WAAW,EAAE,QAAQ;CACtB,CAAC;AAEF,MAAa,qBAAqB,EAAE,OAAO;CACzC,WAAW,EAAE,QAAQ;CACrB,YAAY,EAAE,QAAQ;CACtB,UAAU,EAAE,MAAM,kBAAkB;CACpC,YAAY,EAAE,MAAM,oBAAoB;CACzC,CAAC;;;;;;;;ACTF,IAAa,yBAAb,MAAoC;CAClC,AAAmB,MAAM;CACzB,AAAmB,QAAQ;CAC3B,AAAmB,cAAc,QAAQ,YAAY;;;;;;CAOrD,AAAgB,WAAW,QAAQ;EACjC,MAAM,KAAK;EACX,OAAO,KAAK;EACZ,aAAa;EACb,QAAQ,EACN,UAAU,oBACX;EACD,eAAe,KAAK,YAAY,iBAAiB;EAClD,CAAC;;;;;ACxBJ,IAAa,WAAb,MAAsB;CACpB,AAAmB,cAAc,QAAQ,YAAY;CAErD,AAAgB,aAAa,WAAW;EACtC,aAAa;EACb,MAAM;EACN,SAAS,YAAY;GACnB,MAAMC,UAAQ,MAAM,KAAK,YAAY,kBAAkB;AAEvD,SAAM,QAAQ,IACZA,QAAM,KAAK,SAAS,KAAK,YAAY,WAAW,KAAK,GAAG,CAAC,CAC1D;;EAEJ,CAAC;;;;;;;;;;;;;ACyCJ,MAAa,iBAAiB,QAAQ;CACpC,MAAM;CACN,UAAU;EAAC;EAAgB;EAAwB;EAAU;EAAY;CACzE,WAAW,WAAW;AACpB,SACG,KAAK,aAAa,CAClB,KAAK,kBAAkB,CACvB,KAAK,sBAAsB,CAC3B,KAAK,eAAe,CACpB,KAAK,uBAAuB,CAC5B,KAAK,SAAS;;CAEpB,CAAC"}
|
|
@@ -2,7 +2,7 @@ import { $module, t } from "alepha";
|
|
|
2
2
|
import { logEntrySchema } from "alepha/logger";
|
|
3
3
|
import { $entity, pageQuerySchema, pg } from "alepha/orm";
|
|
4
4
|
|
|
5
|
-
//#region ../../src/api
|
|
5
|
+
//#region ../../src/api/jobs/entities/jobExecutions.ts
|
|
6
6
|
const jobExecutions = $entity({
|
|
7
7
|
name: "job_executions",
|
|
8
8
|
schema: t.object({
|
|
@@ -23,7 +23,7 @@ const jobExecutions = $entity({
|
|
|
23
23
|
});
|
|
24
24
|
|
|
25
25
|
//#endregion
|
|
26
|
-
//#region ../../src/api
|
|
26
|
+
//#region ../../src/api/jobs/schemas/jobExecutionQuerySchema.ts
|
|
27
27
|
const jobExecutionQuerySchema = t.extend(pageQuerySchema, {
|
|
28
28
|
status: t.optional(t.enum([
|
|
29
29
|
"STARTED",
|
|
@@ -34,18 +34,18 @@ const jobExecutionQuerySchema = t.extend(pageQuerySchema, {
|
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
//#endregion
|
|
37
|
-
//#region ../../src/api
|
|
37
|
+
//#region ../../src/api/jobs/schemas/jobExecutionResourceSchema.ts
|
|
38
38
|
const jobExecutionResourceSchema = t.extend(jobExecutions.schema, {}, {
|
|
39
39
|
title: "JobExecutionResource",
|
|
40
40
|
description: "A job execution resource representing the execution details of a job."
|
|
41
41
|
});
|
|
42
42
|
|
|
43
43
|
//#endregion
|
|
44
|
-
//#region ../../src/api
|
|
44
|
+
//#region ../../src/api/jobs/schemas/triggerJobSchema.ts
|
|
45
45
|
const triggerJobSchema = t.object({ name: t.string() });
|
|
46
46
|
|
|
47
47
|
//#endregion
|
|
48
|
-
//#region ../../src/api
|
|
48
|
+
//#region ../../src/api/jobs/index.browser.ts
|
|
49
49
|
const AlephaApiJobs = $module({
|
|
50
50
|
name: "alepha.api.jobs",
|
|
51
51
|
services: []
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.browser.js","names":[],"sources":["../../../src/api/jobs/entities/jobExecutions.ts","../../../src/api/jobs/schemas/jobExecutionQuerySchema.ts","../../../src/api/jobs/schemas/jobExecutionResourceSchema.ts","../../../src/api/jobs/schemas/triggerJobSchema.ts","../../../src/api/jobs/index.browser.ts"],"sourcesContent":["import { type Static, t } from \"alepha\";\nimport { logEntrySchema } from \"alepha/logger\";\nimport { $entity, pg } from \"alepha/orm\";\n\nexport const jobExecutions = $entity({\n name: \"job_executions\",\n schema: t.object({\n id: pg.primaryKey(t.uuid()),\n version: pg.version(),\n createdAt: pg.createdAt(),\n updatedAt: pg.updatedAt(),\n finishedAt: t.optional(t.datetime()),\n job: t.string(),\n status: t.enum([\"STARTED\", \"FAILED\", \"COMPLETED\"]),\n error: t.optional(t.string()),\n logs: t.optional(t.array(logEntrySchema)),\n }),\n});\n\nexport type JobExecutionEntity = Static<typeof jobExecutions.schema>;\n","import type { Static } from \"alepha\";\nimport { t } from \"alepha\";\nimport { pageQuerySchema } from \"alepha/orm\";\n\nexport const jobExecutionQuerySchema = t.extend(pageQuerySchema, {\n status: t.optional(t.enum([\"STARTED\", \"FAILED\", \"COMPLETED\"])),\n job: t.optional(\n t.text({\n description: \"Filter by job name\",\n }),\n ),\n});\n\nexport type JobExecutionQuery = Static<typeof jobExecutionQuerySchema>;\n","import { type Static, t } from \"alepha\";\nimport { jobExecutions } from \"../entities/jobExecutions.ts\";\n\nexport const jobExecutionResourceSchema = t.extend(\n jobExecutions.schema,\n {},\n {\n title: \"JobExecutionResource\",\n description:\n \"A job execution resource representing the execution details of a job.\",\n },\n);\n\nexport type JobExecutionResource = Static<typeof jobExecutionResourceSchema>;\n","import type { Static } from \"alepha\";\nimport { t } from \"alepha\";\n\nexport const triggerJobSchema = t.object({\n name: t.string(),\n});\n\nexport type TriggerJob = Static<typeof triggerJobSchema>;\n","import { $module } from \"alepha\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./entities/jobExecutions.ts\";\nexport * from \"./schemas/jobExecutionQuerySchema.ts\";\nexport * from \"./schemas/jobExecutionResourceSchema.ts\";\nexport * from \"./schemas/triggerJobSchema.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport const AlephaApiJobs = $module({\n name: \"alepha.api.jobs\",\n services: [],\n});\n"],"mappings":";;;;;AAIA,MAAa,gBAAgB,QAAQ;CACnC,MAAM;CACN,QAAQ,EAAE,OAAO;EACf,IAAI,GAAG,WAAW,EAAE,MAAM,CAAC;EAC3B,SAAS,GAAG,SAAS;EACrB,WAAW,GAAG,WAAW;EACzB,WAAW,GAAG,WAAW;EACzB,YAAY,EAAE,SAAS,EAAE,UAAU,CAAC;EACpC,KAAK,EAAE,QAAQ;EACf,QAAQ,EAAE,KAAK;GAAC;GAAW;GAAU;GAAY,CAAC;EAClD,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC;EAC7B,MAAM,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;EAC1C,CAAC;CACH,CAAC;;;;ACbF,MAAa,0BAA0B,EAAE,OAAO,iBAAiB;CAC/D,QAAQ,EAAE,SAAS,EAAE,KAAK;EAAC;EAAW;EAAU;EAAY,CAAC,CAAC;CAC9D,KAAK,EAAE,SACL,EAAE,KAAK,EACL,aAAa,sBACd,CAAC,CACH;CACF,CAAC;;;;ACRF,MAAa,6BAA6B,EAAE,OAC1C,cAAc,QACd,EAAE,EACF;CACE,OAAO;CACP,aACE;CACH,CACF;;;;ACRD,MAAa,mBAAmB,EAAE,OAAO,EACvC,MAAM,EAAE,QAAQ,EACjB,CAAC;;;;ACMF,MAAa,gBAAgB,QAAQ;CACnC,MAAM;CACN,UAAU,EAAE;CACb,CAAC"}
|