alchemy-effect 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/alchemy-effect.js +55354 -8
- package/bin/alchemy-effect.js.map +1 -1
- package/bin/alchemy-effect.ts +266 -10
- package/lib/$.d.ts +5 -0
- package/lib/$.d.ts.map +1 -0
- package/lib/$.js +9 -0
- package/lib/$.js.map +1 -0
- package/lib/app.d.ts +4 -17
- package/lib/app.d.ts.map +1 -1
- package/lib/app.js +0 -20
- package/lib/app.js.map +1 -1
- package/lib/apply.d.ts +15 -75
- package/lib/apply.d.ts.map +1 -1
- package/lib/apply.js +439 -154
- package/lib/apply.js.map +1 -1
- package/lib/assert-never.d.ts +12 -0
- package/lib/assert-never.d.ts.map +1 -0
- package/lib/assert-never.js +11 -0
- package/lib/assert-never.js.map +1 -0
- package/lib/aws/account.d.ts +10 -1
- package/lib/aws/account.d.ts.map +1 -1
- package/lib/aws/account.js +18 -3
- package/lib/aws/account.js.map +1 -1
- package/lib/aws/client.d.ts.map +1 -1
- package/lib/aws/client.js +0 -1
- package/lib/aws/client.js.map +1 -1
- package/lib/aws/config.d.ts +15 -0
- package/lib/aws/config.d.ts.map +1 -0
- package/lib/aws/config.js +1 -0
- package/lib/aws/config.js.map +1 -0
- package/lib/aws/credentials.d.ts +10 -0
- package/lib/aws/credentials.d.ts.map +1 -1
- package/lib/aws/credentials.js +73 -47
- package/lib/aws/credentials.js.map +1 -1
- package/lib/aws/dynamodb/client.d.ts +1 -1
- package/lib/aws/dynamodb/client.d.ts.map +1 -1
- package/lib/aws/dynamodb/index.d.ts +2 -1
- package/lib/aws/dynamodb/index.d.ts.map +1 -1
- package/lib/aws/dynamodb/index.js +1 -2
- package/lib/aws/dynamodb/index.js.map +1 -1
- package/lib/aws/dynamodb/secondary-index.d.ts +5 -4
- package/lib/aws/dynamodb/secondary-index.d.ts.map +1 -1
- package/lib/aws/dynamodb/table.d.ts +23 -20
- package/lib/aws/dynamodb/table.d.ts.map +1 -1
- package/lib/aws/dynamodb/table.get-item.d.ts +8 -6
- package/lib/aws/dynamodb/table.get-item.d.ts.map +1 -1
- package/lib/aws/dynamodb/table.get-item.js +4 -2
- package/lib/aws/dynamodb/table.get-item.js.map +1 -1
- package/lib/aws/dynamodb/table.js.map +1 -1
- package/lib/aws/dynamodb/table.provider.d.ts +3 -4
- package/lib/aws/dynamodb/table.provider.d.ts.map +1 -1
- package/lib/aws/dynamodb/table.provider.js +18 -29
- package/lib/aws/dynamodb/table.provider.js.map +1 -1
- package/lib/aws/ec2/client.d.ts +1 -1
- package/lib/aws/ec2/client.d.ts.map +1 -1
- package/lib/aws/ec2/index.d.ts +11 -0
- package/lib/aws/ec2/index.d.ts.map +1 -1
- package/lib/aws/ec2/index.js +11 -0
- package/lib/aws/ec2/index.js.map +1 -1
- package/lib/aws/ec2/internet-gateway.d.ts +65 -0
- package/lib/aws/ec2/internet-gateway.d.ts.map +1 -0
- package/lib/aws/ec2/internet-gateway.js +4 -0
- package/lib/aws/ec2/internet-gateway.js.map +1 -0
- package/lib/aws/ec2/internet-gateway.provider.d.ts +6 -0
- package/lib/aws/ec2/internet-gateway.provider.d.ts.map +1 -0
- package/lib/aws/ec2/internet-gateway.provider.js +193 -0
- package/lib/aws/ec2/internet-gateway.provider.js.map +1 -0
- package/lib/aws/ec2/route-table-association.d.ts +63 -0
- package/lib/aws/ec2/route-table-association.d.ts.map +1 -0
- package/lib/aws/ec2/route-table-association.js +4 -0
- package/lib/aws/ec2/route-table-association.js.map +1 -0
- package/lib/aws/ec2/route-table-association.provider.d.ts +4 -0
- package/lib/aws/ec2/route-table-association.provider.d.ts.map +1 -0
- package/lib/aws/ec2/route-table-association.provider.js +121 -0
- package/lib/aws/ec2/route-table-association.provider.js.map +1 -0
- package/lib/aws/ec2/route-table.d.ts +159 -0
- package/lib/aws/ec2/route-table.d.ts.map +1 -0
- package/lib/aws/ec2/route-table.js +4 -0
- package/lib/aws/ec2/route-table.js.map +1 -0
- package/lib/aws/ec2/route-table.provider.d.ts +6 -0
- package/lib/aws/ec2/route-table.provider.d.ts.map +1 -0
- package/lib/aws/ec2/route-table.provider.js +213 -0
- package/lib/aws/ec2/route-table.provider.js.map +1 -0
- package/lib/aws/ec2/route.d.ts +155 -0
- package/lib/aws/ec2/route.d.ts.map +1 -0
- package/lib/aws/ec2/route.js +3 -0
- package/lib/aws/ec2/route.js.map +1 -0
- package/lib/aws/ec2/route.provider.d.ts +4 -0
- package/lib/aws/ec2/route.provider.d.ts.map +1 -0
- package/lib/aws/ec2/route.provider.js +166 -0
- package/lib/aws/ec2/route.provider.js.map +1 -0
- package/lib/aws/ec2/subnet.d.ts +175 -0
- package/lib/aws/ec2/subnet.d.ts.map +1 -0
- package/lib/aws/ec2/subnet.js +4 -0
- package/lib/aws/ec2/subnet.js.map +1 -0
- package/lib/aws/ec2/subnet.provider.d.ts +4 -0
- package/lib/aws/ec2/subnet.provider.d.ts.map +1 -0
- package/lib/aws/ec2/subnet.provider.js +250 -0
- package/lib/aws/ec2/subnet.provider.js.map +1 -0
- package/lib/aws/ec2/vpc.d.ts +13 -8
- package/lib/aws/ec2/vpc.d.ts.map +1 -1
- package/lib/aws/ec2/vpc.js +1 -0
- package/lib/aws/ec2/vpc.js.map +1 -1
- package/lib/aws/ec2/vpc.provider.d.ts +1 -2
- package/lib/aws/ec2/vpc.provider.d.ts.map +1 -1
- package/lib/aws/ec2/vpc.provider.js +45 -37
- package/lib/aws/ec2/vpc.provider.js.map +1 -1
- package/lib/aws/index.d.ts +15 -19
- package/lib/aws/index.d.ts.map +1 -1
- package/lib/aws/index.js +8 -10
- package/lib/aws/index.js.map +1 -1
- package/lib/aws/lambda/consume.d.ts +10 -11
- package/lib/aws/lambda/consume.d.ts.map +1 -1
- package/lib/aws/lambda/consume.js +3 -3
- package/lib/aws/lambda/consume.js.map +1 -1
- package/lib/aws/lambda/function.d.ts +7 -7
- package/lib/aws/lambda/function.d.ts.map +1 -1
- package/lib/aws/lambda/function.handler.d.ts +1 -1
- package/lib/aws/lambda/function.handler.d.ts.map +1 -1
- package/lib/aws/lambda/function.handler.js.map +1 -1
- package/lib/aws/lambda/function.invoke.d.ts +6 -4
- package/lib/aws/lambda/function.invoke.d.ts.map +1 -1
- package/lib/aws/lambda/function.invoke.js +3 -1
- package/lib/aws/lambda/function.invoke.js.map +1 -1
- package/lib/aws/lambda/function.js +1 -1
- package/lib/aws/lambda/function.js.map +1 -1
- package/lib/aws/lambda/function.provider.d.ts +3 -2
- package/lib/aws/lambda/function.provider.d.ts.map +1 -1
- package/lib/aws/lambda/function.provider.js +28 -25
- package/lib/aws/lambda/function.provider.js.map +1 -1
- package/lib/aws/lambda/index.d.ts +1 -0
- package/lib/aws/lambda/index.d.ts.map +1 -1
- package/lib/aws/lambda/index.js +1 -0
- package/lib/aws/lambda/index.js.map +1 -1
- package/lib/aws/lambda/serve.d.ts +2 -4
- package/lib/aws/lambda/serve.d.ts.map +1 -1
- package/lib/aws/profile.d.ts +2 -2
- package/lib/aws/profile.d.ts.map +1 -1
- package/lib/aws/profile.js +1 -1
- package/lib/aws/profile.js.map +1 -1
- package/lib/aws/region.d.ts +14 -2
- package/lib/aws/region.d.ts.map +1 -1
- package/lib/aws/region.js +26 -1
- package/lib/aws/region.js.map +1 -1
- package/lib/aws/sqs/client.d.ts +1 -1
- package/lib/aws/sqs/client.d.ts.map +1 -1
- package/lib/aws/sqs/index.d.ts +1 -0
- package/lib/aws/sqs/index.d.ts.map +1 -1
- package/lib/aws/sqs/index.js +1 -0
- package/lib/aws/sqs/index.js.map +1 -1
- package/lib/aws/sqs/queue.consume.d.ts +1 -1
- package/lib/aws/sqs/queue.consume.d.ts.map +1 -1
- package/lib/aws/sqs/queue.consume.js +0 -1
- package/lib/aws/sqs/queue.consume.js.map +1 -1
- package/lib/aws/sqs/queue.d.ts +6 -4
- package/lib/aws/sqs/queue.d.ts.map +1 -1
- package/lib/aws/sqs/queue.event-source.d.ts +8 -6
- package/lib/aws/sqs/queue.event-source.d.ts.map +1 -1
- package/lib/aws/sqs/queue.event-source.js +26 -44
- package/lib/aws/sqs/queue.event-source.js.map +1 -1
- package/lib/aws/sqs/queue.js +1 -1
- package/lib/aws/sqs/queue.js.map +1 -1
- package/lib/aws/sqs/queue.provider.d.ts +2 -2
- package/lib/aws/sqs/queue.provider.d.ts.map +1 -1
- package/lib/aws/sqs/queue.provider.js +2 -1
- package/lib/aws/sqs/queue.provider.js.map +1 -1
- package/lib/aws/sqs/queue.send-message.d.ts +7 -5
- package/lib/aws/sqs/queue.send-message.d.ts.map +1 -1
- package/lib/aws/sqs/queue.send-message.js +4 -2
- package/lib/aws/sqs/queue.send-message.js.map +1 -1
- package/lib/binding.d.ts +12 -12
- package/lib/binding.d.ts.map +1 -1
- package/lib/binding.js.map +1 -1
- package/lib/cli/components/ApprovePlan.d.ts +2 -2
- package/lib/cli/components/ApprovePlan.d.ts.map +1 -1
- package/lib/cli/components/ApprovePlan.js.map +1 -1
- package/lib/cli/components/Plan.d.ts +2 -2
- package/lib/cli/components/Plan.d.ts.map +1 -1
- package/lib/cli/components/Plan.js.map +1 -1
- package/lib/cli/components/PlanProgress.d.ts +8 -4
- package/lib/cli/components/PlanProgress.d.ts.map +1 -1
- package/lib/cli/components/PlanProgress.js +11 -1
- package/lib/cli/components/PlanProgress.js.map +1 -1
- package/lib/cli/index.d.ts +384 -264
- package/lib/cli/index.d.ts.map +1 -1
- package/lib/cli/index.js +57 -65
- package/lib/cli/index.js.map +1 -1
- package/lib/cli/ink-service.d.ts +4 -0
- package/lib/cli/ink-service.d.ts.map +1 -0
- package/lib/cli/ink-service.js +43 -0
- package/lib/cli/ink-service.js.map +1 -0
- package/lib/cli/service.d.ts +21 -0
- package/lib/cli/service.d.ts.map +1 -0
- package/lib/cli/service.js +5 -0
- package/lib/cli/service.js.map +1 -0
- package/lib/cloudflare/account.d.ts +10 -0
- package/lib/cloudflare/account.d.ts.map +1 -0
- package/lib/cloudflare/account.js +24 -0
- package/lib/cloudflare/account.js.map +1 -0
- package/lib/cloudflare/api.d.ts +7 -7
- package/lib/cloudflare/api.d.ts.map +1 -1
- package/lib/cloudflare/api.js +18 -17
- package/lib/cloudflare/api.js.map +1 -1
- package/lib/cloudflare/config.d.ts +9 -0
- package/lib/cloudflare/config.d.ts.map +1 -0
- package/lib/cloudflare/config.js +1 -0
- package/lib/cloudflare/config.js.map +1 -0
- package/lib/cloudflare/index.d.ts +3 -1
- package/lib/cloudflare/index.d.ts.map +1 -1
- package/lib/cloudflare/index.js +3 -0
- package/lib/cloudflare/index.js.map +1 -1
- package/lib/cloudflare/kv/namespace.binding.d.ts +5 -3
- package/lib/cloudflare/kv/namespace.binding.d.ts.map +1 -1
- package/lib/cloudflare/kv/namespace.binding.js +1 -1
- package/lib/cloudflare/kv/namespace.binding.js.map +1 -1
- package/lib/cloudflare/kv/namespace.client.d.ts +1 -1
- package/lib/cloudflare/kv/namespace.d.ts +3 -2
- package/lib/cloudflare/kv/namespace.d.ts.map +1 -1
- package/lib/cloudflare/kv/namespace.js.map +1 -1
- package/lib/cloudflare/kv/namespace.provider.d.ts +3 -2
- package/lib/cloudflare/kv/namespace.provider.d.ts.map +1 -1
- package/lib/cloudflare/kv/namespace.provider.js +9 -7
- package/lib/cloudflare/kv/namespace.provider.js.map +1 -1
- package/lib/cloudflare/live.d.ts +5 -5
- package/lib/cloudflare/live.d.ts.map +1 -1
- package/lib/cloudflare/live.js +5 -8
- package/lib/cloudflare/live.js.map +1 -1
- package/lib/cloudflare/r2/bucket.binding.d.ts +5 -3
- package/lib/cloudflare/r2/bucket.binding.d.ts.map +1 -1
- package/lib/cloudflare/r2/bucket.binding.js +1 -1
- package/lib/cloudflare/r2/bucket.binding.js.map +1 -1
- package/lib/cloudflare/r2/bucket.d.ts +3 -2
- package/lib/cloudflare/r2/bucket.d.ts.map +1 -1
- package/lib/cloudflare/r2/bucket.js.map +1 -1
- package/lib/cloudflare/r2/bucket.provider.d.ts +3 -2
- package/lib/cloudflare/r2/bucket.provider.d.ts.map +1 -1
- package/lib/cloudflare/r2/bucket.provider.js +14 -8
- package/lib/cloudflare/r2/bucket.provider.js.map +1 -1
- package/lib/cloudflare/worker/assets.fetch.d.ts +3 -2
- package/lib/cloudflare/worker/assets.fetch.d.ts.map +1 -1
- package/lib/cloudflare/worker/assets.fetch.js +2 -1
- package/lib/cloudflare/worker/assets.fetch.js.map +1 -1
- package/lib/cloudflare/worker/assets.provider.d.ts +1 -1
- package/lib/cloudflare/worker/assets.provider.d.ts.map +1 -1
- package/lib/cloudflare/worker/index.d.ts +0 -1
- package/lib/cloudflare/worker/index.d.ts.map +1 -1
- package/lib/cloudflare/worker/worker.d.ts +5 -6
- package/lib/cloudflare/worker/worker.d.ts.map +1 -1
- package/lib/cloudflare/worker/worker.handler.d.ts +1 -1
- package/lib/cloudflare/worker/worker.handler.d.ts.map +1 -1
- package/lib/cloudflare/worker/worker.handler.js.map +1 -1
- package/lib/cloudflare/worker/worker.js.map +1 -1
- package/lib/cloudflare/worker/worker.provider.d.ts +3 -2
- package/lib/cloudflare/worker/worker.provider.d.ts.map +1 -1
- package/lib/cloudflare/worker/worker.provider.js +12 -7
- package/lib/cloudflare/worker/worker.provider.js.map +1 -1
- package/lib/cloudflare/worker/worker.serve.d.ts +7 -7
- package/lib/cloudflare/worker/worker.serve.d.ts.map +1 -1
- package/lib/cloudflare/worker/worker.serve.js.map +1 -1
- package/lib/data.d.ts +3 -0
- package/lib/data.d.ts.map +1 -0
- package/lib/data.js +8 -0
- package/lib/data.js.map +1 -0
- package/lib/destroy.d.ts +1 -1
- package/lib/destroy.d.ts.map +1 -1
- package/lib/destroy.js +1 -4
- package/lib/destroy.js.map +1 -1
- package/lib/diff.d.ts +18 -0
- package/lib/diff.d.ts.map +1 -0
- package/lib/diff.js +22 -0
- package/lib/diff.js.map +1 -0
- package/lib/env.d.ts +5 -0
- package/lib/env.d.ts.map +1 -1
- package/lib/env.js +15 -29
- package/lib/env.js.map +1 -1
- package/lib/event.d.ts +1 -1
- package/lib/event.d.ts.map +1 -1
- package/lib/exports.d.ts +9 -0
- package/lib/exports.d.ts.map +1 -0
- package/lib/exports.js +13 -0
- package/lib/exports.js.map +1 -0
- package/lib/index.d.ts +10 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +10 -5
- package/lib/index.js.map +1 -1
- package/lib/input.d.ts +32 -0
- package/lib/input.d.ts.map +1 -0
- package/lib/input.js +1 -0
- package/lib/input.js.map +1 -0
- package/lib/instance-id.d.ts +8 -0
- package/lib/instance-id.d.ts.map +1 -0
- package/lib/instance-id.js +12 -0
- package/lib/instance-id.js.map +1 -0
- package/lib/output.d.ts +145 -0
- package/lib/output.d.ts.map +1 -0
- package/lib/output.js +283 -0
- package/lib/output.js.map +1 -0
- package/lib/physical-name.d.ts +14 -1
- package/lib/physical-name.d.ts.map +1 -1
- package/lib/physical-name.js +41 -2
- package/lib/physical-name.js.map +1 -1
- package/lib/plan.d.ts +84 -58
- package/lib/plan.d.ts.map +1 -1
- package/lib/plan.js +504 -166
- package/lib/plan.js.map +1 -1
- package/lib/policy.d.ts +3 -4
- package/lib/policy.d.ts.map +1 -1
- package/lib/policy.js +0 -1
- package/lib/policy.js.map +1 -1
- package/lib/provider.d.ts +39 -24
- package/lib/provider.d.ts.map +1 -1
- package/lib/provider.js +9 -0
- package/lib/provider.js.map +1 -1
- package/lib/ref.d.ts +14 -0
- package/lib/ref.d.ts.map +1 -0
- package/lib/ref.js +21 -0
- package/lib/ref.js.map +1 -0
- package/lib/resource.d.ts +13 -8
- package/lib/resource.d.ts.map +1 -1
- package/lib/resource.js.map +1 -1
- package/lib/runtime.d.ts +7 -6
- package/lib/runtime.d.ts.map +1 -1
- package/lib/runtime.js.map +1 -1
- package/lib/service.d.ts +9 -6
- package/lib/service.d.ts.map +1 -1
- package/lib/service.js.map +1 -1
- package/lib/stack.d.ts +60 -0
- package/lib/stack.d.ts.map +1 -0
- package/lib/stack.js +11 -0
- package/lib/stack.js.map +1 -0
- package/lib/stage.d.ts +39 -0
- package/lib/stage.d.ts.map +1 -0
- package/lib/stage.js +32 -0
- package/lib/stage.js.map +1 -0
- package/lib/state.d.ts +135 -17
- package/lib/state.d.ts.map +1 -1
- package/lib/state.js +34 -30
- package/lib/state.js.map +1 -1
- package/lib/tags.d.ts +15 -0
- package/lib/tags.d.ts.map +1 -1
- package/lib/tags.js +27 -0
- package/lib/tags.js.map +1 -1
- package/lib/test.d.ts +25 -4
- package/lib/test.d.ts.map +1 -1
- package/lib/test.js +54 -14
- package/lib/test.js.map +1 -1
- package/lib/todo.d.ts +3 -0
- package/lib/todo.d.ts.map +1 -0
- package/lib/todo.js +3 -0
- package/lib/todo.js.map +1 -0
- package/lib/tsconfig.test.tsbuildinfo +1 -1
- package/lib/type.d.ts +3 -0
- package/lib/type.d.ts.map +1 -1
- package/lib/unknown.d.ts +4 -0
- package/lib/unknown.d.ts.map +1 -0
- package/lib/unknown.js +4 -0
- package/lib/unknown.js.map +1 -0
- package/lib/user.d.ts +3 -0
- package/lib/user.d.ts.map +1 -0
- package/lib/user.js +3 -0
- package/lib/user.js.map +1 -0
- package/lib/util.d.ts +6 -0
- package/lib/util.d.ts.map +1 -0
- package/lib/util.js +9 -0
- package/lib/util.js.map +1 -0
- package/package.json +18 -12
- package/src/$.ts +17 -0
- package/src/app.ts +3 -32
- package/src/apply.ts +824 -452
- package/src/assert-never.ts +18 -0
- package/src/aws/account.ts +23 -3
- package/src/aws/client.ts +0 -1
- package/src/aws/config.ts +16 -0
- package/src/aws/credentials.ts +212 -177
- package/src/aws/dynamodb/index.ts +3 -3
- package/src/aws/dynamodb/table.get-item.ts +5 -9
- package/src/aws/dynamodb/table.provider.ts +36 -39
- package/src/aws/dynamodb/table.ts +29 -84
- package/src/aws/ec2/index.ts +12 -0
- package/src/aws/ec2/internet-gateway.provider.ts +316 -0
- package/src/aws/ec2/internet-gateway.ts +79 -0
- package/src/aws/ec2/route-table-association.provider.ts +214 -0
- package/src/aws/ec2/route-table-association.ts +82 -0
- package/src/aws/ec2/route-table.provider.ts +306 -0
- package/src/aws/ec2/route-table.ts +175 -0
- package/src/aws/ec2/route.provider.ts +213 -0
- package/src/aws/ec2/route.ts +192 -0
- package/src/aws/ec2/subnet.provider.ts +358 -0
- package/src/aws/ec2/subnet.ts +213 -0
- package/src/aws/ec2/vpc.provider.ts +58 -50
- package/src/aws/ec2/vpc.ts +21 -8
- package/src/aws/index.ts +49 -40
- package/src/aws/lambda/consume.ts +8 -7
- package/src/aws/lambda/function.handler.ts +1 -1
- package/src/aws/lambda/function.invoke.ts +6 -2
- package/src/aws/lambda/function.provider.ts +41 -32
- package/src/aws/lambda/function.ts +7 -4
- package/src/aws/lambda/index.ts +2 -0
- package/src/aws/profile.ts +1 -4
- package/src/aws/region.ts +42 -3
- package/src/aws/sqs/index.ts +2 -0
- package/src/aws/sqs/queue.consume.ts +1 -1
- package/src/aws/sqs/queue.event-source.ts +29 -55
- package/src/aws/sqs/queue.provider.ts +10 -2
- package/src/aws/sqs/queue.send-message.ts +5 -8
- package/src/aws/sqs/queue.ts +9 -4
- package/src/binding.ts +19 -19
- package/src/cli/components/ApprovePlan.tsx +2 -2
- package/src/cli/components/Plan.tsx +3 -2
- package/src/cli/components/PlanProgress.tsx +32 -14
- package/src/cli/index.ts +2 -6
- package/src/cli/ink-service.tsx +61 -0
- package/src/cli/service.ts +23 -0
- package/src/cloudflare/account.ts +37 -0
- package/src/cloudflare/api.ts +33 -29
- package/src/cloudflare/config.ts +7 -0
- package/src/cloudflare/index.ts +3 -1
- package/src/cloudflare/kv/namespace.binding.ts +3 -1
- package/src/cloudflare/kv/namespace.provider.ts +10 -8
- package/src/cloudflare/kv/namespace.ts +3 -2
- package/src/cloudflare/live.ts +11 -17
- package/src/cloudflare/r2/bucket.binding.ts +3 -1
- package/src/cloudflare/r2/bucket.provider.ts +16 -9
- package/src/cloudflare/r2/bucket.ts +8 -2
- package/src/cloudflare/worker/assets.fetch.ts +3 -1
- package/src/cloudflare/worker/assets.provider.ts +1 -1
- package/src/cloudflare/worker/index.ts +0 -2
- package/src/cloudflare/worker/worker.handler.ts +1 -1
- package/src/cloudflare/worker/worker.provider.ts +21 -14
- package/src/cloudflare/worker/worker.serve.ts +5 -2
- package/src/cloudflare/worker/worker.ts +4 -3
- package/src/data.ts +18 -0
- package/src/destroy.ts +1 -5
- package/src/diff.ts +48 -0
- package/src/env.ts +20 -32
- package/src/event.ts +6 -0
- package/src/exports.ts +21 -0
- package/src/index.ts +10 -5
- package/src/input.ts +81 -0
- package/src/instance-id.ts +16 -0
- package/src/output.ts +542 -0
- package/src/physical-name.ts +57 -2
- package/src/plan.ts +757 -278
- package/src/policy.ts +3 -5
- package/src/provider.ts +70 -31
- package/src/ref.ts +48 -0
- package/src/resource.ts +70 -10
- package/src/runtime.ts +15 -8
- package/src/service.ts +11 -7
- package/src/stack.ts +116 -0
- package/src/stage.ts +85 -0
- package/src/state.ts +269 -76
- package/src/tags.ts +31 -0
- package/src/test.ts +118 -17
- package/src/todo.ts +4 -0
- package/src/type.ts +4 -0
- package/src/unknown.ts +6 -0
- package/src/user.ts +4 -0
- package/src/util.ts +21 -0
- package/lib/approve.d.ts +0 -15
- package/lib/approve.d.ts.map +0 -1
- package/lib/approve.js +0 -7
- package/lib/approve.js.map +0 -1
- package/lib/cli/approve.d.ts +0 -4
- package/lib/cli/approve.d.ts.map +0 -1
- package/lib/cli/approve.js +0 -18
- package/lib/cli/approve.js.map +0 -1
- package/lib/cli/clack.d.ts +0 -14
- package/lib/cli/clack.d.ts.map +0 -1
- package/lib/cli/clack.js +0 -12
- package/lib/cli/clack.js.map +0 -1
- package/lib/cli/main.d.ts +0 -2
- package/lib/cli/main.d.ts.map +0 -1
- package/lib/cli/main.js +0 -1
- package/lib/cli/main.js.map +0 -1
- package/lib/cli/plan.d.ts +0 -13
- package/lib/cli/plan.d.ts.map +0 -1
- package/lib/cli/plan.js +0 -1
- package/lib/cli/plan.js.map +0 -1
- package/lib/cli/progress.d.ts +0 -7
- package/lib/cli/progress.d.ts.map +0 -1
- package/lib/cli/progress.js +0 -30
- package/lib/cli/progress.js.map +0 -1
- package/lib/cli/spinner.d.ts +0 -2
- package/lib/cli/spinner.d.ts.map +0 -1
- package/lib/cli/spinner.js +0 -13
- package/lib/cli/spinner.js.map +0 -1
- package/src/approve.ts +0 -13
- package/src/cli/approve.tsx +0 -30
- package/src/cli/clack.ts +0 -22
- package/src/cli/main.ts +0 -0
- package/src/cli/plan.ts +0 -16
- package/src/cli/progress.tsx +0 -46
- package/src/cli/spinner.ts +0 -14
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { Input } from "../../input.ts";
|
|
2
|
+
import { Resource } from "../../resource.ts";
|
|
3
|
+
import type { AccountID } from "../account.ts";
|
|
4
|
+
import type { RegionID } from "../region.ts";
|
|
5
|
+
import type { VpcId } from "./vpc.ts";
|
|
6
|
+
|
|
7
|
+
export const InternetGateway = Resource<{
|
|
8
|
+
<const ID extends string, const Props extends InternetGatewayProps>(
|
|
9
|
+
id: ID,
|
|
10
|
+
props: Props,
|
|
11
|
+
): InternetGateway<ID, Props>;
|
|
12
|
+
}>("AWS.EC2.InternetGateway");
|
|
13
|
+
|
|
14
|
+
export interface InternetGateway<
|
|
15
|
+
ID extends string = string,
|
|
16
|
+
Props extends InternetGatewayProps = InternetGatewayProps,
|
|
17
|
+
> extends Resource<
|
|
18
|
+
"AWS.EC2.InternetGateway",
|
|
19
|
+
ID,
|
|
20
|
+
Props,
|
|
21
|
+
InternetGatewayAttrs<Input.Resolve<Props>>,
|
|
22
|
+
InternetGateway
|
|
23
|
+
> {}
|
|
24
|
+
|
|
25
|
+
export type InternetGatewayId<ID extends string = string> = `igw-${ID}`;
|
|
26
|
+
export const InternetGatewayId = <ID extends string>(
|
|
27
|
+
id: ID,
|
|
28
|
+
): ID & InternetGatewayId<ID> => `igw-${id}` as ID & InternetGatewayId<ID>;
|
|
29
|
+
|
|
30
|
+
export interface InternetGatewayProps {
|
|
31
|
+
/**
|
|
32
|
+
* The VPC to attach the internet gateway to.
|
|
33
|
+
* If provided, the internet gateway will be automatically attached to the VPC.
|
|
34
|
+
* Optional - you can create an unattached internet gateway and attach it later.
|
|
35
|
+
*/
|
|
36
|
+
vpcId?: Input<VpcId>;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Tags to assign to the internet gateway.
|
|
40
|
+
* These will be merged with alchemy auto-tags (alchemy::app, alchemy::stage, alchemy::id).
|
|
41
|
+
*/
|
|
42
|
+
tags?: Record<string, Input<string>>;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface InternetGatewayAttrs<Props extends InternetGatewayProps> {
|
|
46
|
+
/**
|
|
47
|
+
* The ID of the internet gateway.
|
|
48
|
+
*/
|
|
49
|
+
internetGatewayId: InternetGatewayId;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The Amazon Resource Name (ARN) of the internet gateway.
|
|
53
|
+
*/
|
|
54
|
+
internetGatewayArn: `arn:aws:ec2:${RegionID}:${AccountID}:internet-gateway/${this["internetGatewayId"]}`;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The ID of the VPC the internet gateway is attached to (if any).
|
|
58
|
+
*/
|
|
59
|
+
vpcId?: Props["vpcId"];
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* The ID of the AWS account that owns the internet gateway.
|
|
63
|
+
*/
|
|
64
|
+
ownerId?: string;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* The attachments for the internet gateway.
|
|
68
|
+
*/
|
|
69
|
+
attachments?: Array<{
|
|
70
|
+
/**
|
|
71
|
+
* The current state of the attachment.
|
|
72
|
+
*/
|
|
73
|
+
state: "attaching" | "available" | "detaching" | "detached";
|
|
74
|
+
/**
|
|
75
|
+
* The ID of the VPC.
|
|
76
|
+
*/
|
|
77
|
+
vpcId: string;
|
|
78
|
+
}>;
|
|
79
|
+
}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Schedule from "effect/Schedule";
|
|
3
|
+
|
|
4
|
+
import type { ScopedPlanStatusSession } from "../../cli/service.ts";
|
|
5
|
+
import type { ProviderService } from "../../provider.ts";
|
|
6
|
+
import { EC2Client } from "./client.ts";
|
|
7
|
+
import {
|
|
8
|
+
RouteTableAssociation,
|
|
9
|
+
type RouteTableAssociationAttrs,
|
|
10
|
+
type RouteTableAssociationId,
|
|
11
|
+
type RouteTableAssociationProps,
|
|
12
|
+
} from "./route-table-association.ts";
|
|
13
|
+
|
|
14
|
+
export const routeTableAssociationProvider = () =>
|
|
15
|
+
RouteTableAssociation.provider.effect(
|
|
16
|
+
Effect.gen(function* () {
|
|
17
|
+
const ec2 = yield* EC2Client;
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
stables: ["associationId", "subnetId", "gatewayId"],
|
|
21
|
+
diff: Effect.fn(function* ({ news, olds }) {
|
|
22
|
+
// Subnet/Gateway change requires replacement (use ReplaceRouteTableAssociation internally)
|
|
23
|
+
if (olds.subnetId !== news.subnetId) {
|
|
24
|
+
return { action: "replace" };
|
|
25
|
+
}
|
|
26
|
+
if (olds.gatewayId !== news.gatewayId) {
|
|
27
|
+
return { action: "replace" };
|
|
28
|
+
}
|
|
29
|
+
// Route table change can be done via ReplaceRouteTableAssociation
|
|
30
|
+
}),
|
|
31
|
+
|
|
32
|
+
create: Effect.fn(function* ({ news, session }) {
|
|
33
|
+
// Call AssociateRouteTable
|
|
34
|
+
const result = yield* ec2
|
|
35
|
+
.associateRouteTable({
|
|
36
|
+
RouteTableId: news.routeTableId,
|
|
37
|
+
SubnetId: news.subnetId,
|
|
38
|
+
GatewayId: news.gatewayId,
|
|
39
|
+
DryRun: false,
|
|
40
|
+
})
|
|
41
|
+
.pipe(
|
|
42
|
+
Effect.retry({
|
|
43
|
+
// Retry if route table or subnet/gateway is not yet available
|
|
44
|
+
while: (e) =>
|
|
45
|
+
e._tag === "InvalidRouteTableID.NotFound" ||
|
|
46
|
+
e._tag === "InvalidSubnetID.NotFound",
|
|
47
|
+
schedule: Schedule.exponential(100),
|
|
48
|
+
}),
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
const associationId =
|
|
52
|
+
result.AssociationId! as RouteTableAssociationId;
|
|
53
|
+
yield* session.note(
|
|
54
|
+
`Route table association created: ${associationId}`,
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
// Wait for association to be associated
|
|
58
|
+
yield* waitForAssociationState(
|
|
59
|
+
ec2,
|
|
60
|
+
news.routeTableId,
|
|
61
|
+
associationId,
|
|
62
|
+
"associated",
|
|
63
|
+
session,
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
// Return attributes
|
|
67
|
+
return {
|
|
68
|
+
associationId,
|
|
69
|
+
routeTableId: news.routeTableId,
|
|
70
|
+
subnetId: news.subnetId,
|
|
71
|
+
gatewayId: news.gatewayId,
|
|
72
|
+
associationState: {
|
|
73
|
+
state: result.AssociationState?.State ?? "associated",
|
|
74
|
+
statusMessage: result.AssociationState?.StatusMessage,
|
|
75
|
+
},
|
|
76
|
+
} satisfies RouteTableAssociationAttrs<RouteTableAssociationProps>;
|
|
77
|
+
}),
|
|
78
|
+
|
|
79
|
+
update: Effect.fn(function* ({ news, olds, output, session }) {
|
|
80
|
+
// If route table changed, use ReplaceRouteTableAssociation
|
|
81
|
+
if (news.routeTableId !== olds.routeTableId) {
|
|
82
|
+
const result = yield* ec2.replaceRouteTableAssociation({
|
|
83
|
+
AssociationId: output.associationId,
|
|
84
|
+
RouteTableId: news.routeTableId,
|
|
85
|
+
DryRun: false,
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
const newAssociationId =
|
|
89
|
+
result.NewAssociationId! as RouteTableAssociationId;
|
|
90
|
+
yield* session.note(
|
|
91
|
+
`Route table association replaced: ${newAssociationId}`,
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
// Wait for new association to be associated
|
|
95
|
+
yield* waitForAssociationState(
|
|
96
|
+
ec2,
|
|
97
|
+
news.routeTableId,
|
|
98
|
+
newAssociationId,
|
|
99
|
+
"associated",
|
|
100
|
+
session,
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
associationId: newAssociationId,
|
|
105
|
+
routeTableId: news.routeTableId,
|
|
106
|
+
subnetId: news.subnetId,
|
|
107
|
+
gatewayId: news.gatewayId,
|
|
108
|
+
associationState: {
|
|
109
|
+
state: result.AssociationState?.State ?? "associated",
|
|
110
|
+
statusMessage: result.AssociationState?.StatusMessage,
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// No changes needed
|
|
116
|
+
return output;
|
|
117
|
+
}),
|
|
118
|
+
|
|
119
|
+
delete: Effect.fn(function* ({ output, session }) {
|
|
120
|
+
yield* session.note(
|
|
121
|
+
`Deleting route table association: ${output.associationId}`,
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
// Disassociate the route table
|
|
125
|
+
yield* ec2
|
|
126
|
+
.disassociateRouteTable({
|
|
127
|
+
AssociationId: output.associationId,
|
|
128
|
+
DryRun: false,
|
|
129
|
+
})
|
|
130
|
+
.pipe(
|
|
131
|
+
Effect.tapError(Effect.log),
|
|
132
|
+
Effect.catchTag(
|
|
133
|
+
"InvalidAssociationID.NotFound",
|
|
134
|
+
() => Effect.void,
|
|
135
|
+
),
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
yield* session.note(
|
|
139
|
+
`Route table association ${output.associationId} deleted successfully`,
|
|
140
|
+
);
|
|
141
|
+
}),
|
|
142
|
+
} satisfies ProviderService<RouteTableAssociation>;
|
|
143
|
+
}),
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Wait for association to reach a specific state
|
|
148
|
+
*/
|
|
149
|
+
const waitForAssociationState = (
|
|
150
|
+
ec2: import("itty-aws/ec2").EC2,
|
|
151
|
+
routeTableId: string,
|
|
152
|
+
associationId: string,
|
|
153
|
+
targetState:
|
|
154
|
+
| "associating"
|
|
155
|
+
| "associated"
|
|
156
|
+
| "disassociating"
|
|
157
|
+
| "disassociated",
|
|
158
|
+
session?: ScopedPlanStatusSession,
|
|
159
|
+
) =>
|
|
160
|
+
Effect.retry(
|
|
161
|
+
Effect.gen(function* () {
|
|
162
|
+
const result = yield* ec2
|
|
163
|
+
.describeRouteTables({ RouteTableIds: [routeTableId] })
|
|
164
|
+
.pipe(
|
|
165
|
+
Effect.catchTag("InvalidRouteTableID.NotFound", () =>
|
|
166
|
+
Effect.succeed({ RouteTables: [] }),
|
|
167
|
+
),
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
const routeTable = result.RouteTables?.[0];
|
|
171
|
+
if (!routeTable) {
|
|
172
|
+
return yield* Effect.fail(new Error("Route table not found"));
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const association = routeTable.Associations?.find(
|
|
176
|
+
(a) => a.RouteTableAssociationId === associationId,
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
if (!association) {
|
|
180
|
+
// Association might not exist yet, retry
|
|
181
|
+
return yield* Effect.fail(new Error("Association not found"));
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (association.AssociationState?.State === targetState) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (association.AssociationState?.State === "failed") {
|
|
189
|
+
return yield* Effect.fail(
|
|
190
|
+
new Error(
|
|
191
|
+
`Association failed: ${association.AssociationState.StatusMessage}`,
|
|
192
|
+
),
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Still in progress, fail to trigger retry
|
|
197
|
+
return yield* Effect.fail(
|
|
198
|
+
new Error(`Association state: ${association.AssociationState?.State}`),
|
|
199
|
+
);
|
|
200
|
+
}),
|
|
201
|
+
{
|
|
202
|
+
schedule: Schedule.fixed(1000).pipe(
|
|
203
|
+
// Check every second
|
|
204
|
+
Schedule.intersect(Schedule.recurs(30)), // Max 30 seconds
|
|
205
|
+
Schedule.tapOutput(([, attempt]) =>
|
|
206
|
+
session
|
|
207
|
+
? session.note(
|
|
208
|
+
`Waiting for association to be ${targetState}... (${attempt + 1}s)`,
|
|
209
|
+
)
|
|
210
|
+
: Effect.void,
|
|
211
|
+
),
|
|
212
|
+
),
|
|
213
|
+
},
|
|
214
|
+
);
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type * as EC2 from "itty-aws/ec2";
|
|
2
|
+
import type { Input } from "../../input.ts";
|
|
3
|
+
import { Resource } from "../../resource.ts";
|
|
4
|
+
import type { RouteTableId } from "./route-table.ts";
|
|
5
|
+
import type { SubnetId } from "./subnet.ts";
|
|
6
|
+
|
|
7
|
+
export const RouteTableAssociation = Resource<{
|
|
8
|
+
<const ID extends string, const Props extends RouteTableAssociationProps>(
|
|
9
|
+
id: ID,
|
|
10
|
+
props: Props,
|
|
11
|
+
): RouteTableAssociation<ID, Props>;
|
|
12
|
+
}>("AWS.EC2.RouteTableAssociation");
|
|
13
|
+
|
|
14
|
+
export interface RouteTableAssociation<
|
|
15
|
+
ID extends string = string,
|
|
16
|
+
Props extends RouteTableAssociationProps = RouteTableAssociationProps,
|
|
17
|
+
> extends Resource<
|
|
18
|
+
"AWS.EC2.RouteTableAssociation",
|
|
19
|
+
ID,
|
|
20
|
+
Props,
|
|
21
|
+
RouteTableAssociationAttrs<Input.Resolve<Props>>,
|
|
22
|
+
RouteTableAssociation
|
|
23
|
+
> {}
|
|
24
|
+
|
|
25
|
+
export type RouteTableAssociationId<ID extends string = string> =
|
|
26
|
+
`rtbassoc-${ID}`;
|
|
27
|
+
export const RouteTableAssociationId = <ID extends string>(
|
|
28
|
+
id: ID,
|
|
29
|
+
): ID & RouteTableAssociationId<ID> =>
|
|
30
|
+
`rtbassoc-${id}` as ID & RouteTableAssociationId<ID>;
|
|
31
|
+
|
|
32
|
+
export interface RouteTableAssociationProps {
|
|
33
|
+
/**
|
|
34
|
+
* The ID of the route table.
|
|
35
|
+
* Required.
|
|
36
|
+
*/
|
|
37
|
+
routeTableId: Input<RouteTableId>;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The ID of the subnet to associate with the route table.
|
|
41
|
+
* Either subnetId or gatewayId is required, but not both.
|
|
42
|
+
*/
|
|
43
|
+
subnetId?: Input<SubnetId>;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* The ID of the gateway (internet gateway or virtual private gateway) to associate with the route table.
|
|
47
|
+
* Either subnetId or gatewayId is required, but not both.
|
|
48
|
+
*/
|
|
49
|
+
gatewayId?: Input<string>;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface RouteTableAssociationAttrs<
|
|
53
|
+
Props extends RouteTableAssociationProps,
|
|
54
|
+
> {
|
|
55
|
+
/**
|
|
56
|
+
* The ID of the association.
|
|
57
|
+
*/
|
|
58
|
+
associationId: RouteTableAssociationId;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The ID of the route table.
|
|
62
|
+
*/
|
|
63
|
+
routeTableId: Props["routeTableId"];
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* The ID of the subnet (if the association is with a subnet).
|
|
67
|
+
*/
|
|
68
|
+
subnetId?: Props["subnetId"];
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* The ID of the gateway (if the association is with a gateway).
|
|
72
|
+
*/
|
|
73
|
+
gatewayId?: Props["gatewayId"];
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* The state of the association.
|
|
77
|
+
*/
|
|
78
|
+
associationState: {
|
|
79
|
+
state: EC2.RouteTableAssociationStateCode;
|
|
80
|
+
statusMessage?: string;
|
|
81
|
+
};
|
|
82
|
+
}
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Schedule from "effect/Schedule";
|
|
3
|
+
|
|
4
|
+
import type { EC2 } from "itty-aws/ec2";
|
|
5
|
+
|
|
6
|
+
import type { ScopedPlanStatusSession } from "../../cli/service.ts";
|
|
7
|
+
import type { ProviderService } from "../../provider.ts";
|
|
8
|
+
import { createTagger, createTagsList } from "../../tags.ts";
|
|
9
|
+
import { Account } from "../account.ts";
|
|
10
|
+
import { Region } from "../region.ts";
|
|
11
|
+
import { EC2Client } from "./client.ts";
|
|
12
|
+
import {
|
|
13
|
+
RouteTable,
|
|
14
|
+
type RouteTableAttrs,
|
|
15
|
+
type RouteTableId,
|
|
16
|
+
type RouteTableProps,
|
|
17
|
+
} from "./route-table.ts";
|
|
18
|
+
|
|
19
|
+
export const routeTableProvider = () =>
|
|
20
|
+
RouteTable.provider.effect(
|
|
21
|
+
Effect.gen(function* () {
|
|
22
|
+
const ec2 = yield* EC2Client;
|
|
23
|
+
const region = yield* Region;
|
|
24
|
+
const accountId = yield* Account;
|
|
25
|
+
const tagged = yield* createTagger();
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
stables: ["routeTableId", "ownerId", "routeTableArn", "vpcId"],
|
|
29
|
+
diff: Effect.fn(function* ({ news, olds }) {
|
|
30
|
+
// VpcId change requires replacement
|
|
31
|
+
if (olds.vpcId !== news.vpcId) {
|
|
32
|
+
return { action: "replace" };
|
|
33
|
+
}
|
|
34
|
+
// Tags can be updated in-place
|
|
35
|
+
}),
|
|
36
|
+
|
|
37
|
+
create: Effect.fn(function* ({ id, news, session }) {
|
|
38
|
+
// 1. Prepare tags
|
|
39
|
+
const alchemyTags = tagged(id);
|
|
40
|
+
const userTags = news.tags ?? {};
|
|
41
|
+
const allTags = { ...alchemyTags, ...userTags };
|
|
42
|
+
|
|
43
|
+
// 2. Call CreateRouteTable
|
|
44
|
+
const createResult = yield* ec2
|
|
45
|
+
.createRouteTable({
|
|
46
|
+
VpcId: news.vpcId,
|
|
47
|
+
TagSpecifications: [
|
|
48
|
+
{
|
|
49
|
+
ResourceType: "route-table",
|
|
50
|
+
Tags: createTagsList(allTags),
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
DryRun: false,
|
|
54
|
+
})
|
|
55
|
+
.pipe(
|
|
56
|
+
Effect.retry({
|
|
57
|
+
// Retry if VPC is not yet available
|
|
58
|
+
while: (e) => e._tag === "InvalidVpcID.NotFound",
|
|
59
|
+
schedule: Schedule.exponential(100),
|
|
60
|
+
}),
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
const routeTableId = createResult.RouteTable!
|
|
64
|
+
.RouteTableId! as RouteTableId;
|
|
65
|
+
yield* session.note(`Route table created: ${routeTableId}`);
|
|
66
|
+
|
|
67
|
+
// 3. Describe to get full details
|
|
68
|
+
const routeTable = yield* describeRouteTable(
|
|
69
|
+
ec2,
|
|
70
|
+
routeTableId,
|
|
71
|
+
session,
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
// 4. Return attributes
|
|
75
|
+
return {
|
|
76
|
+
routeTableId,
|
|
77
|
+
routeTableArn:
|
|
78
|
+
`arn:aws:ec2:${region}:${accountId}:route-table/${routeTableId}` as RouteTableAttrs<RouteTableProps>["routeTableArn"],
|
|
79
|
+
vpcId: news.vpcId,
|
|
80
|
+
ownerId: routeTable.OwnerId,
|
|
81
|
+
associations: routeTable.Associations?.map((assoc) => ({
|
|
82
|
+
main: assoc.Main ?? false,
|
|
83
|
+
routeTableAssociationId: assoc.RouteTableAssociationId,
|
|
84
|
+
routeTableId: assoc.RouteTableId,
|
|
85
|
+
subnetId: assoc.SubnetId,
|
|
86
|
+
gatewayId: assoc.GatewayId,
|
|
87
|
+
associationState: assoc.AssociationState
|
|
88
|
+
? {
|
|
89
|
+
state: assoc.AssociationState.State!,
|
|
90
|
+
statusMessage: assoc.AssociationState.StatusMessage,
|
|
91
|
+
}
|
|
92
|
+
: undefined,
|
|
93
|
+
})),
|
|
94
|
+
routes: routeTable.Routes?.map((route) => ({
|
|
95
|
+
destinationCidrBlock: route.DestinationCidrBlock,
|
|
96
|
+
destinationIpv6CidrBlock: route.DestinationIpv6CidrBlock,
|
|
97
|
+
destinationPrefixListId: route.DestinationPrefixListId,
|
|
98
|
+
egressOnlyInternetGatewayId: route.EgressOnlyInternetGatewayId,
|
|
99
|
+
gatewayId: route.GatewayId,
|
|
100
|
+
instanceId: route.InstanceId,
|
|
101
|
+
instanceOwnerId: route.InstanceOwnerId,
|
|
102
|
+
natGatewayId: route.NatGatewayId,
|
|
103
|
+
transitGatewayId: route.TransitGatewayId,
|
|
104
|
+
localGatewayId: route.LocalGatewayId,
|
|
105
|
+
carrierGatewayId: route.CarrierGatewayId,
|
|
106
|
+
networkInterfaceId: route.NetworkInterfaceId,
|
|
107
|
+
origin: route.Origin!,
|
|
108
|
+
state: route.State!,
|
|
109
|
+
vpcPeeringConnectionId: route.VpcPeeringConnectionId,
|
|
110
|
+
coreNetworkArn: route.CoreNetworkArn,
|
|
111
|
+
})),
|
|
112
|
+
propagatingVgws: routeTable.PropagatingVgws?.map((vgw) => ({
|
|
113
|
+
gatewayId: vgw.GatewayId!,
|
|
114
|
+
})),
|
|
115
|
+
} satisfies RouteTableAttrs<RouteTableProps>;
|
|
116
|
+
}),
|
|
117
|
+
|
|
118
|
+
update: Effect.fn(function* ({ news, olds, output, session }) {
|
|
119
|
+
const routeTableId = output.routeTableId;
|
|
120
|
+
|
|
121
|
+
// Handle tag updates
|
|
122
|
+
if (
|
|
123
|
+
JSON.stringify(news.tags ?? {}) !== JSON.stringify(olds.tags ?? {})
|
|
124
|
+
) {
|
|
125
|
+
const alchemyTags = tagged(output.routeTableId);
|
|
126
|
+
const userTags = news.tags ?? {};
|
|
127
|
+
const allTags = { ...alchemyTags, ...userTags };
|
|
128
|
+
|
|
129
|
+
// Delete old tags that are no longer present
|
|
130
|
+
const oldTagKeys = Object.keys(olds.tags ?? {});
|
|
131
|
+
const newTagKeys = Object.keys(news.tags ?? {});
|
|
132
|
+
const tagsToDelete = oldTagKeys.filter(
|
|
133
|
+
(key) => !newTagKeys.includes(key),
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
if (tagsToDelete.length > 0) {
|
|
137
|
+
yield* ec2.deleteTags({
|
|
138
|
+
Resources: [routeTableId],
|
|
139
|
+
Tags: tagsToDelete.map((key) => ({ Key: key })),
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Create/update tags
|
|
144
|
+
yield* ec2.createTags({
|
|
145
|
+
Resources: [routeTableId],
|
|
146
|
+
Tags: createTagsList(allTags),
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
yield* session.note("Updated tags");
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Re-describe to get current state
|
|
153
|
+
const routeTable = yield* describeRouteTable(
|
|
154
|
+
ec2,
|
|
155
|
+
routeTableId,
|
|
156
|
+
session,
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
return {
|
|
160
|
+
...output,
|
|
161
|
+
associations: routeTable.Associations?.map((assoc) => ({
|
|
162
|
+
main: assoc.Main ?? false,
|
|
163
|
+
routeTableAssociationId: assoc.RouteTableAssociationId,
|
|
164
|
+
routeTableId: assoc.RouteTableId,
|
|
165
|
+
subnetId: assoc.SubnetId,
|
|
166
|
+
gatewayId: assoc.GatewayId,
|
|
167
|
+
associationState: assoc.AssociationState
|
|
168
|
+
? {
|
|
169
|
+
state: assoc.AssociationState.State!,
|
|
170
|
+
statusMessage: assoc.AssociationState.StatusMessage,
|
|
171
|
+
}
|
|
172
|
+
: undefined,
|
|
173
|
+
})),
|
|
174
|
+
routes: routeTable.Routes?.map((route) => ({
|
|
175
|
+
destinationCidrBlock: route.DestinationCidrBlock,
|
|
176
|
+
destinationIpv6CidrBlock: route.DestinationIpv6CidrBlock,
|
|
177
|
+
destinationPrefixListId: route.DestinationPrefixListId,
|
|
178
|
+
egressOnlyInternetGatewayId: route.EgressOnlyInternetGatewayId,
|
|
179
|
+
gatewayId: route.GatewayId,
|
|
180
|
+
instanceId: route.InstanceId,
|
|
181
|
+
instanceOwnerId: route.InstanceOwnerId,
|
|
182
|
+
natGatewayId: route.NatGatewayId,
|
|
183
|
+
transitGatewayId: route.TransitGatewayId,
|
|
184
|
+
localGatewayId: route.LocalGatewayId,
|
|
185
|
+
carrierGatewayId: route.CarrierGatewayId,
|
|
186
|
+
networkInterfaceId: route.NetworkInterfaceId,
|
|
187
|
+
origin: route.Origin!,
|
|
188
|
+
state: route.State!,
|
|
189
|
+
vpcPeeringConnectionId: route.VpcPeeringConnectionId,
|
|
190
|
+
coreNetworkArn: route.CoreNetworkArn,
|
|
191
|
+
})),
|
|
192
|
+
propagatingVgws: routeTable.PropagatingVgws?.map((vgw) => ({
|
|
193
|
+
gatewayId: vgw.GatewayId!,
|
|
194
|
+
})),
|
|
195
|
+
};
|
|
196
|
+
}),
|
|
197
|
+
|
|
198
|
+
delete: Effect.fn(function* ({ output, session }) {
|
|
199
|
+
const routeTableId = output.routeTableId;
|
|
200
|
+
|
|
201
|
+
yield* session.note(`Deleting route table: ${routeTableId}`);
|
|
202
|
+
|
|
203
|
+
// 1. Attempt to delete route table
|
|
204
|
+
yield* ec2
|
|
205
|
+
.deleteRouteTable({
|
|
206
|
+
RouteTableId: routeTableId,
|
|
207
|
+
DryRun: false,
|
|
208
|
+
})
|
|
209
|
+
.pipe(
|
|
210
|
+
Effect.tapError(Effect.logDebug),
|
|
211
|
+
Effect.catchTag(
|
|
212
|
+
"InvalidRouteTableID.NotFound",
|
|
213
|
+
() => Effect.void,
|
|
214
|
+
),
|
|
215
|
+
// Retry on dependency violations (associations still being deleted)
|
|
216
|
+
Effect.retry({
|
|
217
|
+
// DependencyViolation means there are still dependent resources
|
|
218
|
+
while: (e) => {
|
|
219
|
+
return e._tag === "DependencyViolation";
|
|
220
|
+
},
|
|
221
|
+
schedule: Schedule.exponential(1000, 1.5).pipe(
|
|
222
|
+
Schedule.intersect(Schedule.recurs(10)), // Try up to 10 times
|
|
223
|
+
Schedule.tapOutput(([, attempt]) =>
|
|
224
|
+
session.note(
|
|
225
|
+
`Waiting for dependencies to clear... (attempt ${attempt + 1})`,
|
|
226
|
+
),
|
|
227
|
+
),
|
|
228
|
+
),
|
|
229
|
+
}),
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
// 2. Wait for route table to be fully deleted
|
|
233
|
+
yield* waitForRouteTableDeleted(ec2, routeTableId, session);
|
|
234
|
+
|
|
235
|
+
yield* session.note(
|
|
236
|
+
`Route table ${routeTableId} deleted successfully`,
|
|
237
|
+
);
|
|
238
|
+
}),
|
|
239
|
+
} satisfies ProviderService<RouteTable>;
|
|
240
|
+
}),
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Describe a route table by ID
|
|
245
|
+
*/
|
|
246
|
+
const describeRouteTable = (
|
|
247
|
+
ec2: EC2,
|
|
248
|
+
routeTableId: string,
|
|
249
|
+
_session?: ScopedPlanStatusSession,
|
|
250
|
+
) =>
|
|
251
|
+
Effect.gen(function* () {
|
|
252
|
+
const result = yield* ec2
|
|
253
|
+
.describeRouteTables({ RouteTableIds: [routeTableId] })
|
|
254
|
+
.pipe(
|
|
255
|
+
Effect.catchTag("InvalidRouteTableID.NotFound", () =>
|
|
256
|
+
Effect.succeed({ RouteTables: [] }),
|
|
257
|
+
),
|
|
258
|
+
);
|
|
259
|
+
|
|
260
|
+
const routeTable = result.RouteTables?.[0];
|
|
261
|
+
if (!routeTable) {
|
|
262
|
+
return yield* Effect.fail(new Error("Route table not found"));
|
|
263
|
+
}
|
|
264
|
+
return routeTable;
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Wait for route table to be deleted
|
|
269
|
+
*/
|
|
270
|
+
const waitForRouteTableDeleted = (
|
|
271
|
+
ec2: EC2,
|
|
272
|
+
routeTableId: string,
|
|
273
|
+
session: ScopedPlanStatusSession,
|
|
274
|
+
) =>
|
|
275
|
+
Effect.gen(function* () {
|
|
276
|
+
yield* Effect.retry(
|
|
277
|
+
Effect.gen(function* () {
|
|
278
|
+
const result = yield* ec2
|
|
279
|
+
.describeRouteTables({ RouteTableIds: [routeTableId] })
|
|
280
|
+
.pipe(
|
|
281
|
+
Effect.tapError(Effect.logDebug),
|
|
282
|
+
Effect.catchTag("InvalidRouteTableID.NotFound", () =>
|
|
283
|
+
Effect.succeed({ RouteTables: [] }),
|
|
284
|
+
),
|
|
285
|
+
);
|
|
286
|
+
|
|
287
|
+
if (!result.RouteTables || result.RouteTables.length === 0) {
|
|
288
|
+
return; // Successfully deleted
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Still exists, fail to trigger retry
|
|
292
|
+
return yield* Effect.fail(new Error("Route table still exists"));
|
|
293
|
+
}),
|
|
294
|
+
{
|
|
295
|
+
schedule: Schedule.fixed(2000).pipe(
|
|
296
|
+
// Check every 2 seconds
|
|
297
|
+
Schedule.intersect(Schedule.recurs(15)), // Max 30 seconds
|
|
298
|
+
Schedule.tapOutput(([, attempt]) =>
|
|
299
|
+
session.note(
|
|
300
|
+
`Waiting for route table deletion... (${(attempt + 1) * 2}s)`,
|
|
301
|
+
),
|
|
302
|
+
),
|
|
303
|
+
),
|
|
304
|
+
},
|
|
305
|
+
);
|
|
306
|
+
});
|