alchemy 2.0.0-beta.10 → 2.0.0-beta.13
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/bin/alchemy.js +1122 -450
- package/bin/alchemy.js.map +1 -1
- package/bin/alchemy.sh +15 -0
- package/bin/alchemy.ts +22 -727
- package/bin/commands/_shared.ts +237 -0
- package/bin/commands/bootstrap.ts +117 -0
- package/bin/commands/deploy.ts +144 -0
- package/bin/commands/login.ts +93 -0
- package/bin/commands/logs.ts +157 -0
- package/bin/commands/tail.ts +138 -0
- package/lib/AWS/AuthProvider.d.ts +7 -71
- package/lib/AWS/AuthProvider.d.ts.map +1 -1
- package/lib/AWS/AuthProvider.js +27 -22
- package/lib/AWS/AuthProvider.js.map +1 -1
- package/lib/AWS/AutoScaling/LaunchTemplate.d.ts +3 -3
- package/lib/AWS/AutoScaling/LaunchTemplate.d.ts.map +1 -1
- package/lib/AWS/AutoScaling/LaunchTemplate.js +2 -2
- package/lib/AWS/AutoScaling/LaunchTemplate.js.map +1 -1
- package/lib/AWS/Bootstrap.d.ts +2 -1
- package/lib/AWS/Bootstrap.d.ts.map +1 -1
- package/lib/AWS/Bootstrap.js +27 -29
- package/lib/AWS/Bootstrap.js.map +1 -1
- package/lib/AWS/CloudWatch/Alarm.d.ts +2 -2
- package/lib/AWS/CloudWatch/Alarm.d.ts.map +1 -1
- package/lib/AWS/CloudWatch/Alarm.js +2 -2
- package/lib/AWS/CloudWatch/Alarm.js.map +1 -1
- package/lib/AWS/CloudWatch/AlarmMuteRule.d.ts +2 -2
- package/lib/AWS/CloudWatch/AlarmMuteRule.d.ts.map +1 -1
- package/lib/AWS/CloudWatch/AlarmMuteRule.js +2 -2
- package/lib/AWS/CloudWatch/AlarmMuteRule.js.map +1 -1
- package/lib/AWS/CloudWatch/CompositeAlarm.d.ts +2 -2
- package/lib/AWS/CloudWatch/CompositeAlarm.d.ts.map +1 -1
- package/lib/AWS/CloudWatch/CompositeAlarm.js +2 -2
- package/lib/AWS/CloudWatch/CompositeAlarm.js.map +1 -1
- package/lib/AWS/CloudWatch/Dashboard.d.ts +2 -2
- package/lib/AWS/CloudWatch/Dashboard.d.ts.map +1 -1
- package/lib/AWS/CloudWatch/Dashboard.js +2 -2
- package/lib/AWS/CloudWatch/Dashboard.js.map +1 -1
- package/lib/AWS/CloudWatch/InsightRule.d.ts +2 -2
- package/lib/AWS/CloudWatch/InsightRule.d.ts.map +1 -1
- package/lib/AWS/CloudWatch/InsightRule.js +2 -2
- package/lib/AWS/CloudWatch/InsightRule.js.map +1 -1
- package/lib/AWS/CloudWatch/MetricStream.d.ts +2 -2
- package/lib/AWS/CloudWatch/MetricStream.d.ts.map +1 -1
- package/lib/AWS/CloudWatch/MetricStream.js +2 -2
- package/lib/AWS/CloudWatch/MetricStream.js.map +1 -1
- package/lib/AWS/Credentials.d.ts +5 -10
- package/lib/AWS/Credentials.d.ts.map +1 -1
- package/lib/AWS/Credentials.js +6 -30
- package/lib/AWS/Credentials.js.map +1 -1
- package/lib/AWS/DynamoDB/Table.d.ts +1 -1
- package/lib/AWS/DynamoDB/Table.d.ts.map +1 -1
- package/lib/AWS/EC2/EIP.d.ts +3 -3
- package/lib/AWS/EC2/EIP.d.ts.map +1 -1
- package/lib/AWS/EC2/EIP.js +2 -2
- package/lib/AWS/EC2/EIP.js.map +1 -1
- package/lib/AWS/EC2/EgressOnlyInternetGateway.d.ts +3 -3
- package/lib/AWS/EC2/EgressOnlyInternetGateway.d.ts.map +1 -1
- package/lib/AWS/EC2/EgressOnlyInternetGateway.js +2 -2
- package/lib/AWS/EC2/EgressOnlyInternetGateway.js.map +1 -1
- package/lib/AWS/EC2/Instance.d.ts +3 -3
- package/lib/AWS/EC2/Instance.d.ts.map +1 -1
- package/lib/AWS/EC2/Instance.js +2 -2
- package/lib/AWS/EC2/Instance.js.map +1 -1
- package/lib/AWS/EC2/InternetGateway.d.ts +3 -3
- package/lib/AWS/EC2/InternetGateway.d.ts.map +1 -1
- package/lib/AWS/EC2/InternetGateway.js +2 -2
- package/lib/AWS/EC2/InternetGateway.js.map +1 -1
- package/lib/AWS/EC2/NatGateway.d.ts +3 -3
- package/lib/AWS/EC2/NatGateway.d.ts.map +1 -1
- package/lib/AWS/EC2/NatGateway.js +2 -2
- package/lib/AWS/EC2/NatGateway.js.map +1 -1
- package/lib/AWS/EC2/Network.d.ts +1 -1
- package/lib/AWS/EC2/NetworkAcl.d.ts +3 -3
- package/lib/AWS/EC2/NetworkAcl.d.ts.map +1 -1
- package/lib/AWS/EC2/NetworkAcl.js +2 -2
- package/lib/AWS/EC2/NetworkAcl.js.map +1 -1
- package/lib/AWS/EC2/RouteTable.d.ts +3 -3
- package/lib/AWS/EC2/RouteTable.d.ts.map +1 -1
- package/lib/AWS/EC2/RouteTable.js +2 -2
- package/lib/AWS/EC2/RouteTable.js.map +1 -1
- package/lib/AWS/EC2/SecurityGroup.d.ts +3 -3
- package/lib/AWS/EC2/SecurityGroup.d.ts.map +1 -1
- package/lib/AWS/EC2/SecurityGroup.js +2 -2
- package/lib/AWS/EC2/SecurityGroup.js.map +1 -1
- package/lib/AWS/EC2/Subnet.d.ts +1 -1
- package/lib/AWS/EC2/Subnet.d.ts.map +1 -1
- package/lib/AWS/EC2/Vpc.d.ts +3 -3
- package/lib/AWS/EC2/Vpc.d.ts.map +1 -1
- package/lib/AWS/EC2/Vpc.js +2 -2
- package/lib/AWS/EC2/Vpc.js.map +1 -1
- package/lib/AWS/EC2/VpcEndpoint.d.ts +3 -3
- package/lib/AWS/EC2/VpcEndpoint.d.ts.map +1 -1
- package/lib/AWS/EC2/VpcEndpoint.js +2 -2
- package/lib/AWS/EC2/VpcEndpoint.js.map +1 -1
- package/lib/AWS/ECR/Repository.d.ts +1 -1
- package/lib/AWS/ECR/Repository.d.ts.map +1 -1
- package/lib/AWS/ECR/Repository.js +0 -1
- package/lib/AWS/ECR/Repository.js.map +1 -1
- package/lib/AWS/ECS/Cluster.d.ts +2 -2
- package/lib/AWS/ECS/Cluster.d.ts.map +1 -1
- package/lib/AWS/ECS/Cluster.js +2 -2
- package/lib/AWS/ECS/Cluster.js.map +1 -1
- package/lib/AWS/ECS/Service.d.ts +1 -1
- package/lib/AWS/ECS/Service.d.ts.map +1 -1
- package/lib/AWS/ECS/Task.d.ts +2 -2
- package/lib/AWS/ECS/Task.d.ts.map +1 -1
- package/lib/AWS/ECS/Task.js +2 -2
- package/lib/AWS/ECS/Task.js.map +1 -1
- package/lib/AWS/EKS/Cluster.d.ts +1 -1
- package/lib/AWS/EKS/Cluster.d.ts.map +1 -1
- package/lib/AWS/ELBv2/Listener.d.ts +1 -1
- package/lib/AWS/ELBv2/Listener.d.ts.map +1 -1
- package/lib/AWS/ELBv2/LoadBalancer.d.ts +1 -1
- package/lib/AWS/ELBv2/LoadBalancer.d.ts.map +1 -1
- package/lib/AWS/ELBv2/TargetGroup.d.ts +1 -1
- package/lib/AWS/ELBv2/TargetGroup.d.ts.map +1 -1
- package/lib/AWS/Endpoint.d.ts +7 -2
- package/lib/AWS/Endpoint.d.ts.map +1 -1
- package/lib/AWS/Endpoint.js +7 -2
- package/lib/AWS/Endpoint.js.map +1 -1
- package/lib/AWS/Environment.d.ts +68 -0
- package/lib/AWS/Environment.d.ts.map +1 -0
- package/lib/AWS/Environment.js +53 -0
- package/lib/AWS/Environment.js.map +1 -0
- package/lib/AWS/EventBridge/EventBus.d.ts +2 -2
- package/lib/AWS/EventBridge/EventBus.d.ts.map +1 -1
- package/lib/AWS/EventBridge/EventBus.js +2 -2
- package/lib/AWS/EventBridge/EventBus.js.map +1 -1
- package/lib/AWS/EventBridge/ListRules.d.ts +2 -2
- package/lib/AWS/EventBridge/ListRules.d.ts.map +1 -1
- package/lib/AWS/EventBridge/ListRules.js +2 -2
- package/lib/AWS/EventBridge/ListRules.js.map +1 -1
- package/lib/AWS/EventBridge/PutEvents.d.ts +2 -2
- package/lib/AWS/EventBridge/PutEvents.d.ts.map +1 -1
- package/lib/AWS/EventBridge/PutEvents.js +2 -2
- package/lib/AWS/EventBridge/PutEvents.js.map +1 -1
- package/lib/AWS/EventBridge/Rule.d.ts +2 -2
- package/lib/AWS/EventBridge/Rule.d.ts.map +1 -1
- package/lib/AWS/EventBridge/Rule.js +2 -2
- package/lib/AWS/EventBridge/Rule.js.map +1 -1
- package/lib/AWS/IAM/OpenIDConnectProvider.d.ts +2 -2
- package/lib/AWS/IAM/OpenIDConnectProvider.d.ts.map +1 -1
- package/lib/AWS/IAM/OpenIDConnectProvider.js +2 -2
- package/lib/AWS/IAM/OpenIDConnectProvider.js.map +1 -1
- package/lib/AWS/IAM/Policy.d.ts +3 -3
- package/lib/AWS/IAM/Policy.d.ts.map +1 -1
- package/lib/AWS/IAM/Policy.js +2 -2
- package/lib/AWS/IAM/Policy.js.map +1 -1
- package/lib/AWS/IAM/Role.d.ts +3 -3
- package/lib/AWS/IAM/Role.d.ts.map +1 -1
- package/lib/AWS/IAM/Role.js +3 -3
- package/lib/AWS/IAM/Role.js.map +1 -1
- package/lib/AWS/Kinesis/Stream.d.ts +2 -2
- package/lib/AWS/Kinesis/Stream.d.ts.map +1 -1
- package/lib/AWS/Kinesis/Stream.js +2 -2
- package/lib/AWS/Kinesis/Stream.js.map +1 -1
- package/lib/AWS/Lambda/BucketEventSource.d.ts +1 -1
- package/lib/AWS/Lambda/BucketEventSource.d.ts.map +1 -1
- package/lib/AWS/Lambda/EventBridgeEventSource.d.ts +1 -1
- package/lib/AWS/Lambda/EventBridgeEventSource.d.ts.map +1 -1
- package/lib/AWS/Lambda/EventSourceMapping.d.ts +2 -2
- package/lib/AWS/Lambda/EventSourceMapping.d.ts.map +1 -1
- package/lib/AWS/Lambda/EventSourceMapping.js +2 -2
- package/lib/AWS/Lambda/EventSourceMapping.js.map +1 -1
- package/lib/AWS/Lambda/Function.d.ts +2 -2
- package/lib/AWS/Lambda/Function.d.ts.map +1 -1
- package/lib/AWS/Lambda/Function.js +2 -2
- package/lib/AWS/Lambda/Function.js.map +1 -1
- package/lib/AWS/Lambda/Permission.d.ts +1 -1
- package/lib/AWS/Lambda/Permission.js +1 -1
- package/lib/AWS/Lambda/QueueEventSource.d.ts +1 -1
- package/lib/AWS/Lambda/QueueEventSource.d.ts.map +1 -1
- package/lib/AWS/Lambda/StreamEventSource.d.ts +1 -1
- package/lib/AWS/Lambda/StreamEventSource.d.ts.map +1 -1
- package/lib/AWS/Lambda/TableEventSource.d.ts +1 -1
- package/lib/AWS/Lambda/TableEventSource.d.ts.map +1 -1
- package/lib/AWS/Lambda/TopicEventSource.d.ts +1 -1
- package/lib/AWS/Lambda/TopicEventSource.d.ts.map +1 -1
- package/lib/AWS/Logs/LogGroup.d.ts +3 -3
- package/lib/AWS/Logs/LogGroup.d.ts.map +1 -1
- package/lib/AWS/Logs/LogGroup.js +2 -2
- package/lib/AWS/Logs/LogGroup.js.map +1 -1
- package/lib/AWS/Providers.d.ts +1 -2
- package/lib/AWS/Providers.d.ts.map +1 -1
- package/lib/AWS/Providers.js +3 -3
- package/lib/AWS/Providers.js.map +1 -1
- package/lib/AWS/Region.d.ts +6 -22
- package/lib/AWS/Region.d.ts.map +1 -1
- package/lib/AWS/Region.js +6 -39
- package/lib/AWS/Region.js.map +1 -1
- package/lib/AWS/S3/Bucket.d.ts +2 -2
- package/lib/AWS/S3/Bucket.d.ts.map +1 -1
- package/lib/AWS/S3/Bucket.js +2 -2
- package/lib/AWS/S3/Bucket.js.map +1 -1
- package/lib/AWS/SNS/Topic.d.ts +1 -1
- package/lib/AWS/SNS/Topic.d.ts.map +1 -1
- package/lib/AWS/SQS/Queue.d.ts +3 -3
- package/lib/AWS/SQS/Queue.d.ts.map +1 -1
- package/lib/AWS/SQS/Queue.js +2 -2
- package/lib/AWS/SQS/Queue.js.map +1 -1
- package/lib/AWS/index.d.ts +1 -3
- package/lib/AWS/index.d.ts.map +1 -1
- package/lib/AWS/index.js +1 -3
- package/lib/AWS/index.js.map +1 -1
- package/lib/Apply.d.ts.map +1 -1
- package/lib/Apply.js +2 -2
- package/lib/Apply.js.map +1 -1
- package/lib/Auth/AuthProvider.d.ts +51 -7
- package/lib/Auth/AuthProvider.d.ts.map +1 -1
- package/lib/Auth/AuthProvider.js +37 -0
- package/lib/Auth/AuthProvider.js.map +1 -1
- package/lib/Auth/Profile.d.ts +71 -10
- package/lib/Auth/Profile.d.ts.map +1 -1
- package/lib/Auth/Profile.js +47 -30
- package/lib/Auth/Profile.js.map +1 -1
- package/lib/Auth/index.d.ts +1 -1
- package/lib/Auth/index.d.ts.map +1 -1
- package/lib/Cloudflare/Auth/AuthProvider.d.ts +14 -31
- package/lib/Cloudflare/Auth/AuthProvider.d.ts.map +1 -1
- package/lib/Cloudflare/Auth/AuthProvider.js +59 -38
- package/lib/Cloudflare/Auth/AuthProvider.js.map +1 -1
- package/lib/Cloudflare/CloudflareEnvironment.d.ts +11 -0
- package/lib/Cloudflare/CloudflareEnvironment.d.ts.map +1 -0
- package/lib/Cloudflare/CloudflareEnvironment.js +26 -0
- package/lib/Cloudflare/CloudflareEnvironment.js.map +1 -0
- package/lib/Cloudflare/Container/ContainerApplication.d.ts +70 -42
- package/lib/Cloudflare/Container/ContainerApplication.d.ts.map +1 -1
- package/lib/Cloudflare/Container/ContainerApplication.js +49 -24
- package/lib/Cloudflare/Container/ContainerApplication.js.map +1 -1
- package/lib/Cloudflare/Credentials.d.ts +11 -0
- package/lib/Cloudflare/Credentials.d.ts.map +1 -0
- package/lib/Cloudflare/Credentials.js +34 -0
- package/lib/Cloudflare/Credentials.js.map +1 -0
- package/lib/Cloudflare/D1/D1Database.d.ts +2 -2
- package/lib/Cloudflare/D1/D1Database.d.ts.map +1 -1
- package/lib/Cloudflare/D1/D1Database.js +2 -2
- package/lib/Cloudflare/D1/D1Database.js.map +1 -1
- package/lib/Cloudflare/KV/KVNamespace.d.ts +2 -2
- package/lib/Cloudflare/KV/KVNamespace.d.ts.map +1 -1
- package/lib/Cloudflare/KV/KVNamespace.js +2 -2
- package/lib/Cloudflare/KV/KVNamespace.js.map +1 -1
- package/lib/Cloudflare/Providers.d.ts +2 -3
- package/lib/Cloudflare/Providers.d.ts.map +1 -1
- package/lib/Cloudflare/Providers.js +12 -4
- package/lib/Cloudflare/Providers.js.map +1 -1
- package/lib/Cloudflare/Queue/Queue.d.ts +52 -0
- package/lib/Cloudflare/Queue/Queue.d.ts.map +1 -0
- package/lib/Cloudflare/Queue/Queue.js +136 -0
- package/lib/Cloudflare/Queue/Queue.js.map +1 -0
- package/lib/Cloudflare/Queue/QueueBinding.d.ts +35 -0
- package/lib/Cloudflare/Queue/QueueBinding.d.ts.map +1 -0
- package/lib/Cloudflare/Queue/QueueBinding.js +51 -0
- package/lib/Cloudflare/Queue/QueueBinding.js.map +1 -0
- package/lib/Cloudflare/Queue/QueueConsumer.d.ts +86 -0
- package/lib/Cloudflare/Queue/QueueConsumer.d.ts.map +1 -0
- package/lib/Cloudflare/Queue/QueueConsumer.js +138 -0
- package/lib/Cloudflare/Queue/QueueConsumer.js.map +1 -0
- package/lib/Cloudflare/Queue/index.d.ts +4 -0
- package/lib/Cloudflare/Queue/index.d.ts.map +1 -0
- package/lib/Cloudflare/Queue/index.js +4 -0
- package/lib/Cloudflare/Queue/index.js.map +1 -0
- package/lib/Cloudflare/R2/R2Bucket.d.ts +2 -2
- package/lib/Cloudflare/R2/R2Bucket.d.ts.map +1 -1
- package/lib/Cloudflare/R2/R2Bucket.js +2 -2
- package/lib/Cloudflare/R2/R2Bucket.js.map +1 -1
- package/lib/Cloudflare/SecretsStore/Secret.d.ts +74 -0
- package/lib/Cloudflare/SecretsStore/Secret.d.ts.map +1 -0
- package/lib/Cloudflare/SecretsStore/Secret.js +161 -0
- package/lib/Cloudflare/SecretsStore/Secret.js.map +1 -0
- package/lib/Cloudflare/SecretsStore/SecretBinding.d.ts +42 -0
- package/lib/Cloudflare/SecretsStore/SecretBinding.d.ts.map +1 -0
- package/lib/Cloudflare/SecretsStore/SecretBinding.js +49 -0
- package/lib/Cloudflare/SecretsStore/SecretBinding.js.map +1 -0
- package/lib/Cloudflare/SecretsStore/SecretsStore.d.ts +37 -0
- package/lib/Cloudflare/SecretsStore/SecretsStore.d.ts.map +1 -0
- package/lib/Cloudflare/SecretsStore/SecretsStore.js +88 -0
- package/lib/Cloudflare/SecretsStore/SecretsStore.js.map +1 -0
- package/lib/Cloudflare/SecretsStore/index.d.ts +4 -0
- package/lib/Cloudflare/SecretsStore/index.d.ts.map +1 -0
- package/lib/Cloudflare/SecretsStore/index.js +4 -0
- package/lib/Cloudflare/SecretsStore/index.js.map +1 -0
- package/lib/Cloudflare/Workers/InferEnv.d.ts +1 -1
- package/lib/Cloudflare/Workers/InferEnv.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Worker.d.ts +5 -3
- package/lib/Cloudflare/Workers/Worker.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Worker.js +61 -7
- package/lib/Cloudflare/Workers/Worker.js.map +1 -1
- package/lib/Cloudflare/Workers/Workflow.d.ts +10 -4
- package/lib/Cloudflare/Workers/Workflow.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Workflow.js +3 -3
- package/lib/Cloudflare/Workers/Workflow.js.map +1 -1
- package/lib/Cloudflare/index.d.ts +3 -1
- package/lib/Cloudflare/index.d.ts.map +1 -1
- package/lib/Cloudflare/index.js +3 -1
- package/lib/Cloudflare/index.js.map +1 -1
- package/lib/Stack.d.ts +3 -2
- package/lib/Stack.d.ts.map +1 -1
- package/lib/Stack.js +10 -7
- package/lib/Stack.js.map +1 -1
- package/lib/State/LocalState.d.ts.map +1 -1
- package/lib/State/LocalState.js +40 -12
- package/lib/State/LocalState.js.map +1 -1
- package/lib/Test/Bun.d.ts.map +1 -1
- package/lib/Test/Bun.js +3 -2
- package/lib/Test/Bun.js.map +1 -1
- package/lib/Test/Vitest.d.ts +3 -1
- package/lib/Test/Vitest.d.ts.map +1 -1
- package/lib/Test/Vitest.js +19 -16
- package/lib/Test/Vitest.js.map +1 -1
- package/lib/Util/PlatformServices.d.ts +14 -3
- package/lib/Util/PlatformServices.d.ts.map +1 -1
- package/lib/Util/PlatformServices.js +21 -3
- package/lib/Util/PlatformServices.js.map +1 -1
- package/package.json +5 -5
- package/src/AWS/AuthProvider.ts +67 -67
- package/src/AWS/AutoScaling/LaunchTemplate.ts +3 -3
- package/src/AWS/Bootstrap.ts +32 -37
- package/src/AWS/CloudWatch/Alarm.ts +2 -2
- package/src/AWS/CloudWatch/AlarmMuteRule.ts +2 -2
- package/src/AWS/CloudWatch/CompositeAlarm.ts +2 -2
- package/src/AWS/CloudWatch/Dashboard.ts +2 -2
- package/src/AWS/CloudWatch/InsightRule.ts +2 -2
- package/src/AWS/CloudWatch/MetricStream.ts +2 -2
- package/src/AWS/Credentials.ts +9 -44
- package/src/AWS/DynamoDB/Table.ts +1 -1
- package/src/AWS/EC2/EIP.ts +3 -3
- package/src/AWS/EC2/EgressOnlyInternetGateway.ts +3 -3
- package/src/AWS/EC2/Instance.ts +3 -3
- package/src/AWS/EC2/InternetGateway.ts +3 -3
- package/src/AWS/EC2/NatGateway.ts +3 -3
- package/src/AWS/EC2/NetworkAcl.ts +3 -3
- package/src/AWS/EC2/RouteTable.ts +3 -3
- package/src/AWS/EC2/SecurityGroup.ts +3 -3
- package/src/AWS/EC2/Subnet.ts +1 -1
- package/src/AWS/EC2/Vpc.ts +3 -3
- package/src/AWS/EC2/VpcEndpoint.ts +3 -3
- package/src/AWS/ECR/Repository.ts +1 -1
- package/src/AWS/ECS/Cluster.ts +2 -2
- package/src/AWS/ECS/Service.ts +1 -1
- package/src/AWS/ECS/Task.ts +2 -2
- package/src/AWS/EKS/Cluster.ts +1 -1
- package/src/AWS/ELBv2/Listener.ts +1 -1
- package/src/AWS/ELBv2/LoadBalancer.ts +1 -1
- package/src/AWS/ELBv2/TargetGroup.ts +1 -1
- package/src/AWS/Endpoint.ts +12 -8
- package/src/AWS/Environment.ts +123 -0
- package/src/AWS/EventBridge/EventBus.ts +2 -2
- package/src/AWS/EventBridge/ListRules.ts +2 -2
- package/src/AWS/EventBridge/PutEvents.ts +2 -2
- package/src/AWS/EventBridge/Rule.ts +2 -2
- package/src/AWS/IAM/OpenIDConnectProvider.ts +2 -2
- package/src/AWS/IAM/Policy.ts +3 -3
- package/src/AWS/IAM/Role.ts +4 -4
- package/src/AWS/Kinesis/Stream.ts +2 -2
- package/src/AWS/Lambda/EventSourceMapping.ts +2 -2
- package/src/AWS/Lambda/Function.ts +2 -2
- package/src/AWS/Lambda/Permission.ts +1 -1
- package/src/AWS/Logs/LogGroup.ts +3 -3
- package/src/AWS/Providers.ts +7 -7
- package/src/AWS/Region.ts +9 -66
- package/src/AWS/S3/Bucket.ts +2 -2
- package/src/AWS/SNS/Topic.ts +1 -1
- package/src/AWS/SQS/Queue.ts +3 -3
- package/src/AWS/index.ts +1 -3
- package/src/Apply.ts +55 -57
- package/src/Auth/AuthProvider.ts +188 -8
- package/src/Auth/Profile.ts +117 -54
- package/src/Auth/index.ts +1 -1
- package/src/Cloudflare/Auth/AuthProvider.ts +127 -98
- package/src/Cloudflare/CloudflareEnvironment.ts +49 -0
- package/src/Cloudflare/Container/ContainerApplication.ts +172 -94
- package/src/Cloudflare/Credentials.ts +75 -0
- package/src/Cloudflare/D1/D1Database.ts +2 -2
- package/src/Cloudflare/KV/KVNamespace.ts +2 -2
- package/src/Cloudflare/Providers.ts +20 -10
- package/src/Cloudflare/Queue/Queue.ts +174 -0
- package/src/Cloudflare/Queue/QueueBinding.ts +110 -0
- package/src/Cloudflare/Queue/QueueConsumer.ts +219 -0
- package/src/Cloudflare/Queue/index.ts +3 -0
- package/src/Cloudflare/R2/R2Bucket.ts +2 -2
- package/src/Cloudflare/SecretsStore/Secret.ts +229 -0
- package/src/Cloudflare/SecretsStore/SecretBinding.ts +107 -0
- package/src/Cloudflare/SecretsStore/SecretsStore.ts +106 -0
- package/src/Cloudflare/SecretsStore/index.ts +3 -0
- package/src/Cloudflare/Workers/InferEnv.ts +5 -3
- package/src/Cloudflare/Workers/Worker.ts +63 -7
- package/src/Cloudflare/Workers/Workflow.ts +19 -9
- package/src/Cloudflare/index.ts +3 -1
- package/src/Stack.ts +40 -29
- package/src/State/LocalState.ts +43 -16
- package/src/Test/Bun.ts +3 -0
- package/src/Test/Vitest.ts +31 -23
- package/src/Util/PlatformServices.ts +54 -13
- package/bin/process-manager.ts +0 -10
- package/lib/AWS/Account.d.ts +0 -26
- package/lib/AWS/Account.d.ts.map +0 -1
- package/lib/AWS/Account.js +0 -32
- package/lib/AWS/Account.js.map +0 -1
- package/lib/AWS/Profile.d.ts +0 -6
- package/lib/AWS/Profile.d.ts.map +0 -1
- package/lib/AWS/Profile.js +0 -4
- package/lib/AWS/Profile.js.map +0 -1
- package/lib/AWS/StageConfig.d.ts +0 -25
- package/lib/AWS/StageConfig.d.ts.map +0 -1
- package/lib/AWS/StageConfig.js +0 -23
- package/lib/AWS/StageConfig.js.map +0 -1
- package/lib/Cloudflare/Account.d.ts +0 -10
- package/lib/Cloudflare/Account.d.ts.map +0 -1
- package/lib/Cloudflare/Account.js +0 -24
- package/lib/Cloudflare/Account.js.map +0 -1
- package/lib/Cloudflare/StageConfig.d.ts +0 -8
- package/lib/Cloudflare/StageConfig.d.ts.map +0 -1
- package/lib/Cloudflare/StageConfig.js +0 -4
- package/lib/Cloudflare/StageConfig.js.map +0 -1
- package/src/AWS/Account.ts +0 -56
- package/src/AWS/Profile.ts +0 -5
- package/src/AWS/StageConfig.ts +0 -44
- package/src/Cloudflare/Account.ts +0 -38
- package/src/Cloudflare/StageConfig.ts +0 -8
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import * as secretsStore from "@distilled.cloud/cloudflare/secrets-store";
|
|
2
|
+
import * as Effect from "effect/Effect";
|
|
3
|
+
import * as Option from "effect/Option";
|
|
4
|
+
import * as Redacted from "effect/Redacted";
|
|
5
|
+
import * as Stream from "effect/Stream";
|
|
6
|
+
import { isResolved } from "../../Diff.ts";
|
|
7
|
+
import * as Provider from "../../Provider.ts";
|
|
8
|
+
import { Resource } from "../../Resource.ts";
|
|
9
|
+
import type { Providers } from "../Providers.ts";
|
|
10
|
+
import { SecretBinding } from "./SecretBinding.ts";
|
|
11
|
+
export type StoreSecretProps = {
|
|
12
|
+
/**
|
|
13
|
+
* The Secrets Store that owns this secret.
|
|
14
|
+
*/
|
|
15
|
+
store: {
|
|
16
|
+
storeId: string;
|
|
17
|
+
accountId: string;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* The name of the secret within the store.
|
|
21
|
+
* If omitted, the resource's logical ID is used.
|
|
22
|
+
*/
|
|
23
|
+
name?: string;
|
|
24
|
+
/**
|
|
25
|
+
* The secret value. Treated as redacted and never logged.
|
|
26
|
+
*/
|
|
27
|
+
value: Redacted.Redacted<string>;
|
|
28
|
+
/**
|
|
29
|
+
* Services allowed to reference this secret.
|
|
30
|
+
* @default ["workers"]
|
|
31
|
+
*/
|
|
32
|
+
scopes?: string[];
|
|
33
|
+
/**
|
|
34
|
+
* Optional free-form description.
|
|
35
|
+
*/
|
|
36
|
+
comment?: string;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export type Secret = Resource<
|
|
40
|
+
"Cloudflare.SecretsStore.Secret",
|
|
41
|
+
StoreSecretProps,
|
|
42
|
+
{
|
|
43
|
+
secretId: string;
|
|
44
|
+
secretName: string;
|
|
45
|
+
storeId: string;
|
|
46
|
+
accountId: string;
|
|
47
|
+
status: "pending" | "active" | "deleted";
|
|
48
|
+
scopes: string[];
|
|
49
|
+
comment: string | undefined;
|
|
50
|
+
},
|
|
51
|
+
never,
|
|
52
|
+
Providers
|
|
53
|
+
>;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* A single secret stored inside a Cloudflare Secrets Store.
|
|
57
|
+
*
|
|
58
|
+
* The secret value is treated as redacted and is only ever sent to
|
|
59
|
+
* Cloudflare at create time. Updating `scopes` or `comment` issues a
|
|
60
|
+
* PATCH; changing `value` or `name` replaces the secret.
|
|
61
|
+
*
|
|
62
|
+
* @section Creating a Secret
|
|
63
|
+
* @example Basic Secret
|
|
64
|
+
* ```typescript
|
|
65
|
+
* const store = yield* Cloudflare.SecretsStore("MyStore");
|
|
66
|
+
* const apiKey = yield* Cloudflare.StoreSecret("ApiKey", {
|
|
67
|
+
* store,
|
|
68
|
+
* value: Redacted.make(process.env.API_KEY!),
|
|
69
|
+
* });
|
|
70
|
+
* ```
|
|
71
|
+
*
|
|
72
|
+
* @section Binding to a Worker
|
|
73
|
+
* @example Reading a secret at runtime
|
|
74
|
+
* ```typescript
|
|
75
|
+
* const apiKey = yield* Cloudflare.StoreSecret.bind(ApiKey);
|
|
76
|
+
* // `apiKey` is itself an Effect that resolves to the secret value:
|
|
77
|
+
* const value = yield* apiKey;
|
|
78
|
+
* // Or call `.get()` explicitly:
|
|
79
|
+
* const value = yield* apiKey.get();
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export const Secret = Resource<Secret>("Cloudflare.SecretsStore.Secret")({
|
|
83
|
+
bind: SecretBinding.bind,
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const resolveScopes = (scopes: string[] | undefined): string[] =>
|
|
87
|
+
scopes && scopes.length > 0 ? scopes : ["workers"];
|
|
88
|
+
|
|
89
|
+
const resolveName = (id: string, name: string | undefined): string =>
|
|
90
|
+
name ?? id;
|
|
91
|
+
|
|
92
|
+
export const StoreSecretProvider = () =>
|
|
93
|
+
Provider.effect(
|
|
94
|
+
Secret,
|
|
95
|
+
Effect.gen(function* () {
|
|
96
|
+
const createStoreSecret = yield* secretsStore.createStoreSecret;
|
|
97
|
+
const patchStoreSecret = yield* secretsStore.patchStoreSecret;
|
|
98
|
+
const deleteStoreSecret = yield* secretsStore.deleteStoreSecret;
|
|
99
|
+
const getStoreSecret = yield* secretsStore.getStoreSecret;
|
|
100
|
+
const listStoreSecrets = secretsStore.listStoreSecrets;
|
|
101
|
+
|
|
102
|
+
const arraysEqual = (a: string[], b: string[]) =>
|
|
103
|
+
a.length === b.length && a.every((v, i) => v === b[i]);
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
stables: ["secretId", "secretName", "storeId", "accountId"],
|
|
107
|
+
diff: Effect.fn(function* ({ id, olds = {} as any, news, output }) {
|
|
108
|
+
if (!isResolved(news)) return undefined;
|
|
109
|
+
const oldStoreId = output?.storeId ?? olds.store?.storeId;
|
|
110
|
+
const newStoreId = news.store.storeId;
|
|
111
|
+
const oldName = output?.secretName ?? resolveName(id, olds.name);
|
|
112
|
+
const newName = resolveName(id, news.name);
|
|
113
|
+
if (oldStoreId !== newStoreId || oldName !== newName) {
|
|
114
|
+
return { action: "replace" } as const;
|
|
115
|
+
}
|
|
116
|
+
const oldValue = olds.value ? Redacted.value(olds.value) : undefined;
|
|
117
|
+
const newValue = Redacted.value(news.value);
|
|
118
|
+
if (oldValue !== newValue) {
|
|
119
|
+
return { action: "replace" } as const;
|
|
120
|
+
}
|
|
121
|
+
}),
|
|
122
|
+
create: Effect.fn(function* ({ id, news }) {
|
|
123
|
+
const name = resolveName(id, news.name);
|
|
124
|
+
const scopes = resolveScopes(news.scopes);
|
|
125
|
+
const response = yield* createStoreSecret({
|
|
126
|
+
accountId: news.store.accountId,
|
|
127
|
+
storeId: news.store.storeId,
|
|
128
|
+
body: [
|
|
129
|
+
{
|
|
130
|
+
name,
|
|
131
|
+
scopes,
|
|
132
|
+
value: Redacted.value(news.value),
|
|
133
|
+
comment: news.comment,
|
|
134
|
+
},
|
|
135
|
+
],
|
|
136
|
+
});
|
|
137
|
+
const secret = response.result[0]!;
|
|
138
|
+
return {
|
|
139
|
+
secretId: secret.id,
|
|
140
|
+
secretName: secret.name,
|
|
141
|
+
storeId: secret.storeId,
|
|
142
|
+
accountId: news.store.accountId,
|
|
143
|
+
status: secret.status,
|
|
144
|
+
scopes,
|
|
145
|
+
comment: secret.comment ?? undefined,
|
|
146
|
+
};
|
|
147
|
+
}),
|
|
148
|
+
update: Effect.fn(function* ({ news, olds = {} as any, output }) {
|
|
149
|
+
const newScopes = resolveScopes(news.scopes);
|
|
150
|
+
const oldScopes = resolveScopes(olds.scopes);
|
|
151
|
+
const scopesChanged = !arraysEqual(newScopes, oldScopes);
|
|
152
|
+
const commentChanged = (olds.comment ?? undefined) !== news.comment;
|
|
153
|
+
if (!scopesChanged && !commentChanged) {
|
|
154
|
+
return output;
|
|
155
|
+
}
|
|
156
|
+
const patched = yield* patchStoreSecret({
|
|
157
|
+
accountId: output.accountId,
|
|
158
|
+
storeId: output.storeId,
|
|
159
|
+
secretId: output.secretId,
|
|
160
|
+
scopes: scopesChanged ? newScopes : undefined,
|
|
161
|
+
comment: commentChanged ? news.comment : undefined,
|
|
162
|
+
});
|
|
163
|
+
return {
|
|
164
|
+
...output,
|
|
165
|
+
status: patched.status,
|
|
166
|
+
scopes: newScopes,
|
|
167
|
+
comment: patched.comment ?? undefined,
|
|
168
|
+
};
|
|
169
|
+
}),
|
|
170
|
+
delete: Effect.fn(function* ({ output }) {
|
|
171
|
+
yield* deleteStoreSecret({
|
|
172
|
+
accountId: output.accountId,
|
|
173
|
+
storeId: output.storeId,
|
|
174
|
+
secretId: output.secretId,
|
|
175
|
+
}).pipe(
|
|
176
|
+
Effect.catchTag("SecretNotFound", () => Effect.void),
|
|
177
|
+
Effect.catchTag("StoreNotFound", () => Effect.void),
|
|
178
|
+
Effect.catchTag("NotFound", () => Effect.void),
|
|
179
|
+
);
|
|
180
|
+
}),
|
|
181
|
+
read: Effect.fn(function* ({ id, olds, output }) {
|
|
182
|
+
if (output?.secretId) {
|
|
183
|
+
return yield* getStoreSecret({
|
|
184
|
+
accountId: output.accountId,
|
|
185
|
+
storeId: output.storeId,
|
|
186
|
+
secretId: output.secretId,
|
|
187
|
+
}).pipe(
|
|
188
|
+
Effect.map((secret) => ({
|
|
189
|
+
secretId: secret.id,
|
|
190
|
+
secretName: secret.name,
|
|
191
|
+
storeId: secret.storeId,
|
|
192
|
+
accountId: output.accountId,
|
|
193
|
+
status: secret.status,
|
|
194
|
+
scopes: output.scopes,
|
|
195
|
+
comment: secret.comment ?? undefined,
|
|
196
|
+
})),
|
|
197
|
+
Effect.catchTag("SecretNotFound", () =>
|
|
198
|
+
Effect.succeed(undefined),
|
|
199
|
+
),
|
|
200
|
+
Effect.catchTag("StoreNotFound", () => Effect.succeed(undefined)),
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
if (!olds?.store) return undefined;
|
|
204
|
+
const name = resolveName(id, olds.name);
|
|
205
|
+
const match = yield* listStoreSecrets
|
|
206
|
+
.items({
|
|
207
|
+
accountId: olds.store.accountId,
|
|
208
|
+
storeId: olds.store.storeId,
|
|
209
|
+
})
|
|
210
|
+
.pipe(
|
|
211
|
+
Stream.filter((s) => s.name === name),
|
|
212
|
+
Stream.runHead,
|
|
213
|
+
Effect.catchTag("StoreNotFound", () => Effect.succeedNone),
|
|
214
|
+
Effect.map(Option.getOrUndefined),
|
|
215
|
+
);
|
|
216
|
+
if (!match) return undefined;
|
|
217
|
+
return {
|
|
218
|
+
secretId: match.id,
|
|
219
|
+
secretName: match.name,
|
|
220
|
+
storeId: match.storeId,
|
|
221
|
+
accountId: olds.store.accountId,
|
|
222
|
+
status: match.status,
|
|
223
|
+
scopes: resolveScopes(olds.scopes),
|
|
224
|
+
comment: match.comment ?? undefined,
|
|
225
|
+
};
|
|
226
|
+
}),
|
|
227
|
+
};
|
|
228
|
+
}),
|
|
229
|
+
);
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type * as runtime from "@cloudflare/workers-types";
|
|
2
|
+
import * as Data from "effect/Data";
|
|
3
|
+
import * as Effect from "effect/Effect";
|
|
4
|
+
import * as Layer from "effect/Layer";
|
|
5
|
+
import * as Binding from "../../Binding.ts";
|
|
6
|
+
import type { ResourceLike } from "../../Resource.ts";
|
|
7
|
+
import { isWorker, WorkerEnvironment } from "../Workers/Worker.ts";
|
|
8
|
+
import type { Secret } from "./Secret.ts";
|
|
9
|
+
|
|
10
|
+
export class SecretError extends Data.TaggedError("SecretError")<{
|
|
11
|
+
message: string;
|
|
12
|
+
cause: Error;
|
|
13
|
+
}> {}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* A bound secret. The client itself is an `Effect` that resolves to the
|
|
17
|
+
* secret's current value, so you can `yield* apiKey` directly. Use `.get()`
|
|
18
|
+
* for the same thing as a callable, or `.raw` for the underlying
|
|
19
|
+
* `SecretsStoreSecret` binding.
|
|
20
|
+
*/
|
|
21
|
+
export interface SecretClient extends Effect.Effect<
|
|
22
|
+
string,
|
|
23
|
+
SecretError,
|
|
24
|
+
WorkerEnvironment
|
|
25
|
+
> {
|
|
26
|
+
/**
|
|
27
|
+
* Effect that resolves to the raw Cloudflare `SecretsStoreSecret` binding.
|
|
28
|
+
*/
|
|
29
|
+
raw: Effect.Effect<runtime.SecretsStoreSecret, never, WorkerEnvironment>;
|
|
30
|
+
/**
|
|
31
|
+
* Read the current value of the secret.
|
|
32
|
+
*/
|
|
33
|
+
get(): Effect.Effect<string, SecretError, WorkerEnvironment>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export class SecretBinding extends Binding.Service<
|
|
37
|
+
SecretBinding,
|
|
38
|
+
(secret: Secret) => Effect.Effect<SecretClient>
|
|
39
|
+
>()("Cloudflare.SecretsStore.Secret") {}
|
|
40
|
+
|
|
41
|
+
export const SecretBindingLive = Layer.effect(
|
|
42
|
+
SecretBinding,
|
|
43
|
+
Effect.gen(function* () {
|
|
44
|
+
const bind = yield* SecretBindingPolicy;
|
|
45
|
+
|
|
46
|
+
return Effect.fn(function* (secret: Secret) {
|
|
47
|
+
yield* bind(secret);
|
|
48
|
+
const env = WorkerEnvironment.asEffect();
|
|
49
|
+
const raw = env.pipe(
|
|
50
|
+
Effect.map(
|
|
51
|
+
(env) =>
|
|
52
|
+
(env as Record<string, runtime.SecretsStoreSecret>)[
|
|
53
|
+
secret.LogicalId
|
|
54
|
+
],
|
|
55
|
+
),
|
|
56
|
+
);
|
|
57
|
+
const tryPromise = <T>(
|
|
58
|
+
fn: () => Promise<T>,
|
|
59
|
+
): Effect.Effect<T, SecretError> =>
|
|
60
|
+
Effect.tryPromise({
|
|
61
|
+
try: fn,
|
|
62
|
+
catch: (error: any) =>
|
|
63
|
+
new SecretError({
|
|
64
|
+
message: error.message ?? "Unknown error",
|
|
65
|
+
cause: error,
|
|
66
|
+
}),
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
const getEffect: Effect.Effect<string, SecretError, WorkerEnvironment> =
|
|
70
|
+
raw.pipe(Effect.flatMap((raw) => tryPromise(() => raw.get())));
|
|
71
|
+
|
|
72
|
+
return Object.assign(
|
|
73
|
+
Effect.suspend(() => getEffect),
|
|
74
|
+
{
|
|
75
|
+
raw,
|
|
76
|
+
get: () => getEffect,
|
|
77
|
+
},
|
|
78
|
+
) as SecretClient;
|
|
79
|
+
});
|
|
80
|
+
}),
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
export class SecretBindingPolicy extends Binding.Policy<
|
|
84
|
+
SecretBindingPolicy,
|
|
85
|
+
(secret: Secret) => Effect.Effect<void>
|
|
86
|
+
>()("Cloudflare.SecretsStore.Secret") {}
|
|
87
|
+
|
|
88
|
+
export const SecretBindingPolicyLive = SecretBindingPolicy.layer.succeed(
|
|
89
|
+
Effect.fn(function* (host: ResourceLike, secret: Secret) {
|
|
90
|
+
if (isWorker(host)) {
|
|
91
|
+
yield* host.bind`${secret}`({
|
|
92
|
+
bindings: [
|
|
93
|
+
{
|
|
94
|
+
type: "secrets_store_secret",
|
|
95
|
+
name: secret.LogicalId,
|
|
96
|
+
secretName: secret.secretName,
|
|
97
|
+
storeId: secret.storeId,
|
|
98
|
+
},
|
|
99
|
+
],
|
|
100
|
+
});
|
|
101
|
+
} else {
|
|
102
|
+
return yield* Effect.die(
|
|
103
|
+
new Error(`SecretBinding does not support runtime '${host.Type}'`),
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
}),
|
|
107
|
+
);
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import * as secretsStore from "@distilled.cloud/cloudflare/secrets-store";
|
|
2
|
+
import * as Effect from "effect/Effect";
|
|
3
|
+
import * as Provider from "../../Provider.ts";
|
|
4
|
+
import { Resource } from "../../Resource.ts";
|
|
5
|
+
import { CloudflareEnvironment } from "../CloudflareEnvironment.ts";
|
|
6
|
+
import type { Providers } from "../Providers.ts";
|
|
7
|
+
|
|
8
|
+
export type SecretsStore = Resource<
|
|
9
|
+
"Cloudflare.SecretsStore",
|
|
10
|
+
{},
|
|
11
|
+
{
|
|
12
|
+
storeId: string;
|
|
13
|
+
storeName: string;
|
|
14
|
+
accountId: string;
|
|
15
|
+
},
|
|
16
|
+
never,
|
|
17
|
+
Providers
|
|
18
|
+
>;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* A Cloudflare Secrets Store, a per-account container for secrets that
|
|
22
|
+
* can be bound into Workers with full redaction and audit support.
|
|
23
|
+
*
|
|
24
|
+
* Cloudflare enforces a limit of **one Secrets Store per account**.
|
|
25
|
+
* Deleting a store changes its ID and permanently destroys all secrets
|
|
26
|
+
* inside it. Because of this, the provider always **adopts** an existing
|
|
27
|
+
* store rather than creating a new one, and **never deletes** the store
|
|
28
|
+
* on teardown. If no store exists yet, one is created, but once it
|
|
29
|
+
* exists it is treated as account-level infrastructure that outlives
|
|
30
|
+
* any single stack.
|
|
31
|
+
*
|
|
32
|
+
* @section Creating a Store
|
|
33
|
+
* @example Basic Secrets Store (adopts existing or creates one)
|
|
34
|
+
* ```typescript
|
|
35
|
+
* const store = yield* Cloudflare.SecretsStore("MyStore");
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* @example Adopt a specific named store
|
|
39
|
+
* ```typescript
|
|
40
|
+
* const store = yield* Cloudflare.SecretsStore("MyStore", {
|
|
41
|
+
* name: "production-secrets",
|
|
42
|
+
* });
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export const SecretsStore = Resource<SecretsStore>("Cloudflare.SecretsStore");
|
|
46
|
+
|
|
47
|
+
export const SecretsStoreProvider = () =>
|
|
48
|
+
Provider.effect(
|
|
49
|
+
SecretsStore,
|
|
50
|
+
Effect.gen(function* () {
|
|
51
|
+
const { accountId } = yield* CloudflareEnvironment;
|
|
52
|
+
const createStore = yield* secretsStore.createStore;
|
|
53
|
+
const listStores = yield* secretsStore.listStores;
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
stables: ["storeId", "storeName", "accountId"],
|
|
57
|
+
create: Effect.fn(function* () {
|
|
58
|
+
const stores = yield* listStores({ accountId });
|
|
59
|
+
if (stores.result.length > 0) {
|
|
60
|
+
// No name specified — adopt the first (and likely only) store.
|
|
61
|
+
const first = stores.result[0]!;
|
|
62
|
+
return {
|
|
63
|
+
storeId: first.id,
|
|
64
|
+
storeName: first.name,
|
|
65
|
+
accountId,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// No store exists yet — create one.
|
|
70
|
+
const response = yield* createStore({
|
|
71
|
+
accountId,
|
|
72
|
+
//`default_secrets_store` is the name cloudflare uses to create a secret store
|
|
73
|
+
body: [{ name: "default_secrets_store" }],
|
|
74
|
+
});
|
|
75
|
+
const store = response.result[0]!;
|
|
76
|
+
return {
|
|
77
|
+
storeId: store.id,
|
|
78
|
+
storeName: store.name,
|
|
79
|
+
accountId,
|
|
80
|
+
};
|
|
81
|
+
}),
|
|
82
|
+
update: Effect.fn(function* ({ output }) {
|
|
83
|
+
return output;
|
|
84
|
+
}),
|
|
85
|
+
delete: Effect.fn(function* () {
|
|
86
|
+
// Intentional no-op. Cloudflare only allows one Secrets Store per
|
|
87
|
+
// account and deleting it permanently destroys all secrets inside.
|
|
88
|
+
// The store is treated as shared, account-level infrastructure that
|
|
89
|
+
// should never be torn down by a single stack.
|
|
90
|
+
}),
|
|
91
|
+
read: Effect.fn(function* ({ output }) {
|
|
92
|
+
if (!output?.storeId) return undefined;
|
|
93
|
+
const stores = yield* listStores({
|
|
94
|
+
accountId: output.accountId,
|
|
95
|
+
});
|
|
96
|
+
const match = stores.result.find((s) => s.id === output.storeId);
|
|
97
|
+
if (!match) return undefined;
|
|
98
|
+
return {
|
|
99
|
+
storeId: match.id,
|
|
100
|
+
storeName: match.name,
|
|
101
|
+
accountId: output.accountId,
|
|
102
|
+
};
|
|
103
|
+
}),
|
|
104
|
+
};
|
|
105
|
+
}),
|
|
106
|
+
);
|
|
@@ -22,6 +22,8 @@ type GetBindingType<T> = T extends Cloudflare.Assets
|
|
|
22
22
|
? R2Bucket
|
|
23
23
|
: T extends Cloudflare.KVNamespace
|
|
24
24
|
? KVNamespace
|
|
25
|
-
: T extends Cloudflare.
|
|
26
|
-
?
|
|
27
|
-
:
|
|
25
|
+
: T extends Cloudflare.Queue
|
|
26
|
+
? Queue<unknown>
|
|
27
|
+
: T extends Cloudflare.DurableObjectNamespaceLike
|
|
28
|
+
? DurableObjectNamespace<Exclude<T["Shape"], undefined>>
|
|
29
|
+
: never;
|
|
@@ -16,6 +16,9 @@ import * as Redacted from "effect/Redacted";
|
|
|
16
16
|
import * as Schedule from "effect/Schedule";
|
|
17
17
|
import * as Stream from "effect/Stream";
|
|
18
18
|
import * as Socket from "effect/unstable/socket/Socket";
|
|
19
|
+
import { createRequire } from "node:module";
|
|
20
|
+
import path from "node:path";
|
|
21
|
+
import { pathToFileURL } from "node:url";
|
|
19
22
|
import type * as rolldown from "rolldown";
|
|
20
23
|
import Sonda from "sonda/rolldown";
|
|
21
24
|
import type * as vite from "vite";
|
|
@@ -42,12 +45,14 @@ import { Resource, type ResourceBinding } from "../../Resource.ts";
|
|
|
42
45
|
import { Self } from "../../Self.ts";
|
|
43
46
|
import * as Serverless from "../../Serverless/index.ts";
|
|
44
47
|
import { Stack } from "../../Stack.ts";
|
|
45
|
-
import {
|
|
48
|
+
import { CloudflareEnvironment } from "../CloudflareEnvironment.ts";
|
|
46
49
|
import { D1Database } from "../D1/D1Database.ts";
|
|
47
50
|
import { fromCloudflareFetcher } from "../Fetcher.ts";
|
|
48
51
|
import { CloudflareLogs } from "../Logs.ts";
|
|
49
52
|
import type { Providers } from "../Providers.ts";
|
|
50
53
|
import type { R2Bucket } from "../R2/R2Bucket.ts";
|
|
54
|
+
import type { KVNamespace } from "../KV/KVNamespace.ts";
|
|
55
|
+
import type { Queue as CloudflareQueue } from "../Queue/Queue.ts";
|
|
51
56
|
import {
|
|
52
57
|
isAssets,
|
|
53
58
|
readAssets,
|
|
@@ -176,6 +181,8 @@ export type WorkerBindingResource =
|
|
|
176
181
|
| Assets
|
|
177
182
|
| R2Bucket
|
|
178
183
|
| D1Database
|
|
184
|
+
| KVNamespace
|
|
185
|
+
| CloudflareQueue
|
|
179
186
|
| DurableObjectNamespaceLike<any>;
|
|
180
187
|
|
|
181
188
|
export type WorkerBindings = {
|
|
@@ -683,8 +690,20 @@ export const Worker: Platform<
|
|
|
683
690
|
),
|
|
684
691
|
),
|
|
685
692
|
}
|
|
686
|
-
:
|
|
687
|
-
|
|
693
|
+
: binding.Type === "Cloudflare.KVNamespace"
|
|
694
|
+
? {
|
|
695
|
+
type: "kv_namespace",
|
|
696
|
+
name: bindingName,
|
|
697
|
+
namespaceId: binding.namespaceId,
|
|
698
|
+
}
|
|
699
|
+
: binding.Type === "Cloudflare.Queue"
|
|
700
|
+
? {
|
|
701
|
+
type: "queue",
|
|
702
|
+
name: bindingName,
|
|
703
|
+
queueName: binding.queueName,
|
|
704
|
+
}
|
|
705
|
+
: // TODO(sam): handle others
|
|
706
|
+
undefined;
|
|
688
707
|
|
|
689
708
|
if (bindingMeta) {
|
|
690
709
|
yield* resource.bind`${bindingName}`({
|
|
@@ -912,7 +931,7 @@ export const WorkerProvider = () =>
|
|
|
912
931
|
const fs = yield* FileSystem.FileSystem;
|
|
913
932
|
const path = yield* Path.Path;
|
|
914
933
|
|
|
915
|
-
const accountId = yield*
|
|
934
|
+
const { accountId } = yield* CloudflareEnvironment;
|
|
916
935
|
const virtualEntryPlugin = yield* Bundle.virtualEntryPlugin;
|
|
917
936
|
const stack = yield* Stack;
|
|
918
937
|
|
|
@@ -1171,13 +1190,15 @@ export const WorkerProvider = () =>
|
|
|
1171
1190
|
Effect.gen(function* () {
|
|
1172
1191
|
const main = yield* fs.realPath(props.main);
|
|
1173
1192
|
const cwd = yield* findCwdForBundle(main);
|
|
1193
|
+
const { compatibilityDate, compatibilityFlags } =
|
|
1194
|
+
getCompatibility(props);
|
|
1174
1195
|
const buildBundle = (plugins?: rolldown.RolldownPluginOption) =>
|
|
1175
1196
|
Bundle.build(
|
|
1176
1197
|
{
|
|
1177
1198
|
input: main,
|
|
1178
1199
|
cwd,
|
|
1179
1200
|
plugins: [
|
|
1180
|
-
cloudflareRolldown(
|
|
1201
|
+
cloudflareRolldown({ compatibilityDate, compatibilityFlags }),
|
|
1181
1202
|
plugins,
|
|
1182
1203
|
...(props.build?.metafile ? [Sonda({ open: false })] : []),
|
|
1183
1204
|
],
|
|
@@ -1332,11 +1353,13 @@ ${[
|
|
|
1332
1353
|
}).pipe(Artifacts.cached("build"));
|
|
1333
1354
|
|
|
1334
1355
|
const viteBuild = Effect.fnUntraced(function* (props: WorkerProps) {
|
|
1335
|
-
const vite = yield* Effect.promise(() => import("vite"));
|
|
1336
1356
|
let assetsDirectory: string | undefined;
|
|
1337
1357
|
let serverBundle: vite.Rolldown.OutputBundle | undefined;
|
|
1358
|
+
const { compatibilityDate, compatibilityFlags } =
|
|
1359
|
+
getCompatibility(props);
|
|
1338
1360
|
|
|
1339
1361
|
yield* Effect.promise(async () => {
|
|
1362
|
+
const vite = await loadVite();
|
|
1340
1363
|
const builder = await vite.createBuilder(
|
|
1341
1364
|
{
|
|
1342
1365
|
root: props.vite?.rootDir,
|
|
@@ -1356,7 +1379,10 @@ ${[
|
|
|
1356
1379
|
sharedConfigBuild: true,
|
|
1357
1380
|
},
|
|
1358
1381
|
plugins: [
|
|
1359
|
-
cloudflareVite(
|
|
1382
|
+
cloudflareVite({
|
|
1383
|
+
compatibilityDate,
|
|
1384
|
+
compatibilityFlags,
|
|
1385
|
+
}),
|
|
1360
1386
|
{
|
|
1361
1387
|
name: "output:ssr",
|
|
1362
1388
|
applyToEnvironment(environment) {
|
|
@@ -2268,3 +2294,33 @@ const contentTypeFromExtension = (extension: string) => {
|
|
|
2268
2294
|
return "application/octet-stream";
|
|
2269
2295
|
}
|
|
2270
2296
|
};
|
|
2297
|
+
|
|
2298
|
+
type ViteModule = typeof import("vite");
|
|
2299
|
+
let _viteModule: ViteModule | null = null;
|
|
2300
|
+
|
|
2301
|
+
/**
|
|
2302
|
+
* Dynamically load Vite from the project root. Falls back to the bundled
|
|
2303
|
+
* copy if the project doesn't have its own Vite installation.
|
|
2304
|
+
*/
|
|
2305
|
+
async function loadVite(): Promise<ViteModule> {
|
|
2306
|
+
if (_viteModule) return _viteModule;
|
|
2307
|
+
|
|
2308
|
+
const projectRoot = process.cwd();
|
|
2309
|
+
let vitePath: string;
|
|
2310
|
+
|
|
2311
|
+
try {
|
|
2312
|
+
// Resolve "vite" from the project root, not from vinext's location
|
|
2313
|
+
const require = createRequire(path.join(projectRoot, "package.json"));
|
|
2314
|
+
vitePath = require.resolve("vite");
|
|
2315
|
+
} catch {
|
|
2316
|
+
// Fallback: use the Vite that ships with vinext (works for non-linked installs)
|
|
2317
|
+
vitePath = "vite";
|
|
2318
|
+
}
|
|
2319
|
+
|
|
2320
|
+
// On Windows, absolute paths must be file:// URLs for ESM import().
|
|
2321
|
+
// The fallback ("vite") is a bare specifier and works as-is.
|
|
2322
|
+
const viteUrl = vitePath === "vite" ? vitePath : pathToFileURL(vitePath).href;
|
|
2323
|
+
const vite = (await import(/* @vite-ignore */ viteUrl)) as ViteModule;
|
|
2324
|
+
_viteModule = vite;
|
|
2325
|
+
return vite;
|
|
2326
|
+
}
|
|
@@ -6,7 +6,7 @@ import type { PlatformServices } from "../../Platform.ts";
|
|
|
6
6
|
import * as Provider from "../../Provider.ts";
|
|
7
7
|
import { Resource } from "../../Resource.ts";
|
|
8
8
|
import { effectClass, taggedFunction } from "../../Util/effect.ts";
|
|
9
|
-
import {
|
|
9
|
+
import { CloudflareEnvironment } from "../CloudflareEnvironment.ts";
|
|
10
10
|
import { Worker, WorkerEnvironment, type WorkerServices } from "./Worker.ts";
|
|
11
11
|
|
|
12
12
|
type WorkflowTypeId = "Cloudflare.Workflow";
|
|
@@ -83,8 +83,17 @@ export const sleepUntil = (
|
|
|
83
83
|
|
|
84
84
|
/**
|
|
85
85
|
* The services available inside a workflow run body.
|
|
86
|
+
*
|
|
87
|
+
* `WorkerEnvironment` is provided to the body at runtime by the workflow
|
|
88
|
+
* export wrapper (see `make(env)` below), so users can access env bindings
|
|
89
|
+
* from inside workflow steps via `yield* WorkerEnvironment` — the type must
|
|
90
|
+
* reflect that or `yield* WorkerEnvironment` fails to type-check inside a
|
|
91
|
+
* body even though it succeeds at runtime.
|
|
86
92
|
*/
|
|
87
|
-
export type WorkflowRunServices =
|
|
93
|
+
export type WorkflowRunServices =
|
|
94
|
+
| WorkflowEvent
|
|
95
|
+
| WorkflowStep
|
|
96
|
+
| WorkerEnvironment;
|
|
88
97
|
|
|
89
98
|
export type WorkflowServices = WorkerServices | PlatformServices;
|
|
90
99
|
|
|
@@ -323,13 +332,14 @@ export const Workflow: WorkflowClass = taggedFunction(WorkflowScope, ((
|
|
|
323
332
|
yield* worker.export(name, {
|
|
324
333
|
kind: "workflow",
|
|
325
334
|
make: (env: unknown) =>
|
|
326
|
-
Effect.succeed(
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
335
|
+
Effect.succeed(
|
|
336
|
+
body.pipe(
|
|
337
|
+
Effect.provideService(
|
|
338
|
+
WorkerEnvironment,
|
|
339
|
+
env as Record<string, any>,
|
|
340
|
+
),
|
|
331
341
|
),
|
|
332
|
-
),
|
|
342
|
+
).pipe(Effect.provideContext(services)),
|
|
333
343
|
} satisfies WorkflowExport);
|
|
334
344
|
|
|
335
345
|
return self;
|
|
@@ -370,7 +380,7 @@ export const WorkflowProvider = () =>
|
|
|
370
380
|
Provider.effect(
|
|
371
381
|
WorkflowResource,
|
|
372
382
|
Effect.gen(function* () {
|
|
373
|
-
const accountId = yield*
|
|
383
|
+
const { accountId } = yield* CloudflareEnvironment;
|
|
374
384
|
const putWorkflow = yield* workflows.putWorkflow;
|
|
375
385
|
const deleteWorkflow = yield* workflows.deleteWorkflow;
|
|
376
386
|
|
package/src/Cloudflare/index.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
export * from "./CloudflareEnvironment.ts";
|
|
1
2
|
export * from "./Container/index.ts";
|
|
2
3
|
export * from "./D1/index.ts";
|
|
3
4
|
export * from "./KV/index.ts";
|
|
5
|
+
export * from "./Queue/index.ts";
|
|
4
6
|
export * from "./Providers.ts";
|
|
5
7
|
export * from "./R2/index.ts";
|
|
6
|
-
export * from "./
|
|
8
|
+
export * from "./SecretsStore/index.ts";
|
|
7
9
|
export * from "./Website/index.ts";
|
|
8
10
|
export * from "./Workers/index.ts";
|