alepha 0.22.0 → 0.24.0
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/assets/swagger-ui/swagger-ui-bundle.js +1 -1
- package/assets/swagger-ui/swagger-ui-standalone-preset.js +1 -1
- package/dist/api/audits/index.browser.js +49 -52
- package/dist/api/audits/index.browser.js.map +1 -1
- package/dist/api/audits/index.d.ts +629 -565
- package/dist/api/audits/index.d.ts.map +1 -1
- package/dist/api/audits/index.js +206 -98
- package/dist/api/audits/index.js.map +1 -1
- package/dist/api/files/index.browser.js +44 -44
- package/dist/api/files/index.browser.js.map +1 -1
- package/dist/api/files/index.d.ts +292 -293
- package/dist/api/files/index.d.ts.map +1 -1
- package/dist/api/files/index.js +61 -64
- package/dist/api/files/index.js.map +1 -1
- package/dist/api/jobs/index.browser.js +61 -59
- package/dist/api/jobs/index.browser.js.map +1 -1
- package/dist/api/jobs/index.d.ts +546 -347
- package/dist/api/jobs/index.d.ts.map +1 -1
- package/dist/api/jobs/index.js +165 -86
- package/dist/api/jobs/index.js.map +1 -1
- package/dist/api/keys/index.d.ts +242 -230
- package/dist/api/keys/index.d.ts.map +1 -1
- package/dist/api/keys/index.js +63 -66
- package/dist/api/keys/index.js.map +1 -1
- package/dist/api/notifications/index.browser.js +40 -38
- package/dist/api/notifications/index.browser.js.map +1 -1
- package/dist/api/notifications/index.d.ts +339 -209
- package/dist/api/notifications/index.d.ts.map +1 -1
- package/dist/api/notifications/index.js +108 -60
- package/dist/api/notifications/index.js.map +1 -1
- package/dist/api/oauth/index.d.ts +190 -78
- package/dist/api/oauth/index.d.ts.map +1 -1
- package/dist/api/oauth/index.js +290 -68
- package/dist/api/oauth/index.js.map +1 -1
- package/dist/api/organizations/index.browser.js +14 -14
- package/dist/api/organizations/index.browser.js.map +1 -1
- package/dist/api/organizations/index.d.ts +158 -134
- package/dist/api/organizations/index.d.ts.map +1 -1
- package/dist/api/organizations/index.js +18 -18
- package/dist/api/organizations/index.js.map +1 -1
- package/dist/api/parameters/index.browser.js +74 -53
- package/dist/api/parameters/index.browser.js.map +1 -1
- package/dist/api/parameters/index.d.ts +607 -513
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/parameters/index.js +205 -127
- package/dist/api/parameters/index.js.map +1 -1
- package/dist/api/payments/index.d.ts +652 -449
- package/dist/api/payments/index.d.ts.map +1 -1
- package/dist/api/payments/index.js +159 -93
- package/dist/api/payments/index.js.map +1 -1
- package/dist/api/subscriptions/index.d.ts +1032 -762
- package/dist/api/subscriptions/index.d.ts.map +1 -1
- package/dist/api/subscriptions/index.js +166 -185
- package/dist/api/subscriptions/index.js.map +1 -1
- package/dist/api/users/index.browser.js +48 -71
- package/dist/api/users/index.browser.js.map +1 -1
- package/dist/api/users/index.d.ts +1297 -1109
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +454 -369
- package/dist/api/users/index.js.map +1 -1
- package/dist/api/verifications/index.browser.js +17 -17
- package/dist/api/verifications/index.browser.js.map +1 -1
- package/dist/api/verifications/index.d.ts +169 -157
- package/dist/api/verifications/index.d.ts.map +1 -1
- package/dist/api/verifications/index.js +47 -95
- package/dist/api/verifications/index.js.map +1 -1
- package/dist/background/index.d.ts +0 -1
- package/dist/background/index.d.ts.map +1 -1
- package/dist/background/index.js.map +1 -1
- package/dist/background/index.workerd.js.map +1 -1
- package/dist/batch/index.d.ts +0 -1
- package/dist/batch/index.d.ts.map +1 -1
- package/dist/batch/index.js.map +1 -1
- package/dist/bin/index.js +1 -1
- package/dist/bin/index.js.map +1 -1
- package/dist/bucket/index.d.ts +27 -32
- package/dist/bucket/index.d.ts.map +1 -1
- package/dist/bucket/index.js +56 -26
- package/dist/bucket/index.js.map +1 -1
- package/dist/bucket/index.workerd.js +52 -24
- package/dist/bucket/index.workerd.js.map +1 -1
- package/dist/cache/core/index.d.ts +4 -6
- package/dist/cache/core/index.d.ts.map +1 -1
- package/dist/cache/core/index.js +4 -10
- package/dist/cache/core/index.js.map +1 -1
- package/dist/cache/core/index.workerd.js +4 -10
- package/dist/cache/core/index.workerd.js.map +1 -1
- package/dist/cache/database/index.d.ts +22 -23
- package/dist/cache/database/index.d.ts.map +1 -1
- package/dist/cache/database/index.js +11 -20
- package/dist/cache/database/index.js.map +1 -1
- package/dist/cache/redis/index.d.ts +3 -4
- package/dist/cache/redis/index.d.ts.map +1 -1
- package/dist/cache/redis/index.js +2 -2
- package/dist/cache/redis/index.js.map +1 -1
- package/dist/captcha/index.d.ts.map +1 -1
- package/dist/captcha/index.js +4 -4
- package/dist/captcha/index.js.map +1 -1
- package/dist/cli/config/index.d.ts +0 -1
- package/dist/cli/config/index.d.ts.map +1 -1
- package/dist/cli/core/index.d.ts +244 -475
- package/dist/cli/core/index.d.ts.map +1 -1
- package/dist/cli/core/index.js +308 -383
- package/dist/cli/core/index.js.map +1 -1
- package/dist/cli/devtools/index.d.ts +3 -9
- package/dist/cli/devtools/index.d.ts.map +1 -1
- package/dist/cli/devtools/index.js +3 -3
- package/dist/cli/devtools/index.js.map +1 -1
- package/dist/cli/i18n/index.d.ts +20 -39
- package/dist/cli/i18n/index.d.ts.map +1 -1
- package/dist/cli/i18n/index.js +51 -17
- package/dist/cli/i18n/index.js.map +1 -1
- package/dist/cli/platform/index.d.ts +89 -82
- package/dist/cli/platform/index.d.ts.map +1 -1
- package/dist/cli/platform/index.js +27 -33
- package/dist/cli/platform/index.js.map +1 -1
- package/dist/cli/platform-lib/index.d.ts +383 -410
- package/dist/cli/platform-lib/index.d.ts.map +1 -1
- package/dist/cli/platform-lib/index.js +300 -258
- package/dist/cli/platform-lib/index.js.map +1 -1
- package/dist/cli/vendor/index.d.ts +17 -41
- package/dist/cli/vendor/index.d.ts.map +1 -1
- package/dist/cli/vendor/index.js +10 -13
- package/dist/cli/vendor/index.js.map +1 -1
- package/dist/command/index.d.ts +82 -194
- package/dist/command/index.d.ts.map +1 -1
- package/dist/command/index.js +160 -563
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js +845 -859
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +787 -527
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +845 -859
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +845 -859
- package/dist/core/index.native.js.map +1 -1
- package/dist/core/index.workerd.js +845 -859
- package/dist/core/index.workerd.js.map +1 -1
- package/dist/crypto/index.browser.js +1 -1
- package/dist/crypto/index.browser.js.map +1 -1
- package/dist/crypto/index.d.ts +3 -4
- package/dist/crypto/index.d.ts.map +1 -1
- package/dist/crypto/index.js +6 -3
- package/dist/crypto/index.js.map +1 -1
- package/dist/datetime/index.d.ts +12 -2
- package/dist/datetime/index.d.ts.map +1 -1
- package/dist/datetime/index.js +6 -1
- package/dist/datetime/index.js.map +1 -1
- package/dist/email/brevo/index.d.ts +0 -1
- package/dist/email/brevo/index.d.ts.map +1 -1
- package/dist/email/brevo/index.js +4 -4
- package/dist/email/brevo/index.js.map +1 -1
- package/dist/email/cloudflare/index.d.ts +0 -1
- package/dist/email/cloudflare/index.d.ts.map +1 -1
- package/dist/email/cloudflare/index.js +2 -2
- package/dist/email/cloudflare/index.js.map +1 -1
- package/dist/email/core/index.d.ts +15 -7
- package/dist/email/core/index.d.ts.map +1 -1
- package/dist/email/core/index.js +14 -5
- package/dist/email/core/index.js.map +1 -1
- package/dist/email/core/index.workerd.js +5 -1
- package/dist/email/core/index.workerd.js.map +1 -1
- package/dist/email/smtp/index.d.ts +8 -9
- package/dist/email/smtp/index.d.ts.map +1 -1
- package/dist/email/smtp/index.js +702 -479
- package/dist/email/smtp/index.js.map +1 -1
- package/dist/fake/index.d.ts +1580 -1238
- package/dist/fake/index.d.ts.map +1 -1
- package/dist/fake/index.js +11728 -32131
- package/dist/fake/index.js.map +1 -1
- package/dist/lock/core/index.d.ts +13 -9
- package/dist/lock/core/index.d.ts.map +1 -1
- package/dist/lock/core/index.js +5 -5
- package/dist/lock/core/index.js.map +1 -1
- package/dist/lock/redis/index.d.ts +0 -1
- package/dist/lock/redis/index.d.ts.map +1 -1
- package/dist/lock/redis/index.js.map +1 -1
- package/dist/logger/index.d.ts +81 -69
- package/dist/logger/index.d.ts.map +1 -1
- package/dist/logger/index.js +123 -56
- package/dist/logger/index.js.map +1 -1
- package/dist/mcp/index.d.ts +36 -90
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +65 -70
- package/dist/mcp/index.js.map +1 -1
- package/dist/orm/core/index.browser.js +54 -40
- package/dist/orm/core/index.browser.js.map +1 -1
- package/dist/orm/core/index.bun.js +140 -106
- package/dist/orm/core/index.bun.js.map +1 -1
- package/dist/orm/core/index.d.ts +145 -150
- package/dist/orm/core/index.d.ts.map +1 -1
- package/dist/orm/core/index.js +144 -109
- package/dist/orm/core/index.js.map +1 -1
- package/dist/orm/postgres/index.bun.js +64 -54
- package/dist/orm/postgres/index.bun.js.map +1 -1
- package/dist/orm/postgres/index.d.ts +36 -76
- package/dist/orm/postgres/index.d.ts.map +1 -1
- package/dist/orm/postgres/index.js +67 -57
- package/dist/orm/postgres/index.js.map +1 -1
- package/dist/queue/core/index.d.ts +62 -75
- package/dist/queue/core/index.d.ts.map +1 -1
- package/dist/queue/core/index.js +48 -71
- package/dist/queue/core/index.js.map +1 -1
- package/dist/queue/core/index.workerd.js +48 -71
- package/dist/queue/core/index.workerd.js.map +1 -1
- package/dist/queue/redis/index.d.ts +3 -4
- package/dist/queue/redis/index.d.ts.map +1 -1
- package/dist/queue/redis/index.js +2 -2
- package/dist/queue/redis/index.js.map +1 -1
- package/dist/react/auth/index.browser.js.map +1 -1
- package/dist/react/auth/index.d.ts +7 -4
- package/dist/react/auth/index.d.ts.map +1 -1
- package/dist/react/auth/index.js.map +1 -1
- package/dist/react/core/index.d.ts +87 -5
- package/dist/react/core/index.d.ts.map +1 -1
- package/dist/react/core/index.js +170 -23
- package/dist/react/core/index.js.map +1 -1
- package/dist/react/form/index.d.ts +4 -6
- package/dist/react/form/index.d.ts.map +1 -1
- package/dist/react/form/index.js +107 -71
- package/dist/react/form/index.js.map +1 -1
- package/dist/react/head/index.browser.js.map +1 -1
- package/dist/react/head/index.d.ts +0 -1
- package/dist/react/head/index.d.ts.map +1 -1
- package/dist/react/head/index.js.map +1 -1
- package/dist/react/i18n/index.d.ts +47 -5
- package/dist/react/i18n/index.d.ts.map +1 -1
- package/dist/react/i18n/index.js +116 -12
- package/dist/react/i18n/index.js.map +1 -1
- package/dist/react/intro/index.d.ts +1 -4
- package/dist/react/intro/index.d.ts.map +1 -1
- package/dist/react/intro/index.js.map +1 -1
- package/dist/react/router/index.browser.js +188 -29
- package/dist/react/router/index.browser.js.map +1 -1
- package/dist/react/router/index.d.ts +480 -372
- package/dist/react/router/index.d.ts.map +1 -1
- package/dist/react/router/index.js +261 -47
- package/dist/react/router/index.js.map +1 -1
- package/dist/react/sitemap/index.browser.js +35 -0
- package/dist/react/sitemap/index.browser.js.map +1 -0
- package/dist/react/sitemap/index.d.ts +91 -0
- package/dist/react/sitemap/index.d.ts.map +1 -0
- package/dist/react/sitemap/index.js +131 -0
- package/dist/react/sitemap/index.js.map +1 -0
- package/dist/react/testing/index.d.ts +4 -5
- package/dist/react/testing/index.d.ts.map +1 -1
- package/dist/react/testing/index.js +41 -15
- package/dist/react/testing/index.js.map +1 -1
- package/dist/react/testing/{chunk-BpyX8vjI.js → rolldown-runtime-Bl3dcgcQ.js} +1 -1
- package/dist/react/ui/index.d.ts +35 -34
- package/dist/react/ui/index.d.ts.map +1 -1
- package/dist/react/ui/index.js +12 -17
- package/dist/react/ui/index.js.map +1 -1
- package/dist/redis/index.bun.js +5 -5
- package/dist/redis/index.bun.js.map +1 -1
- package/dist/redis/index.d.ts +6 -7
- package/dist/redis/index.d.ts.map +1 -1
- package/dist/redis/index.js +6 -6
- package/dist/redis/index.js.map +1 -1
- package/dist/retry/index.d.ts +0 -1
- package/dist/retry/index.d.ts.map +1 -1
- package/dist/retry/index.js.map +1 -1
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js.map +1 -1
- package/dist/scheduler/index.d.ts +4 -12
- package/dist/scheduler/index.d.ts.map +1 -1
- package/dist/scheduler/index.js +9 -4
- package/dist/scheduler/index.js.map +1 -1
- package/dist/scheduler/index.workerd.js +9 -4
- package/dist/scheduler/index.workerd.js.map +1 -1
- package/dist/security/index.browser.js +30 -28
- package/dist/security/index.browser.js.map +1 -1
- package/dist/security/index.d.ts +113 -44
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +452 -37
- package/dist/security/index.js.map +1 -1
- package/dist/server/auth/index.browser.js +19 -19
- package/dist/server/auth/index.browser.js.map +1 -1
- package/dist/server/auth/index.d.ts +215 -187
- package/dist/server/auth/index.d.ts.map +1 -1
- package/dist/server/auth/index.js +1145 -86
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/cookies/index.browser.js +103 -5
- package/dist/server/cookies/index.browser.js.map +1 -1
- package/dist/server/cookies/index.d.ts +86 -4
- package/dist/server/cookies/index.d.ts.map +1 -1
- package/dist/server/cookies/index.js +121 -8
- package/dist/server/cookies/index.js.map +1 -1
- package/dist/server/core/index.browser.js +22 -27
- package/dist/server/core/index.browser.js.map +1 -1
- package/dist/server/core/index.d.ts +134 -85
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js +130 -118
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/cors/index.d.ts +9 -10
- package/dist/server/cors/index.d.ts.map +1 -1
- package/dist/server/cors/index.js +14 -26
- package/dist/server/cors/index.js.map +1 -1
- package/dist/server/etag/index.d.ts +2 -3
- package/dist/server/etag/index.d.ts.map +1 -1
- package/dist/server/etag/index.js.map +1 -1
- package/dist/server/health/index.d.ts +18 -19
- package/dist/server/health/index.d.ts.map +1 -1
- package/dist/server/health/index.js +6 -6
- package/dist/server/health/index.js.map +1 -1
- package/dist/server/links/index.browser.js +15 -18
- package/dist/server/links/index.browser.js.map +1 -1
- package/dist/server/links/index.d.ts +66 -67
- package/dist/server/links/index.d.ts.map +1 -1
- package/dist/server/links/index.js +29 -32
- package/dist/server/links/index.js.map +1 -1
- package/dist/server/metrics/index.d.ts +0 -1
- package/dist/server/metrics/index.d.ts.map +1 -1
- package/dist/server/metrics/index.js +10 -3
- package/dist/server/metrics/index.js.map +1 -1
- package/dist/server/proxy/index.d.ts +0 -1
- package/dist/server/proxy/index.d.ts.map +1 -1
- package/dist/server/proxy/index.js.map +1 -1
- package/dist/server/rate-limit/index.d.ts +8 -9
- package/dist/server/rate-limit/index.d.ts.map +1 -1
- package/dist/server/rate-limit/index.js +6 -12
- package/dist/server/rate-limit/index.js.map +1 -1
- package/dist/server/static/index.d.ts +0 -1
- package/dist/server/static/index.d.ts.map +1 -1
- package/dist/server/static/index.js.map +1 -1
- package/dist/server/swagger/index.d.ts +4 -4
- package/dist/server/swagger/index.d.ts.map +1 -1
- package/dist/server/swagger/index.js +37 -25
- package/dist/server/swagger/index.js.map +1 -1
- package/dist/sms/index.d.ts +0 -1
- package/dist/sms/index.d.ts.map +1 -1
- package/dist/sms/index.js.map +1 -1
- package/dist/system/index.browser.js.map +1 -1
- package/dist/system/index.d.ts +0 -1
- package/dist/system/index.d.ts.map +1 -1
- package/dist/system/index.js +2 -1
- package/dist/system/index.js.map +1 -1
- package/dist/system/index.workerd.js.map +1 -1
- package/dist/topic/core/index.d.ts +19 -20
- package/dist/topic/core/index.d.ts.map +1 -1
- package/dist/topic/core/index.js +8 -8
- package/dist/topic/core/index.js.map +1 -1
- package/dist/topic/redis/index.d.ts +3 -4
- package/dist/topic/redis/index.d.ts.map +1 -1
- package/dist/topic/redis/index.js +2 -2
- package/dist/topic/redis/index.js.map +1 -1
- package/package.json +36 -36
- package/src/api/audits/__tests__/AuditJobs.spec.ts +83 -0
- package/src/api/audits/__tests__/AuditService.spec.ts +139 -1
- package/src/api/audits/controllers/AdminAuditController.ts +41 -41
- package/src/api/audits/entities/audits.ts +22 -22
- package/src/api/audits/index.ts +6 -1
- package/src/api/audits/jobs/AuditJobs.ts +29 -0
- package/src/api/audits/parameters/AuditParameters.ts +51 -0
- package/src/api/audits/primitives/$audit.ts +24 -0
- package/src/api/audits/schemas/auditQuerySchema.ts +13 -13
- package/src/api/audits/schemas/createAuditSchema.ts +18 -18
- package/src/api/audits/services/AuditService.ts +79 -7
- package/src/api/files/__tests__/FileController.spec.ts +5 -5
- package/src/api/files/__tests__/FileJobs.spec.ts +6 -0
- package/src/api/files/controllers/FileController.ts +25 -25
- package/src/api/files/entities/files.ts +15 -15
- package/src/api/files/schemas/fileCreatorSummarySchema.ts +7 -7
- package/src/api/files/schemas/fileQuerySchema.ts +9 -9
- package/src/api/files/schemas/fileResourceSchema.ts +7 -9
- package/src/api/files/schemas/storageStatsSchema.ts +13 -13
- package/src/api/jobs/__tests__/$job-hardening.spec.ts +289 -0
- package/src/api/jobs/__tests__/$job.spec.ts +18 -18
- package/src/api/jobs/controllers/AdminJobController.ts +8 -8
- package/src/api/jobs/entities/jobExecutionEntity.ts +29 -19
- package/src/api/jobs/providers/JobProvider.ts +128 -12
- package/src/api/jobs/providers/JobQueueProvider.ts +2 -2
- package/src/api/jobs/schemas/jobConfigAtom.ts +22 -22
- package/src/api/jobs/schemas/jobExecutionQuerySchema.ts +6 -6
- package/src/api/jobs/schemas/jobExecutionResourceSchema.ts +11 -15
- package/src/api/jobs/schemas/jobRegistrationSchema.ts +20 -19
- package/src/api/jobs/schemas/triggerJobSchema.ts +3 -3
- package/src/api/jobs/services/JobService.ts +6 -6
- package/src/api/keys/__tests__/ApiKeyService.spec.ts +2 -2
- package/src/api/keys/controllers/AdminApiKeyController.ts +10 -10
- package/src/api/keys/entities/apiKeyEntity.ts +15 -15
- package/src/api/keys/schemas/adminApiKeyQuerySchema.ts +4 -4
- package/src/api/keys/schemas/adminApiKeyResourceSchema.ts +15 -15
- package/src/api/keys/schemas/createApiKeyBodySchema.ts +5 -5
- package/src/api/keys/schemas/createApiKeyResponseSchema.ts +9 -9
- package/src/api/keys/schemas/listApiKeyResponseSchema.ts +13 -13
- package/src/api/keys/schemas/revokeApiKeyParamsSchema.ts +3 -3
- package/src/api/keys/schemas/revokeApiKeyResponseSchema.ts +3 -3
- package/src/api/notifications/__tests__/AlephaApiNotifications.spec.ts +2 -2
- package/src/api/notifications/controllers/AdminNotificationController.ts +38 -14
- package/src/api/notifications/jobs/NotificationJobs.ts +7 -6
- package/src/api/notifications/primitives/$notification.ts +43 -4
- package/src/api/notifications/schemas/notificationContactPreferencesSchema.ts +4 -4
- package/src/api/notifications/schemas/notificationContactSchema.ts +7 -7
- package/src/api/notifications/schemas/notificationDetailResourceSchema.ts +9 -11
- package/src/api/notifications/schemas/notificationPayloadSchema.ts +11 -9
- package/src/api/notifications/schemas/notificationQuerySchema.ts +6 -6
- package/src/api/notifications/schemas/notificationResourceSchema.ts +14 -14
- package/src/api/notifications/services/NotificationSenderService.ts +38 -2
- package/src/api/oauth/__tests__/OAuthClientService.spec.ts +42 -0
- package/src/api/oauth/__tests__/OAuthController.spec.ts +128 -0
- package/src/api/oauth/controllers/OAuthController.ts +132 -12
- package/src/api/oauth/entities/oauthClientEntity.ts +29 -12
- package/src/api/oauth/helpers/oauthMetadata.ts +1 -0
- package/src/api/oauth/helpers/oidcMetadata.ts +19 -0
- package/src/api/oauth/index.ts +1 -0
- package/src/api/oauth/schemas/authorizeDecisionBodySchema.ts +12 -11
- package/src/api/oauth/schemas/authorizeQuerySchema.ts +12 -10
- package/src/api/oauth/schemas/registerClientBodySchema.ts +10 -11
- package/src/api/oauth/schemas/tokenRequestBodySchema.ts +9 -8
- package/src/api/oauth/services/OAuthClientService.ts +228 -15
- package/src/api/organizations/controllers/AdminOrganizationController.ts +8 -8
- package/src/api/organizations/entities/organizations.ts +6 -6
- package/src/api/organizations/schemas/createOrganizationSchema.ts +5 -5
- package/src/api/organizations/schemas/organizationQuerySchema.ts +4 -4
- package/src/api/organizations/schemas/updateOrganizationSchema.ts +1 -2
- package/src/api/parameters/__tests__/$parameter.spec.ts +229 -50
- package/src/api/parameters/controllers/AdminParameterController.ts +9 -12
- package/src/api/parameters/entities/parameters.ts +29 -16
- package/src/api/parameters/primitives/$parameter.ts +3 -3
- package/src/api/parameters/schemas/activateParameterBodySchema.ts +4 -4
- package/src/api/parameters/schemas/createParameterVersionBodySchema.ts +15 -15
- package/src/api/parameters/schemas/parameterCreatorSummarySchema.ts +7 -7
- package/src/api/parameters/schemas/parameterCurrentResponseSchema.ts +7 -7
- package/src/api/parameters/schemas/parameterHistoryResponseSchema.ts +3 -3
- package/src/api/parameters/schemas/parameterNameParamSchema.ts +2 -3
- package/src/api/parameters/schemas/parameterNamesResponseSchema.ts +3 -3
- package/src/api/parameters/schemas/parameterResponseSchema.ts +3 -3
- package/src/api/parameters/schemas/parameterStatusSchema.ts +2 -2
- package/src/api/parameters/schemas/parameterTreeNodeSchema.ts +6 -6
- package/src/api/parameters/schemas/parameterVersionParamSchema.ts +5 -6
- package/src/api/parameters/schemas/parameterVersionResponseSchema.ts +3 -3
- package/src/api/parameters/schemas/rollbackParameterBodySchema.ts +6 -9
- package/src/api/parameters/services/ParameterProvider.ts +152 -65
- package/src/api/payments/controllers/AdminPaymentController.ts +7 -7
- package/src/api/payments/controllers/MockCheckoutController.ts +79 -28
- package/src/api/payments/controllers/PaymentController.ts +4 -4
- package/src/api/payments/entities/paymentIntents.ts +11 -11
- package/src/api/payments/entities/paymentMethods.ts +11 -11
- package/src/api/payments/entities/refunds.ts +9 -9
- package/src/api/payments/providers/PaymentProvider.ts +18 -0
- package/src/api/payments/schemas/intentSchemas.ts +25 -25
- package/src/api/payments/schemas/paymentMethodSchemas.ts +3 -3
- package/src/api/payments/services/PaymentService.ts +60 -3
- package/src/api/subscriptions/__tests__/SubscriptionService.spec.ts +14 -0
- package/src/api/subscriptions/controllers/AdminSubscriptionController.ts +11 -11
- package/src/api/subscriptions/controllers/SubscriptionController.ts +5 -4
- package/src/api/subscriptions/entities/subscriptionEvents.ts +15 -15
- package/src/api/subscriptions/entities/subscriptions.ts +22 -22
- package/src/api/subscriptions/notifications/SubscriptionNotifications.ts +22 -22
- package/src/api/subscriptions/schemas/cancelSubscriptionSchema.ts +4 -4
- package/src/api/subscriptions/schemas/changePlanSchema.ts +5 -5
- package/src/api/subscriptions/schemas/createSubscriptionSchema.ts +14 -7
- package/src/api/subscriptions/schemas/entitlementsSchema.ts +10 -10
- package/src/api/subscriptions/schemas/mrrSchema.ts +9 -9
- package/src/api/subscriptions/schemas/planDefinitionSchema.ts +21 -21
- package/src/api/subscriptions/schemas/planResourceSchema.ts +19 -19
- package/src/api/subscriptions/schemas/subscriptionQuerySchema.ts +8 -8
- package/src/api/subscriptions/schemas/subscriptionSettingsSchema.ts +7 -7
- package/src/api/subscriptions/schemas/subscriptionStatsSchema.ts +17 -17
- package/src/api/subscriptions/services/SubscriptionConfig.ts +2 -2
- package/src/api/users/__tests__/ApiKeys-integration.spec.ts +11 -11
- package/src/api/users/atoms/realmAuthSettingsAtom.ts +111 -119
- package/src/api/users/controllers/AdminIdentityController.ts +29 -19
- package/src/api/users/controllers/AdminSessionController.ts +37 -27
- package/src/api/users/controllers/AdminUserController.ts +75 -53
- package/src/api/users/controllers/MySessionController.ts +125 -0
- package/src/api/users/controllers/RealmController.ts +9 -9
- package/src/api/users/controllers/UserController.ts +55 -55
- package/src/api/users/entities/identities.ts +8 -8
- package/src/api/users/entities/sessions.ts +17 -17
- package/src/api/users/entities/users.ts +17 -17
- package/src/api/users/index.ts +3 -0
- package/src/api/users/notifications/UserNotifications.ts +76 -24
- package/src/api/users/primitives/$realm.ts +12 -0
- package/src/api/users/schemas/completePasswordResetRequestSchema.ts +8 -12
- package/src/api/users/schemas/completeRegistrationRequestSchema.ts +17 -20
- package/src/api/users/schemas/createUserSchema.ts +2 -2
- package/src/api/users/schemas/identityQuerySchema.ts +4 -4
- package/src/api/users/schemas/identityResourceSchema.ts +3 -2
- package/src/api/users/schemas/loginSchema.ts +4 -4
- package/src/api/users/schemas/passwordResetIntentResponseSchema.ts +6 -8
- package/src/api/users/schemas/realmConfigSchema.ts +10 -10
- package/src/api/users/schemas/registerQuerySchema.ts +6 -6
- package/src/api/users/schemas/registerRequestSchema.ts +21 -43
- package/src/api/users/schemas/registerResponseSchema.ts +2 -2
- package/src/api/users/schemas/registerSchema.ts +13 -31
- package/src/api/users/schemas/registrationIntentResponseSchema.ts +19 -23
- package/src/api/users/schemas/resetPasswordSchema.ts +10 -17
- package/src/api/users/schemas/sessionQuerySchema.ts +3 -3
- package/src/api/users/schemas/sessionResourceSchema.ts +25 -25
- package/src/api/users/schemas/updateUserSchema.ts +3 -4
- package/src/api/users/schemas/userQuerySchema.ts +7 -7
- package/src/api/users/services/RegistrationService.ts +25 -11
- package/src/api/users/services/UserService.ts +12 -6
- package/src/api/verifications/__tests__/CodeVerification.spec.ts +63 -101
- package/src/api/verifications/__tests__/LinkVerification.spec.ts +23 -92
- package/src/api/verifications/controllers/VerificationController.ts +13 -27
- package/src/api/verifications/entities/verifications.ts +13 -14
- package/src/api/verifications/schemas/requestVerificationCodeResponseSchema.ts +17 -14
- package/src/api/verifications/schemas/validateVerificationCodeResponseSchema.ts +9 -10
- package/src/api/verifications/schemas/verificationSettingsSchema.ts +65 -66
- package/src/api/verifications/schemas/verificationTypeEnumSchema.ts +2 -2
- package/src/api/verifications/services/VerificationService.ts +12 -0
- package/src/background/__tests__/BackgroundTaskProvider.spec.ts +36 -0
- package/src/batch/__tests__/$batch.spec.ts +22 -22
- package/src/batch/__tests__/startup-buffering.spec.ts +9 -9
- package/src/bin/index.ts +1 -1
- package/src/bucket/__tests__/TenantScopedBucket.spec.ts +60 -0
- package/src/bucket/providers/LocalFileStorageProvider.ts +14 -6
- package/src/bucket/providers/MemoryFileStorageProvider.ts +18 -7
- package/src/bucket/providers/R2FileStorageProvider.ts +14 -6
- package/src/bucket/providers/S3FileStorageProvider.ts +31 -15
- package/src/cache/core/primitives/$cache.ts +7 -10
- package/src/cache/database/entities/cacheEntries.ts +16 -27
- package/src/cache/database/providers/DatabaseCacheProvider.ts +15 -13
- package/src/cache/redis/providers/RedisCacheProvider.ts +6 -6
- package/src/captcha/providers/TurnstileCaptchaProvider.ts +4 -4
- package/src/cli/core/__tests__/BuildCloudflareTask.spec.ts +178 -0
- package/src/cli/core/__tests__/BuildDockerTask.spec.ts +0 -2
- package/src/cli/core/__tests__/DbCommand.spec.ts +108 -0
- package/src/cli/core/atoms/appEntryOptions.ts +5 -5
- package/src/cli/core/atoms/buildOptions.ts +76 -88
- package/src/cli/core/atoms/changelogOptions.ts +3 -3
- package/src/cli/core/atoms/devOptions.ts +3 -3
- package/src/cli/core/commands/build.ts +36 -49
- package/src/cli/core/commands/db.ts +171 -83
- package/src/cli/core/commands/dev.ts +8 -8
- package/src/cli/core/commands/gen/changelog.ts +12 -14
- package/src/cli/core/commands/gen/env.ts +6 -6
- package/src/cli/core/commands/gen/openapi.ts +6 -6
- package/src/cli/core/commands/init.ts +28 -33
- package/src/cli/core/commands/pack.ts +10 -10
- package/src/cli/core/commands/root.ts +7 -8
- package/src/cli/core/commands/test.ts +17 -20
- package/src/cli/core/index.ts +0 -3
- package/src/cli/core/tasks/BuildCloudflareTask.ts +138 -245
- package/src/cli/core/tasks/BuildPrerenderTask.ts +44 -7
- package/src/cli/core/templates/apiHelloResponseSchemaTs.ts +4 -4
- package/src/cli/devtools/atoms/devtoolsOptions.ts +6 -6
- package/src/cli/i18n/__tests__/I18nCheckService.spec.ts +48 -0
- package/src/cli/i18n/atoms/i18nOptions.ts +8 -8
- package/src/cli/i18n/services/I18nCheckService.ts +65 -11
- package/src/cli/platform/commands/SecretsCommand.ts +24 -25
- package/src/cli/platform/commands/platform.ts +40 -46
- package/src/cli/platform/index.ts +1 -1
- package/src/cli/platform-lib/__tests__/CloudflareAdapter.spec.ts +0 -4
- package/src/cli/platform-lib/__tests__/PlatformInspector.spec.ts +10 -3
- package/src/cli/platform-lib/__tests__/VercelAdapter.spec.ts +0 -2
- package/src/cli/platform-lib/adapters/CloudflareAdapter.ts +141 -50
- package/src/cli/platform-lib/adapters/VercelAdapter.ts +6 -11
- package/src/cli/platform-lib/atoms/platformOptions.ts +46 -25
- package/src/cli/platform-lib/schemas/cloudflare.ts +87 -87
- package/src/cli/platform-lib/schemas/platform.ts +51 -51
- package/src/cli/platform-lib/schemas/vercel.ts +28 -28
- package/src/cli/platform-lib/services/CloudflareApi.ts +5 -5
- package/src/cli/platform-lib/services/VercelApi.ts +4 -4
- package/src/cli/platform-lib/services/VercelCli.ts +6 -15
- package/src/cli/platform-lib/services/WranglerApi.ts +6 -15
- package/src/cli/vendor/atoms/vendorOptions.ts +9 -9
- package/src/cli/vendor/commands/VendorCommand.ts +11 -12
- package/src/command/__tests__/$command.spec.ts +82 -83
- package/src/command/__tests__/Asker.spec.ts +6 -13
- package/src/command/__tests__/CliProvider.spec.ts +136 -149
- package/src/command/__tests__/Runner.spec.ts +86 -110
- package/src/command/helpers/Asker.ts +23 -58
- package/src/command/helpers/Runner.ts +34 -110
- package/src/command/index.ts +4 -9
- package/src/command/primitives/$command.ts +10 -10
- package/src/command/providers/CliProvider.ts +183 -161
- package/src/core/Alepha.ts +62 -13
- package/src/core/__tests__/$atom.spec.ts +52 -3
- package/src/core/__tests__/$computed.spec.ts +129 -0
- package/src/core/__tests__/$env.spec.ts +13 -13
- package/src/core/__tests__/$inject.spec.ts +4 -4
- package/src/core/__tests__/$module.spec.ts +1 -1
- package/src/core/__tests__/Alepha-graph.spec.ts +1 -1
- package/src/core/__tests__/Alepha-parseEnv.spec.ts +32 -32
- package/src/core/__tests__/Alepha-start.spec.ts +3 -3
- package/src/core/__tests__/CodecManager.spec.ts +113 -94
- package/src/core/__tests__/KeylessJsonSchemaCodec.spec.ts +138 -138
- package/src/core/__tests__/SchemaValidator.spec.ts +43 -44
- package/src/core/__tests__/StateManager.persist.browser.spec.ts +87 -0
- package/src/core/__tests__/StateManager.spec.ts +423 -0
- package/src/core/__tests__/TypeBox-usecases.spec.ts +8 -8
- package/src/core/__tests__/TypeProvider.spec.ts +314 -309
- package/src/core/__tests__/dump.spec.ts +6 -6
- package/src/core/__tests__/pagination.spec.ts +4 -4
- package/src/core/__tests__/scoped-after-start.spec.ts +43 -0
- package/src/core/errors/TypeBoxError.ts +10 -4
- package/src/core/helpers/FileLike.ts +5 -5
- package/src/core/helpers/coerceStrings.ts +70 -0
- package/src/core/helpers/jsonSchemaToZod.ts +112 -0
- package/src/core/index.shared.ts +4 -1
- package/src/core/primitives/$atom.ts +95 -27
- package/src/core/primitives/$computed.ts +148 -0
- package/src/core/primitives/$env.ts +5 -5
- package/src/core/primitives/$state.ts +1 -1
- package/src/core/providers/AlsProvider.ts +26 -0
- package/src/core/providers/CodecManager.ts +1 -2
- package/src/core/providers/JsonSchemaCodec.ts +1 -2
- package/src/core/providers/KeylessJsonSchemaCodec.ts +82 -57
- package/src/core/providers/SchemaValidator.ts +48 -158
- package/src/core/providers/StateManager.ts +383 -9
- package/src/core/providers/TypeProvider.ts +80 -734
- package/src/core/providers/ZodProvider.ts +380 -0
- package/src/core/providers/zodAugment.ts +69 -0
- package/src/core/schemas/pageQuerySchema.ts +19 -21
- package/src/core/schemas/pageSchema.ts +47 -57
- package/src/crypto/__tests__/SecretProvider.spec.ts +31 -0
- package/src/crypto/providers/SecretProvider.ts +16 -10
- package/src/datetime/primitives/$throttle.ts +6 -1
- package/src/email/brevo/providers/BrevoEmailProvider.ts +4 -4
- package/src/email/cloudflare/providers/CloudflareEmailProvider.ts +6 -6
- package/src/email/core/index.ts +7 -2
- package/src/email/core/primitives/$email.ts +5 -1
- package/src/email/core/providers/LocalEmailProvider.ts +5 -5
- package/src/email/smtp/providers/NodemailerEmailProvider.ts +41 -52
- package/src/fake/__tests__/FakeProvider.spec.ts +110 -110
- package/src/fake/__tests__/keyName.example.ts +21 -21
- package/src/fake/__tests__/keyName.spec.ts +41 -41
- package/src/fake/__tests__/module.example.ts +8 -8
- package/src/fake/providers/FakeProvider.ts +122 -121
- package/src/lock/core/__tests__/lock-mutual-exclusion.spec.ts +44 -0
- package/src/lock/core/index.ts +1 -0
- package/src/lock/core/primitives/$lock.ts +13 -6
- package/src/logger/__tests__/CliFormatterProvider.spec.ts +76 -0
- package/src/logger/__tests__/Logger.spec.ts +49 -0
- package/src/logger/index.ts +25 -18
- package/src/logger/providers/CliFormatterProvider.ts +75 -0
- package/src/logger/schemas/logEntrySchema.ts +10 -10
- package/src/logger/services/Logger.ts +18 -0
- package/src/mcp/__tests__/$prompt.spec.ts +21 -23
- package/src/mcp/__tests__/$tool.spec.ts +22 -22
- package/src/mcp/__tests__/McpServerProvider.spec.ts +82 -11
- package/src/mcp/__tests__/StreamableHttpMcpTransport.spec.ts +2 -2
- package/src/mcp/__tests__/integration.spec.ts +33 -33
- package/src/mcp/primitives/$prompt.ts +11 -9
- package/src/mcp/primitives/$tool.ts +27 -86
- package/src/mcp/providers/McpServerProvider.ts +55 -0
- package/src/mcp/transports/StreamableHttpMcpTransport.ts +7 -7
- package/src/orm/__tests__/$repository-tests.ts +133 -27
- package/src/orm/__tests__/$repository.spec.ts +23 -0
- package/src/orm/__tests__/$transactional-tests.ts +4 -4
- package/src/orm/__tests__/ModelBuilder-tests.ts +28 -28
- package/src/orm/__tests__/ModelBuilder.spec.ts +124 -106
- package/src/orm/__tests__/QueryManager.spec.ts +5 -5
- package/src/orm/__tests__/delete-returning-tests.ts +11 -11
- package/src/orm/__tests__/deletedAt-tests.ts +3 -3
- package/src/orm/__tests__/enums.spec.ts +29 -25
- package/src/orm/__tests__/execute-tests.ts +8 -8
- package/src/orm/__tests__/fixtures/bigEntitySchema.ts +48 -48
- package/src/orm/__tests__/fixtures/userEntitySchema.ts +6 -6
- package/src/orm/__tests__/joins-tests.ts +30 -30
- package/src/orm/__tests__/organization-tests.ts +105 -3
- package/src/orm/__tests__/organization.spec.ts +46 -0
- package/src/orm/__tests__/orm-errors.spec.ts +10 -10
- package/src/orm/__tests__/orm-next-tests.ts +29 -29
- package/src/orm/__tests__/orm-showcase-tests.ts +9 -9
- package/src/orm/__tests__/primaryKey.spec.ts +4 -4
- package/src/orm/__tests__/query-date-encoding-tests.ts +17 -17
- package/src/orm/__tests__/ref-auto-onDelete.spec.ts +14 -14
- package/src/orm/__tests__/references.spec.ts +7 -7
- package/src/orm/__tests__/security.spec.ts +17 -17
- package/src/orm/__tests__/string-operators-tests.ts +5 -5
- package/src/orm/__tests__/timestamps-tests.ts +14 -14
- package/src/orm/__tests__/validation-tests.ts +5 -5
- package/src/orm/core/__tests__/BunSqliteProvider.bun.spec.ts +8 -8
- package/src/orm/core/constants/PG_SYMBOLS.ts +13 -1
- package/src/orm/core/entities/alephaSequences.ts +8 -8
- package/src/orm/core/helpers/pgAttr.ts +4 -4
- package/src/orm/core/primitives/$entity.ts +10 -6
- package/src/orm/core/providers/DatabaseTypeProvider.ts +46 -53
- package/src/orm/core/providers/drivers/BunSqliteProvider.ts +8 -8
- package/src/orm/core/providers/drivers/CloudflareD1Provider.ts +3 -5
- package/src/orm/core/providers/drivers/NodeSqliteProvider.ts +8 -8
- package/src/orm/core/schemas/databaseEnvSchema.ts +4 -4
- package/src/orm/core/schemas/insertSchema.ts +14 -18
- package/src/orm/core/schemas/legacyIdSchema.ts +2 -2
- package/src/orm/core/schemas/updateSchema.ts +10 -16
- package/src/orm/core/services/PgRelationManager.ts +2 -2
- package/src/orm/core/services/QueryManager.ts +13 -2
- package/src/orm/core/services/Repository.ts +88 -33
- package/src/orm/core/services/SqliteModelBuilder.ts +38 -45
- package/src/orm/postgres/__tests__/BunPostgresProvider.bun.spec.ts +4 -4
- package/src/orm/postgres/providers/CloudflareHyperdriveProvider.ts +4 -6
- package/src/orm/postgres/schemas/postgresEnvSchema.ts +6 -6
- package/src/orm/postgres/services/PostgresModelBuilder.ts +127 -114
- package/src/queue/core/__tests__/$consumer.spec.ts +4 -4
- package/src/queue/core/__tests__/WorkerProvider.spec.ts +4 -4
- package/src/queue/core/__tests__/shared.ts +6 -6
- package/src/queue/core/primitives/$consumer.ts +5 -5
- package/src/queue/core/primitives/$queue.ts +44 -61
- package/src/queue/core/providers/CloudflareQueueProvider.ts +6 -0
- package/src/queue/core/providers/WorkerProvider.ts +17 -14
- package/src/queue/redis/providers/RedisQueueProvider.ts +3 -3
- package/src/react/core/__tests__/ErrorBoundary.browser.spec.tsx +92 -0
- package/src/react/core/__tests__/Router.spec.tsx +4 -4
- package/src/react/core/__tests__/useComputed.browser.spec.tsx +192 -0
- package/src/react/core/__tests__/useQuery.browser.spec.tsx +48 -0
- package/src/react/core/__tests__/useSelector.browser.spec.tsx +105 -0
- package/src/react/core/__tests__/useStore.browser.spec.tsx +113 -0
- package/src/react/core/components/ErrorBoundary.tsx +42 -0
- package/src/react/core/hooks/useAction.ts +56 -19
- package/src/react/core/hooks/useComputed.ts +91 -0
- package/src/react/core/hooks/useSelector.ts +67 -0
- package/src/react/core/hooks/useStore.ts +36 -17
- package/src/react/core/index.ts +3 -0
- package/src/react/core/utils/shallowEqual.ts +36 -0
- package/src/react/form/__tests__/FormModel-submit-loading.spec.ts +71 -0
- package/src/react/form/__tests__/form-submitting-reactive.browser.spec.tsx +96 -0
- package/src/react/form/__tests__/useForm.browser.spec.tsx +54 -54
- package/src/react/form/errors/FormValidationError.ts +0 -2
- package/src/react/form/hooks/useForm.ts +19 -4
- package/src/react/form/hooks/useFormQuerySync.ts +0 -0
- package/src/react/form/services/FormModel.ts +124 -86
- package/src/react/form/services/parseField.ts +66 -27
- package/src/react/i18n/__tests__/I18nProvider.spec.ts +89 -0
- package/src/react/i18n/__tests__/Localize.spec.tsx +1 -1
- package/src/react/i18n/__tests__/locale-routing.spec.ts +107 -0
- package/src/react/i18n/providers/I18nProvider.ts +173 -14
- package/src/react/router/__tests__/$page.browser.spec.tsx +19 -19
- package/src/react/router/__tests__/$page.spec.tsx +21 -21
- package/src/react/router/__tests__/ReactBrowserProvider.browser.spec.ts +87 -1
- package/src/react/router/__tests__/RouterLocaleProvider.spec.ts +127 -0
- package/src/react/router/atoms/ssrManifestAtom.ts +16 -16
- package/src/react/router/components/NestedView.tsx +11 -3
- package/src/react/router/hooks/useQueryParams.ts +1 -1
- package/src/react/router/index.browser.ts +4 -0
- package/src/react/router/index.shared.ts +1 -0
- package/src/react/router/index.ts +9 -0
- package/src/react/router/primitives/$page.ts +2 -2
- package/src/react/router/providers/ReactBrowserProvider.ts +64 -13
- package/src/react/router/providers/ReactBrowserRouterProvider.ts +15 -1
- package/src/react/router/providers/ReactPageProvider.ts +38 -13
- package/src/react/router/providers/ReactServerProvider.ts +105 -16
- package/src/react/router/providers/RootComponentsProvider.ts +13 -0
- package/src/react/router/providers/RouterLocaleProvider.ts +125 -0
- package/src/react/router/providers/__tests__/RootComponentsProvider.spec.ts +15 -0
- package/src/react/router/providers/__tests__/rootComponents.ssr.browser.spec.tsx +67 -0
- package/src/react/sitemap/__tests__/$sitemap.spec.ts +131 -0
- package/src/react/sitemap/index.browser.ts +21 -0
- package/src/react/sitemap/index.ts +25 -0
- package/src/react/sitemap/primitives/$sitemap.browser.ts +26 -0
- package/src/react/sitemap/primitives/$sitemap.ts +196 -0
- package/src/react/ui/atoms/uiAtom.ts +6 -6
- package/src/react/ui/atoms/uiThemeListAtom.ts +7 -7
- package/src/react/ui/hooks/useColorMode.ts +11 -4
- package/src/react/ui/services/SchemaControl.ts +4 -4
- package/src/redis/providers/BunRedisProvider.ts +19 -11
- package/src/redis/providers/NodeRedisProvider.ts +3 -3
- package/src/scheduler/primitives/$scheduler.ts +21 -8
- package/src/security/__tests__/assertRealmScope.spec.ts +29 -0
- package/src/security/atoms/currentTenantAtom.ts +6 -6
- package/src/security/atoms/currentUserAtom.ts +2 -2
- package/src/security/primitives/$issuer.ts +24 -2
- package/src/security/providers/JwtProvider.ts +100 -0
- package/src/security/providers/SecurityProvider.ts +43 -2
- package/src/security/schemas/permissionSchema.ts +19 -19
- package/src/security/schemas/roleSchema.ts +22 -28
- package/src/security/schemas/userAccountInfoSchema.ts +47 -37
- package/src/server/auth/__tests__/appleClientSecret.spec.ts +34 -0
- package/src/server/auth/__tests__/federationRedirectReplay.spec.ts +44 -0
- package/src/server/auth/helpers/appleClientSecret.ts +24 -0
- package/src/server/auth/helpers/jtiReplayGuard.ts +41 -0
- package/src/server/auth/helpers/safeRedirectPath.ts +19 -0
- package/src/server/auth/index.ts +1 -0
- package/src/server/auth/primitives/$auth.ts +6 -6
- package/src/server/auth/primitives/$authApple.ts +10 -10
- package/src/server/auth/primitives/$authFacebook.ts +10 -10
- package/src/server/auth/primitives/$authFranceConnect.ts +10 -10
- package/src/server/auth/primitives/$authGithub.ts +10 -10
- package/src/server/auth/primitives/$authGoogle.ts +10 -10
- package/src/server/auth/primitives/$authMicrosoft.ts +14 -14
- package/src/server/auth/providers/ServerAuthProvider.ts +67 -52
- package/src/server/auth/schemas/authenticationProviderSchema.ts +9 -12
- package/src/server/auth/schemas/tokenResponseSchema.ts +2 -2
- package/src/server/auth/schemas/tokensSchema.ts +16 -16
- package/src/server/auth/schemas/userinfoResponseSchema.ts +3 -3
- package/src/server/cookies/__tests__/AtomCookieBinding.spec.ts +80 -0
- package/src/server/cookies/__tests__/AtomCookiePersistence.browser.spec.ts +169 -0
- package/src/server/cookies/__tests__/AtomCookiePersistence.spec.ts +294 -0
- package/src/server/cookies/__tests__/ServerCookiesProvider.spec.ts +82 -12
- package/src/server/cookies/index.browser.ts +4 -1
- package/src/server/cookies/index.ts +8 -1
- package/src/server/cookies/primitives/$cookie.browser.ts +1 -1
- package/src/server/cookies/primitives/$cookie.ts +16 -0
- package/src/server/cookies/providers/AtomCookiePersistence.browser.ts +133 -0
- package/src/server/cookies/providers/AtomCookiePersistence.ts +148 -0
- package/src/server/cookies/providers/ServerCookiesProvider.ts +32 -4
- package/src/server/cookies/services/CookieParser.ts +6 -1
- package/src/server/core/__tests__/$action.spec.ts +13 -13
- package/src/server/core/__tests__/$middleware.spec.ts +10 -10
- package/src/server/core/__tests__/$route.spec.ts +9 -9
- package/src/server/core/__tests__/$sse.spec.ts +26 -26
- package/src/server/core/__tests__/BunHttpServerProvider.bun.spec.ts +6 -6
- package/src/server/core/__tests__/HttpClient.spec.ts +2 -2
- package/src/server/core/__tests__/NodeHttpServerProvider.spec.ts +15 -3
- package/src/server/core/__tests__/ServerBodyParserProvider.spec.ts +14 -14
- package/src/server/core/__tests__/ServerMultipartProvider.spec.ts +33 -33
- package/src/server/core/__tests__/ServerRouterProvider-errorHandler.spec.ts +5 -1
- package/src/server/core/__tests__/ServerRouterProvider-getRoutes.spec.ts +25 -25
- package/src/server/core/__tests__/ServerRouterProvider-serializationError.spec.ts +9 -5
- package/src/server/core/__tests__/ServerRouterProvider-validationError.spec.ts +56 -24
- package/src/server/core/errors/ValidationError.ts +6 -3
- package/src/server/core/helpers/isMultipart.ts +2 -1
- package/src/server/core/index.ts +5 -2
- package/src/server/core/interfaces/ServerRequest.ts +14 -14
- package/src/server/core/primitives/$action.ts +26 -36
- package/src/server/core/primitives/$route.ts +27 -0
- package/src/server/core/primitives/$sse.ts +3 -3
- package/src/server/core/providers/BunHttpServerProvider.ts +8 -9
- package/src/server/core/providers/NodeHttpServerProvider.ts +8 -9
- package/src/server/core/providers/ServerBodyParserProvider.ts +20 -12
- package/src/server/core/providers/ServerCompressProvider.ts +9 -10
- package/src/server/core/providers/ServerHelmetProvider.ts +26 -27
- package/src/server/core/providers/ServerMultipartProvider.ts +19 -19
- package/src/server/core/providers/ServerRouterProvider.ts +44 -15
- package/src/server/core/schemas/errorSchema.ts +20 -25
- package/src/server/core/schemas/okSchema.ts +9 -14
- package/src/server/core/services/HttpClient.ts +13 -1
- package/src/server/core/services/ServerRequestParser.ts +6 -6
- package/src/server/cors/providers/ServerCorsProvider.ts +26 -28
- package/src/server/health/schemas/healthSchema.ts +6 -6
- package/src/server/links/__tests__/$remote.spec.ts +3 -3
- package/src/server/links/__tests__/BatchEndpoint.spec.ts +9 -9
- package/src/server/links/__tests__/LinkProvider.spec.ts +9 -9
- package/src/server/links/__tests__/ServerLinksProvider.spec.ts +23 -23
- package/src/server/links/__tests__/fixtures/CrudApp.ts +21 -21
- package/src/server/links/atoms/apiLinksAtom.ts +2 -2
- package/src/server/links/atoms/linkOptionsAtom.ts +6 -6
- package/src/server/links/primitives/$remote.ts +3 -3
- package/src/server/links/providers/LinkProvider.ts +3 -3
- package/src/server/links/providers/ServerLinksProvider.ts +20 -20
- package/src/server/links/schemas/apiLinksResponseSchema.ts +23 -23
- package/src/server/proxy/__tests__/$proxy.spec.ts +9 -9
- package/src/server/proxy/providers/ServerProxyProvider.ts +5 -0
- package/src/server/rate-limit/providers/ServerRateLimitProvider.ts +18 -20
- package/src/server/swagger/__tests__/$swagger.spec.ts +91 -94
- package/src/server/swagger/__tests__/ui.spec.ts +3 -3
- package/src/server/swagger/providers/ServerSwaggerProvider.ts +66 -43
- package/src/system/__tests__/NodeShellProvider.spec.ts +46 -0
- package/src/system/providers/NodeShellProvider.ts +4 -1
- package/src/topic/core/__tests__/$subscriber.spec.ts +4 -4
- package/src/topic/core/__tests__/shared.ts +8 -8
- package/src/topic/core/primitives/$subscriber.ts +5 -5
- package/src/topic/core/primitives/$topic.ts +14 -14
- package/src/topic/redis/providers/RedisTopicProvider.ts +3 -3
- package/dist/container/core/index.d.ts +0 -236
- package/dist/container/core/index.d.ts.map +0 -1
- package/dist/container/core/index.js +0 -231
- package/dist/container/core/index.js.map +0 -1
- package/dist/container/core/index.workerd.js +0 -192
- package/dist/container/core/index.workerd.js.map +0 -1
- package/src/cli/core/tasks/BuildSitemapTask.ts +0 -130
- package/src/command/helpers/PrettyAsker.ts +0 -256
- package/src/command/helpers/PrettyPrint.ts +0 -332
- package/src/container/core/__tests__/$container.spec.ts +0 -83
- package/src/container/core/index.ts +0 -50
- package/src/container/core/index.workerd.ts +0 -53
- package/src/container/core/interfaces/ContainerOptions.ts +0 -69
- package/src/container/core/primitives/$container.ts +0 -100
- package/src/container/core/providers/CloudflareContainerProvider.ts +0 -70
- package/src/container/core/providers/ContainerProvider.ts +0 -92
- package/src/container/core/providers/MockContainerProvider.ts +0 -62
- package/src/container/core/providers/NodeContainerProvider.ts +0 -53
- package/src/core/__tests__/jsonSchemaToTypeBox.spec.ts +0 -771
- package/src/core/helpers/jsonSchemaToTypeBox.ts +0 -359
- /package/dist/orm/core/{chunk-B4FMCO8f.js → rolldown-runtime-B4FMCO8f.js} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $inject, $module, Alepha, AlephaError, KIND, Primitive, createPrimitive } from "alepha";
|
|
1
|
+
import { $hook, $inject, $module, Alepha, AlephaError, KIND, Primitive, createPrimitive } from "alepha";
|
|
2
2
|
import { AlephaServer } from "alepha/server";
|
|
3
3
|
import { DateTimeProvider } from "alepha/datetime";
|
|
4
4
|
//#region ../../src/server/cookies/services/CookieParser.ts
|
|
@@ -32,7 +32,7 @@ var CookieParser = class {
|
|
|
32
32
|
const parts = [];
|
|
33
33
|
parts.push(`${name}=${cookie.value}`);
|
|
34
34
|
if (cookie.path) parts.push(`Path=${cookie.path}`);
|
|
35
|
-
if (cookie.maxAge) parts.push(`Max-Age=${cookie.maxAge}`);
|
|
35
|
+
if (cookie.maxAge != null) parts.push(`Max-Age=${cookie.maxAge}`);
|
|
36
36
|
if (cookie.secure !== false && isHttps) parts.push("Secure");
|
|
37
37
|
if (cookie.httpOnly) parts.push("HttpOnly");
|
|
38
38
|
if (cookie.sameSite) parts.push(`SameSite=${cookie.sameSite}`);
|
|
@@ -41,6 +41,100 @@ var CookieParser = class {
|
|
|
41
41
|
}
|
|
42
42
|
};
|
|
43
43
|
//#endregion
|
|
44
|
+
//#region ../../src/server/cookies/providers/AtomCookiePersistence.browser.ts
|
|
45
|
+
/**
|
|
46
|
+
* Browser variant of AtomCookiePersistence: reads `document.cookie` for every
|
|
47
|
+
* `persist: "cookie"` atom, and writes it back on every mutation.
|
|
48
|
+
*
|
|
49
|
+
* Like the server variant, atoms are resolved from the `StateManager`
|
|
50
|
+
* registry (`alepha.store.listAtoms()`) rather than from a map fed by
|
|
51
|
+
* `state:register` — that event fires once, is never replayed, and
|
|
52
|
+
* `$module.register()` registers `atoms[]` before the module's `services[]`
|
|
53
|
+
* exist, so an event-sourced map would miss every atom declared the
|
|
54
|
+
* documented way. The `configure` hook sweeps everything registered up to
|
|
55
|
+
* boot; `state:register` covers atoms that first register later (lazily, on
|
|
56
|
+
* first read).
|
|
57
|
+
*
|
|
58
|
+
* Cookie names are NOT APP_NAME-prefixed here, because `APP_NAME` is not
|
|
59
|
+
* reachable in the browser: `BuildClientTask` only `define`s
|
|
60
|
+
* `process.env.NODE_ENV` for the client bundle, and the SSR hydration
|
|
61
|
+
* payload (`ReactServerTemplateProvider.buildHydrationData`) only carries
|
|
62
|
+
* registered atom values + router layers — never the raw `env` store key.
|
|
63
|
+
* The server variant (`AtomCookiePersistence.ts`) matches this by passing
|
|
64
|
+
* `prefix: false` to `ServerCookiesProvider`, specifically for atom-cookie
|
|
65
|
+
* traffic — every other server cookie ($cookie primitive) still gets the
|
|
66
|
+
* APP_NAME namespace. See `ServerCookiesProvider.prefixName`.
|
|
67
|
+
*/
|
|
68
|
+
var AtomCookiePersistence = class {
|
|
69
|
+
alepha = $inject(Alepha);
|
|
70
|
+
cookieParser = $inject(CookieParser);
|
|
71
|
+
dateTime = $inject(DateTimeProvider);
|
|
72
|
+
onConfigure = $hook({
|
|
73
|
+
on: "configure",
|
|
74
|
+
handler: () => {
|
|
75
|
+
for (const atom of this.cookieAtoms()) this.read(atom);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
onRegister = $hook({
|
|
79
|
+
on: "state:register",
|
|
80
|
+
handler: ({ atom }) => {
|
|
81
|
+
if (atom.options.persist !== "cookie") return;
|
|
82
|
+
this.read(atom);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
onMutate = $hook({
|
|
86
|
+
on: "state:mutate",
|
|
87
|
+
handler: ({ key, value }) => {
|
|
88
|
+
const atom = this.alepha.store.getAtom(String(key));
|
|
89
|
+
if (!atom || atom.options.persist !== "cookie") return;
|
|
90
|
+
if (value === void 0) {
|
|
91
|
+
this.clearCookie(atom.key);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const cookie = {
|
|
95
|
+
value: encodeURIComponent(JSON.stringify(value)),
|
|
96
|
+
path: "/",
|
|
97
|
+
sameSite: "lax",
|
|
98
|
+
maxAge: this.dateTime.duration([365, "days"]).as("seconds")
|
|
99
|
+
};
|
|
100
|
+
document.cookie = this.cookieParser.cookieToString(atom.key, cookie);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
/**
|
|
104
|
+
* Every registered atom declared with `persist: "cookie"`, read live from
|
|
105
|
+
* the state manager's registry.
|
|
106
|
+
*/
|
|
107
|
+
cookieAtoms() {
|
|
108
|
+
return this.alepha.store.listAtoms().filter((atom) => atom.options.persist === "cookie");
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Seed an atom's state from `document.cookie`, if a cookie exists for it.
|
|
112
|
+
* Idempotent: re-reading an atom that already holds the cookie's value is
|
|
113
|
+
* a no-op write of the same data.
|
|
114
|
+
*/
|
|
115
|
+
read(atom) {
|
|
116
|
+
const raw = this.cookieParser.parseRequestCookies(document.cookie)[atom.key];
|
|
117
|
+
if (!raw) return;
|
|
118
|
+
try {
|
|
119
|
+
this.alepha.store.set(atom.key, JSON.parse(decodeURIComponent(raw)), { skipEvents: true });
|
|
120
|
+
} catch {
|
|
121
|
+
this.clearCookie(atom.key);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Expire a cookie immediately, mirroring
|
|
126
|
+
* `ServerCookiesProvider.deleteCookie`'s `Max-Age=0` semantics.
|
|
127
|
+
*/
|
|
128
|
+
clearCookie(name) {
|
|
129
|
+
document.cookie = this.cookieParser.cookieToString(name, {
|
|
130
|
+
value: "",
|
|
131
|
+
path: "/",
|
|
132
|
+
sameSite: "lax",
|
|
133
|
+
maxAge: 0
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
//#endregion
|
|
44
138
|
//#region ../../src/server/cookies/primitives/$cookie.browser.ts
|
|
45
139
|
/**
|
|
46
140
|
* Creates a browser-side cookie primitive for client-side cookie management.
|
|
@@ -56,7 +150,7 @@ var CookieParser = class {
|
|
|
56
150
|
* class ClientCookies {
|
|
57
151
|
* preferences = $cookie({
|
|
58
152
|
* name: "user-prefs",
|
|
59
|
-
* schema:
|
|
153
|
+
* schema: z.object({ theme: z.text(), language: z.text() }),
|
|
60
154
|
* ttl: [30, "days"]
|
|
61
155
|
* });
|
|
62
156
|
*
|
|
@@ -148,9 +242,13 @@ $cookie[KIND] = BrowserCookiePrimitive;
|
|
|
148
242
|
const AlephaServerCookies = $module({
|
|
149
243
|
name: "alepha.server.cookies",
|
|
150
244
|
primitives: [],
|
|
151
|
-
services: [
|
|
245
|
+
services: [
|
|
246
|
+
AlephaServer,
|
|
247
|
+
CookieParser,
|
|
248
|
+
AtomCookiePersistence
|
|
249
|
+
]
|
|
152
250
|
});
|
|
153
251
|
//#endregion
|
|
154
|
-
export { $cookie, AlephaServerCookies, BrowserCookiePrimitive };
|
|
252
|
+
export { $cookie, AlephaServerCookies, AtomCookiePersistence, BrowserCookiePrimitive };
|
|
155
253
|
|
|
156
254
|
//# sourceMappingURL=index.browser.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.browser.js","names":[],"sources":["../../../src/server/cookies/services/CookieParser.ts","../../../src/server/cookies/primitives/$cookie.browser.ts","../../../src/server/cookies/index.browser.ts"],"sourcesContent":["import type { Cookie } from \"../primitives/$cookie.ts\";\n\nexport class CookieParser {\n public parseRequestCookies(header: string): Record<string, string> {\n const cookies: Record<string, string> = {};\n const parts = header.split(\";\");\n for (const part of parts) {\n const eqIndex = part.indexOf(\"=\");\n if (eqIndex === -1) {\n continue;\n }\n\n const key = part.slice(0, eqIndex).trim();\n const value = part.slice(eqIndex + 1).trim();\n\n if (!key || !value) {\n continue;\n }\n\n cookies[key] = value;\n }\n\n return cookies;\n }\n\n public serializeResponseCookies(\n cookies: Record<string, Cookie | null>,\n isHttps: boolean,\n ): string[] {\n const headers = [];\n\n for (const [name, cookie] of Object.entries(cookies)) {\n // If the cookie is null, we need to delete it\n if (cookie == null) {\n headers.push(`${name}=; Path=/; Max-Age=0`);\n continue;\n }\n\n if (!cookie.value) {\n continue;\n }\n\n headers.push(this.cookieToString(name, cookie, isHttps));\n }\n\n return headers;\n }\n\n public cookieToString(\n name: string,\n cookie: Cookie,\n isHttps?: boolean,\n ): string {\n const parts: string[] = [];\n\n parts.push(`${name}=${cookie.value}`);\n\n if (cookie.path) {\n parts.push(`Path=${cookie.path}`);\n }\n if (cookie.maxAge) {\n parts.push(`Max-Age=${cookie.maxAge}`);\n }\n if (cookie.secure !== false && isHttps) {\n parts.push(\"Secure\");\n }\n if (cookie.httpOnly) {\n parts.push(\"HttpOnly\");\n }\n if (cookie.sameSite) {\n parts.push(`SameSite=${cookie.sameSite}`);\n }\n if (cookie.domain) {\n parts.push(`Domain=${cookie.domain}`);\n }\n\n return parts.join(\"; \");\n }\n}\n","import {\n $inject,\n Alepha,\n AlephaError,\n createPrimitive,\n KIND,\n Primitive,\n type Static,\n type TSchema,\n} from \"alepha\";\nimport { DateTimeProvider } from \"alepha/datetime\";\nimport { CookieParser } from \"../services/CookieParser.ts\";\nimport type {\n AbstractCookiePrimitive,\n Cookie,\n CookiePrimitiveOptions,\n Cookies,\n} from \"./$cookie.ts\";\n\n/**\n * Creates a browser-side cookie primitive for client-side cookie management.\n *\n * Browser-specific version of $cookie that uses document.cookie API. Supports type-safe\n * cookie operations with schema validation but excludes encryption/signing (use server-side\n * $cookie for secure operations).\n *\n * **Note**: This is the browser version - encryption, signing, and compression are not supported.\n *\n * @example\n * ```ts\n * class ClientCookies {\n * preferences = $cookie({\n * name: \"user-prefs\",\n * schema: t.object({ theme: t.text(), language: t.text() }),\n * ttl: [30, \"days\"]\n * });\n *\n * savePreferences() {\n * this.preferences.set({ theme: \"dark\", language: \"en\" });\n * }\n *\n * getPreferences() {\n * return this.preferences.get() ?? { theme: \"light\", language: \"en\" };\n * }\n * }\n * ```\n */\nexport const $cookie = <T extends TSchema>(\n options: CookiePrimitiveOptions<T>,\n extendedOptions?: Omit<CookiePrimitiveOptions<T>, \"schema\">,\n): AbstractCookiePrimitive<T> => {\n if (extendedOptions) {\n options = {\n key: options.key,\n schema: options.schema,\n ...extendedOptions,\n };\n }\n return createPrimitive(BrowserCookiePrimitive<T>, options);\n};\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport class BrowserCookiePrimitive<T extends TSchema>\n extends Primitive<CookiePrimitiveOptions<T>>\n implements AbstractCookiePrimitive<T>\n{\n protected cookieParser = $inject(CookieParser);\n protected alepha = $inject(Alepha);\n protected dateTimeProvider = $inject(DateTimeProvider);\n protected cookie?: Cookie;\n\n protected onInit() {\n if (this.options.key) {\n this.alepha.events.on(\"state:mutate\", ({ key, value }) => {\n if (key === this.options.key) {\n this.set(value);\n }\n });\n this.alepha.events.on(\"configure\", () => {\n try {\n const value = this.get();\n if (value !== undefined) {\n this.alepha.set(this.options.key as any, value);\n }\n } catch {}\n });\n }\n }\n\n public get schema(): T {\n return this.options.schema;\n }\n\n public get name(): string {\n return this.options.name ?? `${this.config.propertyKey}`;\n }\n\n public set(data: Static<T>): void {\n const value = JSON.stringify(this.alepha.codec.decode(this.schema, data));\n const options = this.options;\n\n if (options.compress) {\n throw new AlephaError(\"Compression is not supported in browser cookies.\");\n }\n\n if (options.encrypt) {\n throw new AlephaError(\"Encryption is not supported in browser cookies.\");\n }\n\n if (options.sign) {\n throw new AlephaError(\"Signing is not supported in browser cookies.\");\n }\n\n const cookie: Cookie = {\n value: encodeURIComponent(value),\n path: options.path ?? \"/\",\n sameSite: options.sameSite ?? \"lax\",\n secure: false,\n httpOnly: false,\n domain: options.domain,\n };\n\n if (options.ttl) {\n cookie.maxAge = this.dateTimeProvider.duration(options.ttl).as(\"seconds\");\n }\n\n // biome-ignore lint/suspicious/noDocumentCookie: ...\n document.cookie = this.cookieParser.cookieToString(this.name, cookie);\n }\n\n public get(options?: { cookies?: Cookies }): Static<T> | undefined {\n const cookie = this.cookieParser.parseRequestCookies(document.cookie)[\n this.name\n ];\n if (!cookie) {\n return undefined;\n }\n\n const rawValue = decodeURIComponent(cookie);\n\n if (this.options.compress) {\n throw new AlephaError(\"Compression is not supported in browser cookies.\");\n }\n\n if (this.options.encrypt) {\n throw new AlephaError(\"Encryption is not supported in browser cookies.\");\n }\n\n if (this.options.sign) {\n throw new AlephaError(\"Signing is not supported in browser cookies.\");\n }\n\n return this.alepha.codec.decode(this.schema, JSON.parse(rawValue));\n }\n\n public del(): void {\n const options = this.options;\n const cookie: Cookie = {\n value: \"\",\n path: options.path ?? \"/\",\n sameSite: options.sameSite ?? \"lax\",\n secure: false,\n httpOnly: false,\n domain: options.domain,\n maxAge: 0, // Set maxAge to 0 to delete the cookie\n };\n\n // biome-ignore lint/suspicious/noDocumentCookie: ...\n document.cookie = this.cookieParser.cookieToString(this.name, cookie);\n }\n}\n\n$cookie[KIND] = BrowserCookiePrimitive;\n","import { $module } from \"alepha\";\nimport { AlephaServer } from \"alepha/server\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./primitives/$cookie.browser.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport const AlephaServerCookies = $module({\n name: \"alepha.server.cookies\",\n primitives: [],\n services: [AlephaServer],\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.browser.js","names":[],"sources":["../../../src/server/cookies/services/CookieParser.ts","../../../src/server/cookies/providers/AtomCookiePersistence.browser.ts","../../../src/server/cookies/primitives/$cookie.browser.ts","../../../src/server/cookies/index.browser.ts"],"sourcesContent":["import type { Cookie } from \"../primitives/$cookie.ts\";\n\nexport class CookieParser {\n public parseRequestCookies(header: string): Record<string, string> {\n const cookies: Record<string, string> = {};\n const parts = header.split(\";\");\n for (const part of parts) {\n const eqIndex = part.indexOf(\"=\");\n if (eqIndex === -1) {\n continue;\n }\n\n const key = part.slice(0, eqIndex).trim();\n const value = part.slice(eqIndex + 1).trim();\n\n if (!key || !value) {\n continue;\n }\n\n cookies[key] = value;\n }\n\n return cookies;\n }\n\n public serializeResponseCookies(\n cookies: Record<string, Cookie | null>,\n isHttps: boolean,\n ): string[] {\n const headers = [];\n\n for (const [name, cookie] of Object.entries(cookies)) {\n // If the cookie is null, we need to delete it\n if (cookie == null) {\n headers.push(`${name}=; Path=/; Max-Age=0`);\n continue;\n }\n\n if (!cookie.value) {\n continue;\n }\n\n headers.push(this.cookieToString(name, cookie, isHttps));\n }\n\n return headers;\n }\n\n public cookieToString(\n name: string,\n cookie: Cookie,\n isHttps?: boolean,\n ): string {\n const parts: string[] = [];\n\n parts.push(`${name}=${cookie.value}`);\n\n if (cookie.path) {\n parts.push(`Path=${cookie.path}`);\n }\n // `!= null`, not truthy: `maxAge: 0` is the standard \"delete this\n // cookie now\" value (used by AtomCookiePersistence.browser.ts's\n // clearCookie() and BrowserCookiePrimitive.del()). A truthy check would\n // silently drop `Max-Age` for exactly that value, turning a deletion\n // into a plain (non-expiring-until-session-end) write.\n if (cookie.maxAge != null) {\n parts.push(`Max-Age=${cookie.maxAge}`);\n }\n if (cookie.secure !== false && isHttps) {\n parts.push(\"Secure\");\n }\n if (cookie.httpOnly) {\n parts.push(\"HttpOnly\");\n }\n if (cookie.sameSite) {\n parts.push(`SameSite=${cookie.sameSite}`);\n }\n if (cookie.domain) {\n parts.push(`Domain=${cookie.domain}`);\n }\n\n return parts.join(\"; \");\n }\n}\n","import { $hook, $inject, Alepha, type Atom, type State } from \"alepha\";\nimport { DateTimeProvider } from \"alepha/datetime\";\nimport type { Cookie } from \"../primitives/$cookie.ts\";\nimport { CookieParser } from \"../services/CookieParser.ts\";\n\n/**\n * Browser variant of AtomCookiePersistence: reads `document.cookie` for every\n * `persist: \"cookie\"` atom, and writes it back on every mutation.\n *\n * Like the server variant, atoms are resolved from the `StateManager`\n * registry (`alepha.store.listAtoms()`) rather than from a map fed by\n * `state:register` — that event fires once, is never replayed, and\n * `$module.register()` registers `atoms[]` before the module's `services[]`\n * exist, so an event-sourced map would miss every atom declared the\n * documented way. The `configure` hook sweeps everything registered up to\n * boot; `state:register` covers atoms that first register later (lazily, on\n * first read).\n *\n * Cookie names are NOT APP_NAME-prefixed here, because `APP_NAME` is not\n * reachable in the browser: `BuildClientTask` only `define`s\n * `process.env.NODE_ENV` for the client bundle, and the SSR hydration\n * payload (`ReactServerTemplateProvider.buildHydrationData`) only carries\n * registered atom values + router layers — never the raw `env` store key.\n * The server variant (`AtomCookiePersistence.ts`) matches this by passing\n * `prefix: false` to `ServerCookiesProvider`, specifically for atom-cookie\n * traffic — every other server cookie ($cookie primitive) still gets the\n * APP_NAME namespace. See `ServerCookiesProvider.prefixName`.\n */\nexport class AtomCookiePersistence {\n protected readonly alepha = $inject(Alepha);\n protected readonly cookieParser = $inject(CookieParser);\n protected readonly dateTime = $inject(DateTimeProvider);\n\n protected readonly onConfigure = $hook({\n on: \"configure\",\n handler: () => {\n for (const atom of this.cookieAtoms()) {\n this.read(atom);\n }\n },\n });\n\n protected readonly onRegister = $hook({\n on: \"state:register\",\n handler: ({ atom }) => {\n if (atom.options.persist !== \"cookie\") {\n return;\n }\n this.read(atom);\n },\n });\n\n protected readonly onMutate = $hook({\n on: \"state:mutate\",\n handler: ({ key, value }) => {\n const atom = this.alepha.store.getAtom(String(key));\n if (!atom || atom.options.persist !== \"cookie\") {\n return;\n }\n\n if (value === undefined) {\n // Without this branch, `store.del(atom)` would write the literal\n // string \"undefined\", and the next read's `JSON.parse(\"undefined\")`\n // would throw into the catch in `read()` on every page load.\n this.clearCookie(atom.key);\n return;\n }\n\n const cookie: Cookie = {\n value: encodeURIComponent(JSON.stringify(value)),\n path: \"/\",\n sameSite: \"lax\",\n maxAge: this.dateTime.duration([365, \"days\"]).as(\"seconds\"),\n };\n // biome-ignore lint/suspicious/noDocumentCookie: cookie persistence adapter\n document.cookie = this.cookieParser.cookieToString(atom.key, cookie);\n },\n });\n\n /**\n * Every registered atom declared with `persist: \"cookie\"`, read live from\n * the state manager's registry.\n */\n protected cookieAtoms(): Array<Atom<any, any>> {\n return this.alepha.store\n .listAtoms()\n .filter((atom) => atom.options.persist === \"cookie\");\n }\n\n /**\n * Seed an atom's state from `document.cookie`, if a cookie exists for it.\n * Idempotent: re-reading an atom that already holds the cookie's value is\n * a no-op write of the same data.\n */\n protected read(atom: Atom<any, any>): void {\n const raw = this.cookieParser.parseRequestCookies(document.cookie)[\n atom.key\n ];\n if (!raw) {\n return;\n }\n\n try {\n this.alepha.store.set(\n atom.key as keyof State,\n JSON.parse(decodeURIComponent(raw)),\n { skipEvents: true },\n );\n } catch {\n // Corrupted cookie (invalid JSON/encoding, or a value that no longer\n // matches the atom's schema — `store.set` validates against it) —\n // clear it instead of leaving it to keep throwing on every future\n // read. Mirrors the web-storage adapter's parity\n // (StateManager.bindWebStorage removes the bad entry too).\n this.clearCookie(atom.key);\n }\n }\n\n /**\n * Expire a cookie immediately, mirroring\n * `ServerCookiesProvider.deleteCookie`'s `Max-Age=0` semantics.\n */\n protected clearCookie(name: string): void {\n const cookie: Cookie = {\n value: \"\",\n path: \"/\",\n sameSite: \"lax\",\n maxAge: 0,\n };\n // biome-ignore lint/suspicious/noDocumentCookie: cookie persistence adapter\n document.cookie = this.cookieParser.cookieToString(name, cookie);\n }\n}\n","import {\n $inject,\n Alepha,\n AlephaError,\n createPrimitive,\n KIND,\n Primitive,\n type Static,\n type TSchema,\n} from \"alepha\";\nimport { DateTimeProvider } from \"alepha/datetime\";\nimport { CookieParser } from \"../services/CookieParser.ts\";\nimport type {\n AbstractCookiePrimitive,\n Cookie,\n CookiePrimitiveOptions,\n Cookies,\n} from \"./$cookie.ts\";\n\n/**\n * Creates a browser-side cookie primitive for client-side cookie management.\n *\n * Browser-specific version of $cookie that uses document.cookie API. Supports type-safe\n * cookie operations with schema validation but excludes encryption/signing (use server-side\n * $cookie for secure operations).\n *\n * **Note**: This is the browser version - encryption, signing, and compression are not supported.\n *\n * @example\n * ```ts\n * class ClientCookies {\n * preferences = $cookie({\n * name: \"user-prefs\",\n * schema: z.object({ theme: z.text(), language: z.text() }),\n * ttl: [30, \"days\"]\n * });\n *\n * savePreferences() {\n * this.preferences.set({ theme: \"dark\", language: \"en\" });\n * }\n *\n * getPreferences() {\n * return this.preferences.get() ?? { theme: \"light\", language: \"en\" };\n * }\n * }\n * ```\n */\nexport const $cookie = <T extends TSchema>(\n options: CookiePrimitiveOptions<T>,\n extendedOptions?: Omit<CookiePrimitiveOptions<T>, \"schema\">,\n): AbstractCookiePrimitive<T> => {\n if (extendedOptions) {\n options = {\n key: options.key,\n schema: options.schema,\n ...extendedOptions,\n };\n }\n return createPrimitive(BrowserCookiePrimitive<T>, options);\n};\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport class BrowserCookiePrimitive<T extends TSchema>\n extends Primitive<CookiePrimitiveOptions<T>>\n implements AbstractCookiePrimitive<T>\n{\n protected cookieParser = $inject(CookieParser);\n protected alepha = $inject(Alepha);\n protected dateTimeProvider = $inject(DateTimeProvider);\n protected cookie?: Cookie;\n\n protected onInit() {\n if (this.options.key) {\n this.alepha.events.on(\"state:mutate\", ({ key, value }) => {\n if (key === this.options.key) {\n this.set(value);\n }\n });\n this.alepha.events.on(\"configure\", () => {\n try {\n const value = this.get();\n if (value !== undefined) {\n this.alepha.set(this.options.key as any, value);\n }\n } catch {}\n });\n }\n }\n\n public get schema(): T {\n return this.options.schema;\n }\n\n public get name(): string {\n return this.options.name ?? `${this.config.propertyKey}`;\n }\n\n public set(data: Static<T>): void {\n const value = JSON.stringify(this.alepha.codec.decode(this.schema, data));\n const options = this.options;\n\n if (options.compress) {\n throw new AlephaError(\"Compression is not supported in browser cookies.\");\n }\n\n if (options.encrypt) {\n throw new AlephaError(\"Encryption is not supported in browser cookies.\");\n }\n\n if (options.sign) {\n throw new AlephaError(\"Signing is not supported in browser cookies.\");\n }\n\n const cookie: Cookie = {\n value: encodeURIComponent(value),\n path: options.path ?? \"/\",\n sameSite: options.sameSite ?? \"lax\",\n secure: false,\n httpOnly: false,\n domain: options.domain,\n };\n\n if (options.ttl) {\n cookie.maxAge = this.dateTimeProvider.duration(options.ttl).as(\"seconds\");\n }\n\n // biome-ignore lint/suspicious/noDocumentCookie: ...\n document.cookie = this.cookieParser.cookieToString(this.name, cookie);\n }\n\n public get(options?: { cookies?: Cookies }): Static<T> | undefined {\n const cookie = this.cookieParser.parseRequestCookies(document.cookie)[\n this.name\n ];\n if (!cookie) {\n return undefined;\n }\n\n const rawValue = decodeURIComponent(cookie);\n\n if (this.options.compress) {\n throw new AlephaError(\"Compression is not supported in browser cookies.\");\n }\n\n if (this.options.encrypt) {\n throw new AlephaError(\"Encryption is not supported in browser cookies.\");\n }\n\n if (this.options.sign) {\n throw new AlephaError(\"Signing is not supported in browser cookies.\");\n }\n\n return this.alepha.codec.decode(this.schema, JSON.parse(rawValue));\n }\n\n public del(): void {\n const options = this.options;\n const cookie: Cookie = {\n value: \"\",\n path: options.path ?? \"/\",\n sameSite: options.sameSite ?? \"lax\",\n secure: false,\n httpOnly: false,\n domain: options.domain,\n maxAge: 0, // Set maxAge to 0 to delete the cookie\n };\n\n // biome-ignore lint/suspicious/noDocumentCookie: ...\n document.cookie = this.cookieParser.cookieToString(this.name, cookie);\n }\n}\n\n$cookie[KIND] = BrowserCookiePrimitive;\n","import { $module } from \"alepha\";\nimport { AlephaServer } from \"alepha/server\";\nimport { AtomCookiePersistence } from \"./providers/AtomCookiePersistence.browser.ts\";\nimport { CookieParser } from \"./services/CookieParser.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./primitives/$cookie.browser.ts\";\nexport * from \"./providers/AtomCookiePersistence.browser.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport const AlephaServerCookies = $module({\n name: \"alepha.server.cookies\",\n primitives: [],\n services: [AlephaServer, CookieParser, AtomCookiePersistence],\n});\n"],"mappings":"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"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { Alepha, KIND, Primitive, Static, TSchema } from "alepha";
|
|
1
|
+
import { Alepha, Atom, KIND, Primitive, Static, TSchema } from "alepha";
|
|
2
2
|
import { SecretProvider } from "alepha/crypto";
|
|
3
3
|
import { DateTimeProvider, DurationLike } from "alepha/datetime";
|
|
4
|
-
|
|
5
4
|
//#region ../../src/server/cookies/services/CookieParser.d.ts
|
|
6
5
|
declare class CookieParser {
|
|
7
6
|
parseRequestCookies(header: string): Record<string, string>;
|
|
@@ -24,9 +23,29 @@ declare class ServerCookiesProvider {
|
|
|
24
23
|
readonly onAction: import("alepha").HookPrimitive<"action:onRequest">;
|
|
25
24
|
readonly onSend: import("alepha").HookPrimitive<"server:onSend">;
|
|
26
25
|
protected getCookiesFromContext(cookies?: Cookies): Cookies;
|
|
26
|
+
/**
|
|
27
|
+
* Namespaces a cookie name with the app's `APP_NAME` (lowercased) so that
|
|
28
|
+
* two Alepha apps sharing a cookie jar do not collide.
|
|
29
|
+
*
|
|
30
|
+
* Cookies are scoped by host + path only — never by port — so two apps on
|
|
31
|
+
* `localhost:3000` and `localhost:4000` would otherwise both read/write a
|
|
32
|
+
* cookie literally named `tokens` and silently clobber each other (and,
|
|
33
|
+
* because each encrypts with its own `APP_SECRET`, the foreign cookie fails
|
|
34
|
+
* to decrypt and gets deleted, logging the user out).
|
|
35
|
+
*
|
|
36
|
+
* When `APP_NAME` is unset the name is returned unchanged, so existing
|
|
37
|
+
* single-app deployments keep their current cookie names. Same convention as
|
|
38
|
+
* the `APP_NAME` prefix used by R2 storage and server-timing.
|
|
39
|
+
*
|
|
40
|
+
* Pass `prefix = false` to skip the namespace entirely — used for
|
|
41
|
+
* `persist: "cookie"` atoms, whose browser-side counterpart cannot see
|
|
42
|
+
* `APP_NAME` and therefore always uses the bare name. See
|
|
43
|
+
* `CookiePrimitiveOptions.prefix`.
|
|
44
|
+
*/
|
|
45
|
+
protected prefixName(name: string, prefix?: boolean): string;
|
|
27
46
|
getCookie<T extends TSchema>(name: string, options: CookiePrimitiveOptions<T>, contextCookies?: Cookies): Static<T> | undefined;
|
|
28
47
|
setCookie<T extends TSchema>(name: string, options: CookiePrimitiveOptions<T>, data: Static<T>, contextCookies?: Cookies): void;
|
|
29
|
-
deleteCookie<T extends TSchema>(name: string, contextCookies?: Cookies): void;
|
|
48
|
+
deleteCookie<T extends TSchema>(name: string, contextCookies?: Cookies, prefix?: boolean): void;
|
|
30
49
|
protected encrypt(text: string): string;
|
|
31
50
|
protected decrypt(encryptedText: string): string;
|
|
32
51
|
/**
|
|
@@ -96,6 +115,21 @@ interface CookiePrimitiveOptions<T extends TSchema> {
|
|
|
96
115
|
* Optional key to link this cookie to an Atom, enabling automatic synchronization between the cookie and the Atom's state.
|
|
97
116
|
*/
|
|
98
117
|
key?: string;
|
|
118
|
+
/**
|
|
119
|
+
* Internal escape hatch: when explicitly set to `false`, the server skips
|
|
120
|
+
* the `APP_NAME` cookie-name namespace applied by
|
|
121
|
+
* `ServerCookiesProvider.prefixName()`.
|
|
122
|
+
*
|
|
123
|
+
* Used by `AtomCookiePersistence` so the cookie name the server
|
|
124
|
+
* reads/writes for a `persist: "cookie"` atom matches the bare name its
|
|
125
|
+
* browser variant uses — `APP_NAME` is not reachable client-side (not
|
|
126
|
+
* baked into the client bundle, not part of SSR hydration), so the
|
|
127
|
+
* browser can only ever use the bare atom key.
|
|
128
|
+
*
|
|
129
|
+
* Application code declaring `$cookie(...)` directly should leave this
|
|
130
|
+
* unset — it defaults to `true` (prefixed), matching every other cookie.
|
|
131
|
+
*/
|
|
132
|
+
prefix?: boolean;
|
|
99
133
|
}
|
|
100
134
|
interface AbstractCookiePrimitive<T extends TSchema> {
|
|
101
135
|
readonly name: string;
|
|
@@ -150,6 +184,54 @@ interface Cookie {
|
|
|
150
184
|
domain?: string;
|
|
151
185
|
}
|
|
152
186
|
//#endregion
|
|
187
|
+
//#region ../../src/server/cookies/providers/AtomCookiePersistence.d.ts
|
|
188
|
+
/**
|
|
189
|
+
* Binds every atom declared with `persist: "cookie"` to an HTTP cookie.
|
|
190
|
+
*
|
|
191
|
+
* - `server:onRequest` — seeds the request-scoped state from the cookie, so
|
|
192
|
+
* SSR renders with the persisted value.
|
|
193
|
+
* - `state:mutate` — writes the new value back as a Set-Cookie header.
|
|
194
|
+
* - `state:register` — an atom registering lazily *during* a request (first
|
|
195
|
+
* touched by an SSR render, after `server:onRequest` already ran) reads
|
|
196
|
+
* its cookie right away, so that render still sees the persisted value.
|
|
197
|
+
*
|
|
198
|
+
* Atoms are resolved from the `StateManager` registry
|
|
199
|
+
* (`alepha.store.listAtoms()`) on every request and every mutation, never
|
|
200
|
+
* from a map built up from `state:register` events. That event fires exactly
|
|
201
|
+
* once per atom and is never replayed, while `$module.register()` registers
|
|
202
|
+
* `atoms[]` BEFORE it wires `imports[]` and injects `services[]` — so the
|
|
203
|
+
* documented `$module({ atoms, imports: [AlephaServerCookies], services })`
|
|
204
|
+
* shape registers every atom before this provider exists. An event-sourced
|
|
205
|
+
* map would stay empty forever there, making `persist: "cookie"` a silent
|
|
206
|
+
* no-op in both directions. Reading the registry on demand is
|
|
207
|
+
* order-independent.
|
|
208
|
+
*
|
|
209
|
+
* The cookie is named after the atom key, lives 365 days, SameSite=lax,
|
|
210
|
+
* path "/". For custom cookie options (encryption, signing, custom TTL),
|
|
211
|
+
* declare an explicit `$cookie({ key: atom.key, ... })` binding instead.
|
|
212
|
+
*/
|
|
213
|
+
declare class AtomCookiePersistence {
|
|
214
|
+
protected readonly alepha: Alepha;
|
|
215
|
+
protected readonly log: import("alepha/logger").Logger;
|
|
216
|
+
protected readonly serverCookies: ServerCookiesProvider;
|
|
217
|
+
protected readonly onRequest: import("alepha").HookPrimitive<"server:onRequest">;
|
|
218
|
+
protected readonly onRegister: import("alepha").HookPrimitive<"state:register">;
|
|
219
|
+
protected readonly onMutate: import("alepha").HookPrimitive<"state:mutate">;
|
|
220
|
+
/**
|
|
221
|
+
* Every registered atom declared with `persist: "cookie"`, read live from
|
|
222
|
+
* the state manager's registry.
|
|
223
|
+
*/
|
|
224
|
+
protected cookieAtoms(): Array<Atom<any, any>>;
|
|
225
|
+
protected read(atom: Atom<any, any>, cookies?: Cookies): void;
|
|
226
|
+
protected cookieOptions(atom: Atom<any, any>): {
|
|
227
|
+
schema: any;
|
|
228
|
+
path: string;
|
|
229
|
+
sameSite: "lax";
|
|
230
|
+
ttl: DurationLike;
|
|
231
|
+
prefix: boolean;
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
//#endregion
|
|
153
235
|
//#region ../../src/server/cookies/index.d.ts
|
|
154
236
|
declare module "alepha/server" {
|
|
155
237
|
interface ServerRequest {
|
|
@@ -166,5 +248,5 @@ declare module "alepha/server" {
|
|
|
166
248
|
*/
|
|
167
249
|
declare const AlephaServerCookies: import("alepha").Service<import("alepha").Module>;
|
|
168
250
|
//#endregion
|
|
169
|
-
export { $cookie, AbstractCookiePrimitive, AlephaServerCookies, Cookie, CookiePrimitive, CookiePrimitiveOptions, Cookies, ServerCookiesProvider };
|
|
251
|
+
export { $cookie, AbstractCookiePrimitive, AlephaServerCookies, AtomCookiePersistence, Cookie, CookiePrimitive, CookiePrimitiveOptions, Cookies, ServerCookiesProvider };
|
|
170
252
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/server/cookies/services/CookieParser.ts","../../../src/server/cookies/providers/ServerCookiesProvider.ts","../../../src/server/cookies/primitives/$cookie.ts","../../../src/server/cookies/index.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/server/cookies/services/CookieParser.ts","../../../src/server/cookies/providers/ServerCookiesProvider.ts","../../../src/server/cookies/primitives/$cookie.ts","../../../src/server/cookies/providers/AtomCookiePersistence.ts","../../../src/server/cookies/index.ts"],"mappings":";;;;cAEa;EACJ,oBAAoB,iBAAiB;EAsBrC,yBACL,SAAS,eAAe,gBACxB;EAqBK,eACL,cACA,QAAQ,QACR;;;;cCxBS;qBACQ,QAAM;qBACN,6BAAG;qBACH,cAAY;qBACZ,kBAAgB;qBAChB,gBAAc;qBAGd;qBACA;qBACA;qBACA;WAEH,4BAAS;WAYT,2BAAQ;WAYR,yBAAM;YAeZ,sBAAsB,UAAU,UAAU;;;;;;;;;;;;;;;;;;;;YA8B1C,WAAW,cAAc;EAO5B,UAAU,UAAU,SACzB,cACA,SAAS,uBAAuB,IAChC,iBAAiB,UAChB,OAAO;EA8CH,UAAU,UAAU,SACzB,cACA,SAAS,uBAAuB,IAChC,MAAM,OAAO,IACb,iBAAiB;EAoCZ,aAAa,UAAU,SAC5B,cACA,iBAAiB,SACjB;YAQQ,QAAQ;YAWR,QAAQ;;;;;YAyBR,aAAa;YAIb,KAAK;;;;;;;;;cCjPJ;GAAW,UAAU,SAAO,SAC9B,uBAAuB,IAAE,kBAChB,KAAK,uBAAuB,gBAC7C,wBAAwB;;;UAaV,uBAAuB,UAAU;;;;EAIhD,QAAQ;;;;EAKR;;;;EAKA;;;;EAKA,MAAM;;;;EAKN;;;;EAKA;;;;EAKA;;;;EAKA;;;;EAKA;;;;EAKA;;;;EAKA;;;;EAKA;;;;;;;;;;;;;;;EAgBA;;UAGe,wBAAwB,UAAU;WACxC;WACA,SAAS,uBAAuB;EACzC,IACE,OAAO,OAAO,IACd;IAAY,UAAU;IAAS,MAAM;;EAEvC,IAAI;IAAY,UAAU;MAAY,OAAO;EAC7C,IAAI;IAAY,UAAU;;;cAGf,gBAAgB,UAAU,iBAC7B,UAAU,uBAAuB,eAC9B,wBAAwB;qBAEhB,uBAAqB;YAE9B;MAoBC,UAAU;MAIV;;;;EAOJ,IACL,OAAO,OAAO,IACd;IAAY,UAAU;IAAS,MAAM;;;;;EAgBhC,IAAI;IAAY,UAAU;MAAY,OAAO;;;;EAW7C,IAAI;IAAY,UAAU;;;UASlB;EACf,KAAK;EACL,KAAK,eAAe;;UAGL;EACf;EACA;EACA;EACA;EACA;EACA;EACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cCjLW;qBACQ,QAAM;qBACN,6BAAG;qBACH,eAAa;qBAEb,4BAAS;qBAmBT,6BAAU;qBAeV,2BAAQ;;;;;YAwBjB,eAAe,MAAM;YAMrB,KAAK,MAAM,gBAAgB,UAAU;YA+BrC,cAAc,MAAM;IAE1B;IACA;IACA;IACA,KAAsB;IAQtB;;;;;;YChIM;IACR,SAAS;;;;;;;;;;;cAYA,sCAAmB,yBAAA"}
|
|
@@ -36,7 +36,7 @@ var CookieParser = class {
|
|
|
36
36
|
const parts = [];
|
|
37
37
|
parts.push(`${name}=${cookie.value}`);
|
|
38
38
|
if (cookie.path) parts.push(`Path=${cookie.path}`);
|
|
39
|
-
if (cookie.maxAge) parts.push(`Max-Age=${cookie.maxAge}`);
|
|
39
|
+
if (cookie.maxAge != null) parts.push(`Max-Age=${cookie.maxAge}`);
|
|
40
40
|
if (cookie.secure !== false && isHttps) parts.push("Secure");
|
|
41
41
|
if (cookie.httpOnly) parts.push("HttpOnly");
|
|
42
42
|
if (cookie.sameSite) parts.push(`SameSite=${cookie.sameSite}`);
|
|
@@ -89,9 +89,35 @@ var ServerCookiesProvider = class {
|
|
|
89
89
|
if (contextCookies) return contextCookies;
|
|
90
90
|
throw new AlephaError("Cookie context is not available. This method must be called within a server request cycle.");
|
|
91
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Namespaces a cookie name with the app's `APP_NAME` (lowercased) so that
|
|
94
|
+
* two Alepha apps sharing a cookie jar do not collide.
|
|
95
|
+
*
|
|
96
|
+
* Cookies are scoped by host + path only — never by port — so two apps on
|
|
97
|
+
* `localhost:3000` and `localhost:4000` would otherwise both read/write a
|
|
98
|
+
* cookie literally named `tokens` and silently clobber each other (and,
|
|
99
|
+
* because each encrypts with its own `APP_SECRET`, the foreign cookie fails
|
|
100
|
+
* to decrypt and gets deleted, logging the user out).
|
|
101
|
+
*
|
|
102
|
+
* When `APP_NAME` is unset the name is returned unchanged, so existing
|
|
103
|
+
* single-app deployments keep their current cookie names. Same convention as
|
|
104
|
+
* the `APP_NAME` prefix used by R2 storage and server-timing.
|
|
105
|
+
*
|
|
106
|
+
* Pass `prefix = false` to skip the namespace entirely — used for
|
|
107
|
+
* `persist: "cookie"` atoms, whose browser-side counterpart cannot see
|
|
108
|
+
* `APP_NAME` and therefore always uses the bare name. See
|
|
109
|
+
* `CookiePrimitiveOptions.prefix`.
|
|
110
|
+
*/
|
|
111
|
+
prefixName(name, prefix = true) {
|
|
112
|
+
if (!prefix) return name;
|
|
113
|
+
const app = this.alepha.env.APP_NAME;
|
|
114
|
+
if (!app) return name;
|
|
115
|
+
return `${String(app).toLowerCase()}.${name}`;
|
|
116
|
+
}
|
|
92
117
|
getCookie(name, options, contextCookies) {
|
|
93
118
|
const cookies = this.getCookiesFromContext(contextCookies);
|
|
94
|
-
|
|
119
|
+
const prefixed = options.prefix !== false;
|
|
120
|
+
let rawValue = cookies.req[this.prefixName(name, prefixed)];
|
|
95
121
|
if (!rawValue) return void 0;
|
|
96
122
|
try {
|
|
97
123
|
rawValue = decodeURIComponent(rawValue);
|
|
@@ -110,7 +136,7 @@ var ServerCookiesProvider = class {
|
|
|
110
136
|
return this.alepha.codec.decode(options.schema, JSON.parse(rawValue));
|
|
111
137
|
} catch (error) {
|
|
112
138
|
this.log.warn(`Failed to parse cookie "${name}"`, error);
|
|
113
|
-
this.deleteCookie(name, cookies);
|
|
139
|
+
this.deleteCookie(name, cookies, prefixed);
|
|
114
140
|
return;
|
|
115
141
|
}
|
|
116
142
|
}
|
|
@@ -129,11 +155,11 @@ var ServerCookiesProvider = class {
|
|
|
129
155
|
domain: options.domain
|
|
130
156
|
};
|
|
131
157
|
if (options.ttl) cookie.maxAge = this.dateTimeProvider.duration(options.ttl).as("seconds");
|
|
132
|
-
cookies.res[name] = cookie;
|
|
158
|
+
cookies.res[this.prefixName(name, options.prefix !== false)] = cookie;
|
|
133
159
|
}
|
|
134
|
-
deleteCookie(name, contextCookies) {
|
|
160
|
+
deleteCookie(name, contextCookies, prefix = true) {
|
|
135
161
|
const cookies = this.getCookiesFromContext(contextCookies);
|
|
136
|
-
cookies.res[name] = null;
|
|
162
|
+
cookies.res[this.prefixName(name, prefix)] = null;
|
|
137
163
|
}
|
|
138
164
|
encrypt(text) {
|
|
139
165
|
const iv = randomBytes(this.IV_LENGTH);
|
|
@@ -226,6 +252,92 @@ var CookiePrimitive = class extends Primitive {
|
|
|
226
252
|
};
|
|
227
253
|
$cookie[KIND] = CookiePrimitive;
|
|
228
254
|
//#endregion
|
|
255
|
+
//#region ../../src/server/cookies/providers/AtomCookiePersistence.ts
|
|
256
|
+
/**
|
|
257
|
+
* Binds every atom declared with `persist: "cookie"` to an HTTP cookie.
|
|
258
|
+
*
|
|
259
|
+
* - `server:onRequest` — seeds the request-scoped state from the cookie, so
|
|
260
|
+
* SSR renders with the persisted value.
|
|
261
|
+
* - `state:mutate` — writes the new value back as a Set-Cookie header.
|
|
262
|
+
* - `state:register` — an atom registering lazily *during* a request (first
|
|
263
|
+
* touched by an SSR render, after `server:onRequest` already ran) reads
|
|
264
|
+
* its cookie right away, so that render still sees the persisted value.
|
|
265
|
+
*
|
|
266
|
+
* Atoms are resolved from the `StateManager` registry
|
|
267
|
+
* (`alepha.store.listAtoms()`) on every request and every mutation, never
|
|
268
|
+
* from a map built up from `state:register` events. That event fires exactly
|
|
269
|
+
* once per atom and is never replayed, while `$module.register()` registers
|
|
270
|
+
* `atoms[]` BEFORE it wires `imports[]` and injects `services[]` — so the
|
|
271
|
+
* documented `$module({ atoms, imports: [AlephaServerCookies], services })`
|
|
272
|
+
* shape registers every atom before this provider exists. An event-sourced
|
|
273
|
+
* map would stay empty forever there, making `persist: "cookie"` a silent
|
|
274
|
+
* no-op in both directions. Reading the registry on demand is
|
|
275
|
+
* order-independent.
|
|
276
|
+
*
|
|
277
|
+
* The cookie is named after the atom key, lives 365 days, SameSite=lax,
|
|
278
|
+
* path "/". For custom cookie options (encryption, signing, custom TTL),
|
|
279
|
+
* declare an explicit `$cookie({ key: atom.key, ... })` binding instead.
|
|
280
|
+
*/
|
|
281
|
+
var AtomCookiePersistence = class {
|
|
282
|
+
alepha = $inject(Alepha);
|
|
283
|
+
log = $logger();
|
|
284
|
+
serverCookies = $inject(ServerCookiesProvider);
|
|
285
|
+
onRequest = $hook({
|
|
286
|
+
on: "server:onRequest",
|
|
287
|
+
after: [this.serverCookies],
|
|
288
|
+
handler: ({ request }) => {
|
|
289
|
+
for (const atom of this.cookieAtoms()) this.read(atom, request.cookies);
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
onRegister = $hook({
|
|
293
|
+
on: "state:register",
|
|
294
|
+
handler: ({ atom }) => {
|
|
295
|
+
if (atom.options.persist !== "cookie") return;
|
|
296
|
+
if (this.alepha.store.get("alepha.http.request")) this.read(atom);
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
onMutate = $hook({
|
|
300
|
+
on: "state:mutate",
|
|
301
|
+
handler: ({ key, value }) => {
|
|
302
|
+
const atom = this.alepha.store.getAtom(String(key));
|
|
303
|
+
if (!atom || atom.options.persist !== "cookie") return;
|
|
304
|
+
try {
|
|
305
|
+
this.serverCookies.setCookie(atom.key, this.cookieOptions(atom), value);
|
|
306
|
+
} catch (error) {
|
|
307
|
+
this.log.debug(`Cannot persist atom "${atom.key}" to cookie`, { error });
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
/**
|
|
312
|
+
* Every registered atom declared with `persist: "cookie"`, read live from
|
|
313
|
+
* the state manager's registry.
|
|
314
|
+
*/
|
|
315
|
+
cookieAtoms() {
|
|
316
|
+
return this.alepha.store.listAtoms().filter((atom) => atom.options.persist === "cookie");
|
|
317
|
+
}
|
|
318
|
+
read(atom, cookies) {
|
|
319
|
+
if (!this.alepha.context.exists()) {
|
|
320
|
+
this.log.debug(`Skipping cookie read for atom "${atom.key}": no active request context.`);
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
try {
|
|
324
|
+
const value = this.serverCookies.getCookie(atom.key, this.cookieOptions(atom), cookies);
|
|
325
|
+
if (value !== void 0) this.alepha.store.set(atom.key, value, { skipEvents: true });
|
|
326
|
+
} catch (error) {
|
|
327
|
+
this.log.debug(`Cannot read cookie for atom "${atom.key}"`, { error });
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
cookieOptions(atom) {
|
|
331
|
+
return {
|
|
332
|
+
schema: atom.schema,
|
|
333
|
+
path: "/",
|
|
334
|
+
sameSite: "lax",
|
|
335
|
+
ttl: [365, "days"],
|
|
336
|
+
prefix: false
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
//#endregion
|
|
229
341
|
//#region ../../src/server/cookies/index.ts
|
|
230
342
|
/**
|
|
231
343
|
* Server and browser-safe cookie handling.
|
|
@@ -241,10 +353,11 @@ const AlephaServerCookies = $module({
|
|
|
241
353
|
services: [
|
|
242
354
|
AlephaServer,
|
|
243
355
|
ServerCookiesProvider,
|
|
244
|
-
CookieParser
|
|
356
|
+
CookieParser,
|
|
357
|
+
AtomCookiePersistence
|
|
245
358
|
]
|
|
246
359
|
});
|
|
247
360
|
//#endregion
|
|
248
|
-
export { $cookie, AlephaServerCookies, CookiePrimitive, ServerCookiesProvider };
|
|
361
|
+
export { $cookie, AlephaServerCookies, AtomCookiePersistence, CookiePrimitive, ServerCookiesProvider };
|
|
249
362
|
|
|
250
363
|
//# sourceMappingURL=index.js.map
|