alepha 0.21.2 → 0.22.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 +289 -292
- 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 +211 -216
- 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 +1073 -1006
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +283 -61
- 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 +134 -140
- 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 +417 -214
- package/dist/cli/core/index.d.ts.map +1 -1
- package/dist/cli/core/index.js +325 -563
- 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 +8 -12
- package/dist/cli/i18n/index.d.ts.map +1 -1
- 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 +1446 -0
- package/dist/cli/platform-lib/index.d.ts.map +1 -0
- package/dist/cli/platform-lib/index.js +2597 -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 +21 -20
- 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 +16 -20
- package/dist/mcp/index.d.ts.map +1 -1
- 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 -4
- package/dist/react/form/index.d.ts.map +1 -1
- 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 +47 -11
- package/dist/react/i18n/index.d.ts.map +1 -1
- package/dist/react/i18n/index.js +33 -1
- 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 +65 -19
- package/dist/react/router/index.browser.js.map +1 -1
- package/dist/react/router/index.d.ts +327 -222
- package/dist/react/router/index.d.ts.map +1 -1
- package/dist/react/router/index.js +65 -29
- package/dist/react/router/index.js.map +1 -1
- 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 +167 -172
- package/dist/server/auth/index.d.ts.map +1 -1
- package/dist/server/auth/index.js +4 -8
- 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 +5 -7
- package/dist/server/cookies/index.d.ts.map +1 -1
- 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 +88 -73
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js +19 -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 +45 -22
- 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/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 +3 -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/commands/__tests__/BuildCommand.spec.ts +43 -0
- package/src/cli/core/commands/build.ts +108 -30
- 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 -0
- 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 +353 -47
- package/src/cli/core/tasks/BuildDockerTask.ts +33 -3
- 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/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 +402 -165
- 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/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/i18n/components/Translate.tsx +47 -0
- package/src/react/i18n/index.ts +2 -0
- package/src/react/intro/components/GettingStartedAdminSlide.tsx +2 -2
- package/src/react/router/__tests__/$page.spec.tsx +3 -2
- package/src/react/router/__tests__/page-can.spec.ts +18 -13
- package/src/react/router/hooks/useQueryParams.ts +114 -14
- package/src/react/router/primitives/$page.ts +85 -4
- package/src/react/router/providers/ReactBrowserRouterProvider.ts +3 -7
- package/src/react/router/providers/ReactServerProvider.ts +4 -13
- package/src/react/ui/services/SchemaControl.ts +3 -4
- 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/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 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/containers/core/providers/ContainerProvider.ts","../../../src/containers/core/primitives/$container.ts","../../../src/containers/core/providers/MockContainerProvider.ts","../../../src/containers/core/providers/NodeContainerProvider.ts","../../../src/containers/core/index.ts"],"sourcesContent":["import { AlephaError } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport type { ContainerPrimitive } from \"../primitives/$container.ts\";\n\nexport interface ContainerInvokeConfig {\n body?: unknown;\n query?: Record<string, unknown>;\n params?: Record<string, unknown>;\n headers?: Record<string, string>;\n}\n\n/**\n * Abstract transport for `$container` proxies.\n *\n * Concrete subclasses translate a `(container, action, config)` call\n * into an HTTP request that reaches the running container. The default\n * binding on Node throws — apps must register either a\n * `NodeContainerProvider` (with `url` on each primitive) or the\n * Cloudflare workerd variant.\n */\nexport abstract class ContainerProvider {\n protected readonly log = $logger();\n\n /**\n * Invoke a remote action on the container. Subclasses do the work;\n * the default implementation rejects to make missing wiring obvious.\n */\n public async invoke(\n container: ContainerPrimitive,\n action: string,\n config: ContainerInvokeConfig,\n ): Promise<unknown> {\n void config;\n throw new AlephaError(\n `No ContainerProvider configured for container '${container.name}' (action '${action}'). ` +\n `Set up alepha/containers via AlephaContainers and either supply 'url' (Node) or build for target=cloudflare.`,\n );\n }\n\n /**\n * Helper: build the fetch path/body for an action call. Kept as a\n * protected method so workerd and Node providers share the wire\n * shape — `POST /api/<action>` with the JSON body, query params on\n * the URL, and the request headers merged in.\n */\n protected buildRequest(\n action: string,\n config: ContainerInvokeConfig,\n ): { path: string; init: RequestInit } {\n const params = new URLSearchParams();\n if (config.query) {\n for (const [k, v] of Object.entries(config.query)) {\n if (v !== undefined && v !== null) params.set(k, String(v));\n }\n }\n\n let path = `/api/${action}`;\n if (config.params) {\n for (const [k, v] of Object.entries(config.params)) {\n path = path.replace(`:${k}`, encodeURIComponent(String(v)));\n }\n }\n\n const search = params.toString();\n if (search) path += `?${search}`;\n\n const init: RequestInit = {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n ...(config.headers ?? {}),\n },\n body: config.body !== undefined ? JSON.stringify(config.body) : undefined,\n };\n\n return { path, init };\n }\n}\n","import { $inject, AlephaError, createPrimitive, KIND, Primitive } from \"alepha\";\nimport type { ContainerPrimitiveOptions } from \"../interfaces/ContainerOptions.ts\";\nimport { ContainerProvider } from \"../providers/ContainerProvider.ts\";\n\n/**\n * `$container` — typed RPC client to a containerized Alepha app.\n *\n * Returns a typed Proxy whose method calls map 1:1 to the target\n * controller's `$action` endpoints. The wire format mirrors what a\n * normal Alepha server exposes (`POST /api/<method>` with a JSON body),\n * so the container is literally a tiny Alepha worker.\n *\n * Transport is owned by the active {@link ContainerProvider}:\n * - `target=cloudflare` → `CloudflareContainerProvider` routes through\n * the Containers binding (`env.<NAME>.getContainer(...).fetch()`).\n * - Node (with `url` set) → `NodeContainerProvider` uses plain\n * `fetch()` against the configured URL.\n *\n * Build-time, `BuildCloudflareTask.enhanceContainers` walks\n * `alepha.primitives($container)` to emit the matching `wrangler.jsonc`\n * entries and Durable Object class declarations into\n * `main.cloudflare.js`.\n *\n * @example\n * ```ts\n * import { $container } from \"alepha/containers\";\n * import type { RocketController } from \"@alepha/rocket\";\n *\n * class DeployService {\n * rocket = $container<RocketController>({\n * image: \"alepha/rocket:latest\",\n * port: 3000,\n * sleepAfter: \"15m\",\n * });\n *\n * async deploy() {\n * return this.rocket.createJob({ body: { op: \"up\" } });\n * }\n * }\n * ```\n */\nexport const $container = <T extends object = any>(\n options: ContainerPrimitiveOptions,\n): ContainerProxy<T> => {\n if (!options.image) {\n throw new AlephaError(\"$container requires an 'image' option\");\n }\n const instance = createPrimitive(ContainerPrimitive, options);\n return instance.proxy() as ContainerProxy<T>;\n};\n\n/**\n * Typed proxy returned by `$container<T>()`. Each `$action` member of\n * `T` becomes a callable returning the action's response body.\n *\n * The runtime shape is a `Proxy(primitive)` — own-property reads hit the\n * underlying `ContainerPrimitive` (so `alepha.primitives($container)`\n * still finds it via the `instanceof Primitive` check inside\n * `Alepha.new()`), and anything else is treated as an action name and\n * routed through the active `ContainerProvider`.\n */\nexport type ContainerProxy<T extends object> = {\n [K in keyof T]: T[K] extends (...args: infer A) => infer R\n ? (...args: A) => Promise<Awaited<R>>\n : (config?: {\n body?: unknown;\n query?: unknown;\n params?: unknown;\n }) => Promise<any>;\n};\n\nexport class ContainerPrimitive extends Primitive<ContainerPrimitiveOptions> {\n protected readonly provider = $inject(ContainerProvider);\n\n public get name(): string {\n return this.options.name ?? this.config.propertyKey;\n }\n\n /**\n * Build the typed Proxy. The target is the primitive itself so\n * `instanceof Primitive` keeps working (required by Alepha's\n * primitive registration in `Alepha.new`). Property reads that match\n * an own/inherited member return that member; anything else is\n * treated as an action name and routed through the provider.\n */\n public proxy<T extends object = any>(): ContainerProxy<T> {\n const primitive = this;\n return new Proxy(primitive as any, {\n get(target: any, prop: string | symbol, receiver: any) {\n if (typeof prop === \"symbol\" || prop in target) {\n return Reflect.get(target, prop, receiver);\n }\n return (config: any = {}) =>\n primitive.provider.invoke(primitive, prop as string, config);\n },\n }) as ContainerProxy<T>;\n }\n}\n\n$container[KIND] = ContainerPrimitive;\n","import { $inject, Alepha, AlephaError } from \"alepha\";\nimport type { ContainerPrimitive } from \"../primitives/$container.ts\";\nimport {\n type ContainerInvokeConfig,\n ContainerProvider,\n} from \"./ContainerProvider.ts\";\n\n/**\n * In-process test provider.\n *\n * Resolves the action name against `LinkProvider`'s registered links in\n * the SAME Alepha instance — effectively calling the \"containerized\"\n * controller as if it were local. Use it in tests: register the\n * controller class on the test container alongside the consumer and\n * substitute `ContainerProvider` with `MockContainerProvider`.\n *\n * @example\n * ```ts\n * const alepha = Alepha.create()\n * .with(AlephaContainers)\n * .with(RocketController)\n * .with(MyApp)\n * .with({ provide: ContainerProvider, use: MockContainerProvider });\n * ```\n */\nexport class MockContainerProvider extends ContainerProvider {\n protected readonly alepha = $inject(Alepha);\n\n public override async invoke(\n container: ContainerPrimitive,\n action: string,\n config: ContainerInvokeConfig,\n ): Promise<unknown> {\n void container;\n // Lazy-resolve LinkProvider so tests that don't load `alepha/server/links`\n // still get a clear error message.\n const linkProviderClass = await this.loadLinkProvider();\n const linkProvider = this.alepha.inject(linkProviderClass) as {\n follow: (\n name: string,\n config?: Record<string, unknown>,\n ) => Promise<unknown>;\n };\n return await linkProvider.follow(action, {\n body: config.body,\n query: config.query,\n params: config.params,\n headers: config.headers,\n });\n }\n\n protected async loadLinkProvider(): Promise<any> {\n try {\n const mod = await import(\"alepha/server/links\");\n return mod.LinkProvider;\n } catch {\n throw new AlephaError(\n \"MockContainerProvider needs 'alepha/server/links' to be available — add AlephaServerLinks to the test app.\",\n );\n }\n }\n}\n","import { AlephaError } from \"alepha\";\nimport type { ContainerPrimitive } from \"../primitives/$container.ts\";\nimport {\n type ContainerInvokeConfig,\n ContainerProvider,\n} from \"./ContainerProvider.ts\";\n\n/**\n * Node (dev / test / non-Cloudflare) container provider.\n *\n * Routes proxy calls through plain `fetch()` against the URL given on\n * the `$container` primitive. If no `url` is supplied, calls throw —\n * v1 deliberately has no Docker spawning. This is the \"temporary, not\n * perfect\" Node path documented in the spec; the longer-term plan is\n * to plug in a `target=docker` adapter once that lands.\n */\nexport class NodeContainerProvider extends ContainerProvider {\n public override async invoke(\n container: ContainerPrimitive,\n action: string,\n config: ContainerInvokeConfig,\n ): Promise<unknown> {\n const url = this.resolveUrl(container);\n if (!url) {\n throw new AlephaError(\n `Container '${container.name}' has no 'url' configured — NodeContainerProvider cannot reach the container.`,\n );\n }\n\n const { path, init } = this.buildRequest(action, config);\n const response = await fetch(`${url.replace(/\\/$/, \"\")}${path}`, init);\n\n if (!response.ok) {\n const text = await response.text().catch(() => \"\");\n throw new AlephaError(\n `Container '${container.name}' action '${action}' failed: ${response.status} ${response.statusText}${\n text ? ` — ${text}` : \"\"\n }`,\n );\n }\n\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n if (contentType.includes(\"application/json\")) {\n return await response.json();\n }\n return await response.text();\n }\n\n protected resolveUrl(container: ContainerPrimitive): string | undefined {\n const url = container.options.url;\n return typeof url === \"function\" ? url() : url;\n }\n}\n","import { $module } from \"alepha\";\nimport { $container } from \"./primitives/$container.ts\";\nimport { ContainerProvider } from \"./providers/ContainerProvider.ts\";\nimport { MockContainerProvider } from \"./providers/MockContainerProvider.ts\";\nimport { NodeContainerProvider } from \"./providers/NodeContainerProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./interfaces/ContainerOptions.ts\";\nexport * from \"./primitives/$container.ts\";\nexport * from \"./providers/ContainerProvider.ts\";\nexport * from \"./providers/MockContainerProvider.ts\";\nexport * from \"./providers/NodeContainerProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Type-safe RPC clients for ephemeral containerized Alepha apps.\n *\n * **Features:**\n * - `$container<T>()` directive returns a typed Proxy onto a remote\n * Alepha controller's `$action` endpoints — the wire format is the\n * same `POST /api/<method>` shape served by every Alepha server.\n * - Pluggable transport: Node (plain `fetch` against a configured URL),\n * Mock (in-process call via `LinkProvider.follow` for tests),\n * Cloudflare workerd (`getContainer().fetch()` through the Containers\n * binding — see `alepha/containers` workerd entry).\n * - Build-time integration: `BuildCloudflareTask.enhanceContainers`\n * emits the matching wrangler bindings and Durable Object class\n * declarations.\n *\n * The Node binding is the \"temporary, not perfect\" path documented in\n * the spec — apps need to provide an explicit `url` per primitive\n * until a `target=docker` adapter ships.\n *\n * @module alepha.containers\n */\nexport const AlephaContainers = $module({\n name: \"alepha.containers\",\n primitives: [$container],\n services: [ContainerProvider],\n variants: [MockContainerProvider, NodeContainerProvider],\n register: (alepha) => {\n alepha.with({\n optional: true,\n provide: ContainerProvider,\n use: alepha.isTest() ? MockContainerProvider : NodeContainerProvider,\n });\n },\n});\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.workerd.js","names":[],"sources":["../../../src/containers/core/providers/ContainerProvider.ts","../../../src/containers/core/primitives/$container.ts","../../../src/containers/core/providers/CloudflareContainerProvider.ts","../../../src/containers/core/index.workerd.ts"],"sourcesContent":["import { AlephaError } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport type { ContainerPrimitive } from \"../primitives/$container.ts\";\n\nexport interface ContainerInvokeConfig {\n body?: unknown;\n query?: Record<string, unknown>;\n params?: Record<string, unknown>;\n headers?: Record<string, string>;\n}\n\n/**\n * Abstract transport for `$container` proxies.\n *\n * Concrete subclasses translate a `(container, action, config)` call\n * into an HTTP request that reaches the running container. The default\n * binding on Node throws — apps must register either a\n * `NodeContainerProvider` (with `url` on each primitive) or the\n * Cloudflare workerd variant.\n */\nexport abstract class ContainerProvider {\n protected readonly log = $logger();\n\n /**\n * Invoke a remote action on the container. Subclasses do the work;\n * the default implementation rejects to make missing wiring obvious.\n */\n public async invoke(\n container: ContainerPrimitive,\n action: string,\n config: ContainerInvokeConfig,\n ): Promise<unknown> {\n void config;\n throw new AlephaError(\n `No ContainerProvider configured for container '${container.name}' (action '${action}'). ` +\n `Set up alepha/containers via AlephaContainers and either supply 'url' (Node) or build for target=cloudflare.`,\n );\n }\n\n /**\n * Helper: build the fetch path/body for an action call. Kept as a\n * protected method so workerd and Node providers share the wire\n * shape — `POST /api/<action>` with the JSON body, query params on\n * the URL, and the request headers merged in.\n */\n protected buildRequest(\n action: string,\n config: ContainerInvokeConfig,\n ): { path: string; init: RequestInit } {\n const params = new URLSearchParams();\n if (config.query) {\n for (const [k, v] of Object.entries(config.query)) {\n if (v !== undefined && v !== null) params.set(k, String(v));\n }\n }\n\n let path = `/api/${action}`;\n if (config.params) {\n for (const [k, v] of Object.entries(config.params)) {\n path = path.replace(`:${k}`, encodeURIComponent(String(v)));\n }\n }\n\n const search = params.toString();\n if (search) path += `?${search}`;\n\n const init: RequestInit = {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n ...(config.headers ?? {}),\n },\n body: config.body !== undefined ? JSON.stringify(config.body) : undefined,\n };\n\n return { path, init };\n }\n}\n","import { $inject, AlephaError, createPrimitive, KIND, Primitive } from \"alepha\";\nimport type { ContainerPrimitiveOptions } from \"../interfaces/ContainerOptions.ts\";\nimport { ContainerProvider } from \"../providers/ContainerProvider.ts\";\n\n/**\n * `$container` — typed RPC client to a containerized Alepha app.\n *\n * Returns a typed Proxy whose method calls map 1:1 to the target\n * controller's `$action` endpoints. The wire format mirrors what a\n * normal Alepha server exposes (`POST /api/<method>` with a JSON body),\n * so the container is literally a tiny Alepha worker.\n *\n * Transport is owned by the active {@link ContainerProvider}:\n * - `target=cloudflare` → `CloudflareContainerProvider` routes through\n * the Containers binding (`env.<NAME>.getContainer(...).fetch()`).\n * - Node (with `url` set) → `NodeContainerProvider` uses plain\n * `fetch()` against the configured URL.\n *\n * Build-time, `BuildCloudflareTask.enhanceContainers` walks\n * `alepha.primitives($container)` to emit the matching `wrangler.jsonc`\n * entries and Durable Object class declarations into\n * `main.cloudflare.js`.\n *\n * @example\n * ```ts\n * import { $container } from \"alepha/containers\";\n * import type { RocketController } from \"@alepha/rocket\";\n *\n * class DeployService {\n * rocket = $container<RocketController>({\n * image: \"alepha/rocket:latest\",\n * port: 3000,\n * sleepAfter: \"15m\",\n * });\n *\n * async deploy() {\n * return this.rocket.createJob({ body: { op: \"up\" } });\n * }\n * }\n * ```\n */\nexport const $container = <T extends object = any>(\n options: ContainerPrimitiveOptions,\n): ContainerProxy<T> => {\n if (!options.image) {\n throw new AlephaError(\"$container requires an 'image' option\");\n }\n const instance = createPrimitive(ContainerPrimitive, options);\n return instance.proxy() as ContainerProxy<T>;\n};\n\n/**\n * Typed proxy returned by `$container<T>()`. Each `$action` member of\n * `T` becomes a callable returning the action's response body.\n *\n * The runtime shape is a `Proxy(primitive)` — own-property reads hit the\n * underlying `ContainerPrimitive` (so `alepha.primitives($container)`\n * still finds it via the `instanceof Primitive` check inside\n * `Alepha.new()`), and anything else is treated as an action name and\n * routed through the active `ContainerProvider`.\n */\nexport type ContainerProxy<T extends object> = {\n [K in keyof T]: T[K] extends (...args: infer A) => infer R\n ? (...args: A) => Promise<Awaited<R>>\n : (config?: {\n body?: unknown;\n query?: unknown;\n params?: unknown;\n }) => Promise<any>;\n};\n\nexport class ContainerPrimitive extends Primitive<ContainerPrimitiveOptions> {\n protected readonly provider = $inject(ContainerProvider);\n\n public get name(): string {\n return this.options.name ?? this.config.propertyKey;\n }\n\n /**\n * Build the typed Proxy. The target is the primitive itself so\n * `instanceof Primitive` keeps working (required by Alepha's\n * primitive registration in `Alepha.new`). Property reads that match\n * an own/inherited member return that member; anything else is\n * treated as an action name and routed through the provider.\n */\n public proxy<T extends object = any>(): ContainerProxy<T> {\n const primitive = this;\n return new Proxy(primitive as any, {\n get(target: any, prop: string | symbol, receiver: any) {\n if (typeof prop === \"symbol\" || prop in target) {\n return Reflect.get(target, prop, receiver);\n }\n return (config: any = {}) =>\n primitive.provider.invoke(primitive, prop as string, config);\n },\n }) as ContainerProxy<T>;\n }\n}\n\n$container[KIND] = ContainerPrimitive;\n","import { $inject, Alepha, AlephaError } from \"alepha\";\nimport type { ContainerPrimitive } from \"../primitives/$container.ts\";\nimport {\n type ContainerInvokeConfig,\n ContainerProvider,\n} from \"./ContainerProvider.ts\";\n\n/**\n * Cloudflare Workers (workerd) container provider.\n *\n * Routes proxy calls through the Cloudflare Containers binding bound on\n * `env.<NAME>`, using a single shared instance per container\n * (`getContainer(env.NAME, \"shared\")`). The binding is generated by\n * `BuildCloudflareTask.enhanceContainers` from the `$container`\n * primitives discovered in the app.\n *\n * The runtime `env` object is pulled from the Alepha store key\n * `cloudflare.env` — the worker entry point publishes it there on every\n * fetch (`__alepha.set(\"cloudflare.env\", env)`).\n */\nexport class CloudflareContainerProvider extends ContainerProvider {\n protected readonly alepha = $inject(Alepha);\n\n public override async invoke(\n container: ContainerPrimitive,\n action: string,\n config: ContainerInvokeConfig,\n ): Promise<unknown> {\n const env = this.alepha.store.get(\"cloudflare.env\") as\n | Record<string, unknown>\n | undefined;\n if (!env) {\n throw new AlephaError(\n `CloudflareContainerProvider could not resolve 'cloudflare.env' from the store — is the app running on workerd?`,\n );\n }\n\n const binding = env[container.name.toUpperCase()] as\n | {\n getContainer?: (id: string) => {\n fetch(req: Request): Promise<Response>;\n };\n }\n | undefined;\n\n if (!binding?.getContainer) {\n throw new AlephaError(\n `Cloudflare Containers binding '${container.name.toUpperCase()}' not found on env — check wrangler.jsonc.`,\n );\n }\n\n const instance = binding.getContainer(\"shared\");\n const { path, init } = this.buildRequest(action, config);\n const request = new Request(`http://container${path}`, init);\n const response = await instance.fetch(request);\n\n if (!response.ok) {\n const text = await response.text().catch(() => \"\");\n throw new AlephaError(\n `Container '${container.name}' action '${action}' failed: ${response.status} ${response.statusText}${\n text ? ` — ${text}` : \"\"\n }`,\n );\n }\n\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n if (contentType.includes(\"application/json\")) {\n return await response.json();\n }\n return await response.text();\n }\n}\n","import { $module } from \"alepha\";\nimport { $container } from \"./primitives/$container.ts\";\nimport { CloudflareContainerProvider } from \"./providers/CloudflareContainerProvider.ts\";\nimport { ContainerProvider } from \"./providers/ContainerProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./interfaces/ContainerOptions.ts\";\nexport * from \"./primitives/$container.ts\";\nexport * from \"./providers/CloudflareContainerProvider.ts\";\nexport * from \"./providers/ContainerProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Type-safe RPC clients for ephemeral containerized Alepha apps,\n * Cloudflare workerd build.\n *\n * Auto-binds `CloudflareContainerProvider` so `$container()` calls\n * route through `env.<NAME>.getContainer(...).fetch()`. Pair with\n * `BuildCloudflareTask.enhanceContainers` (in `alepha/cli/core`) which\n * emits the wrangler.jsonc bindings and DO class declarations.\n *\n * @module alepha.containers\n */\nexport const AlephaContainers = $module({\n name: \"alepha.containers\",\n primitives: [$container],\n services: [ContainerProvider, CloudflareContainerProvider],\n register: (alepha) => {\n alepha.with({\n optional: true,\n provide: ContainerProvider,\n use: CloudflareContainerProvider,\n });\n },\n});\n"],"mappings":"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"}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `components.json` is the shadcn CLI's project config — it tells
|
|
3
|
-
* `shadcn add` where to drop primitives, which tailwind tokens to use,
|
|
4
|
-
* which icon library to wire up, and which custom registries to resolve.
|
|
5
|
-
*
|
|
6
|
-
* Aliases follow shadcn's defaults (`@/components`, `@/lib/utils`) so the
|
|
7
|
-
* CLI honors them across `init` + `add` calls. Alepha app code lives at
|
|
8
|
-
* `src/web/` (Home, AppRouter, …) and the shadcn primitives live at
|
|
9
|
-
* `src/components/` — kept separate to make the registry components
|
|
10
|
-
* trivially upgradable via `shadcn add --overwrite`.
|
|
11
|
-
*
|
|
12
|
-
* The `registries` block pre-wires the public Alepha registry — consumers
|
|
13
|
-
* can immediately run e.g. `shadcn add @alepha/auth-login`.
|
|
14
|
-
*/
|
|
15
|
-
export const componentsJsonTs = () =>
|
|
16
|
-
`{
|
|
17
|
-
"$schema": "https://ui.shadcn.com/schema.json",
|
|
18
|
-
"style": "new-york",
|
|
19
|
-
"rsc": false,
|
|
20
|
-
"tsx": true,
|
|
21
|
-
"tailwind": {
|
|
22
|
-
"config": "",
|
|
23
|
-
"css": "src/main.css",
|
|
24
|
-
"baseColor": "neutral",
|
|
25
|
-
"cssVariables": true
|
|
26
|
-
},
|
|
27
|
-
"aliases": {
|
|
28
|
-
"components": "@/components",
|
|
29
|
-
"utils": "@/lib/utils",
|
|
30
|
-
"ui": "@/components/ui",
|
|
31
|
-
"lib": "@/lib",
|
|
32
|
-
"hooks": "@/hooks"
|
|
33
|
-
},
|
|
34
|
-
"iconLibrary": "lucide",
|
|
35
|
-
"registries": {
|
|
36
|
-
"@alepha": "https://alepha.dev/r/{name}.json"
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
`;
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SaaS admin layout — full AppShell on /admin with a sidebar, breadcrumbs,
|
|
3
|
-
* a Sonner toaster, and a confirm provider. The page list grows with
|
|
4
|
-
* whatever `admin-*` registry components the user adds.
|
|
5
|
-
*
|
|
6
|
-
* All UI primitives come from `src/components/*` where `shadcn add` drops
|
|
7
|
-
* them; alepha app code lives in `src/web/*` and references them via the
|
|
8
|
-
* `@/components/*` alias.
|
|
9
|
-
*/
|
|
10
|
-
export const saasAdminLayoutTsx = () =>
|
|
11
|
-
`import { AppShell } from "@/components/app-shell/app-shell";
|
|
12
|
-
import { Toaster } from "@/components/ui/sonner";
|
|
13
|
-
import { TooltipProvider } from "@/components/ui/tooltip";
|
|
14
|
-
import { DialogProvider } from "@/components/use-dialog/use-dialog";
|
|
15
|
-
import { NestedView, useRouterState } from "alepha/react/router";
|
|
16
|
-
import { ShieldCheck, Users } from "lucide-react";
|
|
17
|
-
|
|
18
|
-
const NAV = [
|
|
19
|
-
{
|
|
20
|
-
label: "Identity",
|
|
21
|
-
items: [
|
|
22
|
-
{ href: "/admin/users", label: "Users", icon: Users },
|
|
23
|
-
{ href: "/admin/sessions", label: "Sessions", icon: ShieldCheck },
|
|
24
|
-
],
|
|
25
|
-
},
|
|
26
|
-
] as const;
|
|
27
|
-
|
|
28
|
-
const findCrumbs = (pathname: string): { label: string; href?: string }[] => {
|
|
29
|
-
for (const group of NAV) {
|
|
30
|
-
const match = group.items.find((it) => it.href === pathname);
|
|
31
|
-
if (match) return [{ label: group.label }, { label: match.label }];
|
|
32
|
-
}
|
|
33
|
-
return [];
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const AdminLayout = () => {
|
|
37
|
-
const state = useRouterState();
|
|
38
|
-
const crumbs = findCrumbs(state.url.pathname);
|
|
39
|
-
|
|
40
|
-
return (
|
|
41
|
-
<TooltipProvider>
|
|
42
|
-
<DialogProvider>
|
|
43
|
-
<AppShell
|
|
44
|
-
brand={
|
|
45
|
-
<a
|
|
46
|
-
href="/admin"
|
|
47
|
-
className="flex items-center gap-2 px-2 py-2 font-semibold group-data-[collapsible=icon]:justify-center group-data-[collapsible=icon]:px-0"
|
|
48
|
-
>
|
|
49
|
-
<span className="bg-primary text-primary-foreground flex size-7 shrink-0 items-center justify-center rounded">
|
|
50
|
-
α
|
|
51
|
-
</span>
|
|
52
|
-
<span className="truncate group-data-[collapsible=icon]:hidden">
|
|
53
|
-
Admin
|
|
54
|
-
</span>
|
|
55
|
-
</a>
|
|
56
|
-
}
|
|
57
|
-
nav={NAV.map((group) => ({
|
|
58
|
-
label: group.label,
|
|
59
|
-
items: group.items.map((it) => ({
|
|
60
|
-
href: it.href,
|
|
61
|
-
label: it.label,
|
|
62
|
-
icon: it.icon,
|
|
63
|
-
active: it.href === state.url.pathname,
|
|
64
|
-
})),
|
|
65
|
-
}))}
|
|
66
|
-
breadcrumbs={crumbs.length ? crumbs : undefined}
|
|
67
|
-
>
|
|
68
|
-
<NestedView />
|
|
69
|
-
</AppShell>
|
|
70
|
-
<Toaster />
|
|
71
|
-
</DialogProvider>
|
|
72
|
-
</TooltipProvider>
|
|
73
|
-
);
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
export default AdminLayout;
|
|
77
|
-
`;
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Admin pages — each is a thin wrapper around the matching `admin-*`
|
|
3
|
-
* registry component (placed at `src/components/admin/*`). The starter
|
|
4
|
-
* ships with Users + Sessions; add more by `shadcn add @alepha/admin-…`
|
|
5
|
-
* and a matching `$page(...)` in AppRouter.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
export const saasAdminUsersTsx = () =>
|
|
9
|
-
`import { AdminUsers } from "@/components/admin/admin-users";
|
|
10
|
-
|
|
11
|
-
const AdminUsersPage = () => {
|
|
12
|
-
return <AdminUsers />;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export default AdminUsersPage;
|
|
16
|
-
`;
|
|
17
|
-
|
|
18
|
-
export const saasAdminSessionsTsx = () =>
|
|
19
|
-
`import { AdminSessions } from "@/components/admin/admin-sessions";
|
|
20
|
-
|
|
21
|
-
const AdminSessionsPage = () => {
|
|
22
|
-
return <AdminSessions />;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export default AdminSessionsPage;
|
|
26
|
-
`;
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SaaS auth layout — route parent for every /auth/* page (login, register,
|
|
3
|
-
* reset-password, verify-email), mounted as children so they share it.
|
|
4
|
-
*
|
|
5
|
-
* The auth-* blocks from the registry are self-contained full-page layouts
|
|
6
|
-
* (they own their own min-height, centering and padding), so this layout is
|
|
7
|
-
* just a passthrough — wrapping them in another centered, padded, full-height
|
|
8
|
-
* box would overflow the viewport and add a scrollbar.
|
|
9
|
-
*/
|
|
10
|
-
export const saasAuthLayoutTsx = () =>
|
|
11
|
-
`import { NestedView } from "alepha/react/router";
|
|
12
|
-
|
|
13
|
-
const AuthLayout = () => {
|
|
14
|
-
return (
|
|
15
|
-
<div className="bg-background">
|
|
16
|
-
<NestedView />
|
|
17
|
-
</div>
|
|
18
|
-
);
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export default AuthLayout;
|
|
22
|
-
`;
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Per-page wrapper around the registry components. The registry component
|
|
3
|
-
* receives the realm config from the page loader; the page itself stays a
|
|
4
|
-
* thin shell so apps can layer their branding around it.
|
|
5
|
-
*
|
|
6
|
-
* Registry components land at `src/components/auth/*` (shadcn defaults).
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
export const saasAuthLoginTsx = () =>
|
|
10
|
-
`import { AuthLogin } from "@/components/auth/auth-login";
|
|
11
|
-
import type { RealmConfig } from "alepha/api/users";
|
|
12
|
-
|
|
13
|
-
export interface AuthLoginPageProps {
|
|
14
|
-
realmConfig: RealmConfig;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const AuthLoginPage = (props: AuthLoginPageProps) => {
|
|
18
|
-
return <AuthLogin realmConfig={props.realmConfig} />;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export default AuthLoginPage;
|
|
22
|
-
`;
|
|
23
|
-
|
|
24
|
-
export const saasAuthRegisterTsx = () =>
|
|
25
|
-
`import { AuthRegister } from "@/components/auth/auth-register";
|
|
26
|
-
import type { RealmConfig } from "alepha/api/users";
|
|
27
|
-
|
|
28
|
-
export interface AuthRegisterPageProps {
|
|
29
|
-
realmConfig: RealmConfig;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const AuthRegisterPage = (props: AuthRegisterPageProps) => {
|
|
33
|
-
return <AuthRegister realmConfig={props.realmConfig} />;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export default AuthRegisterPage;
|
|
37
|
-
`;
|
|
38
|
-
|
|
39
|
-
export const saasAuthResetPasswordTsx = () =>
|
|
40
|
-
`import { AuthResetPassword } from "@/components/auth/auth-reset-password";
|
|
41
|
-
import type { RealmConfig } from "alepha/api/users";
|
|
42
|
-
|
|
43
|
-
export interface AuthResetPasswordPageProps {
|
|
44
|
-
realmConfig: RealmConfig;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const AuthResetPasswordPage = (props: AuthResetPasswordPageProps) => {
|
|
48
|
-
return <AuthResetPassword realmConfig={props.realmConfig} />;
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
export default AuthResetPasswordPage;
|
|
52
|
-
`;
|
|
53
|
-
|
|
54
|
-
export const saasAuthVerifyEmailTsx = () =>
|
|
55
|
-
`import { AuthVerifyEmail } from "@/components/auth/auth-verify-email";
|
|
56
|
-
|
|
57
|
-
const AuthVerifyEmailPage = () => {
|
|
58
|
-
return <AuthVerifyEmail />;
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
export default AuthVerifyEmailPage;
|
|
62
|
-
`;
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Realm provider scaffolded by `alepha init --saas`.
|
|
3
|
-
*
|
|
4
|
-
* Minimal hello-world setup: credentials login with email, admins seeded
|
|
5
|
-
* from the `ADMIN_EMAILS` env var, and an `admin:ui` permission used by the
|
|
6
|
-
* AppRouter to gate `/admin/*`. The default `admin` role grants `*` (so it
|
|
7
|
-
* inherits `admin:ui`); the default `user` role excludes `admin:*` (so
|
|
8
|
-
* non-admins get a 403 before the shell renders).
|
|
9
|
-
*
|
|
10
|
-
* Admin emails are read from the environment, never hard-coded — they are
|
|
11
|
-
* deployment config (different per environment, and personal data) and
|
|
12
|
-
* belong in `.env`, not in committed source.
|
|
13
|
-
*/
|
|
14
|
-
export const saasRealmProviderTs = () => {
|
|
15
|
-
return `import { $env, t } from "alepha";
|
|
16
|
-
import { $realm } from "alepha/api/users";
|
|
17
|
-
import { $permission } from "alepha/security";
|
|
18
|
-
|
|
19
|
-
export class RealmProvider {
|
|
20
|
-
/**
|
|
21
|
-
* Permission required to open the admin UI. Wired into AppRouter.adminLayout
|
|
22
|
-
* via \`$secure({ permissions: ["admin:ui"] })\`.
|
|
23
|
-
*/
|
|
24
|
-
adminUi = $permission({
|
|
25
|
-
group: "admin",
|
|
26
|
-
name: "ui",
|
|
27
|
-
description: "Access to the admin UI shell",
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Admin emails — set \`ADMIN_EMAILS\` in \`.env\` (comma-separated for
|
|
32
|
-
* several). Keep emails out of source: they are config, not code.
|
|
33
|
-
*/
|
|
34
|
-
protected readonly env = $env(
|
|
35
|
-
t.object({
|
|
36
|
-
ADMIN_EMAILS: t.text({ default: "" }),
|
|
37
|
-
}),
|
|
38
|
-
);
|
|
39
|
-
|
|
40
|
-
realm = $realm({
|
|
41
|
-
settings: {
|
|
42
|
-
adminEmails: this.env.ADMIN_EMAILS.split(",")
|
|
43
|
-
.map((email) => email.trim())
|
|
44
|
-
.filter(Boolean),
|
|
45
|
-
},
|
|
46
|
-
identities: {
|
|
47
|
-
credentials: true,
|
|
48
|
-
},
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
`;
|
|
52
|
-
};
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generates deterministic resource names for cloud deployments.
|
|
3
|
-
*
|
|
4
|
-
* Pattern: `<project>-<env>`.
|
|
5
|
-
*
|
|
6
|
-
* All segments are slugified (lowercase, alphanumeric + dashes, max 63
|
|
7
|
-
* chars). One app per workspace — see `alepha platform`.
|
|
8
|
-
*/
|
|
9
|
-
export class NamingService {
|
|
10
|
-
public forContext(project: string, env: string): NamingContext {
|
|
11
|
-
const prefix = `${this.slugify(project)}-${this.slugify(env)}`;
|
|
12
|
-
return new NamingContext(prefix);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
public slugify(name: string): string {
|
|
16
|
-
return name
|
|
17
|
-
.toLowerCase()
|
|
18
|
-
.replace(/[^a-z0-9]+/g, "-")
|
|
19
|
-
.replace(/^-+|-+$/g, "")
|
|
20
|
-
.slice(0, 63);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export class NamingContext {
|
|
25
|
-
protected readonly prefix: string;
|
|
26
|
-
|
|
27
|
-
constructor(prefix: string) {
|
|
28
|
-
this.prefix = prefix;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
public worker(): string {
|
|
32
|
-
return this.prefix;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
public d1(): string {
|
|
36
|
-
return this.prefix;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
public hyperdrive(): string {
|
|
40
|
-
return this.prefix;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
public r2(): string {
|
|
44
|
-
return this.prefix;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
public kv(): string {
|
|
48
|
-
return this.prefix;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
public queue(): string {
|
|
52
|
-
return this.prefix;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|