alepha 0.21.2 → 0.23.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/README.md +0 -1
- package/dist/api/audits/index.browser.js.map +1 -1
- package/dist/api/audits/index.d.ts +393 -403
- package/dist/api/audits/index.d.ts.map +1 -1
- package/dist/api/audits/index.js +25 -56
- package/dist/api/audits/index.js.map +1 -1
- package/dist/api/files/index.browser.js +31 -1
- package/dist/api/files/index.browser.js.map +1 -1
- package/dist/api/files/index.d.ts +313 -208
- package/dist/api/files/index.d.ts.map +1 -1
- package/dist/api/files/index.js +152 -42
- package/dist/api/files/index.js.map +1 -1
- package/dist/api/jobs/index.browser.js +2 -2
- package/dist/api/jobs/index.browser.js.map +1 -1
- package/dist/api/jobs/index.d.ts +282 -285
- package/dist/api/jobs/index.d.ts.map +1 -1
- package/dist/api/jobs/index.js +39 -33
- package/dist/api/jobs/index.js.map +1 -1
- package/dist/api/keys/index.d.ts +217 -222
- package/dist/api/keys/index.d.ts.map +1 -1
- package/dist/api/keys/index.js.map +1 -1
- package/dist/api/notifications/index.browser.js.map +1 -1
- package/dist/api/notifications/index.d.ts +188 -195
- package/dist/api/notifications/index.d.ts.map +1 -1
- package/dist/api/notifications/index.js.map +1 -1
- package/dist/api/oauth/index.d.ts +71 -76
- package/dist/api/oauth/index.d.ts.map +1 -1
- package/dist/api/oauth/index.js.map +1 -1
- package/dist/api/organizations/index.browser.js.map +1 -1
- package/dist/api/organizations/index.d.ts +104 -109
- package/dist/api/organizations/index.d.ts.map +1 -1
- package/dist/api/organizations/index.js.map +1 -1
- package/dist/api/parameters/index.browser.js +43 -16
- package/dist/api/parameters/index.browser.js.map +1 -1
- package/dist/api/parameters/index.d.ts +488 -344
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/parameters/index.js +175 -35
- package/dist/api/parameters/index.js.map +1 -1
- package/dist/api/payments/index.d.ts +396 -402
- package/dist/api/payments/index.d.ts.map +1 -1
- package/dist/api/payments/index.js.map +1 -1
- package/dist/api/subscriptions/index.d.ts +644 -652
- package/dist/api/subscriptions/index.d.ts.map +1 -1
- package/dist/api/subscriptions/index.js +1 -1
- package/dist/api/subscriptions/index.js.map +1 -1
- package/dist/api/users/index.browser.js +7 -0
- package/dist/api/users/index.browser.js.map +1 -1
- package/dist/api/users/index.d.ts +1106 -1005
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +307 -64
- package/dist/api/users/index.js.map +1 -1
- package/dist/api/verifications/index.browser.js.map +1 -1
- package/dist/api/verifications/index.d.ts +137 -143
- package/dist/api/verifications/index.d.ts.map +1 -1
- package/dist/api/verifications/index.js.map +1 -1
- package/dist/background/index.d.ts +95 -0
- package/dist/background/index.d.ts.map +1 -0
- package/dist/background/index.js +121 -0
- package/dist/background/index.js.map +1 -0
- package/dist/background/index.workerd.js +110 -0
- package/dist/background/index.workerd.js.map +1 -0
- package/dist/batch/index.d.ts +5 -7
- package/dist/batch/index.d.ts.map +1 -1
- package/dist/batch/index.js.map +1 -1
- package/dist/bin/index.js.map +1 -1
- package/dist/bucket/index.d.ts +76 -54
- package/dist/bucket/index.d.ts.map +1 -1
- package/dist/bucket/index.js +58 -11
- package/dist/bucket/index.js.map +1 -1
- package/dist/bucket/index.workerd.js +200 -5
- package/dist/bucket/index.workerd.js.map +1 -1
- package/dist/cache/core/index.d.ts +7 -10
- package/dist/cache/core/index.d.ts.map +1 -1
- package/dist/cache/core/index.js.map +1 -1
- package/dist/cache/core/index.workerd.js.map +1 -1
- package/dist/cache/database/index.d.ts +22 -26
- package/dist/cache/database/index.d.ts.map +1 -1
- package/dist/cache/database/index.js.map +1 -1
- package/dist/cache/redis/index.d.ts +4 -7
- package/dist/cache/redis/index.d.ts.map +1 -1
- package/dist/cache/redis/index.js.map +1 -1
- package/dist/captcha/index.d.ts +3 -6
- package/dist/captcha/index.d.ts.map +1 -1
- package/dist/captcha/index.js.map +1 -1
- package/dist/cli/config/index.d.ts.map +1 -1
- package/dist/cli/config/index.js.map +1 -1
- package/dist/cli/core/index.d.ts +458 -249
- package/dist/cli/core/index.d.ts.map +1 -1
- package/dist/cli/core/index.js +372 -660
- package/dist/cli/core/index.js.map +1 -1
- package/dist/cli/devtools/index.d.ts +3 -5
- package/dist/cli/devtools/index.d.ts.map +1 -1
- package/dist/cli/devtools/index.js.map +1 -1
- package/dist/cli/i18n/index.d.ts +20 -17
- package/dist/cli/i18n/index.d.ts.map +1 -1
- package/dist/cli/i18n/index.js +45 -11
- package/dist/cli/i18n/index.js.map +1 -1
- package/dist/cli/platform/index.d.ts +126 -1342
- package/dist/cli/platform/index.d.ts.map +1 -1
- package/dist/cli/platform/index.js +136 -2374
- package/dist/cli/platform/index.js.map +1 -1
- package/dist/cli/platform-lib/index.d.ts +1472 -0
- package/dist/cli/platform-lib/index.d.ts.map +1 -0
- package/dist/cli/platform-lib/index.js +2660 -0
- package/dist/cli/platform-lib/index.js.map +1 -0
- package/dist/cli/vendor/index.d.ts +17 -21
- package/dist/cli/vendor/index.d.ts.map +1 -1
- package/dist/cli/vendor/index.js.map +1 -1
- package/dist/command/index.d.ts +20 -19
- package/dist/command/index.d.ts.map +1 -1
- package/dist/command/index.js +39 -10
- package/dist/command/index.js.map +1 -1
- package/dist/{containers → container}/core/index.d.ts +13 -15
- package/dist/container/core/index.d.ts.map +1 -0
- package/dist/{containers → container}/core/index.js +23 -14
- package/dist/container/core/index.js.map +1 -0
- package/dist/{containers → container}/core/index.workerd.js +37 -22
- package/dist/container/core/index.workerd.js.map +1 -0
- package/dist/core/index.browser.js +27 -1
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +48 -24
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +27 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +27 -1
- package/dist/core/index.native.js.map +1 -1
- package/dist/core/index.workerd.js +27 -1
- package/dist/core/index.workerd.js.map +1 -1
- package/dist/crypto/index.browser.js.map +1 -1
- package/dist/crypto/index.d.ts +5 -8
- package/dist/crypto/index.d.ts.map +1 -1
- package/dist/crypto/index.js.map +1 -1
- package/dist/datetime/index.d.ts +3 -4
- package/dist/datetime/index.d.ts.map +1 -1
- package/dist/datetime/index.js.map +1 -1
- package/dist/email/brevo/index.d.ts +2 -4
- package/dist/email/brevo/index.d.ts.map +1 -1
- package/dist/email/brevo/index.js.map +1 -1
- package/dist/email/cloudflare/index.d.ts +20 -7
- package/dist/email/cloudflare/index.d.ts.map +1 -1
- package/dist/email/cloudflare/index.js +46 -9
- package/dist/email/cloudflare/index.js.map +1 -1
- package/dist/email/core/index.d.ts +6 -9
- package/dist/email/core/index.d.ts.map +1 -1
- package/dist/email/core/index.js.map +1 -1
- package/dist/email/core/index.workerd.js.map +1 -1
- package/dist/email/smtp/index.d.ts +10 -13
- package/dist/email/smtp/index.d.ts.map +1 -1
- package/dist/email/smtp/index.js +107 -32
- package/dist/email/smtp/index.js.map +1 -1
- package/dist/fake/index.d.ts +1 -2
- package/dist/fake/index.d.ts.map +1 -1
- package/dist/fake/index.js.map +1 -1
- package/dist/lock/core/index.d.ts +9 -14
- package/dist/lock/core/index.d.ts.map +1 -1
- package/dist/lock/core/index.js.map +1 -1
- package/dist/lock/redis/index.d.ts +2 -4
- 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 +105 -76
- package/dist/logger/index.d.ts.map +1 -1
- package/dist/logger/index.js +196 -174
- package/dist/logger/index.js.map +1 -1
- package/dist/mcp/index.d.ts +25 -20
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +23 -0
- package/dist/mcp/index.js.map +1 -1
- package/dist/orm/core/index.browser.js.map +1 -1
- package/dist/orm/core/index.bun.js +19 -1
- package/dist/orm/core/index.bun.js.map +1 -1
- package/dist/orm/core/index.d.ts +76 -62
- package/dist/orm/core/index.d.ts.map +1 -1
- package/dist/orm/core/index.js +20 -2
- package/dist/orm/core/index.js.map +1 -1
- package/dist/orm/postgres/index.bun.js.map +1 -1
- package/dist/orm/postgres/index.d.ts +28 -20
- package/dist/orm/postgres/index.d.ts.map +1 -1
- package/dist/orm/postgres/index.js.map +1 -1
- package/dist/queue/core/index.d.ts +12 -15
- package/dist/queue/core/index.d.ts.map +1 -1
- package/dist/queue/core/index.js.map +1 -1
- package/dist/queue/core/index.workerd.js.map +1 -1
- package/dist/queue/redis/index.d.ts +3 -5
- package/dist/queue/redis/index.d.ts.map +1 -1
- package/dist/queue/redis/index.js.map +1 -1
- package/dist/react/auth/index.browser.js +9 -2
- package/dist/react/auth/index.browser.js.map +1 -1
- package/dist/react/auth/index.d.ts +14 -9
- package/dist/react/auth/index.d.ts.map +1 -1
- package/dist/react/auth/index.js +9 -2
- package/dist/react/auth/index.js.map +1 -1
- package/dist/react/core/index.d.ts +7 -8
- package/dist/react/core/index.d.ts.map +1 -1
- package/dist/react/core/index.js +6 -3
- package/dist/react/core/index.js.map +1 -1
- package/dist/react/form/index.d.ts +2 -5
- package/dist/react/form/index.d.ts.map +1 -1
- package/dist/react/form/index.js +16 -15
- 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 +2 -4
- 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 +90 -11
- package/dist/react/i18n/index.d.ts.map +1 -1
- package/dist/react/i18n/index.js +147 -11
- package/dist/react/i18n/index.js.map +1 -1
- package/dist/react/intro/index.d.ts +1 -2
- package/dist/react/intro/index.d.ts.map +1 -1
- package/dist/react/intro/index.js +2 -2
- package/dist/react/intro/index.js.map +1 -1
- package/dist/react/router/index.browser.js +193 -24
- package/dist/react/router/index.browser.js.map +1 -1
- package/dist/react/router/index.d.ts +434 -222
- package/dist/react/router/index.d.ts.map +1 -1
- package/dist/react/router/index.js +249 -35
- 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 +92 -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 +1 -2
- package/dist/react/testing/index.d.ts.map +1 -1
- package/dist/react/testing/index.js +16 -17
- package/dist/react/testing/index.js.map +1 -1
- package/dist/react/ui/index.d.ts +20 -25
- package/dist/react/ui/index.d.ts.map +1 -1
- package/dist/react/ui/index.js.map +1 -1
- package/dist/redis/index.bun.js.map +1 -1
- package/dist/redis/index.d.ts +17 -19
- package/dist/redis/index.d.ts.map +1 -1
- package/dist/redis/index.js.map +1 -1
- package/dist/retry/index.d.ts +2 -4
- 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 +10 -13
- package/dist/scheduler/index.d.ts.map +1 -1
- package/dist/scheduler/index.js.map +1 -1
- package/dist/scheduler/index.workerd.js.map +1 -1
- package/dist/security/index.browser.js.map +1 -1
- package/dist/security/index.d.ts +45 -48
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js.map +1 -1
- package/dist/server/auth/index.browser.js.map +1 -1
- package/dist/server/auth/index.d.ts +272 -173
- package/dist/server/auth/index.d.ts.map +1 -1
- package/dist/server/auth/index.js +1608 -15
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/cookies/index.browser.js.map +1 -1
- package/dist/server/cookies/index.d.ts +20 -7
- package/dist/server/cookies/index.d.ts.map +1 -1
- package/dist/server/cookies/index.js +22 -3
- package/dist/server/cookies/index.js.map +1 -1
- package/dist/server/core/index.browser.js.map +1 -1
- package/dist/server/core/index.d.ts +106 -73
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js +44 -0
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/cors/index.d.ts +11 -14
- package/dist/server/cors/index.d.ts.map +1 -1
- package/dist/server/cors/index.js.map +1 -1
- package/dist/server/etag/index.d.ts +6 -9
- 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 -21
- package/dist/server/health/index.d.ts.map +1 -1
- package/dist/server/health/index.js.map +1 -1
- package/dist/server/links/index.browser.js +2 -0
- package/dist/server/links/index.browser.js.map +1 -1
- package/dist/server/links/index.d.ts +63 -67
- package/dist/server/links/index.d.ts.map +1 -1
- package/dist/server/links/index.js +2 -0
- package/dist/server/links/index.js.map +1 -1
- package/dist/server/metrics/index.d.ts +5 -7
- package/dist/server/metrics/index.d.ts.map +1 -1
- package/dist/server/metrics/index.js.map +1 -1
- package/dist/server/proxy/index.d.ts +3 -5
- 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 +10 -13
- package/dist/server/rate-limit/index.d.ts.map +1 -1
- package/dist/server/rate-limit/index.js.map +1 -1
- package/dist/server/static/index.d.ts +3 -5
- 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 +5 -8
- package/dist/server/swagger/index.d.ts.map +1 -1
- package/dist/server/swagger/index.js.map +1 -1
- package/dist/sms/index.d.ts +3 -5
- 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 +2 -4
- package/dist/system/index.d.ts.map +1 -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 +4 -6
- package/dist/topic/core/index.d.ts.map +1 -1
- package/dist/topic/core/index.js.map +1 -1
- package/dist/topic/redis/index.d.ts +5 -8
- package/dist/topic/redis/index.d.ts.map +1 -1
- package/dist/topic/redis/index.js.map +1 -1
- package/package.json +59 -23
- package/src/api/audits/__tests__/AuditService.spec.ts +18 -110
- package/src/api/audits/controllers/AdminAuditController.ts +14 -0
- package/src/api/audits/services/AuditService.ts +21 -88
- package/src/api/files/__tests__/FileService.spec.ts +207 -2
- package/src/api/files/index.ts +3 -0
- package/src/api/files/schemas/fileCreatorSummarySchema.ts +22 -0
- package/src/api/files/schemas/fileResourceSchema.ts +10 -1
- package/src/api/files/services/FileService.ts +170 -72
- package/src/api/jobs/__tests__/$job.spec.ts +24 -1
- package/src/api/jobs/index.ts +4 -3
- package/src/api/jobs/primitives/$job.ts +7 -3
- package/src/api/jobs/providers/DirectJobDispatcher.ts +17 -36
- package/src/api/jobs/providers/JobProvider.ts +53 -24
- package/src/api/jobs/schemas/jobConfigAtom.ts +1 -1
- package/src/api/jobs/schemas/jobExecutionResourceSchema.ts +4 -1
- package/src/api/keys/schemas/adminApiKeyResourceSchema.ts +3 -1
- package/src/api/parameters/__tests__/$parameter.spec.ts +19 -2
- package/src/api/parameters/audits/ParameterAudits.ts +17 -0
- package/src/api/parameters/controllers/AdminParameterController.ts +95 -19
- package/src/api/parameters/index.ts +3 -0
- package/src/api/parameters/schemas/activateParameterBodySchema.ts +3 -3
- package/src/api/parameters/schemas/createParameterVersionBodySchema.ts +3 -2
- package/src/api/parameters/schemas/parameterCreatorSummarySchema.ts +25 -0
- package/src/api/parameters/schemas/parameterResponseSchema.ts +5 -0
- package/src/api/parameters/schemas/rollbackParameterBodySchema.ts +4 -2
- package/src/api/parameters/services/ParameterProvider.ts +69 -6
- package/src/api/subscriptions/jobs/SubscriptionJobs.ts +1 -1
- package/src/api/users/__tests__/AdminSessionController.spec.ts +37 -0
- package/src/api/users/audits/SessionAudits.ts +33 -0
- package/src/api/users/audits/UserAudits.ts +19 -43
- package/src/api/users/controllers/AdminUserController.ts +66 -1
- package/src/api/users/controllers/RealmController.ts +1 -0
- package/src/api/users/entities/sessions.ts +6 -0
- package/src/api/users/entities/users.ts +2 -0
- package/src/api/users/index.ts +9 -1
- package/src/api/users/primitives/$realm.ts +29 -0
- package/src/api/users/providers/RealmProvider.ts +15 -0
- package/src/api/users/schemas/realmConfigSchema.ts +14 -0
- package/src/api/users/schemas/sessionResourceSchema.ts +16 -0
- package/src/api/users/schemas/updateUserSchema.ts +1 -8
- package/src/api/users/schemas/userQuerySchema.ts +7 -0
- package/src/api/users/services/CredentialService.ts +15 -6
- package/src/api/users/services/IdentityService.ts +2 -1
- package/src/api/users/services/RegistrationService.ts +2 -1
- package/src/api/users/services/SessionCrudService.ts +19 -2
- package/src/api/users/services/SessionService.ts +39 -19
- package/src/api/users/services/UserService.ts +106 -8
- package/src/background/__tests__/BackgroundTaskProvider.spec.ts +96 -0
- package/src/background/index.ts +37 -0
- package/src/background/index.workerd.ts +28 -0
- package/src/background/providers/BackgroundTaskProvider.ts +70 -0
- package/src/background/providers/WorkerdBackgroundTaskProvider.ts +43 -0
- package/src/bucket/__tests__/$bucket.spec.ts +18 -0
- package/src/bucket/__tests__/LocalFileStorageProvider.spec.ts +5 -0
- package/src/bucket/__tests__/MemoryFileStorageProvider.spec.ts +5 -0
- package/src/bucket/__tests__/NodeS3BucketProvider.spec.ts +23 -4
- package/src/bucket/__tests__/shared.ts +30 -0
- package/src/bucket/index.ts +5 -5
- package/src/bucket/index.workerd.ts +11 -4
- package/src/bucket/primitives/$bucket.ts +27 -0
- package/src/bucket/providers/FileStorageProvider.ts +13 -0
- package/src/bucket/providers/LocalFileStorageProvider.ts +17 -1
- package/src/bucket/providers/MemoryFileStorageProvider.ts +7 -0
- package/src/bucket/providers/{CloudflareR2Provider.ts → R2FileStorageProvider.ts} +10 -1
- package/src/bucket/providers/{NodeS3BucketProvider.ts → S3FileStorageProvider.ts} +27 -5
- package/src/cli/core/__tests__/BuildDockerTask.spec.ts +25 -1
- package/src/cli/core/__tests__/init.spec.ts +0 -219
- package/src/cli/core/atoms/buildOptions.ts +0 -12
- package/src/cli/core/commands/__tests__/BuildCommand.spec.ts +43 -0
- package/src/cli/core/commands/build.ts +105 -37
- package/src/cli/core/commands/init.ts +0 -12
- package/src/cli/core/commands/pack.ts +133 -0
- package/src/cli/core/index.ts +3 -3
- package/src/cli/core/providers/ViteDevServerProvider.ts +40 -16
- package/src/cli/core/services/PackageManagerUtils.ts +0 -16
- package/src/cli/core/services/ProjectScaffolder.ts +29 -291
- package/src/cli/core/tasks/BuildCloudflareTask.ts +382 -56
- package/src/cli/core/tasks/BuildDockerTask.ts +33 -3
- package/src/cli/core/tasks/BuildPrerenderTask.ts +44 -7
- package/src/cli/core/tasks/BuildTask.ts +34 -0
- package/src/cli/core/templates/apiIndexTs.ts +1 -22
- package/src/cli/core/templates/mainCss.ts +0 -1
- package/src/cli/core/templates/webAppRouterTs.ts +0 -99
- package/src/cli/core/templates/webIndexTs.ts +1 -22
- package/src/cli/i18n/__tests__/I18nCheckService.spec.ts +48 -0
- package/src/cli/i18n/services/I18nCheckService.ts +65 -11
- package/src/cli/platform/__tests__/SecretsCommand.spec.ts +5 -3
- package/src/cli/platform/commands/SecretsCommand.ts +8 -6
- package/src/cli/platform/commands/platform.ts +192 -46
- package/src/cli/platform/index.ts +12 -52
- package/src/cli/{platform → platform-lib}/__tests__/CloudflareAdapter.spec.ts +426 -169
- package/src/cli/{platform → platform-lib}/__tests__/NamingService.spec.ts +91 -4
- package/src/cli/{platform → platform-lib}/__tests__/VercelAdapter.spec.ts +56 -85
- package/src/cli/{platform → platform-lib}/adapters/CloudflareAdapter.ts +519 -190
- package/src/cli/{platform → platform-lib}/adapters/PlatformAdapter.ts +62 -35
- package/src/cli/{platform → platform-lib}/adapters/VercelAdapter.ts +6 -10
- package/src/cli/{platform → platform-lib}/atoms/platformOptions.ts +34 -1
- package/src/cli/platform-lib/index.ts +67 -0
- package/src/cli/platform-lib/services/NamingService.ts +136 -0
- package/src/cli/{platform → platform-lib}/services/PlatformInspector.ts +60 -13
- package/src/cli/{platform → platform-lib}/services/PlatformOrchestrator.ts +54 -43
- package/src/cli/{platform → platform-lib}/services/WranglerApi.ts +4 -2
- package/src/command/__tests__/Runner.spec.ts +20 -0
- package/src/command/helpers/EnvUtils.ts +19 -3
- package/src/command/helpers/Runner.ts +12 -2
- package/src/command/providers/CliProvider.ts +34 -1
- package/src/{containers → container}/core/__tests__/$container.spec.ts +5 -5
- package/src/{containers → container}/core/index.ts +4 -4
- package/src/{containers → container}/core/index.workerd.ts +19 -3
- package/src/{containers → container}/core/primitives/$container.ts +1 -1
- package/src/{containers → container}/core/providers/CloudflareContainerProvider.ts +17 -19
- package/src/{containers → container}/core/providers/ContainerProvider.ts +16 -2
- package/src/{containers → container}/core/providers/MockContainerProvider.ts +1 -1
- package/src/core/Alepha.ts +49 -1
- package/src/core/__tests__/$env.spec.ts +42 -0
- package/src/core/__tests__/dump.spec.ts +47 -0
- package/src/email/cloudflare/__tests__/CloudflareEmailProvider.spec.ts +42 -10
- package/src/email/cloudflare/index.ts +14 -5
- package/src/email/cloudflare/providers/CloudflareEmailProvider.ts +54 -9
- package/src/logger/__tests__/Logger.spec.ts +55 -0
- package/src/logger/index.ts +13 -0
- package/src/logger/services/Logger.ts +31 -1
- package/src/mcp/__tests__/McpServerProvider.spec.ts +71 -0
- package/src/mcp/providers/McpServerProvider.ts +55 -0
- package/src/orm/__tests__/orm-showcase-tests.ts +27 -0
- package/src/orm/__tests__/orm-showcase.spec.ts +12 -0
- package/src/orm/core/interfaces/PgQuery.ts +4 -1
- package/src/orm/core/services/Repository.ts +27 -11
- package/src/react/auth/hooks/useAuth.ts +10 -5
- package/src/react/core/__tests__/useQuery.browser.spec.tsx +25 -0
- package/src/react/core/hooks/useAction.ts +14 -3
- package/src/react/core/hooks/useQuery.ts +24 -4
- 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/services/FormModel.ts +57 -39
- package/src/react/i18n/__tests__/I18nProvider.spec.ts +89 -0
- package/src/react/i18n/__tests__/locale-routing.spec.ts +107 -0
- package/src/react/i18n/components/Translate.tsx +47 -0
- package/src/react/i18n/index.ts +2 -0
- package/src/react/i18n/providers/I18nProvider.ts +171 -12
- package/src/react/intro/components/GettingStartedAdminSlide.tsx +2 -2
- package/src/react/router/__tests__/$page.spec.tsx +3 -2
- package/src/react/router/__tests__/RouterLocaleProvider.spec.ts +127 -0
- package/src/react/router/__tests__/page-can.spec.ts +18 -13
- package/src/react/router/hooks/useQueryParams.ts +114 -14
- 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 +85 -4
- package/src/react/router/providers/ReactBrowserRouterProvider.ts +18 -8
- package/src/react/router/providers/ReactPageProvider.ts +12 -1
- package/src/react/router/providers/ReactServerProvider.ts +96 -14
- 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/services/SchemaControl.ts +3 -4
- package/src/server/auth/__tests__/appleClientSecret.spec.ts +34 -0
- package/src/server/auth/__tests__/authFederationClient.spec.ts +40 -0
- package/src/server/auth/__tests__/federationAssertion.spec.ts +146 -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/federationAssertion.ts +74 -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 +4 -0
- package/src/server/auth/primitives/$authFederationBroker.ts +273 -0
- package/src/server/auth/primitives/$authFederationClient.ts +89 -0
- package/src/server/auth/providers/ServerAuthProvider.ts +18 -4
- package/src/server/cookies/__tests__/ServerCookiesProvider.spec.ts +70 -0
- package/src/server/cookies/providers/ServerCookiesProvider.ts +23 -3
- package/src/server/core/interfaces/ServerRequest.ts +8 -0
- package/src/server/core/primitives/$route.ts +27 -0
- package/src/server/core/providers/ServerMultipartProvider.ts +19 -0
- package/src/server/links/providers/LinkProvider.ts +10 -0
- package/dist/containers/core/index.d.ts.map +0 -1
- package/dist/containers/core/index.js.map +0 -1
- package/dist/containers/core/index.workerd.js.map +0 -1
- package/src/cli/core/tasks/BuildSitemapTask.ts +0 -130
- package/src/cli/core/templates/componentsJsonTs.ts +0 -39
- package/src/cli/core/templates/saasAdminLayoutTsx.ts +0 -77
- package/src/cli/core/templates/saasAdminPagesTsx.ts +0 -26
- package/src/cli/core/templates/saasAuthLayoutTsx.ts +0 -22
- package/src/cli/core/templates/saasAuthPagesTsx.ts +0 -62
- package/src/cli/core/templates/saasRealmProviderTs.ts +0 -52
- package/src/cli/platform/services/NamingService.ts +0 -54
- /package/dist/orm/core/{chunk-o8xxKEmq.js → chunk-B4FMCO8f.js} +0 -0
- /package/dist/react/testing/{chunk-6Ep1yQYe.js → chunk-BpyX8vjI.js} +0 -0
- /package/src/cli/{platform → platform-lib}/__tests__/GitHubSecretStore.spec.ts +0 -0
- /package/src/cli/{platform → platform-lib}/__tests__/PlatformCacheProvider.spec.ts +0 -0
- /package/src/cli/{platform → platform-lib}/__tests__/PlatformInspector.spec.ts +0 -0
- /package/src/cli/{platform → platform-lib}/__tests__/PlatformOrchestrator.spec.ts +0 -0
- /package/src/cli/{platform → platform-lib}/__tests__/SecretFilterService.spec.ts +0 -0
- /package/src/cli/{platform → platform-lib}/__tests__/detectResources.spec.ts +0 -0
- /package/src/cli/{platform → platform-lib}/providers/GitHubSecretStore.ts +0 -0
- /package/src/cli/{platform → platform-lib}/providers/MemorySecretStore.ts +0 -0
- /package/src/cli/{platform → platform-lib}/providers/PlatformCacheProvider.ts +0 -0
- /package/src/cli/{platform → platform-lib}/providers/SecretStoreProvider.ts +0 -0
- /package/src/cli/{platform → platform-lib}/schemas/cloudflare.ts +0 -0
- /package/src/cli/{platform → platform-lib}/schemas/platform.ts +0 -0
- /package/src/cli/{platform → platform-lib}/schemas/vercel.ts +0 -0
- /package/src/cli/{platform → platform-lib}/services/CloudflareApi.ts +0 -0
- /package/src/cli/{platform → platform-lib}/services/SecretFilterService.ts +0 -0
- /package/src/cli/{platform → platform-lib}/services/VercelApi.ts +0 -0
- /package/src/cli/{platform → platform-lib}/services/VercelCli.ts +0 -0
- /package/src/{containers → container}/core/interfaces/ContainerOptions.ts +0 -0
- /package/src/{containers → container}/core/providers/NodeContainerProvider.ts +0 -0
|
@@ -1,22 +1,113 @@
|
|
|
1
1
|
import { basename } from "node:path";
|
|
2
2
|
import { $inject } from "alepha";
|
|
3
3
|
import { KV_DEFAULT_BINDING } from "alepha/cache";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
CloudflareEmailProvider,
|
|
8
|
-
SEND_EMAIL_DEFAULT_BINDING,
|
|
9
|
-
} from "alepha/email/cloudflare";
|
|
4
|
+
import type { ContainerPrimitive } from "alepha/container";
|
|
5
|
+
import { SEND_EMAIL_DEFAULT_BINDING } from "alepha/email/cloudflare";
|
|
10
6
|
import { QUEUE_DEFAULT_BINDING } from "alepha/queue";
|
|
11
7
|
import type { CronProvider, WorkerdCronProvider } from "alepha/scheduler";
|
|
12
8
|
import { FileSystemProvider } from "alepha/system";
|
|
13
9
|
import { ViteUtils } from "../services/ViteUtils.ts";
|
|
14
10
|
import { BuildTask, type BuildTaskContext } from "./BuildTask.ts";
|
|
15
11
|
|
|
12
|
+
// Looked up by class name string (not by class identity) because
|
|
13
|
+
// BuildCloudflareTask runs in the CLI's Alepha context while ctx.alepha
|
|
14
|
+
// is the workspace's separate context. Two module graphs = two distinct
|
|
15
|
+
// `CloudflareEmailProvider` class objects, so the imported reference
|
|
16
|
+
// here wouldn't match the one the workspace registered.
|
|
17
|
+
const CLOUDFLARE_EMAIL_PROVIDER_NAME = "CloudflareEmailProvider";
|
|
18
|
+
|
|
16
19
|
interface WranglerConfig {
|
|
17
20
|
[key: string]: any;
|
|
18
21
|
}
|
|
19
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Build-time snapshot describing what the workspace needs at deploy
|
|
25
|
+
* time. Written to `dist/manifest.json` alongside `wrangler.jsonc`.
|
|
26
|
+
*
|
|
27
|
+
* Lets `alepha platform up --prebuilt` skip the Vite-based
|
|
28
|
+
* introspection step on the deploy side — and lets Alepha Rocket skip
|
|
29
|
+
* the workspace's runtime `npm install` because no app source is
|
|
30
|
+
* booted at deploy time. The manifest captures the bits of primitive
|
|
31
|
+
* data that the deploy steps (provision, secrets, hooks) need to
|
|
32
|
+
* know.
|
|
33
|
+
*/
|
|
34
|
+
export interface BuildManifest {
|
|
35
|
+
version: 1;
|
|
36
|
+
project: string;
|
|
37
|
+
/**
|
|
38
|
+
* Default environment when `--env` is omitted at deploy time.
|
|
39
|
+
* Captured from `platformOptions.default` (defaults to `"production"`).
|
|
40
|
+
*/
|
|
41
|
+
defaultEnv: string;
|
|
42
|
+
/**
|
|
43
|
+
* Multi-tenancy mode (`none` | `optional` | `required`). Captured from
|
|
44
|
+
* `platformOptions.tenancy` so the prebuilt deploy side (Rocket) can
|
|
45
|
+
* validate `--tenant` without re-evaluating `alepha.config.ts`.
|
|
46
|
+
*/
|
|
47
|
+
tenancy?: "none" | "optional" | "required";
|
|
48
|
+
/**
|
|
49
|
+
* Resolved `platform({ environments: ... })` map. Captured at build
|
|
50
|
+
* time from the workspace's `alepha.config.ts` so the deploy side
|
|
51
|
+
* doesn't need to re-evaluate the config. Each value is the same
|
|
52
|
+
* `EnvironmentConfig` shape consumed by the orchestrator (adapter,
|
|
53
|
+
* domain, zone, jurisdiction, accountId).
|
|
54
|
+
*/
|
|
55
|
+
environments: Record<
|
|
56
|
+
string,
|
|
57
|
+
{
|
|
58
|
+
adapter: "cloudflare" | "vercel";
|
|
59
|
+
domain?: string;
|
|
60
|
+
zone?: string;
|
|
61
|
+
jurisdiction?: "eu" | "fedramp";
|
|
62
|
+
accountId?: string;
|
|
63
|
+
}
|
|
64
|
+
>;
|
|
65
|
+
resources: {
|
|
66
|
+
hasDatabase: boolean;
|
|
67
|
+
hasBucket: boolean;
|
|
68
|
+
hasKV: boolean;
|
|
69
|
+
hasQueue: boolean;
|
|
70
|
+
hasCron: boolean;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* All distinct cron expressions registered by `$scheduler`
|
|
74
|
+
* primitives. Empty when `hasCron` is false.
|
|
75
|
+
*/
|
|
76
|
+
crons: string[];
|
|
77
|
+
/**
|
|
78
|
+
* Cloudflare email binding, captured when the app registers
|
|
79
|
+
* `CloudflareEmailProvider` at artifact-build time. The prebuilt/manifest
|
|
80
|
+
* deploy path (Alepha Rocket `--prebuilt`) has no Vite introspection, so it
|
|
81
|
+
* reads this to re-emit the `send_email` wrangler binding. Absent when the
|
|
82
|
+
* app doesn't use Cloudflare email.
|
|
83
|
+
*/
|
|
84
|
+
email?: { binding: string };
|
|
85
|
+
/**
|
|
86
|
+
* `$container()` descriptors — image, port, lifecycle settings.
|
|
87
|
+
* Used both to populate Cloudflare Containers bindings in
|
|
88
|
+
* wrangler.jsonc and (in future) to know which images Rocket should
|
|
89
|
+
* pull on the deploy side.
|
|
90
|
+
*/
|
|
91
|
+
containers: Array<{
|
|
92
|
+
name: string;
|
|
93
|
+
className: string;
|
|
94
|
+
image: string;
|
|
95
|
+
port: number;
|
|
96
|
+
sleepAfter: string;
|
|
97
|
+
instanceType: string;
|
|
98
|
+
maxInstances: number;
|
|
99
|
+
}>;
|
|
100
|
+
/**
|
|
101
|
+
* Every env var the app declares via `$env`, captured from
|
|
102
|
+
* `alepha.dump().env` at build time. The deploy `secrets` step uses this
|
|
103
|
+
* as the worker-secret allowlist (minus build/binding vars) so CI can
|
|
104
|
+
* deliver secrets straight from `process.env` without a `.env` file —
|
|
105
|
+
* `platform.secrets.keys` overrides it when set. Empty when introspection
|
|
106
|
+
* was unavailable (older artifacts / prebuilt mode).
|
|
107
|
+
*/
|
|
108
|
+
env: string[];
|
|
109
|
+
}
|
|
110
|
+
|
|
20
111
|
/**
|
|
21
112
|
* Generate Cloudflare Workers deployment configuration.
|
|
22
113
|
*
|
|
@@ -52,7 +143,15 @@ export class BuildCloudflareTask extends BuildTask {
|
|
|
52
143
|
distDir: string,
|
|
53
144
|
): Promise<void> {
|
|
54
145
|
const root = ctx.root;
|
|
55
|
-
|
|
146
|
+
// Slugify the dir basename — wrangler rejects names that aren't
|
|
147
|
+
// `^[a-z0-9-]+$` (no uppercase, dots, underscores, spaces, etc.).
|
|
148
|
+
// Without this, running `alepha build -t cloudflare` in a dir like
|
|
149
|
+
// `My App` or `club-0.0.2` produces an unusable `wrangler.jsonc`.
|
|
150
|
+
const name = basename(root)
|
|
151
|
+
.toLowerCase()
|
|
152
|
+
.replace(/[^a-z0-9-]+/g, "-")
|
|
153
|
+
.replace(/^-+|-+$/g, "")
|
|
154
|
+
.slice(0, 63);
|
|
56
155
|
const hasAssets = await this.fs.exists(
|
|
57
156
|
this.fs.join(root, distDir, "public"),
|
|
58
157
|
);
|
|
@@ -98,9 +197,137 @@ export class BuildCloudflareTask extends BuildTask {
|
|
|
98
197
|
JSON.stringify(wrangler, null, 2),
|
|
99
198
|
);
|
|
100
199
|
|
|
200
|
+
// Only write a fresh manifest when we discovered it from a booted
|
|
201
|
+
// Alepha instance. In manifest mode (ctx.manifest != null) we're
|
|
202
|
+
// re-emitting the same data we just read — skip to avoid a redundant
|
|
203
|
+
// write and to keep the original manifest as the canonical record.
|
|
204
|
+
if (!ctx.manifest) {
|
|
205
|
+
await this.writeManifest(ctx, root, distDir, name, containers);
|
|
206
|
+
}
|
|
101
207
|
await this.writeWorkerEntryPoint(root, distDir, containers);
|
|
102
208
|
}
|
|
103
209
|
|
|
210
|
+
/**
|
|
211
|
+
* Write `dist/manifest.json` — a build-time snapshot of everything
|
|
212
|
+
* downstream tooling needs to know about the app without re-booting
|
|
213
|
+
* it. Used by `alepha platform up --prebuilt` (and Alepha Rocket) so
|
|
214
|
+
* the deploy path can skip the Vite-based introspection step and the
|
|
215
|
+
* workspace's runtime npm install.
|
|
216
|
+
*/
|
|
217
|
+
protected async writeManifest(
|
|
218
|
+
ctx: BuildTaskContext,
|
|
219
|
+
root: string,
|
|
220
|
+
distDir: string,
|
|
221
|
+
name: string,
|
|
222
|
+
containers: ContainerDescriptor[],
|
|
223
|
+
): Promise<void> {
|
|
224
|
+
// Discover the same primitive shapes the enhance* methods read.
|
|
225
|
+
// Errors are silently swallowed — an absent primitive class just
|
|
226
|
+
// means the app doesn't use that resource.
|
|
227
|
+
let hasDatabase = false;
|
|
228
|
+
let hasBucket = false;
|
|
229
|
+
let hasKV = false;
|
|
230
|
+
let hasQueue = false;
|
|
231
|
+
let crons: string[] = [];
|
|
232
|
+
|
|
233
|
+
try {
|
|
234
|
+
const repo = ctx.alepha.inject("RepositoryProvider") as {
|
|
235
|
+
getRepositories?: () => unknown[];
|
|
236
|
+
};
|
|
237
|
+
hasDatabase = (repo.getRepositories?.() ?? []).length > 0;
|
|
238
|
+
} catch {}
|
|
239
|
+
|
|
240
|
+
try {
|
|
241
|
+
hasBucket = ctx.alepha.primitives("$bucket").length > 0;
|
|
242
|
+
} catch {}
|
|
243
|
+
|
|
244
|
+
try {
|
|
245
|
+
// Only count $cache primitives without an explicit `provider`
|
|
246
|
+
// option — those fall back to KV on workerd. Explicit memory /
|
|
247
|
+
// Redis / Postgres providers opt out of KV provisioning.
|
|
248
|
+
hasKV =
|
|
249
|
+
ctx.alepha
|
|
250
|
+
.primitives("cache")
|
|
251
|
+
.filter(
|
|
252
|
+
(p) =>
|
|
253
|
+
(p as { options?: { provider?: unknown } }).options?.provider ==
|
|
254
|
+
null,
|
|
255
|
+
).length > 0;
|
|
256
|
+
} catch {}
|
|
257
|
+
|
|
258
|
+
try {
|
|
259
|
+
hasQueue = ctx.alepha.primitives("$queue").length > 0;
|
|
260
|
+
} catch {}
|
|
261
|
+
|
|
262
|
+
try {
|
|
263
|
+
const cronProvider = ctx.alepha.inject("CronProvider") as {
|
|
264
|
+
getCronJobs?: () => Array<{ expression: string }>;
|
|
265
|
+
};
|
|
266
|
+
crons = [
|
|
267
|
+
...new Set(
|
|
268
|
+
(cronProvider.getCronJobs?.() ?? []).map((c) => c.expression),
|
|
269
|
+
),
|
|
270
|
+
];
|
|
271
|
+
} catch {}
|
|
272
|
+
|
|
273
|
+
// platformOptions come from the CLI's Alepha instance (where
|
|
274
|
+
// alepha.config.ts ran during the configure hook). BuildCommand
|
|
275
|
+
// reads them up there and threads them via ctx — ctx.alepha here
|
|
276
|
+
// is the WORKSPACE's Vite-booted Alepha, which never saw the
|
|
277
|
+
// platform options.
|
|
278
|
+
const defaultEnv = ctx.platformOptions?.default ?? "production";
|
|
279
|
+
const environments = (ctx.platformOptions?.environments ??
|
|
280
|
+
{}) as BuildManifest["environments"];
|
|
281
|
+
|
|
282
|
+
// Every declared `$env` key. dump() force-instantiates the graph (no
|
|
283
|
+
// start/ready hooks), so this is the full env surface — used by the
|
|
284
|
+
// deploy `secrets` step as the worker-secret allowlist.
|
|
285
|
+
let env: string[] = [];
|
|
286
|
+
try {
|
|
287
|
+
env = Object.keys(ctx.alepha.dump().env).sort();
|
|
288
|
+
} catch {}
|
|
289
|
+
|
|
290
|
+
// Capture the CF email binding so manifest-mode deploys (Rocket) can
|
|
291
|
+
// re-emit `send_email` — `enhanceEmail` can't introspect there.
|
|
292
|
+
let email: BuildManifest["email"];
|
|
293
|
+
try {
|
|
294
|
+
ctx.alepha.inject(CLOUDFLARE_EMAIL_PROVIDER_NAME);
|
|
295
|
+
email = { binding: SEND_EMAIL_DEFAULT_BINDING };
|
|
296
|
+
} catch {}
|
|
297
|
+
|
|
298
|
+
const manifest: BuildManifest = {
|
|
299
|
+
version: 1,
|
|
300
|
+
project: name,
|
|
301
|
+
defaultEnv,
|
|
302
|
+
tenancy: ctx.platformOptions?.tenancy,
|
|
303
|
+
environments,
|
|
304
|
+
resources: {
|
|
305
|
+
hasDatabase,
|
|
306
|
+
hasBucket,
|
|
307
|
+
hasKV,
|
|
308
|
+
hasQueue,
|
|
309
|
+
hasCron: crons.length > 0,
|
|
310
|
+
},
|
|
311
|
+
crons,
|
|
312
|
+
containers: containers.map((c) => ({
|
|
313
|
+
name: c.name,
|
|
314
|
+
className: c.className,
|
|
315
|
+
image: c.image,
|
|
316
|
+
port: c.port,
|
|
317
|
+
sleepAfter: c.sleepAfter,
|
|
318
|
+
instanceType: c.instanceType,
|
|
319
|
+
maxInstances: c.maxInstances,
|
|
320
|
+
})),
|
|
321
|
+
email,
|
|
322
|
+
env,
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
await this.fs.writeFile(
|
|
326
|
+
this.fs.join(root, distDir, "manifest.json"),
|
|
327
|
+
JSON.stringify(manifest, null, 2),
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
|
|
104
331
|
protected enhanceDomain(wrangler: WranglerConfig): void {
|
|
105
332
|
const domain = process.env.CLOUDFLARE_DOMAIN;
|
|
106
333
|
if (!domain) {
|
|
@@ -132,23 +359,29 @@ export class BuildCloudflareTask extends BuildTask {
|
|
|
132
359
|
}
|
|
133
360
|
|
|
134
361
|
protected enhanceCron(ctx: BuildTaskContext, wrangler: WranglerConfig): void {
|
|
135
|
-
|
|
362
|
+
const cronExpressions = ctx.manifest
|
|
363
|
+
? ctx.manifest.crons
|
|
364
|
+
: this.discoverCrons(ctx);
|
|
365
|
+
if (cronExpressions.length === 0) {
|
|
136
366
|
return;
|
|
137
367
|
}
|
|
368
|
+
wrangler.triggers ??= {};
|
|
369
|
+
wrangler.triggers.crons = cronExpressions;
|
|
370
|
+
}
|
|
138
371
|
|
|
372
|
+
protected discoverCrons(ctx: BuildTaskContext): string[] {
|
|
373
|
+
if (ctx.alepha.primitives("scheduler").length === 0) {
|
|
374
|
+
return [];
|
|
375
|
+
}
|
|
139
376
|
let cronProvider: CronProvider | undefined;
|
|
140
377
|
try {
|
|
141
378
|
cronProvider = ctx.alepha.inject("CronProvider") as WorkerdCronProvider;
|
|
142
379
|
} catch {}
|
|
143
|
-
|
|
144
380
|
const crons = cronProvider?.getCronJobs();
|
|
145
381
|
if (!crons || crons.length === 0) {
|
|
146
|
-
return;
|
|
382
|
+
return [];
|
|
147
383
|
}
|
|
148
|
-
|
|
149
|
-
const cronExpressions = [...new Set(crons.map((c) => c.expression))];
|
|
150
|
-
wrangler.triggers ??= {};
|
|
151
|
-
wrangler.triggers.crons = cronExpressions;
|
|
384
|
+
return [...new Set(crons.map((c) => c.expression))];
|
|
152
385
|
}
|
|
153
386
|
|
|
154
387
|
protected enhanceDatabase(wrangler: WranglerConfig): void {
|
|
@@ -256,33 +489,44 @@ export class BuildCloudflareTask extends BuildTask {
|
|
|
256
489
|
ctx: BuildTaskContext,
|
|
257
490
|
wrangler: WranglerConfig,
|
|
258
491
|
): void {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
492
|
+
// Resolve the CF email binding from whichever source this build path has:
|
|
493
|
+
// - manifest/prebuilt mode (Alepha Rocket `--prebuilt`): no app boot, so
|
|
494
|
+
// read the binding captured into the manifest at artifact-build time.
|
|
495
|
+
// Without this the deploy silently drops `send_email` and the worker
|
|
496
|
+
// boots with email inert (binding not found).
|
|
497
|
+
// - full Vite introspection (`ctx.alepha`, no manifest): probe for the
|
|
498
|
+
// registered CloudflareEmailProvider.
|
|
499
|
+
let binding: string | undefined;
|
|
500
|
+
if (ctx.manifest) {
|
|
501
|
+
binding = ctx.manifest.email?.binding;
|
|
502
|
+
} else if (ctx.alepha) {
|
|
503
|
+
try {
|
|
504
|
+
ctx.alepha.inject(CLOUDFLARE_EMAIL_PROVIDER_NAME);
|
|
505
|
+
binding = SEND_EMAIL_DEFAULT_BINDING;
|
|
506
|
+
} catch {
|
|
507
|
+
// app doesn't use CloudflareEmailProvider — nothing to emit
|
|
508
|
+
}
|
|
264
509
|
}
|
|
265
|
-
|
|
266
|
-
if (!(provider instanceof CloudflareEmailProvider)) {
|
|
510
|
+
if (!binding) {
|
|
267
511
|
return;
|
|
268
512
|
}
|
|
269
513
|
|
|
270
514
|
wrangler.send_email = wrangler.send_email || [];
|
|
271
|
-
if (
|
|
272
|
-
wrangler.send_email.some(
|
|
273
|
-
(b: { name: string }) => b.name === SEND_EMAIL_DEFAULT_BINDING,
|
|
274
|
-
)
|
|
275
|
-
) {
|
|
515
|
+
if (wrangler.send_email.some((b: { name: string }) => b.name === binding)) {
|
|
276
516
|
return;
|
|
277
517
|
}
|
|
278
518
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
519
|
+
// NOTE: do NOT set `destination_address` here. On a Cloudflare
|
|
520
|
+
// `send_email` binding, `destination_address` is a *recipient* allow-list
|
|
521
|
+
// lock (the worker may then only send TO that one address) — it is not the
|
|
522
|
+
// sender. Setting it to `EMAIL_FROM` (the sender) broke all outbound mail:
|
|
523
|
+
// a bare address locked delivery to that single recipient ("email to … not
|
|
524
|
+
// allowed"), and a display-name form like `Lore <noreply@…>` is a malformed
|
|
525
|
+
// destination value that Cloudflare rejects with "internal error". The
|
|
526
|
+
// sender goes in the message `from` field (see CloudflareEmailProvider.send);
|
|
527
|
+
// leaving the binding unrestricted lets the worker send to any verified
|
|
528
|
+
// destination.
|
|
529
|
+
wrangler.send_email.push({ name: binding });
|
|
286
530
|
}
|
|
287
531
|
|
|
288
532
|
/**
|
|
@@ -295,18 +539,19 @@ export class BuildCloudflareTask extends BuildTask {
|
|
|
295
539
|
* `writeWorkerEntryPoint` can emit `export class <NAME> extends
|
|
296
540
|
* Container` declarations referencing them.
|
|
297
541
|
*/
|
|
298
|
-
protected
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
542
|
+
protected discoverContainers(ctx: BuildTaskContext): ContainerDescriptor[] {
|
|
543
|
+
// String key, not the `$container` factory. The build task runs in
|
|
544
|
+
// the CLI's Node realm, while the workspace's entry module is
|
|
545
|
+
// loaded by Vite — two separate module copies of
|
|
546
|
+
// `alepha/container`. Looking up by `$container[KIND]` (a class
|
|
547
|
+
// reference) would dereference the CLI's ContainerPrimitive class,
|
|
548
|
+
// which never matches the workspace's. The string form iterates
|
|
549
|
+
// the registry by class name and survives the dual-realm — same
|
|
550
|
+
// pattern used for `$bucket`, `$queue`, `scheduler` below.
|
|
302
551
|
const primitives = ctx.alepha.primitives(
|
|
303
|
-
|
|
552
|
+
"container",
|
|
304
553
|
) as ContainerPrimitive[];
|
|
305
|
-
|
|
306
|
-
return [];
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
const descriptors: ContainerDescriptor[] = primitives.map((p) => ({
|
|
554
|
+
return primitives.map((p) => ({
|
|
310
555
|
name: p.name.toUpperCase(),
|
|
311
556
|
className: p.name
|
|
312
557
|
.split(/[^a-zA-Z0-9]/)
|
|
@@ -317,10 +562,67 @@ export class BuildCloudflareTask extends BuildTask {
|
|
|
317
562
|
port: p.options.port ?? 3000,
|
|
318
563
|
sleepAfter:
|
|
319
564
|
typeof p.options.sleepAfter === "string" ? p.options.sleepAfter : "15m",
|
|
320
|
-
|
|
565
|
+
// `lite` is the post-GA name for what `$container` historically
|
|
566
|
+
// called `dev`. Default to `lite` here and rewrite any
|
|
567
|
+
// explicit `dev` to it on the way out — wrangler warns
|
|
568
|
+
// otherwise.
|
|
569
|
+
instanceType:
|
|
570
|
+
p.options.instanceType === "dev"
|
|
571
|
+
? "lite"
|
|
572
|
+
: (p.options.instanceType ?? "lite"),
|
|
321
573
|
maxInstances: p.options.maxInstances ?? 5,
|
|
322
574
|
envVars: p.options.envVars,
|
|
323
575
|
}));
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* Expand a short image ref (e.g. `alepha-rocket:0.1.0`) into the
|
|
580
|
+
* fully-qualified `registry.cloudflare.com/<account>/<image>:<tag>`
|
|
581
|
+
* URL that wrangler validates at deploy time.
|
|
582
|
+
*
|
|
583
|
+
* Cloudflare Containers only pulls from `registry.cloudflare.com`;
|
|
584
|
+
* wrangler accepts either a Dockerfile path or a fully-qualified
|
|
585
|
+
* registry URL in the `image` field — not a bare DockerHub-style
|
|
586
|
+
* name. We let `$container({ image })` callers write the short
|
|
587
|
+
* form (it matches what `wrangler containers push <local>` accepts
|
|
588
|
+
* + matches the local docker tag) and rewrite to the CF registry
|
|
589
|
+
* URL here.
|
|
590
|
+
*
|
|
591
|
+
* Pass-through cases:
|
|
592
|
+
* - already a full URL: starts with `registry.cloudflare.com/`
|
|
593
|
+
* or contains a scheme/`://`
|
|
594
|
+
* - looks like a Dockerfile path: starts with `./` or `/`
|
|
595
|
+
*/
|
|
596
|
+
protected resolveContainerImage(image: string): string {
|
|
597
|
+
if (
|
|
598
|
+
image.startsWith("./") ||
|
|
599
|
+
image.startsWith("/") ||
|
|
600
|
+
image.startsWith("registry.cloudflare.com/") ||
|
|
601
|
+
image.includes("://")
|
|
602
|
+
) {
|
|
603
|
+
return image;
|
|
604
|
+
}
|
|
605
|
+
const accountId = process.env.CLOUDFLARE_ACCOUNT_ID;
|
|
606
|
+
if (!accountId) {
|
|
607
|
+
// No account id — leave the short form and let wrangler error
|
|
608
|
+
// out with a clearer message. This branch fires only in dry
|
|
609
|
+
// builds where the env isn't wired (e.g. `alepha build` without
|
|
610
|
+
// `alepha platform up` around it).
|
|
611
|
+
return image;
|
|
612
|
+
}
|
|
613
|
+
return `registry.cloudflare.com/${accountId}/${image}`;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
protected enhanceContainers(
|
|
617
|
+
ctx: BuildTaskContext,
|
|
618
|
+
wrangler: WranglerConfig,
|
|
619
|
+
): ContainerDescriptor[] {
|
|
620
|
+
const descriptors: ContainerDescriptor[] = ctx.manifest
|
|
621
|
+
? (ctx.manifest.containers as ContainerDescriptor[])
|
|
622
|
+
: this.discoverContainers(ctx);
|
|
623
|
+
if (descriptors.length === 0) {
|
|
624
|
+
return [];
|
|
625
|
+
}
|
|
324
626
|
|
|
325
627
|
wrangler.containers = wrangler.containers || [];
|
|
326
628
|
wrangler.durable_objects = wrangler.durable_objects || {};
|
|
@@ -331,7 +633,7 @@ export class BuildCloudflareTask extends BuildTask {
|
|
|
331
633
|
for (const d of descriptors) {
|
|
332
634
|
wrangler.containers.push({
|
|
333
635
|
class_name: d.className,
|
|
334
|
-
image: d.image,
|
|
636
|
+
image: this.resolveContainerImage(d.image),
|
|
335
637
|
instance_type: d.instanceType,
|
|
336
638
|
max_instances: d.maxInstances,
|
|
337
639
|
});
|
|
@@ -357,20 +659,24 @@ export class BuildCloudflareTask extends BuildTask {
|
|
|
357
659
|
distDir: string,
|
|
358
660
|
containers: ContainerDescriptor[] = [],
|
|
359
661
|
): Promise<void> {
|
|
662
|
+
// Extend `globalThis.__alepha_CloudflareContainer` instead of
|
|
663
|
+
// importing `@cloudflare/containers` directly. The entry is
|
|
664
|
+
// written AFTER Vite, so any bare specifier in here survives to
|
|
665
|
+
// workerd (which has `no_bundle: true`) and 10021's out. The
|
|
666
|
+
// global is set by a side-effect in `alepha/container`'s
|
|
667
|
+
// workerd entry, which Vite has already inlined into
|
|
668
|
+
// `./index.js`. ESM evaluates top-level imports before the
|
|
669
|
+
// module body, so by the time the `extends` expression below is
|
|
670
|
+
// evaluated, the global is set.
|
|
360
671
|
const containerDeclarations = containers
|
|
361
672
|
.map((c) => {
|
|
362
673
|
const envVars = c.envVars
|
|
363
674
|
? ` envVars = ${JSON.stringify(c.envVars)};\n`
|
|
364
675
|
: "";
|
|
365
|
-
return `export class ${c.className} extends
|
|
676
|
+
return `export class ${c.className} extends globalThis.__alepha_CloudflareContainer {\n defaultPort = ${c.port};\n sleepAfter = "${c.sleepAfter}";\n${envVars}}`;
|
|
366
677
|
})
|
|
367
678
|
.join("\n\n");
|
|
368
679
|
|
|
369
|
-
const containerImport =
|
|
370
|
-
containers.length > 0
|
|
371
|
-
? `import { Container } from "@cloudflare/containers";\n\n${containerDeclarations}\n\n`
|
|
372
|
-
: "";
|
|
373
|
-
|
|
374
680
|
const workerCode = `
|
|
375
681
|
import "./index.js";
|
|
376
682
|
|
|
@@ -385,11 +691,19 @@ const setWaitUntil = (executionCtx) => {
|
|
|
385
691
|
}
|
|
386
692
|
};
|
|
387
693
|
|
|
694
|
+
// Bind the per-invocation Worker \`env\`: keep the full binding (D1, R2, KV, …)
|
|
695
|
+
// in the store for providers, and lift its string values (secrets/vars like
|
|
696
|
+
// PUBLIC_URL) into \`alepha.env\` so \`$env\` resolves them at runtime.
|
|
697
|
+
const bindEnv = (env) => {
|
|
698
|
+
__alepha.set("cloudflare.env", env);
|
|
699
|
+
__alepha.loadEnv(env);
|
|
700
|
+
};
|
|
701
|
+
|
|
388
702
|
export default {
|
|
389
703
|
fetch: async (request, env, executionCtx) => {
|
|
390
704
|
const ctx = { req: request, res: undefined };
|
|
391
705
|
|
|
392
|
-
|
|
706
|
+
bindEnv(env);
|
|
393
707
|
setWaitUntil(executionCtx);
|
|
394
708
|
|
|
395
709
|
try {
|
|
@@ -405,7 +719,7 @@ export default {
|
|
|
405
719
|
},
|
|
406
720
|
|
|
407
721
|
scheduled: async (event, env, executionCtx) => {
|
|
408
|
-
|
|
722
|
+
bindEnv(env);
|
|
409
723
|
setWaitUntil(executionCtx);
|
|
410
724
|
|
|
411
725
|
try {
|
|
@@ -422,7 +736,7 @@ export default {
|
|
|
422
736
|
},
|
|
423
737
|
|
|
424
738
|
queue: async (batch, env, executionCtx) => {
|
|
425
|
-
|
|
739
|
+
bindEnv(env);
|
|
426
740
|
setWaitUntil(executionCtx);
|
|
427
741
|
|
|
428
742
|
try {
|
|
@@ -444,9 +758,12 @@ export default {
|
|
|
444
758
|
};
|
|
445
759
|
`.trim();
|
|
446
760
|
|
|
761
|
+
const containerBlock =
|
|
762
|
+
containers.length > 0 ? `${containerDeclarations}\n\n` : "";
|
|
763
|
+
|
|
447
764
|
await this.fs.writeFile(
|
|
448
765
|
this.fs.join(root, distDir, "main.cloudflare.js"),
|
|
449
|
-
`${this.warningComment}\n${
|
|
766
|
+
`${this.warningComment}\n${containerBlock}${workerCode}`.trim(),
|
|
450
767
|
);
|
|
451
768
|
}
|
|
452
769
|
}
|
|
@@ -457,7 +774,16 @@ interface ContainerDescriptor {
|
|
|
457
774
|
image: string;
|
|
458
775
|
port: number;
|
|
459
776
|
sleepAfter: string;
|
|
460
|
-
|
|
777
|
+
/**
|
|
778
|
+
* Cloudflare Containers instance class.
|
|
779
|
+
*
|
|
780
|
+
* `dev` is the wrangler-pre-GA name; the platform accepts it but
|
|
781
|
+
* emits a deprecation warning telling you to use `lite`. We
|
|
782
|
+
* silently translate at write time (see `discoverContainers`
|
|
783
|
+
* default + `enhanceContainers` write) so older
|
|
784
|
+
* `$container({ instanceType: "dev" })` declarations keep working.
|
|
785
|
+
*/
|
|
786
|
+
instanceType: "dev" | "lite" | "basic" | "standard";
|
|
461
787
|
maxInstances: number;
|
|
462
788
|
envVars?: Record<string, string>;
|
|
463
789
|
}
|
|
@@ -73,10 +73,12 @@ export class BuildDockerTask extends BuildTask {
|
|
|
73
73
|
name: "generate deploy config (docker)",
|
|
74
74
|
handler: async () => {
|
|
75
75
|
const migrationsCopied = await this.copyMigrations(ctx.root, distDir);
|
|
76
|
+
const hasDeps = await this.hasRuntimeDeps(ctx.root, distDir);
|
|
76
77
|
await this.writeDockerfile(ctx.root, distDir, {
|
|
77
78
|
compile,
|
|
78
79
|
standard: { image: dockerFrom, command: dockerCommand },
|
|
79
80
|
hasMigrations: migrationsCopied,
|
|
81
|
+
hasDeps,
|
|
80
82
|
install: ctx.options.docker?.install ?? [],
|
|
81
83
|
});
|
|
82
84
|
},
|
|
@@ -211,6 +213,28 @@ export class BuildDockerTask extends BuildTask {
|
|
|
211
213
|
return false;
|
|
212
214
|
}
|
|
213
215
|
|
|
216
|
+
/**
|
|
217
|
+
* Whether the produced `dist/package.json` declares any runtime
|
|
218
|
+
* dependencies. Alepha apps normally bundle everything into the
|
|
219
|
+
* server entry via Vite, leaving `dependencies: {}` — in which case
|
|
220
|
+
* the generated Dockerfile's `RUN npm install` is wasted work
|
|
221
|
+
* (and emits deprecation noise). Skip the line when empty.
|
|
222
|
+
*/
|
|
223
|
+
protected async hasRuntimeDeps(
|
|
224
|
+
root: string,
|
|
225
|
+
distDir: string,
|
|
226
|
+
): Promise<boolean> {
|
|
227
|
+
try {
|
|
228
|
+
const pkg = await this.fs.readJsonFile<{
|
|
229
|
+
dependencies?: Record<string, string>;
|
|
230
|
+
}>(this.fs.join(root, distDir, "package.json"));
|
|
231
|
+
return Object.keys(pkg.dependencies ?? {}).length > 0;
|
|
232
|
+
} catch {
|
|
233
|
+
// No package.json in dist/ → nothing to install.
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
214
238
|
protected async writeDockerfile(
|
|
215
239
|
root: string,
|
|
216
240
|
distDir: string,
|
|
@@ -218,6 +242,7 @@ export class BuildDockerTask extends BuildTask {
|
|
|
218
242
|
compile: ResolvedCompile | null;
|
|
219
243
|
standard: { image: string; command: string };
|
|
220
244
|
hasMigrations: boolean;
|
|
245
|
+
hasDeps: boolean;
|
|
221
246
|
install: string[];
|
|
222
247
|
},
|
|
223
248
|
): Promise<void> {
|
|
@@ -244,12 +269,18 @@ ENTRYPOINT ["/app/app"]
|
|
|
244
269
|
`;
|
|
245
270
|
} else {
|
|
246
271
|
const { image, command } = opts.standard;
|
|
272
|
+
// Skip `RUN <pm> install` when `dist/package.json` declares no
|
|
273
|
+
// runtime deps — Alepha apps normally bundle everything via Vite,
|
|
274
|
+
// making the install a no-op that just emits deprecation noise.
|
|
275
|
+
const baseInstallLine = opts.hasDeps
|
|
276
|
+
? `RUN ${command === "bun" ? "bun" : "npm"} install\n`
|
|
277
|
+
: "";
|
|
247
278
|
// Install requested packages locally (no --global). They land in
|
|
248
279
|
// `/app/node_modules/`, alongside the app's own deps. Use
|
|
249
280
|
// `--no-save` so we don't mutate the bundled package.json. Node
|
|
250
281
|
// module resolution walks up into `/app/node_modules/` when the
|
|
251
282
|
// workspace lives under `/app/workspace/<deploy-id>/`.
|
|
252
|
-
const
|
|
283
|
+
const extraInstallLine = opts.install.length
|
|
253
284
|
? `RUN npm install --no-save --no-fund --no-audit ${opts.install.join(" ")}\n`
|
|
254
285
|
: "";
|
|
255
286
|
dockerfile = `${header}FROM ${image}
|
|
@@ -257,8 +288,7 @@ WORKDIR /app
|
|
|
257
288
|
|
|
258
289
|
COPY . .
|
|
259
290
|
|
|
260
|
-
|
|
261
|
-
${installLine}
|
|
291
|
+
${baseInstallLine}${extraInstallLine}
|
|
262
292
|
ENV SERVER_HOST=0.0.0.0
|
|
263
293
|
|
|
264
294
|
CMD ["${command}", "index.js"]
|