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
|
@@ -19,6 +19,20 @@ export interface ErrorBoundaryProps {
|
|
|
19
19
|
* Use this to log errors to a monitoring service.
|
|
20
20
|
*/
|
|
21
21
|
onError?: (error: Error, info: ErrorInfo) => void;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Clear a caught error whenever any of these values changes (compared with
|
|
25
|
+
* `Object.is`, positionally).
|
|
26
|
+
*
|
|
27
|
+
* A boundary that catches has to be told when the reason to fail is gone —
|
|
28
|
+
* otherwise the fallback latches and every later render keeps showing the
|
|
29
|
+
* stale error. The router passes the current path, so navigating away from a
|
|
30
|
+
* page that threw recovers on its own.
|
|
31
|
+
*
|
|
32
|
+
* Unlike remounting via `key`, this clears the error WITHOUT tearing down the
|
|
33
|
+
* children, so unrelated component state survives an ordinary navigation.
|
|
34
|
+
*/
|
|
35
|
+
resetKeys?: readonly unknown[];
|
|
22
36
|
}
|
|
23
37
|
|
|
24
38
|
/**
|
|
@@ -61,6 +75,34 @@ export class ErrorBoundary extends React.Component<
|
|
|
61
75
|
}
|
|
62
76
|
}
|
|
63
77
|
|
|
78
|
+
/**
|
|
79
|
+
* Recover once the caller signals the failing input is gone.
|
|
80
|
+
*/
|
|
81
|
+
componentDidUpdate(prevProps: PropsWithChildren<ErrorBoundaryProps>): void {
|
|
82
|
+
if (!this.state.error) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (this.hasResetKeyChanged(prevProps.resetKeys, this.props.resetKeys)) {
|
|
87
|
+
this.setState({ error: undefined });
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
protected hasResetKeyChanged(
|
|
92
|
+
previous: readonly unknown[] | undefined,
|
|
93
|
+
next: readonly unknown[] | undefined,
|
|
94
|
+
): boolean {
|
|
95
|
+
if (previous === next) {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (!previous || !next || previous.length !== next.length) {
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return previous.some((value, i) => !Object.is(value, next[i]));
|
|
104
|
+
}
|
|
105
|
+
|
|
64
106
|
render(): ReactNode {
|
|
65
107
|
if (this.state.error) {
|
|
66
108
|
const reset = () => {
|
|
@@ -133,6 +133,10 @@ export function useAction<Args extends any[], Result = void>(
|
|
|
133
133
|
const abortControllerRef = useRef<AbortController | undefined>(undefined);
|
|
134
134
|
const isMountedRef = useRef(true);
|
|
135
135
|
const intervalRef = useRef<Interval | undefined>(undefined);
|
|
136
|
+
// Monotonic id of the latest run. A superseded run keeps executing until its
|
|
137
|
+
// abort lands, so every state write is gated on "am I still the latest?" —
|
|
138
|
+
// otherwise the stale run's `finally` would clear the newer run's `loading`.
|
|
139
|
+
const runIdRef = useRef(0);
|
|
136
140
|
|
|
137
141
|
// Track mount state — must set true in body for React StrictMode double-invoke
|
|
138
142
|
useEffect(() => {
|
|
@@ -171,13 +175,21 @@ export function useAction<Args extends any[], Result = void>(
|
|
|
171
175
|
}, []);
|
|
172
176
|
|
|
173
177
|
const executeAction = useCallback(
|
|
174
|
-
async (
|
|
175
|
-
|
|
176
|
-
|
|
178
|
+
async (
|
|
179
|
+
args: Args,
|
|
180
|
+
{ supersede = false }: { supersede?: boolean } = {},
|
|
181
|
+
): Promise<Result | undefined> => {
|
|
182
|
+
if (isExecutingRef.current && !supersede) {
|
|
183
|
+
// A manual `run()` must not fire twice — this is what stops a
|
|
184
|
+
// double-clicked mutation from being submitted twice.
|
|
177
185
|
return;
|
|
178
186
|
}
|
|
179
187
|
|
|
180
|
-
//
|
|
188
|
+
// A dep-change or interval run supersedes: the in-flight request was
|
|
189
|
+
// issued for inputs that are now stale, so its result must never win.
|
|
190
|
+
// (This is why the guard above is skipped rather than short-circuiting —
|
|
191
|
+
// otherwise `useQuery([userId])` whose `userId` changes mid-flight would
|
|
192
|
+
// never refetch, and the old user's data would stay on screen.)
|
|
181
193
|
if (abortControllerRef.current) {
|
|
182
194
|
abortControllerRef.current.abort();
|
|
183
195
|
}
|
|
@@ -186,6 +198,9 @@ export function useAction<Args extends any[], Result = void>(
|
|
|
186
198
|
const abortController = new AbortController();
|
|
187
199
|
abortControllerRef.current = abortController;
|
|
188
200
|
|
|
201
|
+
const runId = ++runIdRef.current;
|
|
202
|
+
const isLatestRun = () => runIdRef.current === runId;
|
|
203
|
+
|
|
189
204
|
isExecutingRef.current = true;
|
|
190
205
|
setLoading(true);
|
|
191
206
|
setError(undefined);
|
|
@@ -200,8 +215,12 @@ export function useAction<Args extends any[], Result = void>(
|
|
|
200
215
|
signal: abortController.signal,
|
|
201
216
|
} as any);
|
|
202
217
|
|
|
203
|
-
// Only update state if still mounted and not
|
|
204
|
-
if (
|
|
218
|
+
// Only update state if still mounted, not aborted, and not superseded
|
|
219
|
+
if (
|
|
220
|
+
!isMountedRef.current ||
|
|
221
|
+
abortController.signal.aborted ||
|
|
222
|
+
!isLatestRun()
|
|
223
|
+
) {
|
|
205
224
|
return;
|
|
206
225
|
}
|
|
207
226
|
|
|
@@ -223,8 +242,8 @@ export function useAction<Args extends any[], Result = void>(
|
|
|
223
242
|
return;
|
|
224
243
|
}
|
|
225
244
|
|
|
226
|
-
// Only update state if still mounted
|
|
227
|
-
if (!isMountedRef.current) {
|
|
245
|
+
// Only update state if still mounted and not superseded
|
|
246
|
+
if (!isMountedRef.current || !isLatestRun()) {
|
|
228
247
|
return;
|
|
229
248
|
}
|
|
230
249
|
|
|
@@ -246,9 +265,13 @@ export function useAction<Args extends any[], Result = void>(
|
|
|
246
265
|
// fire-and-forget `action.run()` calls from producing unhandled
|
|
247
266
|
// promise rejections.
|
|
248
267
|
} finally {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
268
|
+
// A superseded run must not release the guard or drop `loading` — the
|
|
269
|
+
// run that replaced it is still in flight.
|
|
270
|
+
if (isLatestRun()) {
|
|
271
|
+
isExecutingRef.current = false;
|
|
272
|
+
if (isMountedRef.current) {
|
|
273
|
+
setLoading(false);
|
|
274
|
+
}
|
|
252
275
|
}
|
|
253
276
|
|
|
254
277
|
await alepha.events.emit("react:action:end", {
|
|
@@ -265,8 +288,11 @@ export function useAction<Args extends any[], Result = void>(
|
|
|
265
288
|
[...deps, options.id, options.onError, options.onSuccess],
|
|
266
289
|
);
|
|
267
290
|
|
|
268
|
-
const
|
|
269
|
-
async (
|
|
291
|
+
const runAction = useCallback(
|
|
292
|
+
async (
|
|
293
|
+
args: Args,
|
|
294
|
+
options_: { supersede?: boolean } = {},
|
|
295
|
+
): Promise<Result | undefined> => {
|
|
270
296
|
if (options.debounce) {
|
|
271
297
|
// clear existing timer
|
|
272
298
|
if (debounceTimerRef.current) {
|
|
@@ -277,7 +303,7 @@ export function useAction<Args extends any[], Result = void>(
|
|
|
277
303
|
return new Promise((resolve) => {
|
|
278
304
|
debounceTimerRef.current = dateTimeProvider.createTimeout(
|
|
279
305
|
async () => {
|
|
280
|
-
const result = await executeAction(
|
|
306
|
+
const result = await executeAction(args, options_);
|
|
281
307
|
resolve(result);
|
|
282
308
|
},
|
|
283
309
|
options.debounce ?? 0,
|
|
@@ -285,11 +311,20 @@ export function useAction<Args extends any[], Result = void>(
|
|
|
285
311
|
});
|
|
286
312
|
}
|
|
287
313
|
|
|
288
|
-
return executeAction(
|
|
314
|
+
return executeAction(args, options_);
|
|
289
315
|
},
|
|
290
316
|
[executeAction, options.debounce],
|
|
291
317
|
);
|
|
292
318
|
|
|
319
|
+
/**
|
|
320
|
+
* Public `run()` — a user-initiated call. Deduped while one is in flight so a
|
|
321
|
+
* double-clicked mutation submits once.
|
|
322
|
+
*/
|
|
323
|
+
const handler = useCallback(
|
|
324
|
+
(...args: Args): Promise<Result | undefined> => runAction(args),
|
|
325
|
+
[runAction],
|
|
326
|
+
);
|
|
327
|
+
|
|
293
328
|
const cancel = useCallback(() => {
|
|
294
329
|
// clear debounce timer
|
|
295
330
|
if (debounceTimerRef.current) {
|
|
@@ -310,10 +345,12 @@ export function useAction<Args extends any[], Result = void>(
|
|
|
310
345
|
}
|
|
311
346
|
}, []);
|
|
312
347
|
|
|
313
|
-
// Run action on mount
|
|
348
|
+
// Run action on mount, and again whenever `deps` change. These runs supersede
|
|
349
|
+
// an in-flight request: it was issued for the previous deps, so its result is
|
|
350
|
+
// already stale.
|
|
314
351
|
useEffect(() => {
|
|
315
352
|
if (options.runOnInit) {
|
|
316
|
-
|
|
353
|
+
runAction([] as any, { supersede: true });
|
|
317
354
|
}
|
|
318
355
|
}, deps);
|
|
319
356
|
|
|
@@ -325,7 +362,7 @@ export function useAction<Args extends any[], Result = void>(
|
|
|
325
362
|
|
|
326
363
|
// Set up interval
|
|
327
364
|
intervalRef.current = dateTimeProvider.createInterval(
|
|
328
|
-
() =>
|
|
365
|
+
() => runAction([] as any, { supersede: true }),
|
|
329
366
|
options.runEvery,
|
|
330
367
|
true,
|
|
331
368
|
);
|
|
@@ -337,7 +374,7 @@ export function useAction<Args extends any[], Result = void>(
|
|
|
337
374
|
intervalRef.current = undefined;
|
|
338
375
|
}
|
|
339
376
|
};
|
|
340
|
-
}, [
|
|
377
|
+
}, [runAction, options.runEvery]);
|
|
341
378
|
|
|
342
379
|
return {
|
|
343
380
|
run: handler,
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { Computed } from "alepha";
|
|
2
|
+
import { useCallback, useRef, useSyncExternalStore } from "react";
|
|
3
|
+
import { useAlepha } from "./useAlepha.ts";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Subscribes to a `$computed` value.
|
|
7
|
+
*
|
|
8
|
+
* `getSnapshot` always reads the dependency atoms **live** off the store —
|
|
9
|
+
* never through a subscription-set dirty flag. A dirty flag is only ever
|
|
10
|
+
* flipped by the `state:mutate` listener registered in `subscribe`, which
|
|
11
|
+
* React wires up in a passive effect (after commit); `EventManager.emit` is
|
|
12
|
+
* async on top of that. A mutation dispatched between the initial render and
|
|
13
|
+
* that effect committing would be invisible to the flag, so `getSnapshot`
|
|
14
|
+
* (including React's own post-subscribe consistency re-check) would keep
|
|
15
|
+
* returning the stale pre-mutation value. See `useStore.ts` and
|
|
16
|
+
* `useSelector.ts` for the same rationale.
|
|
17
|
+
*
|
|
18
|
+
* Referential stability for `useSyncExternalStore` comes from comparing the
|
|
19
|
+
* *inputs* (the resolved values of the computed's transitive atom
|
|
20
|
+
* dependencies) by identity, not from caching on a mount-time ref: when none
|
|
21
|
+
* of the inputs changed since the last snapshot, the previous output
|
|
22
|
+
* reference is returned as-is; when any input changed (or `target` itself
|
|
23
|
+
* was swapped for a different `Computed`), the value is recomputed and a new
|
|
24
|
+
* reference is cached.
|
|
25
|
+
*
|
|
26
|
+
* A `Computed` passed here should be declared at module scope, like an
|
|
27
|
+
* atom — constructing one inline in a component body creates a new
|
|
28
|
+
* instance every render, which (because `subscribe`/`getSnapshot` are keyed
|
|
29
|
+
* on `target.key`, matching `useStore`/`useSelector`) is tolerated for
|
|
30
|
+
* resubscription purposes, but any closures captured by that instance's
|
|
31
|
+
* `get()` will be locked to whichever render first created the subscription
|
|
32
|
+
* until `target.key` itself changes.
|
|
33
|
+
*
|
|
34
|
+
* ```tsx
|
|
35
|
+
* const total = useComputed(cartTotal);
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
function useComputed<R>(target: Computed<R>): R {
|
|
39
|
+
const alepha = useAlepha();
|
|
40
|
+
const key = target.key;
|
|
41
|
+
|
|
42
|
+
// A ref, not state: the cached snapshot must survive re-renders without
|
|
43
|
+
// scheduling them. It exists purely to give `useSyncExternalStore` a
|
|
44
|
+
// stable reference when the resolved dependency values haven't changed —
|
|
45
|
+
// it is never the source of truth for staleness (see rationale above).
|
|
46
|
+
const cache = useRef<{
|
|
47
|
+
target: Computed<R>;
|
|
48
|
+
inputs: unknown[];
|
|
49
|
+
value: R;
|
|
50
|
+
} | null>(null);
|
|
51
|
+
|
|
52
|
+
const subscribe = useCallback(
|
|
53
|
+
(onStoreChange: () => void) => {
|
|
54
|
+
if (!alepha.isBrowser()) {
|
|
55
|
+
return () => {};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const keys = new Set(target.keys());
|
|
59
|
+
return alepha.events.on("state:mutate", (ev) => {
|
|
60
|
+
if (keys.has(ev.key as string)) {
|
|
61
|
+
onStoreChange();
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
},
|
|
65
|
+
[alepha, key],
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
const getSnapshot = useCallback((): R => {
|
|
69
|
+
const inputs = target
|
|
70
|
+
.keys()
|
|
71
|
+
.map((depKey) => alepha.store.get(depKey as any));
|
|
72
|
+
|
|
73
|
+
const prev = cache.current;
|
|
74
|
+
if (
|
|
75
|
+
prev &&
|
|
76
|
+
prev.target === target &&
|
|
77
|
+
prev.inputs.length === inputs.length &&
|
|
78
|
+
prev.inputs.every((value, index) => Object.is(value, inputs[index]))
|
|
79
|
+
) {
|
|
80
|
+
return prev.value;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const value = alepha.store.get(target);
|
|
84
|
+
cache.current = { target, inputs, value };
|
|
85
|
+
return value;
|
|
86
|
+
}, [alepha, key]);
|
|
87
|
+
|
|
88
|
+
return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export { useComputed };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { Atom, Static, TAtomObject } from "alepha";
|
|
2
|
+
import { useCallback, useRef, useSyncExternalStore } from "react";
|
|
3
|
+
import { useAlepha } from "./useAlepha.ts";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Subscribes to a slice of an atom's state.
|
|
7
|
+
*
|
|
8
|
+
* Unlike {@link useStore}, which re-renders on every mutation of the atom,
|
|
9
|
+
* `useSelector` re-renders only when the selected slice actually changes
|
|
10
|
+
* according to `equality` (default: `Object.is`). Pass {@link shallowEqual}
|
|
11
|
+
* when the selector builds a fresh object on each call.
|
|
12
|
+
*
|
|
13
|
+
* ```tsx
|
|
14
|
+
* const theme = useSelector(uiAtom, (s) => s.theme);
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
function useSelector<T extends TAtomObject, R>(
|
|
18
|
+
target: Atom<T>,
|
|
19
|
+
select: (state: Static<T>) => R,
|
|
20
|
+
equality: (a: R, b: R) => boolean = Object.is,
|
|
21
|
+
): R {
|
|
22
|
+
const alepha = useAlepha();
|
|
23
|
+
const key = target.key;
|
|
24
|
+
|
|
25
|
+
// Refs, not state: the memoized snapshot must survive re-renders without
|
|
26
|
+
// scheduling them, and `getSnapshot` must return a referentially stable
|
|
27
|
+
// value for unchanged slices or `useSyncExternalStore` re-renders forever.
|
|
28
|
+
const cache = useRef<{ input: unknown; selected: R } | null>(null);
|
|
29
|
+
const selectRef = useRef(select);
|
|
30
|
+
selectRef.current = select;
|
|
31
|
+
const equalityRef = useRef(equality);
|
|
32
|
+
equalityRef.current = equality;
|
|
33
|
+
|
|
34
|
+
const subscribe = useCallback(
|
|
35
|
+
(onStoreChange: () => void) => {
|
|
36
|
+
if (!alepha.isBrowser()) {
|
|
37
|
+
return () => {};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return alepha.events.on("state:mutate", (ev) => {
|
|
41
|
+
if (ev.key === key) {
|
|
42
|
+
onStoreChange();
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
},
|
|
46
|
+
[alepha, key],
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
const getSnapshot = useCallback(() => {
|
|
50
|
+
const input = alepha.store.get(target);
|
|
51
|
+
const prev = cache.current;
|
|
52
|
+
if (prev && Object.is(prev.input, input)) {
|
|
53
|
+
return prev.selected;
|
|
54
|
+
}
|
|
55
|
+
const selected = selectRef.current(input);
|
|
56
|
+
if (prev && equalityRef.current(prev.selected, selected)) {
|
|
57
|
+
cache.current = { input, selected: prev.selected };
|
|
58
|
+
return prev.selected;
|
|
59
|
+
}
|
|
60
|
+
cache.current = { input, selected };
|
|
61
|
+
return selected;
|
|
62
|
+
}, [alepha, key]);
|
|
63
|
+
|
|
64
|
+
return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export { useSelector };
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import type { State, Static, TAtomObject } from "alepha";
|
|
2
2
|
import { Atom } from "alepha";
|
|
3
|
-
import {
|
|
3
|
+
import { useCallback, useMemo, useSyncExternalStore } from "react";
|
|
4
4
|
import { useAlepha } from "./useAlepha.ts";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Hook to access and mutate the Alepha state.
|
|
8
|
+
*
|
|
9
|
+
* Reads through `useSyncExternalStore`, so the store — not a `useState` copy of
|
|
10
|
+
* it — is the single source of truth. That is what keeps the value correct when
|
|
11
|
+
* a mutation lands between render and effect-commit, when the component swaps
|
|
12
|
+
* which `target` it watches, and when React renders concurrently (no tearing).
|
|
8
13
|
*/
|
|
9
14
|
function useStore<T extends TAtomObject>(
|
|
10
15
|
target: Atom<T>,
|
|
@@ -16,35 +21,49 @@ function useStore<Key extends keyof State>(
|
|
|
16
21
|
): UseStoreReturn<State[Key]>;
|
|
17
22
|
function useStore(target: any, defaultValue?: any): any {
|
|
18
23
|
const alepha = useAlepha();
|
|
24
|
+
const key: string = target instanceof Atom ? target.key : target;
|
|
19
25
|
|
|
26
|
+
// Seed during render (not in an effect) on purpose: effects don't run during
|
|
27
|
+
// SSR, and the default has to be in the store before `exportAtoms` serializes
|
|
28
|
+
// the hydration payload. Idempotent — only fills an empty slot.
|
|
20
29
|
useMemo(() => {
|
|
21
30
|
if (defaultValue != null && alepha.store.get(target) == null) {
|
|
22
31
|
alepha.store.set(target, defaultValue);
|
|
23
32
|
}
|
|
24
|
-
}, [defaultValue]);
|
|
33
|
+
}, [defaultValue, key]);
|
|
25
34
|
|
|
26
|
-
const
|
|
35
|
+
const subscribe = useCallback(
|
|
36
|
+
(onStoreChange: () => void) => {
|
|
37
|
+
if (!alepha.isBrowser()) {
|
|
38
|
+
return () => {};
|
|
39
|
+
}
|
|
27
40
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
41
|
+
return alepha.events.on("state:mutate", (ev) => {
|
|
42
|
+
if (ev.key === key) {
|
|
43
|
+
onStoreChange();
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
},
|
|
47
|
+
[alepha, key],
|
|
48
|
+
);
|
|
32
49
|
|
|
33
|
-
|
|
50
|
+
// Read straight from the store rather than caching the event payload, so the
|
|
51
|
+
// snapshot stays correct no matter who mutated the key or when.
|
|
52
|
+
const getSnapshot = useCallback(
|
|
53
|
+
() => alepha.store.get(target),
|
|
54
|
+
[alepha, key],
|
|
55
|
+
);
|
|
34
56
|
|
|
35
|
-
|
|
36
|
-
if (ev.key === key) {
|
|
37
|
-
setState(ev.value);
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
}, []);
|
|
57
|
+
const state = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
41
58
|
|
|
42
|
-
|
|
43
|
-
state,
|
|
59
|
+
const setState = useCallback(
|
|
44
60
|
(value: any) => {
|
|
45
61
|
alepha.store.set(target, value);
|
|
46
62
|
},
|
|
47
|
-
|
|
63
|
+
[alepha, key],
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
return [state, setState] as const;
|
|
48
67
|
}
|
|
49
68
|
|
|
50
69
|
export type UseStoreReturn<T> = [T, (value: T) => void];
|
package/src/react/core/index.ts
CHANGED
|
@@ -11,10 +11,13 @@ export * from "./contexts/AlephaProvider.tsx";
|
|
|
11
11
|
export * from "./hooks/useAction.ts";
|
|
12
12
|
export * from "./hooks/useAlepha.ts";
|
|
13
13
|
export * from "./hooks/useClient.ts";
|
|
14
|
+
export * from "./hooks/useComputed.ts";
|
|
14
15
|
export * from "./hooks/useEvents.ts";
|
|
15
16
|
export * from "./hooks/useInject.ts";
|
|
16
17
|
export * from "./hooks/useQuery.ts";
|
|
18
|
+
export * from "./hooks/useSelector.ts";
|
|
17
19
|
export * from "./hooks/useStore.ts";
|
|
20
|
+
export * from "./utils/shallowEqual.ts";
|
|
18
21
|
|
|
19
22
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
20
23
|
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shallow structural equality over own enumerable keys.
|
|
3
|
+
*
|
|
4
|
+
* Intended as the `equality` argument of `useSelector` when the selector
|
|
5
|
+
* builds a fresh object/array on every call (e.g. `(s) => ({ a: s.a })`).
|
|
6
|
+
*/
|
|
7
|
+
export const shallowEqual = (a: unknown, b: unknown): boolean => {
|
|
8
|
+
if (Object.is(a, b)) {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
if (
|
|
12
|
+
typeof a !== "object" ||
|
|
13
|
+
a === null ||
|
|
14
|
+
typeof b !== "object" ||
|
|
15
|
+
b === null
|
|
16
|
+
) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
const keysA = Object.keys(a);
|
|
20
|
+
const keysB = Object.keys(b);
|
|
21
|
+
if (keysA.length !== keysB.length) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
for (const key of keysA) {
|
|
25
|
+
if (
|
|
26
|
+
!Object.hasOwn(b, key) ||
|
|
27
|
+
!Object.is(
|
|
28
|
+
(a as Record<string, unknown>)[key],
|
|
29
|
+
(b as Record<string, unknown>)[key],
|
|
30
|
+
)
|
|
31
|
+
) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return true;
|
|
36
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Alepha, z } from "alepha";
|
|
2
|
+
import { AlephaLogger } from "alepha/logger";
|
|
3
|
+
import { describe, it } from "vitest";
|
|
4
|
+
import { FormModel } from "../services/FormModel.ts";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Repro for: a form whose submit fails TypeBox validation (missing field)
|
|
8
|
+
* leaves the submit button stuck in its loading state forever.
|
|
9
|
+
*
|
|
10
|
+
* The button's loading is driven by the `form:submit:begin` / `form:submit:end`
|
|
11
|
+
* event pair (see useFormState). So the invariant that matters is: every
|
|
12
|
+
* `form:submit:begin` is followed by a `form:submit:end`, even when validation
|
|
13
|
+
* throws AND even when a downstream error listener (e.g. the action-error
|
|
14
|
+
* toaster) itself throws.
|
|
15
|
+
*/
|
|
16
|
+
describe("FormModel.submit loading pairing", () => {
|
|
17
|
+
const makeForm = (alepha: Alepha) =>
|
|
18
|
+
alepha.inject(FormModel as any, {
|
|
19
|
+
lifetime: "transient",
|
|
20
|
+
args: [
|
|
21
|
+
"f1",
|
|
22
|
+
{
|
|
23
|
+
id: "f1",
|
|
24
|
+
schema: z.object({ email: z.text(), password: z.text() }),
|
|
25
|
+
handler: () => {},
|
|
26
|
+
initialValues: {}, // both required fields missing → decode throws
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
}) as FormModel<any>;
|
|
30
|
+
|
|
31
|
+
it("emits form:submit:end on a validation error (intrinsic)", async ({
|
|
32
|
+
expect,
|
|
33
|
+
}) => {
|
|
34
|
+
const alepha = Alepha.create().with(AlephaLogger);
|
|
35
|
+
await alepha.start();
|
|
36
|
+
const form = makeForm(alepha);
|
|
37
|
+
let begun = false;
|
|
38
|
+
let ended = false;
|
|
39
|
+
alepha.events.on("form:submit:begin", () => {
|
|
40
|
+
begun = true;
|
|
41
|
+
});
|
|
42
|
+
alepha.events.on("form:submit:end", () => {
|
|
43
|
+
ended = true;
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
await form.submit().catch(() => {});
|
|
47
|
+
|
|
48
|
+
expect(begun).toBe(true);
|
|
49
|
+
expect(ended).toBe(true); // pairing must hold
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("emits form:submit:end even when a react:action:error listener throws", async ({
|
|
53
|
+
expect,
|
|
54
|
+
}) => {
|
|
55
|
+
const alepha = Alepha.create().with(AlephaLogger);
|
|
56
|
+
await alepha.start();
|
|
57
|
+
const form = makeForm(alepha);
|
|
58
|
+
let ended = false;
|
|
59
|
+
alepha.events.on("form:submit:end", () => {
|
|
60
|
+
ended = true;
|
|
61
|
+
});
|
|
62
|
+
// Simulates a globally-mounted listener (e.g. ActionErrorToaster) throwing.
|
|
63
|
+
alepha.events.on("react:action:error", () => {
|
|
64
|
+
throw new Error("toaster boom");
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
await form.submit().catch(() => {});
|
|
68
|
+
|
|
69
|
+
expect(ended).toBe(true); // currently FAILS: end is skipped → button stuck
|
|
70
|
+
});
|
|
71
|
+
});
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { fireEvent, render, waitFor } from "@testing-library/react";
|
|
2
|
+
import { Alepha, z } from "alepha";
|
|
3
|
+
import { AlephaLogger } from "alepha/logger";
|
|
4
|
+
import { AlephaContext } from "alepha/react";
|
|
5
|
+
import { describe, it } from "vitest";
|
|
6
|
+
import { useForm, useFormState } from "../index.ts";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Submit buttons bind their loading state to `useFormState(form, ["loading"])`
|
|
10
|
+
* (the reactive form-state API; the non-reactive `form.submitting` getter was
|
|
11
|
+
* removed). This loading must:
|
|
12
|
+
* - turn ON while an async submit is in flight, and
|
|
13
|
+
* - turn OFF again afterwards — including after a TypeBox validation error.
|
|
14
|
+
*
|
|
15
|
+
* The OFF guarantee relies on `FormModel.submit` always emitting
|
|
16
|
+
* `form:submit:end` (see FormModel-submit-loading.spec.ts).
|
|
17
|
+
*/
|
|
18
|
+
describe("useFormState loading drives the submit button", () => {
|
|
19
|
+
const mount = (alepha: Alepha, ui: React.ReactNode) =>
|
|
20
|
+
render(
|
|
21
|
+
<AlephaContext.Provider value={alepha}>{ui}</AlephaContext.Provider>,
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
it("turns loading on during an async submit and off after", async ({
|
|
25
|
+
expect,
|
|
26
|
+
}) => {
|
|
27
|
+
const alepha = Alepha.create().with(AlephaLogger);
|
|
28
|
+
let release!: () => void;
|
|
29
|
+
|
|
30
|
+
const Form = () => {
|
|
31
|
+
const form = useForm({
|
|
32
|
+
id: "async",
|
|
33
|
+
schema: z.object({ name: z.string().min(1) }),
|
|
34
|
+
initialValues: { name: "ok" },
|
|
35
|
+
handler: () => new Promise<void>((r) => (release = r)),
|
|
36
|
+
});
|
|
37
|
+
const { loading } = useFormState(form, ["loading"]);
|
|
38
|
+
return (
|
|
39
|
+
<form {...form.props} data-testid="form">
|
|
40
|
+
<button
|
|
41
|
+
type="submit"
|
|
42
|
+
data-testid="submit"
|
|
43
|
+
data-loading={loading ? "true" : "false"}
|
|
44
|
+
>
|
|
45
|
+
go
|
|
46
|
+
</button>
|
|
47
|
+
</form>
|
|
48
|
+
);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const { getByTestId } = mount(alepha, <Form />);
|
|
52
|
+
fireEvent.submit(getByTestId("form"));
|
|
53
|
+
|
|
54
|
+
await waitFor(() =>
|
|
55
|
+
expect(getByTestId("submit").getAttribute("data-loading")).toBe("true"),
|
|
56
|
+
);
|
|
57
|
+
release();
|
|
58
|
+
await waitFor(() =>
|
|
59
|
+
expect(getByTestId("submit").getAttribute("data-loading")).toBe("false"),
|
|
60
|
+
);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it("clears loading after a TypeBox validation error", async ({ expect }) => {
|
|
64
|
+
const alepha = Alepha.create().with(AlephaLogger);
|
|
65
|
+
|
|
66
|
+
const Form = () => {
|
|
67
|
+
const form = useForm({
|
|
68
|
+
id: "login",
|
|
69
|
+
schema: z.object({
|
|
70
|
+
identifier: z.string().min(1),
|
|
71
|
+
password: z.string().min(6),
|
|
72
|
+
}),
|
|
73
|
+
handler: async () => {},
|
|
74
|
+
});
|
|
75
|
+
const { loading } = useFormState(form, ["loading"]);
|
|
76
|
+
return (
|
|
77
|
+
<form {...form.props} data-testid="form">
|
|
78
|
+
<button
|
|
79
|
+
type="submit"
|
|
80
|
+
data-testid="submit"
|
|
81
|
+
data-loading={loading ? "true" : "false"}
|
|
82
|
+
>
|
|
83
|
+
Sign in
|
|
84
|
+
</button>
|
|
85
|
+
</form>
|
|
86
|
+
);
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const { getByTestId } = mount(alepha, <Form />);
|
|
90
|
+
fireEvent.submit(getByTestId("form")); // empty → validation error
|
|
91
|
+
|
|
92
|
+
await waitFor(() =>
|
|
93
|
+
expect(getByTestId("submit").getAttribute("data-loading")).toBe("false"),
|
|
94
|
+
);
|
|
95
|
+
});
|
|
96
|
+
});
|