alepha 0.20.1 → 0.20.3
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/assets/swagger-ui/swagger-ui-bundle.js +1 -1
- package/assets/swagger-ui/swagger-ui.css +1 -1
- package/dist/api/audits/index.browser.js +49 -0
- package/dist/api/audits/index.browser.js.map +1 -1
- package/dist/api/audits/index.d.ts.map +1 -1
- package/dist/api/audits/index.js +49 -0
- package/dist/api/audits/index.js.map +1 -1
- package/dist/api/files/index.d.ts.map +1 -1
- package/dist/api/files/index.js +2 -1
- package/dist/api/files/index.js.map +1 -1
- package/dist/api/jobs/index.browser.js +64 -148
- package/dist/api/jobs/index.browser.js.map +1 -1
- package/dist/api/jobs/index.d.ts +339 -600
- package/dist/api/jobs/index.d.ts.map +1 -1
- package/dist/api/jobs/index.js +605 -1012
- package/dist/api/jobs/index.js.map +1 -1
- package/dist/api/keys/index.js.map +1 -1
- package/dist/api/notifications/index.d.ts +79 -27
- package/dist/api/notifications/index.d.ts.map +1 -1
- package/dist/api/notifications/index.js +90 -23
- package/dist/api/notifications/index.js.map +1 -1
- package/dist/api/organizations/index.d.ts.map +1 -1
- package/dist/api/parameters/index.browser.js +37 -0
- package/dist/api/parameters/index.browser.js.map +1 -1
- package/dist/api/parameters/index.d.ts +4 -65
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/parameters/index.js +37 -0
- package/dist/api/parameters/index.js.map +1 -1
- package/dist/api/payments/index.d.ts +2 -1
- package/dist/api/payments/index.d.ts.map +1 -1
- package/dist/api/payments/index.js +4 -2
- package/dist/api/payments/index.js.map +1 -1
- package/dist/api/users/index.d.ts +225 -5199
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +15 -11
- package/dist/api/users/index.js.map +1 -1
- package/dist/api/verifications/index.d.ts.map +1 -1
- package/dist/api/verifications/index.js +4 -2
- package/dist/api/verifications/index.js.map +1 -1
- package/dist/bucket/index.js +5 -1
- package/dist/bucket/index.js.map +1 -1
- package/dist/bucket/index.workerd.js +5 -1
- package/dist/bucket/index.workerd.js.map +1 -1
- package/dist/cache/core/index.js.map +1 -1
- package/dist/cache/core/index.workerd.js.map +1 -1
- package/dist/captcha/index.js.map +1 -1
- package/dist/cli/core/index.d.ts +225 -11681
- package/dist/cli/core/index.d.ts.map +1 -1
- package/dist/cli/core/index.js +732 -257
- package/dist/cli/core/index.js.map +1 -1
- package/dist/cli/devtools/index.js +7 -1
- package/dist/cli/devtools/index.js.map +1 -1
- package/dist/cli/platform/index.d.ts +65 -63
- package/dist/cli/platform/index.d.ts.map +1 -1
- package/dist/cli/platform/index.js +140 -27
- package/dist/cli/platform/index.js.map +1 -1
- package/dist/cli/vendor/index.js +15 -0
- package/dist/cli/vendor/index.js.map +1 -1
- package/dist/command/index.d.ts +1 -1
- package/dist/command/index.js +1 -1
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js +6 -0
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +8 -8
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +6 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +6 -0
- package/dist/core/index.native.js.map +1 -1
- package/dist/core/index.workerd.js +6 -0
- package/dist/core/index.workerd.js.map +1 -1
- package/dist/crypto/index.js.map +1 -1
- package/dist/datetime/index.js.map +1 -1
- package/dist/email/core/index.js.map +1 -1
- package/dist/email/smtp/index.js +2 -10522
- package/dist/email/smtp/index.js.map +1 -1
- package/dist/fake/index.d.ts +4 -8085
- package/dist/fake/index.d.ts.map +1 -1
- package/dist/fake/index.js +3 -33554
- package/dist/fake/index.js.map +1 -1
- package/dist/lock/core/index.js.map +1 -1
- package/dist/lock/redis/index.js.map +1 -1
- package/dist/logger/index.js +32 -1
- package/dist/logger/index.js.map +1 -1
- package/dist/mcp/index.js +5 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/orm/core/index.browser.js +1 -361
- package/dist/orm/core/index.browser.js.map +1 -1
- package/dist/orm/core/index.bun.js +14 -406
- package/dist/orm/core/index.bun.js.map +1 -1
- package/dist/orm/core/index.d.ts +96 -5117
- package/dist/orm/core/index.d.ts.map +1 -1
- package/dist/orm/core/index.js +23 -419
- package/dist/orm/core/index.js.map +1 -1
- package/dist/orm/postgres/index.bun.js +17 -20
- package/dist/orm/postgres/index.bun.js.map +1 -1
- package/dist/orm/postgres/index.d.ts +2 -613
- package/dist/orm/postgres/index.d.ts.map +1 -1
- package/dist/orm/postgres/index.js +17 -20
- package/dist/orm/postgres/index.js.map +1 -1
- package/dist/react/core/index.js.map +1 -1
- package/dist/react/form/index.d.ts +60 -1
- package/dist/react/form/index.d.ts.map +1 -1
- package/dist/react/form/index.js +86 -1
- package/dist/react/form/index.js.map +1 -1
- package/dist/react/head/index.browser.js +16 -1
- package/dist/react/head/index.browser.js.map +1 -1
- package/dist/react/head/index.d.ts +6 -0
- package/dist/react/head/index.d.ts.map +1 -1
- package/dist/react/head/index.js +16 -1
- package/dist/react/head/index.js.map +1 -1
- package/dist/react/i18n/index.js.map +1 -1
- package/dist/react/intro/index.js +22 -17
- package/dist/react/intro/index.js.map +1 -1
- package/dist/react/router/index.browser.js +78 -12
- package/dist/react/router/index.browser.js.map +1 -1
- package/dist/react/router/index.d.ts +57 -13
- package/dist/react/router/index.d.ts.map +1 -1
- package/dist/react/router/index.js +102 -14
- package/dist/react/router/index.js.map +1 -1
- package/dist/react/testing/index.d.ts +1 -411
- package/dist/react/testing/index.d.ts.map +1 -1
- package/dist/react/testing/index.js +13 -12293
- package/dist/react/testing/index.js.map +1 -1
- package/dist/react/ui/index.d.ts +124 -0
- package/dist/react/ui/index.d.ts.map +1 -0
- package/dist/react/ui/index.js +209 -0
- package/dist/react/ui/index.js.map +1 -0
- package/dist/react/websocket/index.js.map +1 -1
- package/dist/redis/index.js.map +1 -1
- package/dist/router/index.d.ts +13 -13
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +45 -32
- package/dist/router/index.js.map +1 -1
- package/dist/scheduler/index.d.ts +1 -83
- package/dist/scheduler/index.d.ts.map +1 -1
- package/dist/scheduler/index.js +2 -391
- package/dist/scheduler/index.js.map +1 -1
- package/dist/scheduler/index.workerd.js +2 -391
- package/dist/scheduler/index.workerd.js.map +1 -1
- package/dist/security/index.browser.js.map +1 -1
- package/dist/security/index.d.ts +2 -325
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +3 -1362
- package/dist/security/index.js.map +1 -1
- package/dist/server/auth/index.d.ts +1 -1054
- package/dist/server/auth/index.d.ts.map +1 -1
- package/dist/server/auth/index.js +16 -1224
- package/dist/server/auth/index.js.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 +1 -4
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js +19 -4
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/links/index.browser.js.map +1 -1
- package/dist/server/links/index.js.map +1 -1
- package/dist/server/metrics/index.d.ts +1 -514
- package/dist/server/metrics/index.d.ts.map +1 -1
- package/dist/server/metrics/index.js +4 -4356
- package/dist/server/metrics/index.js.map +1 -1
- package/dist/server/rate-limit/index.js.map +1 -1
- package/dist/server/static/index.js.map +1 -1
- package/dist/server/swagger/index.js +1 -1
- package/dist/server/swagger/index.js.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.map +1 -1
- package/dist/system/index.js +1 -0
- package/dist/system/index.js.map +1 -1
- package/dist/system/index.workerd.js.map +1 -1
- package/dist/topic/core/index.js +1 -1
- package/dist/topic/core/index.js.map +1 -1
- package/dist/websocket/index.browser.js +21 -0
- package/dist/websocket/index.browser.js.map +1 -1
- package/dist/websocket/index.js +21 -0
- package/dist/websocket/index.js.map +1 -1
- package/package.json +23 -37
- package/src/api/files/__tests__/FileController.spec.ts +1 -1
- package/src/api/files/jobs/FileJobs.ts +2 -1
- package/src/api/jobs/__tests__/$job.spec.ts +320 -2867
- package/src/api/jobs/controllers/AdminJobController.ts +29 -138
- package/src/api/jobs/entities/jobExecutionEntity.ts +27 -19
- package/src/api/jobs/index.browser.ts +5 -7
- package/src/api/jobs/index.ts +23 -51
- package/src/api/jobs/primitives/$job.ts +66 -58
- package/src/api/jobs/providers/JobProvider.ts +561 -566
- package/src/api/jobs/providers/JobQueueProvider.ts +18 -19
- package/src/api/jobs/schemas/jobConfigAtom.ts +20 -23
- package/src/api/jobs/schemas/jobExecutionQuerySchema.ts +3 -27
- package/src/api/jobs/schemas/jobExecutionResourceSchema.ts +5 -7
- package/src/api/jobs/schemas/jobRegistrationSchema.ts +7 -4
- package/src/api/jobs/schemas/triggerJobSchema.ts +0 -1
- package/src/api/jobs/services/JobService.ts +90 -483
- package/src/api/notifications/controllers/AdminNotificationController.ts +19 -12
- package/src/api/notifications/index.ts +7 -4
- package/src/api/notifications/jobs/NotificationJobs.ts +83 -12
- package/src/api/payments/services/PaymentService.ts +4 -2
- package/src/api/users/__tests__/UserJobs.spec.ts +10 -49
- package/src/api/users/audits/UserAudits.ts +3 -1
- package/src/api/users/buckets/UserBuckets.ts +2 -1
- package/src/api/users/index.ts +1 -4
- package/src/api/users/jobs/UserJobs.ts +5 -4
- package/src/api/users/schemas/userQuerySchema.ts +0 -1
- package/src/api/users/services/UserService.ts +1 -5
- package/src/api/verifications/__tests__/CodeVerification.spec.ts +14 -0
- package/src/api/verifications/__tests__/LinkVerification.spec.ts +14 -0
- package/src/api/verifications/jobs/VerificationJobs.ts +2 -1
- package/src/api/verifications/services/VerificationService.ts +1 -0
- package/src/cli/core/__tests__/init.spec.ts +209 -1
- package/src/cli/core/commands/init.ts +9 -9
- package/src/cli/core/services/PackageManagerUtils.ts +22 -12
- package/src/cli/core/services/ProjectScaffolder.ts +300 -70
- package/src/cli/core/tasks/BuildDockerTask.ts +9 -10
- package/src/cli/core/tasks/BuildServerTask.ts +8 -0
- package/src/cli/core/templates/agentMd.ts +2 -8
- package/src/cli/core/templates/apiIndexTs.ts +22 -14
- package/src/cli/core/templates/componentsJsonTs.ts +39 -0
- package/src/cli/core/templates/mainCss.ts +2 -36
- package/src/cli/core/templates/saasAdminLayoutTsx.ts +77 -0
- package/src/cli/core/templates/saasAdminPagesTsx.ts +26 -0
- package/src/cli/core/templates/saasAuthLayoutTsx.ts +20 -0
- package/src/cli/core/templates/saasAuthPagesTsx.ts +62 -0
- package/src/cli/core/templates/saasRealmProviderTs.ts +46 -0
- package/src/cli/core/templates/vitestConfigTs.ts +17 -0
- package/src/cli/core/templates/webAppRouterTs.ts +102 -82
- package/src/cli/core/templates/webIndexTs.ts +23 -1
- package/src/cli/platform/__tests__/CloudflareAdapter.spec.ts +22 -71
- package/src/cli/platform/__tests__/SecretsCommand.spec.ts +2 -0
- package/src/cli/platform/adapters/CloudflareAdapter.ts +12 -11
- package/src/cli/platform/atoms/platformOptions.ts +9 -0
- package/src/cli/platform/schemas/cloudflare.ts +3 -2
- package/src/cli/platform/services/CloudflareApi.ts +164 -25
- package/src/cli/platform/services/WranglerApi.ts +0 -17
- package/src/command/providers/CliProvider.ts +1 -1
- package/src/core/Alepha.ts +9 -0
- package/src/core/interfaces/Service.ts +3 -1
- package/src/core/providers/TypeProvider.ts +1 -1
- package/src/logger/services/Logger.ts +1 -1
- package/src/mcp/__tests__/$resource.spec.ts +1 -1
- package/src/mcp/__tests__/$tool.spec.ts +1 -1
- package/src/mcp/__tests__/McpServerProvider.spec.ts +1 -1
- package/src/orm/__tests__/$repository-tests.ts +1 -0
- package/src/orm/__tests__/orm-next-tests.ts +2 -67
- package/src/orm/__tests__/orm-next.spec.ts +0 -21
- package/src/orm/core/index.shared.ts +0 -2
- package/src/orm/core/index.ts +1 -2
- package/src/orm/core/primitives/$repository.ts +3 -6
- package/src/orm/core/providers/drivers/DatabaseProvider.ts +0 -5
- package/src/orm/core/providers/drivers/NodeSqliteProvider.ts +11 -13
- package/src/orm/core/services/ModelBuilder.ts +1 -13
- package/src/orm/core/services/Repository.ts +1 -42
- package/src/orm/core/services/SqliteModelBuilder.ts +2 -33
- package/src/orm/postgres/services/PostgresModelBuilder.ts +10 -45
- package/src/react/form/index.ts +2 -0
- package/src/react/form/services/parseField.ts +163 -0
- package/src/react/form/services/prettyName.ts +19 -0
- package/src/react/head/providers/BrowserHeadProvider.ts +31 -10
- package/src/react/intro/components/GettingStartedAuthSlide.tsx +11 -4
- package/src/react/router/__tests__/ReactBrowserProvider.browser.spec.ts +213 -2
- package/src/react/router/primitives/$page.ts +35 -12
- package/src/react/router/providers/ReactBrowserProvider.ts +73 -0
- package/src/react/router/providers/ReactBrowserRouterProvider.ts +1 -1
- package/src/react/router/providers/ReactPreloadProvider.ts +1 -1
- package/src/react/router/providers/ReactServerProvider.ts +1 -0
- package/src/react/ui/atoms/uiAtom.ts +28 -0
- package/src/react/ui/components/ColorScheme.tsx +36 -0
- package/src/react/ui/hooks/useColorMode.ts +49 -0
- package/src/react/ui/hooks/useSidebarState.ts +26 -0
- package/src/react/ui/hooks/useTheme.ts +22 -0
- package/src/react/ui/index.ts +35 -0
- package/src/react/ui/services/UiPersistence.ts +41 -0
- package/src/router/TemplatedPathParser.ts +50 -51
- package/src/router/__tests__/RouterProvider.spec.ts +62 -0
- package/src/router/__tests__/TemplatedPathParser.spec.ts +18 -0
- package/src/router/providers/RouterProvider.ts +10 -5
- package/src/scheduler/providers/CronProvider.ts +1 -1
- package/src/security/primitives/$basicAuth.ts +1 -1
- package/src/server/auth/providers/ServerAuthProvider.ts +5 -1
- package/src/server/core/interfaces/ServerRequest.ts +1 -0
- package/src/server/core/providers/ServerProvider.ts +1 -1
- package/src/server/core/providers/ServerRouterProvider.ts +2 -2
- package/src/server/core/services/HttpClient.ts +1 -1
- package/src/server/swagger/providers/ServerSwaggerProvider.ts +1 -1
- package/src/system/providers/NodeShellProvider.ts +1 -0
- package/src/topic/core/providers/TopicProvider.ts +1 -1
- package/dist/api/invitations/index.d.ts +0 -790
- package/dist/api/invitations/index.d.ts.map +0 -1
- package/dist/api/invitations/index.js +0 -662
- package/dist/api/invitations/index.js.map +0 -1
- package/dist/api/issues/index.d.ts +0 -810
- package/dist/api/issues/index.d.ts.map +0 -1
- package/dist/api/issues/index.js +0 -444
- package/dist/api/issues/index.js.map +0 -1
- package/dist/api/subscriptions/index.d.ts +0 -1692
- package/dist/api/subscriptions/index.d.ts.map +0 -1
- package/dist/api/subscriptions/index.js +0 -1867
- package/dist/api/subscriptions/index.js.map +0 -1
- package/dist/api/workflows/index.browser.js +0 -246
- package/dist/api/workflows/index.browser.js.map +0 -1
- package/dist/api/workflows/index.d.ts +0 -1618
- package/dist/api/workflows/index.d.ts.map +0 -1
- package/dist/api/workflows/index.js +0 -1495
- package/dist/api/workflows/index.js.map +0 -1
- package/dist/react/testing/chunk-DBEY4PJZ.js +0 -16
- package/src/api/invitations/__tests__/InvitationService.spec.ts +0 -439
- package/src/api/invitations/controllers/AdminInvitationController.ts +0 -86
- package/src/api/invitations/controllers/InvitationController.ts +0 -84
- package/src/api/invitations/entities/invitations.ts +0 -33
- package/src/api/invitations/index.ts +0 -58
- package/src/api/invitations/jobs/InvitationJobs.ts +0 -37
- package/src/api/invitations/providers/InvitationProvider.ts +0 -45
- package/src/api/invitations/schemas/createInvitationSchema.ts +0 -12
- package/src/api/invitations/schemas/invitationConfigAtom.ts +0 -20
- package/src/api/invitations/schemas/invitationQuerySchema.ts +0 -15
- package/src/api/invitations/schemas/invitationResourceSchema.ts +0 -6
- package/src/api/invitations/schemas/invitationWithResourceInfoSchema.ts +0 -22
- package/src/api/invitations/schemas/myInvitationsQuerySchema.ts +0 -10
- package/src/api/invitations/services/InvitationService.ts +0 -556
- package/src/api/issues/__tests__/IssueService.spec.ts +0 -263
- package/src/api/issues/controllers/AdminIssueController.ts +0 -149
- package/src/api/issues/controllers/IssueController.ts +0 -44
- package/src/api/issues/entities/issues.ts +0 -49
- package/src/api/issues/index.ts +0 -50
- package/src/api/issues/schemas/createIssueSchema.ts +0 -13
- package/src/api/issues/schemas/issueConfigAtom.ts +0 -13
- package/src/api/issues/schemas/issueQuerySchema.ts +0 -18
- package/src/api/issues/schemas/issueResourceSchema.ts +0 -6
- package/src/api/issues/schemas/myIssueQuerySchema.ts +0 -10
- package/src/api/issues/schemas/updateIssueSchema.ts +0 -13
- package/src/api/issues/services/IssueService.ts +0 -264
- package/src/api/jobs/__tests__/$job-middleware.spec.ts +0 -126
- package/src/api/jobs/__tests__/JobService.spec.ts +0 -31
- package/src/api/jobs/entities/jobExecutionLogEntity.ts +0 -13
- package/src/api/jobs/schemas/jobActivitySchema.ts +0 -15
- package/src/api/jobs/schemas/jobCronInfoSchema.ts +0 -22
- package/src/api/jobs/schemas/jobExecutionDetailResourceSchema.ts +0 -20
- package/src/api/jobs/schemas/jobFailureSchema.ts +0 -9
- package/src/api/jobs/schemas/jobQueueDepthSchema.ts +0 -14
- package/src/api/jobs/schemas/jobStatsSchema.ts +0 -14
- package/src/api/jobs/services/JobService-tests.ts +0 -157
- package/src/api/subscriptions/__tests__/BillingService.spec.ts +0 -218
- package/src/api/subscriptions/__tests__/SubscriptionService.spec.ts +0 -278
- package/src/api/subscriptions/controllers/AdminSubscriptionController.ts +0 -212
- package/src/api/subscriptions/controllers/SubscriptionController.ts +0 -189
- package/src/api/subscriptions/entities/subscriptionEvents.ts +0 -54
- package/src/api/subscriptions/entities/subscriptions.ts +0 -68
- package/src/api/subscriptions/index.ts +0 -133
- package/src/api/subscriptions/jobs/SubscriptionJobs.ts +0 -382
- package/src/api/subscriptions/middleware/$requireLimit.ts +0 -50
- package/src/api/subscriptions/middleware/$requirePlan.ts +0 -49
- package/src/api/subscriptions/notifications/SubscriptionNotifications.ts +0 -110
- package/src/api/subscriptions/schemas/cancelSubscriptionSchema.ts +0 -8
- package/src/api/subscriptions/schemas/changePlanSchema.ts +0 -9
- package/src/api/subscriptions/schemas/createSubscriptionSchema.ts +0 -11
- package/src/api/subscriptions/schemas/entitlementsSchema.ts +0 -21
- package/src/api/subscriptions/schemas/mrrSchema.ts +0 -13
- package/src/api/subscriptions/schemas/planDefinitionSchema.ts +0 -71
- package/src/api/subscriptions/schemas/planResourceSchema.ts +0 -25
- package/src/api/subscriptions/schemas/subscriptionEventResourceSchema.ts +0 -8
- package/src/api/subscriptions/schemas/subscriptionQuerySchema.ts +0 -19
- package/src/api/subscriptions/schemas/subscriptionResourceSchema.ts +0 -6
- package/src/api/subscriptions/schemas/subscriptionSettingsSchema.ts +0 -32
- package/src/api/subscriptions/schemas/subscriptionStatsSchema.ts +0 -23
- package/src/api/subscriptions/services/BillingService.ts +0 -437
- package/src/api/subscriptions/services/SubscriptionConfig.ts +0 -56
- package/src/api/subscriptions/services/SubscriptionService.ts +0 -867
- package/src/api/subscriptions/services/UsageService.ts +0 -118
- package/src/api/workflows/__tests__/$workflow.spec.ts +0 -616
- package/src/api/workflows/controllers/AdminWorkflowController.ts +0 -191
- package/src/api/workflows/entities/workflowExecutions.ts +0 -74
- package/src/api/workflows/entities/workflowStepExecutions.ts +0 -74
- package/src/api/workflows/entities/workflowStepLogs.ts +0 -13
- package/src/api/workflows/index.browser.ts +0 -22
- package/src/api/workflows/index.ts +0 -115
- package/src/api/workflows/jobs/WorkflowJobs.ts +0 -77
- package/src/api/workflows/primitives/$workflow.ts +0 -202
- package/src/api/workflows/providers/WorkflowProvider.ts +0 -1284
- package/src/api/workflows/schemas/workflowActivitySchema.ts +0 -15
- package/src/api/workflows/schemas/workflowConfigAtom.ts +0 -51
- package/src/api/workflows/schemas/workflowExecutionDetailSchema.ts +0 -18
- package/src/api/workflows/schemas/workflowExecutionQuerySchema.ts +0 -26
- package/src/api/workflows/schemas/workflowExecutionResourceSchema.ts +0 -30
- package/src/api/workflows/schemas/workflowRegistrationSchema.ts +0 -26
- package/src/api/workflows/schemas/workflowStatsSchema.ts +0 -16
- package/src/api/workflows/schemas/workflowStepExecutionResourceSchema.ts +0 -15
- package/src/api/workflows/services/WorkflowService.ts +0 -382
- package/src/cli/core/templates/apiAppSecurityTs.ts +0 -43
- package/src/cli/core/templates/webAdminDashboardTsx.ts +0 -17
- package/src/orm/core/__tests__/parseQueryString.spec.ts +0 -196
- package/src/orm/core/helpers/parseQueryString.ts +0 -502
- package/src/orm/core/primitives/$view.ts +0 -88
|
@@ -119,6 +119,18 @@ class MemoryCloudflareApi extends CloudflareApi {
|
|
|
119
119
|
return this.secrets.get(scriptName) ?? [];
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
+
public override async putSecret(
|
|
123
|
+
scriptName: string,
|
|
124
|
+
name: string,
|
|
125
|
+
_value: string,
|
|
126
|
+
) {
|
|
127
|
+
const existing = this.secrets.get(scriptName) ?? [];
|
|
128
|
+
if (!existing.some((s) => s.name === name)) {
|
|
129
|
+
existing.push({ name, type: "secret_text" });
|
|
130
|
+
}
|
|
131
|
+
this.secrets.set(scriptName, existing);
|
|
132
|
+
}
|
|
133
|
+
|
|
122
134
|
public override async listDeployments() {
|
|
123
135
|
return [];
|
|
124
136
|
}
|
|
@@ -379,10 +391,10 @@ describe("CloudflareAdapter", () => {
|
|
|
379
391
|
});
|
|
380
392
|
|
|
381
393
|
describe("secrets", () => {
|
|
382
|
-
test("pushes non-binding env vars via
|
|
394
|
+
test("pushes non-binding env vars via REST putSecret", async ({
|
|
383
395
|
expect,
|
|
384
396
|
}) => {
|
|
385
|
-
const { adapter, fs,
|
|
397
|
+
const { adapter, fs, naming, api } = createTestEnv();
|
|
386
398
|
const ctx = makeCtx(naming, {
|
|
387
399
|
apps: [
|
|
388
400
|
{
|
|
@@ -400,7 +412,6 @@ describe("CloudflareAdapter", () => {
|
|
|
400
412
|
],
|
|
401
413
|
});
|
|
402
414
|
|
|
403
|
-
// Write .env.production with a mix of secrets and excluded vars
|
|
404
415
|
await fs.writeFile(
|
|
405
416
|
"/project/.env.production",
|
|
406
417
|
[
|
|
@@ -418,62 +429,13 @@ describe("CloudflareAdapter", () => {
|
|
|
418
429
|
const run = createMockRun();
|
|
419
430
|
await adapter.secrets(ctx, run);
|
|
420
431
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
/wrangler secret bulk.*--name=acme-portal-production/,
|
|
425
|
-
),
|
|
426
|
-
).toBe(true);
|
|
427
|
-
|
|
428
|
-
// Verify the secrets JSON was written (only non-excluded vars)
|
|
429
|
-
expect(
|
|
430
|
-
fs.wasWrittenMatching(
|
|
431
|
-
"/project/node_modules/.alepha/secrets.json",
|
|
432
|
-
/GOOGLE_API_KEY/,
|
|
433
|
-
),
|
|
434
|
-
).toBe(true);
|
|
435
|
-
expect(
|
|
436
|
-
fs.wasWrittenMatching(
|
|
437
|
-
"/project/node_modules/.alepha/secrets.json",
|
|
438
|
-
/APP_SECRET/,
|
|
439
|
-
),
|
|
440
|
-
).toBe(true);
|
|
441
|
-
|
|
442
|
-
// Excluded vars should NOT be in the secrets file
|
|
443
|
-
expect(
|
|
444
|
-
fs.wasWrittenMatching(
|
|
445
|
-
"/project/node_modules/.alepha/secrets.json",
|
|
446
|
-
/DATABASE_URL/,
|
|
447
|
-
),
|
|
448
|
-
).toBe(false);
|
|
449
|
-
expect(
|
|
450
|
-
fs.wasWrittenMatching(
|
|
451
|
-
"/project/node_modules/.alepha/secrets.json",
|
|
452
|
-
/R2_BUCKET_NAME/,
|
|
453
|
-
),
|
|
454
|
-
).toBe(false);
|
|
455
|
-
expect(
|
|
456
|
-
fs.wasWrittenMatching(
|
|
457
|
-
"/project/node_modules/.alepha/secrets.json",
|
|
458
|
-
/CLOUDFLARE_DOMAIN/,
|
|
459
|
-
),
|
|
460
|
-
).toBe(false);
|
|
461
|
-
expect(
|
|
462
|
-
fs.wasWrittenMatching(
|
|
463
|
-
"/project/node_modules/.alepha/secrets.json",
|
|
464
|
-
/VITE_PUBLIC_KEY/,
|
|
465
|
-
),
|
|
466
|
-
).toBe(false);
|
|
467
|
-
expect(
|
|
468
|
-
fs.wasWrittenMatching(
|
|
469
|
-
"/project/node_modules/.alepha/secrets.json",
|
|
470
|
-
/NODE_ENV/,
|
|
471
|
-
),
|
|
472
|
-
).toBe(false);
|
|
432
|
+
const pushed = api.secrets.get("acme-portal-production") ?? [];
|
|
433
|
+
const names = pushed.map((s) => s.name).sort();
|
|
434
|
+
expect(names).toEqual(["APP_SECRET", "GOOGLE_API_KEY"]);
|
|
473
435
|
});
|
|
474
436
|
|
|
475
437
|
test("skips when no env file exists", async ({ expect }) => {
|
|
476
|
-
const { adapter,
|
|
438
|
+
const { adapter, naming, api } = createTestEnv();
|
|
477
439
|
const ctx = makeCtx(naming, {
|
|
478
440
|
apps: [
|
|
479
441
|
{
|
|
@@ -494,11 +456,11 @@ describe("CloudflareAdapter", () => {
|
|
|
494
456
|
const run = createMockRun();
|
|
495
457
|
await adapter.secrets(ctx, run);
|
|
496
458
|
|
|
497
|
-
expect(
|
|
459
|
+
expect(api.secrets.size).toBe(0);
|
|
498
460
|
});
|
|
499
461
|
|
|
500
462
|
test("skips comments and empty lines", async ({ expect }) => {
|
|
501
|
-
const { adapter, fs,
|
|
463
|
+
const { adapter, fs, naming, api } = createTestEnv();
|
|
502
464
|
const ctx = makeCtx(naming, {
|
|
503
465
|
apps: [
|
|
504
466
|
{
|
|
@@ -524,19 +486,8 @@ describe("CloudflareAdapter", () => {
|
|
|
524
486
|
const run = createMockRun();
|
|
525
487
|
await adapter.secrets(ctx, run);
|
|
526
488
|
|
|
527
|
-
|
|
528
|
-
expect(
|
|
529
|
-
fs.wasWrittenMatching(
|
|
530
|
-
"/project/node_modules/.alepha/secrets.json",
|
|
531
|
-
/ONLY_SECRET/,
|
|
532
|
-
),
|
|
533
|
-
).toBe(true);
|
|
534
|
-
expect(
|
|
535
|
-
fs.wasWrittenMatching(
|
|
536
|
-
"/project/node_modules/.alepha/secrets.json",
|
|
537
|
-
/comment/,
|
|
538
|
-
),
|
|
539
|
-
).toBe(false);
|
|
489
|
+
const pushed = api.secrets.get("acme-portal-production") ?? [];
|
|
490
|
+
expect(pushed.map((s) => s.name)).toEqual(["ONLY_SECRET"]);
|
|
540
491
|
});
|
|
541
492
|
});
|
|
542
493
|
|
|
@@ -252,8 +252,10 @@ describe("SecretsCommand", () => {
|
|
|
252
252
|
|
|
253
253
|
const output = writes.join("");
|
|
254
254
|
expect(output).toContain("env:");
|
|
255
|
+
// biome-ignore lint/suspicious/noTemplateCurlyInString: GitHub Actions `${{ ... }}` syntax in plain string
|
|
255
256
|
expect(output).toContain("API_KEY: ${{ secrets.API_KEY }}");
|
|
256
257
|
expect(output).toContain(
|
|
258
|
+
// biome-ignore lint/suspicious/noTemplateCurlyInString: GitHub Actions `${{ ... }}` syntax in plain string
|
|
257
259
|
"GITHUB_CLIENT_ID: ${{ secrets.APP_GITHUB_CLIENT_ID }}",
|
|
258
260
|
);
|
|
259
261
|
});
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { $inject, Alepha } from "alepha";
|
|
2
|
-
import { AlephaCliUtils } from "alepha/cli";
|
|
3
2
|
import { EnvUtils, Runner, type RunnerMethod } from "alepha/command";
|
|
4
3
|
import { $logger } from "alepha/logger";
|
|
5
4
|
import { FileSystemProvider, ShellProvider } from "alepha/system";
|
|
@@ -24,7 +23,6 @@ export class CloudflareAdapter extends PlatformAdapter {
|
|
|
24
23
|
protected readonly log = $logger();
|
|
25
24
|
protected readonly fs = $inject(FileSystemProvider);
|
|
26
25
|
protected readonly shell = $inject(ShellProvider);
|
|
27
|
-
protected readonly utils = $inject(AlephaCliUtils);
|
|
28
26
|
protected readonly cache = $inject(PlatformCacheProvider);
|
|
29
27
|
protected readonly alepha = $inject(Alepha);
|
|
30
28
|
protected readonly envUtils = $inject(EnvUtils);
|
|
@@ -57,6 +55,7 @@ export class CloudflareAdapter extends PlatformAdapter {
|
|
|
57
55
|
*/
|
|
58
56
|
protected configureApi(ctx: PlatformContext): void {
|
|
59
57
|
this.api.setJurisdiction(ctx.envConfig.jurisdiction);
|
|
58
|
+
this.api.setAccountId(ctx.envConfig.accountId);
|
|
60
59
|
}
|
|
61
60
|
|
|
62
61
|
protected async runShell(
|
|
@@ -256,7 +255,9 @@ export class CloudflareAdapter extends PlatformAdapter {
|
|
|
256
255
|
return;
|
|
257
256
|
}
|
|
258
257
|
|
|
259
|
-
// Push secrets to each worker
|
|
258
|
+
// Push secrets to each worker via the REST API (one PUT per secret).
|
|
259
|
+
// Historically we shelled out to `wrangler secret bulk`, but it has an
|
|
260
|
+
// open hang issue (workers-sdk#10555) and is redundant given putSecret.
|
|
260
261
|
for (const app of ctx.apps) {
|
|
261
262
|
const workerName = ctx.naming.worker(
|
|
262
263
|
ctx.apps.length > 1 ? app.name : undefined,
|
|
@@ -265,13 +266,9 @@ export class CloudflareAdapter extends PlatformAdapter {
|
|
|
265
266
|
await run({
|
|
266
267
|
name: `push secrets to ${workerName}`,
|
|
267
268
|
handler: async () => {
|
|
268
|
-
const
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
ctx.root,
|
|
272
|
-
);
|
|
273
|
-
|
|
274
|
-
await this.wrangler.secretBulk(secretsPath, workerName);
|
|
269
|
+
for (const [name, value] of Object.entries(secrets)) {
|
|
270
|
+
await this.api.putSecret(workerName, name, value);
|
|
271
|
+
}
|
|
275
272
|
},
|
|
276
273
|
});
|
|
277
274
|
}
|
|
@@ -882,7 +879,11 @@ export class CloudflareAdapter extends PlatformAdapter {
|
|
|
882
879
|
> {
|
|
883
880
|
const deployments = await this.api.listDeployments(workerName);
|
|
884
881
|
|
|
885
|
-
|
|
882
|
+
// API ordering is not guaranteed across releases — sort explicitly.
|
|
883
|
+
const sorted = [...deployments].sort((a, b) =>
|
|
884
|
+
b.created_on.localeCompare(a.created_on),
|
|
885
|
+
);
|
|
886
|
+
const latest = sorted[0];
|
|
886
887
|
if (!latest?.versions?.[0]) {
|
|
887
888
|
return undefined;
|
|
888
889
|
}
|
|
@@ -74,6 +74,14 @@ export const platformOptions = $atom({
|
|
|
74
74
|
* Omit for the default (global) jurisdiction.
|
|
75
75
|
*/
|
|
76
76
|
jurisdiction: t.optional(t.enum(["eu", "fedramp"])),
|
|
77
|
+
/**
|
|
78
|
+
* Cloudflare account ID to deploy into.
|
|
79
|
+
*
|
|
80
|
+
* Falls back to `CLOUDFLARE_ACCOUNT_ID` env var, then to the
|
|
81
|
+
* token's account when the token is scoped to exactly one.
|
|
82
|
+
* Required when the token has access to multiple accounts.
|
|
83
|
+
*/
|
|
84
|
+
accountId: t.optional(t.text()),
|
|
77
85
|
}),
|
|
78
86
|
),
|
|
79
87
|
}),
|
|
@@ -93,4 +101,5 @@ export interface EnvironmentConfig {
|
|
|
93
101
|
domain?: string;
|
|
94
102
|
vars?: Record<string, string>;
|
|
95
103
|
jurisdiction?: "eu" | "fedramp";
|
|
104
|
+
accountId?: string;
|
|
96
105
|
}
|
|
@@ -40,7 +40,7 @@ export type CloudflareKV = Static<typeof cloudflareKVSchema>;
|
|
|
40
40
|
|
|
41
41
|
export const cloudflareR2Schema = t.object({
|
|
42
42
|
name: t.string(),
|
|
43
|
-
creation_date: t.string(),
|
|
43
|
+
creation_date: t.optional(t.string()),
|
|
44
44
|
});
|
|
45
45
|
|
|
46
46
|
export type CloudflareR2 = Static<typeof cloudflareR2Schema>;
|
|
@@ -61,8 +61,9 @@ export const cloudflareQueueSchema = t.object({
|
|
|
61
61
|
export type CloudflareQueue = Static<typeof cloudflareQueueSchema>;
|
|
62
62
|
|
|
63
63
|
export const cloudflareQueueConsumerSchema = t.object({
|
|
64
|
+
consumer_id: t.string(),
|
|
64
65
|
service: t.string(),
|
|
65
|
-
environment: t.string(),
|
|
66
|
+
environment: t.optional(t.string()),
|
|
66
67
|
});
|
|
67
68
|
|
|
68
69
|
export type CloudflareQueueConsumer = Static<
|
|
@@ -22,9 +22,9 @@ import {
|
|
|
22
22
|
cloudflareKVSchema,
|
|
23
23
|
cloudflareQueueConsumerSchema,
|
|
24
24
|
cloudflareQueueSchema,
|
|
25
|
-
|
|
25
|
+
cloudflareR2Schema,
|
|
26
26
|
cloudflareSecretSchema,
|
|
27
|
-
|
|
27
|
+
cloudflareVersionSchema,
|
|
28
28
|
cloudflareWorkerSchema,
|
|
29
29
|
createD1BodySchema,
|
|
30
30
|
createHyperdriveBodySchema,
|
|
@@ -81,6 +81,16 @@ export class CloudflareApi {
|
|
|
81
81
|
this.jurisdiction = jurisdiction;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Override the Cloudflare account ID (from platform config).
|
|
86
|
+
*
|
|
87
|
+
* When unset, `resolveAccountId` falls back to `CLOUDFLARE_ACCOUNT_ID` env
|
|
88
|
+
* var or the token's single account.
|
|
89
|
+
*/
|
|
90
|
+
public setAccountId(accountId?: string): void {
|
|
91
|
+
this.accountId = accountId;
|
|
92
|
+
}
|
|
93
|
+
|
|
84
94
|
// -------------------------------------------------------------------------
|
|
85
95
|
// Auth
|
|
86
96
|
// -------------------------------------------------------------------------
|
|
@@ -107,6 +117,12 @@ export class CloudflareApi {
|
|
|
107
117
|
return this.accountId;
|
|
108
118
|
}
|
|
109
119
|
|
|
120
|
+
const fromEnv = process.env.CLOUDFLARE_ACCOUNT_ID;
|
|
121
|
+
if (fromEnv) {
|
|
122
|
+
this.accountId = fromEnv;
|
|
123
|
+
return this.accountId;
|
|
124
|
+
}
|
|
125
|
+
|
|
110
126
|
const res = await this.fetch<CloudflareAccount[]>("/accounts", {
|
|
111
127
|
schema: t.array(cloudflareAccountSchema),
|
|
112
128
|
});
|
|
@@ -115,6 +131,15 @@ export class CloudflareApi {
|
|
|
115
131
|
throw new AlephaError("No Cloudflare accounts found for this token.");
|
|
116
132
|
}
|
|
117
133
|
|
|
134
|
+
if (res.length > 1) {
|
|
135
|
+
const list = res.map((a) => ` - ${a.id} ${a.name}`).join("\n");
|
|
136
|
+
throw new AlephaError(
|
|
137
|
+
`Cloudflare token has access to ${res.length} accounts; set ` +
|
|
138
|
+
`\`CLOUDFLARE_ACCOUNT_ID\` or the \`accountId\` field in your ` +
|
|
139
|
+
`platform config to pick one:\n${list}`,
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
118
143
|
this.accountId = res[0].id;
|
|
119
144
|
return this.accountId;
|
|
120
145
|
}
|
|
@@ -125,9 +150,9 @@ export class CloudflareApi {
|
|
|
125
150
|
|
|
126
151
|
public async listD1(): Promise<CloudflareD1[]> {
|
|
127
152
|
const accountId = await this.resolveAccountId();
|
|
128
|
-
return await this.
|
|
153
|
+
return await this.paginate<CloudflareD1>(
|
|
129
154
|
`/accounts/${accountId}/d1/database`,
|
|
130
|
-
|
|
155
|
+
cloudflareD1Schema,
|
|
131
156
|
);
|
|
132
157
|
}
|
|
133
158
|
|
|
@@ -136,15 +161,19 @@ export class CloudflareApi {
|
|
|
136
161
|
location = "weur", // TODO: move to config (or auto-resolve based on account info, or ask ?)
|
|
137
162
|
): Promise<CloudflareD1> {
|
|
138
163
|
const accountId = await this.resolveAccountId();
|
|
164
|
+
// When jurisdiction is set, `primary_location_hint` is silently ignored
|
|
165
|
+
// by the API, so omit it to avoid confusion.
|
|
166
|
+
const body: Record<string, unknown> = { name };
|
|
167
|
+
if (this.jurisdiction) {
|
|
168
|
+
body.jurisdiction = this.jurisdiction;
|
|
169
|
+
} else {
|
|
170
|
+
body.primary_location_hint = location;
|
|
171
|
+
}
|
|
139
172
|
return await this.fetch<CloudflareD1>(
|
|
140
173
|
`/accounts/${accountId}/d1/database`,
|
|
141
174
|
{
|
|
142
175
|
method: "POST",
|
|
143
|
-
body
|
|
144
|
-
name,
|
|
145
|
-
primary_location_hint: location,
|
|
146
|
-
...(this.jurisdiction ? { jurisdiction: this.jurisdiction } : {}),
|
|
147
|
-
},
|
|
176
|
+
body,
|
|
148
177
|
bodySchema: createD1BodySchema,
|
|
149
178
|
schema: cloudflareD1Schema,
|
|
150
179
|
},
|
|
@@ -164,9 +193,10 @@ export class CloudflareApi {
|
|
|
164
193
|
|
|
165
194
|
public async listKV(): Promise<CloudflareKV[]> {
|
|
166
195
|
const accountId = await this.resolveAccountId();
|
|
167
|
-
return await this.
|
|
196
|
+
return await this.paginate<CloudflareKV>(
|
|
168
197
|
`/accounts/${accountId}/storage/kv/namespaces`,
|
|
169
|
-
|
|
198
|
+
cloudflareKVSchema,
|
|
199
|
+
100, // KV list caps at 100 per page
|
|
170
200
|
);
|
|
171
201
|
}
|
|
172
202
|
|
|
@@ -197,11 +227,11 @@ export class CloudflareApi {
|
|
|
197
227
|
|
|
198
228
|
public async listR2(): Promise<CloudflareR2[]> {
|
|
199
229
|
const accountId = await this.resolveAccountId();
|
|
200
|
-
|
|
230
|
+
return await this.paginateCursor<CloudflareR2>(
|
|
201
231
|
`/accounts/${accountId}/r2/buckets`,
|
|
202
|
-
|
|
232
|
+
"buckets",
|
|
233
|
+
cloudflareR2Schema,
|
|
203
234
|
);
|
|
204
|
-
return res.buckets;
|
|
205
235
|
}
|
|
206
236
|
|
|
207
237
|
public async createR2(name: string): Promise<void> {
|
|
@@ -226,9 +256,9 @@ export class CloudflareApi {
|
|
|
226
256
|
|
|
227
257
|
public async listQueues(): Promise<CloudflareQueue[]> {
|
|
228
258
|
const accountId = await this.resolveAccountId();
|
|
229
|
-
return await this.
|
|
259
|
+
return await this.paginate<CloudflareQueue>(
|
|
230
260
|
`/accounts/${accountId}/queues`,
|
|
231
|
-
|
|
261
|
+
cloudflareQueueSchema,
|
|
232
262
|
);
|
|
233
263
|
}
|
|
234
264
|
|
|
@@ -253,9 +283,9 @@ export class CloudflareApi {
|
|
|
253
283
|
queueId: string,
|
|
254
284
|
): Promise<CloudflareQueueConsumer[]> {
|
|
255
285
|
const accountId = await this.resolveAccountId();
|
|
256
|
-
return await this.
|
|
286
|
+
return await this.paginate<CloudflareQueueConsumer>(
|
|
257
287
|
`/accounts/${accountId}/queues/${queueId}/consumers`,
|
|
258
|
-
|
|
288
|
+
cloudflareQueueConsumerSchema,
|
|
259
289
|
);
|
|
260
290
|
}
|
|
261
291
|
|
|
@@ -264,8 +294,13 @@ export class CloudflareApi {
|
|
|
264
294
|
consumerService: string,
|
|
265
295
|
): Promise<void> {
|
|
266
296
|
const accountId = await this.resolveAccountId();
|
|
297
|
+
const consumers = await this.listQueueConsumers(queueId);
|
|
298
|
+
const consumer = consumers.find((c) => c.service === consumerService);
|
|
299
|
+
if (!consumer) {
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
267
302
|
await this.fetch(
|
|
268
|
-
`/accounts/${accountId}/queues/${queueId}/consumers/${
|
|
303
|
+
`/accounts/${accountId}/queues/${queueId}/consumers/${consumer.consumer_id}`,
|
|
269
304
|
{ method: "DELETE" },
|
|
270
305
|
);
|
|
271
306
|
}
|
|
@@ -276,9 +311,9 @@ export class CloudflareApi {
|
|
|
276
311
|
|
|
277
312
|
public async listHyperdrive(): Promise<CloudflareHyperdrive[]> {
|
|
278
313
|
const accountId = await this.resolveAccountId();
|
|
279
|
-
return await this.
|
|
314
|
+
return await this.paginate<CloudflareHyperdrive>(
|
|
280
315
|
`/accounts/${accountId}/hyperdrive/configs`,
|
|
281
|
-
|
|
316
|
+
cloudflareHyperdriveSchema,
|
|
282
317
|
);
|
|
283
318
|
}
|
|
284
319
|
|
|
@@ -338,20 +373,22 @@ export class CloudflareApi {
|
|
|
338
373
|
scriptName: string,
|
|
339
374
|
): Promise<CloudflareDeployment[]> {
|
|
340
375
|
const accountId = await this.resolveAccountId();
|
|
376
|
+
// Deployments list is wrapped in `{ deployments }` and returns newest
|
|
377
|
+
// first; for picking the active deployment we only need the top page.
|
|
341
378
|
const res = await this.fetch<{ deployments: CloudflareDeployment[] }>(
|
|
342
379
|
`/accounts/${accountId}/workers/scripts/${scriptName}/deployments`,
|
|
343
|
-
{ schema: cloudflareDeploymentListSchema },
|
|
380
|
+
{ schema: cloudflareDeploymentListSchema, query: { per_page: "100" } },
|
|
344
381
|
);
|
|
345
382
|
return res.deployments;
|
|
346
383
|
}
|
|
347
384
|
|
|
348
385
|
public async listVersions(scriptName: string): Promise<CloudflareVersion[]> {
|
|
349
386
|
const accountId = await this.resolveAccountId();
|
|
350
|
-
|
|
387
|
+
return await this.paginateCursor<CloudflareVersion>(
|
|
351
388
|
`/accounts/${accountId}/workers/scripts/${scriptName}/versions`,
|
|
352
|
-
|
|
389
|
+
"items",
|
|
390
|
+
cloudflareVersionSchema,
|
|
353
391
|
);
|
|
354
|
-
return res.items;
|
|
355
392
|
}
|
|
356
393
|
|
|
357
394
|
// -------------------------------------------------------------------------
|
|
@@ -428,6 +465,13 @@ export class CloudflareApi {
|
|
|
428
465
|
success: boolean;
|
|
429
466
|
result: T;
|
|
430
467
|
errors: CloudflareApiError[];
|
|
468
|
+
result_info?: {
|
|
469
|
+
page: number;
|
|
470
|
+
per_page: number;
|
|
471
|
+
total_pages?: number;
|
|
472
|
+
count?: number;
|
|
473
|
+
total_count?: number;
|
|
474
|
+
};
|
|
431
475
|
};
|
|
432
476
|
|
|
433
477
|
if (!json.success) {
|
|
@@ -444,6 +488,101 @@ export class CloudflareApi {
|
|
|
444
488
|
return json.result;
|
|
445
489
|
}
|
|
446
490
|
|
|
491
|
+
/**
|
|
492
|
+
* Paginate a page-based list endpoint (`result_info.total_pages`).
|
|
493
|
+
*
|
|
494
|
+
* Cloudflare defaults to `per_page=20`; we push it to 1000 (max on most
|
|
495
|
+
* list endpoints) and loop if more pages exist. Each page is validated
|
|
496
|
+
* against the item schema.
|
|
497
|
+
*/
|
|
498
|
+
protected async paginate<T>(
|
|
499
|
+
path: string,
|
|
500
|
+
itemSchema: TSchema,
|
|
501
|
+
perPage = 1000,
|
|
502
|
+
): Promise<T[]> {
|
|
503
|
+
const results: T[] = [];
|
|
504
|
+
let page = 1;
|
|
505
|
+
|
|
506
|
+
while (true) {
|
|
507
|
+
const token = await this.resolveToken();
|
|
508
|
+
const url = `${CloudflareApi.BASE}${path}?per_page=${perPage}&page=${page}`;
|
|
509
|
+
|
|
510
|
+
const headers: Record<string, string> = {
|
|
511
|
+
Authorization: `Bearer ${token}`,
|
|
512
|
+
};
|
|
513
|
+
if (this.jurisdiction && /\/r2\//.test(path)) {
|
|
514
|
+
headers["cf-r2-jurisdiction"] = this.jurisdiction;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
const response = await globalThis.fetch(url, { method: "GET", headers });
|
|
518
|
+
const json = (await response.json()) as {
|
|
519
|
+
success: boolean;
|
|
520
|
+
result: T[];
|
|
521
|
+
errors: CloudflareApiError[];
|
|
522
|
+
result_info?: { page: number; total_pages?: number };
|
|
523
|
+
};
|
|
524
|
+
|
|
525
|
+
if (!json.success) {
|
|
526
|
+
const messages = json.errors.map((e) => e.message).join(", ");
|
|
527
|
+
throw new AlephaError(
|
|
528
|
+
`Cloudflare API error (GET ${path}): ${messages}`,
|
|
529
|
+
);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
const validated = this.alepha.codec.validate(
|
|
533
|
+
t.array(itemSchema),
|
|
534
|
+
json.result,
|
|
535
|
+
) as T[];
|
|
536
|
+
results.push(...validated);
|
|
537
|
+
|
|
538
|
+
const totalPages = json.result_info?.total_pages;
|
|
539
|
+
if (!totalPages || page >= totalPages || validated.length === 0) {
|
|
540
|
+
break;
|
|
541
|
+
}
|
|
542
|
+
page++;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
return results;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* Paginate a cursor-based list endpoint where `result` is an object
|
|
550
|
+
* containing both the items array and a `cursor` field (R2 buckets,
|
|
551
|
+
* Workers versions). Returns the flattened item array.
|
|
552
|
+
*/
|
|
553
|
+
protected async paginateCursor<T>(
|
|
554
|
+
path: string,
|
|
555
|
+
itemsKey: string,
|
|
556
|
+
itemSchema: TSchema,
|
|
557
|
+
perPage = 1000,
|
|
558
|
+
): Promise<T[]> {
|
|
559
|
+
const results: T[] = [];
|
|
560
|
+
let cursor: string | undefined;
|
|
561
|
+
|
|
562
|
+
while (true) {
|
|
563
|
+
const query: Record<string, string> = { per_page: String(perPage) };
|
|
564
|
+
if (cursor) {
|
|
565
|
+
query.cursor = cursor;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
const res = await this.fetch<Record<string, unknown>>(path, { query });
|
|
569
|
+
const items = (res[itemsKey] as unknown[]) ?? [];
|
|
570
|
+
const validated = this.alepha.codec.validate(
|
|
571
|
+
t.array(itemSchema),
|
|
572
|
+
items,
|
|
573
|
+
) as T[];
|
|
574
|
+
results.push(...validated);
|
|
575
|
+
|
|
576
|
+
const nextCursor = res.cursor as string | undefined;
|
|
577
|
+
if (!nextCursor || validated.length === 0) {
|
|
578
|
+
break;
|
|
579
|
+
}
|
|
580
|
+
cursor = nextCursor;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
return results;
|
|
584
|
+
}
|
|
585
|
+
|
|
447
586
|
// -------------------------------------------------------------------------
|
|
448
587
|
// Helpers
|
|
449
588
|
// -------------------------------------------------------------------------
|
|
@@ -124,21 +124,4 @@ export class WranglerApi {
|
|
|
124
124
|
{ resolve: true, env: { CI: "1" } },
|
|
125
125
|
);
|
|
126
126
|
}
|
|
127
|
-
|
|
128
|
-
// -------------------------------------------------------------------------
|
|
129
|
-
// Secrets
|
|
130
|
-
// -------------------------------------------------------------------------
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Push secrets in bulk to a worker.
|
|
134
|
-
*/
|
|
135
|
-
public async secretBulk(
|
|
136
|
-
secretsPath: string,
|
|
137
|
-
workerName: string,
|
|
138
|
-
): Promise<void> {
|
|
139
|
-
await this.runShell(
|
|
140
|
-
`wrangler secret bulk ${secretsPath} --name=${workerName}`,
|
|
141
|
-
{ resolve: true },
|
|
142
|
-
);
|
|
143
|
-
}
|
|
144
127
|
}
|
|
@@ -555,7 +555,7 @@ export class CliProvider {
|
|
|
555
555
|
const parsed = this.parseFlags(argv, flagDefs);
|
|
556
556
|
|
|
557
557
|
// Remove the mode flag from parsed result (it's handled separately)
|
|
558
|
-
|
|
558
|
+
parsed.__mode__ = undefined;
|
|
559
559
|
|
|
560
560
|
// apply manually defaults for optional properties that have defaults
|
|
561
561
|
for (const [key, value] of Object.entries(schema.properties)) {
|
package/src/core/Alepha.ts
CHANGED
|
@@ -826,6 +826,15 @@ export class Alepha {
|
|
|
826
826
|
return this;
|
|
827
827
|
}
|
|
828
828
|
|
|
829
|
+
/**
|
|
830
|
+
* Alias for {@link Alepha#with}.
|
|
831
|
+
*/
|
|
832
|
+
public register<T extends object>(
|
|
833
|
+
serviceEntry: ServiceEntry<T> | { default: ServiceEntry<T> },
|
|
834
|
+
): this {
|
|
835
|
+
return this.with(serviceEntry);
|
|
836
|
+
}
|
|
837
|
+
|
|
829
838
|
/**
|
|
830
839
|
* Get an instance of the specified service from the container.
|
|
831
840
|
*
|
|
@@ -8,7 +8,9 @@ export type Service<T extends object = any> =
|
|
|
8
8
|
| AbstractClass<T>
|
|
9
9
|
| RunFunction<T>;
|
|
10
10
|
|
|
11
|
-
export type RunFunction<T extends object = any> = (
|
|
11
|
+
export type RunFunction<T extends object = any> = (
|
|
12
|
+
...args: any[]
|
|
13
|
+
) => T | undefined;
|
|
12
14
|
|
|
13
15
|
export type InstantiableClass<T extends object = any> = new (
|
|
14
16
|
...args: any[]
|
|
@@ -447,7 +447,7 @@ export class TypeProvider {
|
|
|
447
447
|
/**
|
|
448
448
|
* Create a schema that maps all properties of an object schema to nullable.
|
|
449
449
|
*/
|
|
450
|
-
public nullify =
|
|
450
|
+
public nullify = (schema: TSchema, options?: TObjectOptions): TSchema =>
|
|
451
451
|
Type.Mapped(
|
|
452
452
|
Type.Identifier("K"),
|
|
453
453
|
Type.KeyOf(schema),
|
|
@@ -146,7 +146,7 @@ export class Logger implements LoggerInterface {
|
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
let _data: object | Error | undefined;
|
|
149
|
-
if (typeof data === "object" &&
|
|
149
|
+
if (typeof data === "object" && data) {
|
|
150
150
|
_data = data;
|
|
151
151
|
} else if (typeof message === "object" && message) {
|
|
152
152
|
_data = message;
|
|
@@ -364,7 +364,7 @@ describe("$resource primitive", () => {
|
|
|
364
364
|
uri: "protected://resource",
|
|
365
365
|
handler: async ({ context }) => {
|
|
366
366
|
const authHeader = context?.headers?.authorization;
|
|
367
|
-
if (!authHeader
|
|
367
|
+
if (!authHeader?.toString().startsWith("Bearer ")) {
|
|
368
368
|
throw new Error("Unauthorized");
|
|
369
369
|
}
|
|
370
370
|
return { text: "Secret content" };
|
|
@@ -379,7 +379,7 @@ describe("$tool primitive", () => {
|
|
|
379
379
|
},
|
|
380
380
|
handler: async ({ context }) => {
|
|
381
381
|
const authHeader = context?.headers?.authorization;
|
|
382
|
-
if (!authHeader
|
|
382
|
+
if (!authHeader?.toString().startsWith("Bearer ")) {
|
|
383
383
|
throw new Error("Unauthorized");
|
|
384
384
|
}
|
|
385
385
|
return "Access granted";
|
|
@@ -751,7 +751,7 @@ describe("McpServerProvider", () => {
|
|
|
751
751
|
schema: { result: t.text() },
|
|
752
752
|
handler: async ({ context }) => {
|
|
753
753
|
const auth = context?.headers?.authorization;
|
|
754
|
-
if (!auth
|
|
754
|
+
if (!auth?.toString().startsWith("Bearer ")) {
|
|
755
755
|
throw new Error("Unauthorized");
|
|
756
756
|
}
|
|
757
757
|
return "Access granted";
|