alchemy-effect 0.0.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +179 -0
- package/bin/alchemy-effect.js +15 -0
- package/bin/alchemy-effect.js.map +1 -0
- package/bin/alchemy-effect.ts +10 -0
- package/lib/app.d.ts +7 -2
- package/lib/app.d.ts.map +1 -1
- package/lib/app.js +1 -0
- package/lib/app.js.map +1 -1
- package/lib/apply.d.ts +57 -1
- package/lib/apply.d.ts.map +1 -1
- package/lib/apply.js +141 -55
- package/lib/apply.js.map +1 -1
- package/lib/aws/account.d.ts +18 -0
- package/lib/aws/account.d.ts.map +1 -0
- package/lib/aws/account.js +18 -0
- package/lib/aws/account.js.map +1 -0
- package/lib/aws/arn.d.ts +2 -0
- package/lib/aws/arn.d.ts.map +1 -0
- package/lib/aws/arn.js +1 -0
- package/lib/aws/arn.js.map +1 -0
- package/lib/aws/assets.d.ts +8 -0
- package/lib/aws/assets.d.ts.map +1 -0
- package/lib/aws/assets.js +4 -0
- package/lib/aws/assets.js.map +1 -0
- package/lib/aws/bundle.d.ts +4 -0
- package/lib/aws/bundle.d.ts.map +1 -0
- package/lib/aws/bundle.js +4 -0
- package/lib/aws/bundle.js.map +1 -0
- package/lib/aws/client.d.ts +8 -0
- package/lib/aws/client.d.ts.map +1 -0
- package/lib/aws/client.js +28 -0
- package/lib/aws/client.js.map +1 -0
- package/lib/aws/credentials.d.ts +146 -0
- package/lib/aws/credentials.d.ts.map +1 -0
- package/lib/aws/credentials.js +170 -0
- package/lib/aws/credentials.js.map +1 -0
- package/lib/aws/dynamodb/attribute-value.d.ts +20 -0
- package/lib/aws/dynamodb/attribute-value.d.ts.map +1 -0
- package/lib/aws/dynamodb/attribute-value.js +217 -0
- package/lib/aws/dynamodb/attribute-value.js.map +1 -0
- package/lib/aws/dynamodb/client.d.ts +12 -0
- package/lib/aws/dynamodb/client.d.ts.map +1 -0
- package/lib/aws/dynamodb/client.js +11 -0
- package/lib/aws/dynamodb/client.js.map +1 -0
- package/lib/aws/dynamodb/expr.d.ts +41 -0
- package/lib/aws/dynamodb/expr.d.ts.map +1 -0
- package/lib/aws/dynamodb/expr.js +1 -0
- package/lib/aws/dynamodb/expr.js.map +1 -0
- package/lib/aws/dynamodb/index.d.ts +9 -0
- package/lib/aws/dynamodb/index.d.ts.map +1 -0
- package/lib/aws/dynamodb/index.js +10 -0
- package/lib/aws/dynamodb/index.js.map +1 -0
- package/lib/aws/dynamodb/projection.d.ts +25 -0
- package/lib/aws/dynamodb/projection.d.ts.map +1 -0
- package/lib/aws/dynamodb/projection.js +1 -0
- package/lib/aws/dynamodb/projection.js.map +1 -0
- package/lib/aws/dynamodb/secondary-index.d.ts +25 -0
- package/lib/aws/dynamodb/secondary-index.d.ts.map +1 -0
- package/lib/aws/dynamodb/secondary-index.js +4 -0
- package/lib/aws/dynamodb/secondary-index.js.map +1 -0
- package/lib/aws/dynamodb/table.d.ts +56 -0
- package/lib/aws/dynamodb/table.d.ts.map +1 -0
- package/lib/aws/dynamodb/table.get-item.d.ts +55 -0
- package/lib/aws/dynamodb/table.get-item.d.ts.map +1 -0
- package/lib/aws/dynamodb/table.get-item.js +75 -0
- package/lib/aws/dynamodb/table.get-item.js.map +1 -0
- package/lib/aws/dynamodb/table.js +4 -0
- package/lib/aws/dynamodb/table.js.map +1 -0
- package/lib/aws/dynamodb/table.provider.d.ts +8 -0
- package/lib/aws/dynamodb/table.provider.d.ts.map +1 -0
- package/lib/aws/dynamodb/table.provider.js +199 -0
- package/lib/aws/dynamodb/table.provider.js.map +1 -0
- package/lib/aws/ec2/client.d.ts +12 -0
- package/lib/aws/ec2/client.d.ts.map +1 -0
- package/lib/aws/ec2/client.js +11 -0
- package/lib/aws/ec2/client.js.map +1 -0
- package/lib/aws/ec2/index.d.ts +4 -0
- package/lib/aws/ec2/index.d.ts.map +1 -0
- package/lib/aws/ec2/index.js +4 -0
- package/lib/aws/ec2/index.js.map +1 -0
- package/lib/aws/ec2/vpc.d.ts +131 -0
- package/lib/aws/ec2/vpc.d.ts.map +1 -0
- package/lib/aws/ec2/vpc.js +3 -0
- package/lib/aws/ec2/vpc.js.map +1 -0
- package/lib/aws/ec2/vpc.provider.d.ts +7 -0
- package/lib/aws/ec2/vpc.provider.d.ts.map +1 -0
- package/lib/aws/ec2/vpc.provider.js +198 -0
- package/lib/aws/ec2/vpc.provider.js.map +1 -0
- package/lib/aws/iam.d.ts +23 -0
- package/lib/aws/iam.d.ts.map +1 -0
- package/lib/aws/iam.js +7 -0
- package/lib/aws/iam.js.map +1 -0
- package/lib/aws/index.d.ts +32 -0
- package/lib/aws/index.d.ts.map +1 -0
- package/lib/aws/index.js +23 -0
- package/lib/aws/index.js.map +1 -0
- package/lib/aws/lambda/client.d.ts +8 -0
- package/lib/aws/lambda/client.d.ts.map +1 -0
- package/lib/aws/lambda/client.js +7 -0
- package/lib/aws/lambda/client.js.map +1 -0
- package/lib/aws/lambda/consume.d.ts +17 -0
- package/lib/aws/lambda/consume.d.ts.map +1 -0
- package/lib/aws/lambda/consume.js +30 -0
- package/lib/aws/lambda/consume.js.map +1 -0
- package/lib/aws/lambda/function.d.ts +41 -0
- package/lib/aws/lambda/function.d.ts.map +1 -0
- package/lib/aws/lambda/function.handler.d.ts +7 -0
- package/lib/aws/lambda/function.handler.d.ts.map +1 -0
- package/lib/aws/lambda/function.handler.js +8 -0
- package/lib/aws/lambda/function.handler.js.map +1 -0
- package/lib/aws/lambda/function.invoke.d.ts +10 -0
- package/lib/aws/lambda/function.invoke.d.ts.map +1 -0
- package/lib/aws/lambda/function.invoke.js +31 -0
- package/lib/aws/lambda/function.invoke.js.map +1 -0
- package/lib/aws/lambda/function.js +3 -0
- package/lib/aws/lambda/function.js.map +1 -0
- package/lib/aws/lambda/function.provider.d.ts +9 -0
- package/lib/aws/lambda/function.provider.d.ts.map +1 -0
- package/lib/aws/lambda/function.provider.js +465 -0
- package/lib/aws/lambda/function.provider.js.map +1 -0
- package/lib/aws/lambda/index.d.ts +8 -0
- package/lib/aws/lambda/index.d.ts.map +1 -0
- package/lib/aws/lambda/index.js +9 -0
- package/lib/aws/lambda/index.js.map +1 -0
- package/lib/aws/lambda/serve.d.ts +14 -0
- package/lib/aws/lambda/serve.d.ts.map +1 -0
- package/lib/aws/lambda/serve.js +7 -0
- package/lib/aws/lambda/serve.js.map +1 -0
- package/lib/aws/parse-ini.d.ts +4 -0
- package/lib/aws/parse-ini.d.ts.map +1 -0
- package/lib/aws/parse-ini.js +67 -0
- package/lib/aws/parse-ini.js.map +1 -0
- package/lib/aws/profile.d.ts +6 -0
- package/lib/aws/profile.d.ts.map +1 -0
- package/lib/aws/profile.js +4 -0
- package/lib/aws/profile.js.map +1 -0
- package/lib/aws/region.d.ts +19 -0
- package/lib/aws/region.d.ts.map +1 -0
- package/lib/aws/region.js +21 -0
- package/lib/aws/region.js.map +1 -0
- package/lib/aws/s3.d.ts +8 -0
- package/lib/aws/s3.d.ts.map +1 -0
- package/lib/aws/s3.js +7 -0
- package/lib/aws/s3.js.map +1 -0
- package/lib/aws/sqs/client.d.ts +12 -0
- package/lib/aws/sqs/client.d.ts.map +1 -0
- package/lib/aws/sqs/client.js +11 -0
- package/lib/aws/sqs/client.js.map +1 -0
- package/lib/aws/sqs/index.d.ts +7 -0
- package/lib/aws/sqs/index.d.ts.map +1 -0
- package/lib/aws/sqs/index.js +7 -0
- package/lib/aws/sqs/index.js.map +1 -0
- package/lib/aws/sqs/queue.consume.d.ts +12 -0
- package/lib/aws/sqs/queue.consume.d.ts.map +1 -0
- package/lib/aws/sqs/queue.consume.js +3 -0
- package/lib/aws/sqs/queue.consume.js.map +1 -0
- package/lib/aws/sqs/queue.d.ts +79 -0
- package/lib/aws/sqs/queue.d.ts.map +1 -0
- package/lib/aws/sqs/queue.event-source.d.ts +20 -0
- package/lib/aws/sqs/queue.event-source.d.ts.map +1 -0
- package/lib/aws/sqs/queue.event-source.js +148 -0
- package/lib/aws/sqs/queue.event-source.js.map +1 -0
- package/lib/aws/sqs/queue.js +3 -0
- package/lib/aws/sqs/queue.js.map +1 -0
- package/lib/aws/sqs/queue.provider.d.ts +7 -0
- package/lib/aws/sqs/queue.provider.d.ts.map +1 -0
- package/lib/aws/sqs/queue.provider.js +79 -0
- package/lib/aws/sqs/queue.provider.js.map +1 -0
- package/lib/aws/sqs/queue.send-message.d.ts +11 -0
- package/lib/aws/sqs/queue.send-message.d.ts.map +1 -0
- package/lib/aws/sqs/queue.send-message.js +32 -0
- package/lib/aws/sqs/queue.send-message.js.map +1 -0
- package/lib/aws/sts.d.ts +8 -0
- package/lib/aws/sts.d.ts.map +1 -0
- package/lib/aws/sts.js +7 -0
- package/lib/aws/sts.js.map +1 -0
- package/lib/aws/zip.d.ts +3 -0
- package/lib/aws/zip.d.ts.map +1 -0
- package/lib/aws/zip.js +12 -0
- package/lib/aws/zip.js.map +1 -0
- package/lib/binding.d.ts +70 -22
- package/lib/binding.d.ts.map +1 -1
- package/lib/binding.js.map +1 -1
- package/lib/capability.d.ts +38 -0
- package/lib/capability.d.ts.map +1 -1
- package/lib/cli/approve.d.ts +4 -0
- package/lib/cli/approve.d.ts.map +1 -0
- package/lib/cli/approve.js +18 -0
- package/lib/cli/approve.js.map +1 -0
- package/lib/cli/clack.d.ts +14 -0
- package/lib/cli/clack.d.ts.map +1 -0
- package/lib/cli/clack.js +12 -0
- package/lib/cli/clack.js.map +1 -0
- package/lib/cli/components/ApprovePlan.d.ts +8 -0
- package/lib/cli/components/ApprovePlan.d.ts.map +1 -0
- package/lib/cli/components/ApprovePlan.js +30 -0
- package/lib/cli/components/ApprovePlan.js.map +1 -0
- package/lib/cli/components/Plan.d.ts +7 -0
- package/lib/cli/components/Plan.d.ts.map +1 -0
- package/lib/cli/components/Plan.js +100 -0
- package/lib/cli/components/Plan.js.map +1 -0
- package/lib/cli/components/PlanProgress.d.ts +9 -0
- package/lib/cli/components/PlanProgress.d.ts.map +1 -0
- package/lib/cli/components/PlanProgress.js +166 -0
- package/lib/cli/components/PlanProgress.js.map +1 -0
- package/lib/cli/index.d.ts +449 -0
- package/lib/cli/index.d.ts.map +1 -0
- package/lib/cli/index.js +39912 -0
- package/lib/cli/index.js.map +1 -0
- package/lib/cli/main.d.ts +2 -0
- package/lib/cli/main.d.ts.map +1 -0
- package/lib/cli/main.js +1 -0
- package/lib/cli/main.js.map +1 -0
- package/lib/cli/plan.d.ts +13 -0
- package/lib/cli/plan.d.ts.map +1 -0
- package/lib/cli/plan.js +1 -0
- package/lib/cli/plan.js.map +1 -0
- package/lib/cli/progress.d.ts +7 -0
- package/lib/cli/progress.d.ts.map +1 -0
- package/lib/cli/progress.js +30 -0
- package/lib/cli/progress.js.map +1 -0
- package/lib/cli/spinner.d.ts +2 -0
- package/lib/cli/spinner.d.ts.map +1 -0
- package/lib/cli/spinner.js +13 -0
- package/lib/cli/spinner.js.map +1 -0
- package/lib/cloudflare/api.d.ts +36 -0
- package/lib/cloudflare/api.d.ts.map +1 -0
- package/lib/cloudflare/api.js +99 -0
- package/lib/cloudflare/api.js.map +1 -0
- package/lib/cloudflare/context.d.ts +27 -0
- package/lib/cloudflare/context.d.ts.map +1 -0
- package/lib/cloudflare/context.js +24 -0
- package/lib/cloudflare/context.js.map +1 -0
- package/lib/cloudflare/index.d.ts +6 -0
- package/lib/cloudflare/index.d.ts.map +1 -0
- package/lib/cloudflare/index.js +5 -0
- package/lib/cloudflare/index.js.map +1 -0
- package/lib/cloudflare/kv/index.d.ts +4 -0
- package/lib/cloudflare/kv/index.d.ts.map +1 -0
- package/lib/cloudflare/kv/index.js +4 -0
- package/lib/cloudflare/kv/index.js.map +1 -0
- package/lib/cloudflare/kv/namespace.binding.d.ts +8 -0
- package/lib/cloudflare/kv/namespace.binding.d.ts.map +1 -0
- package/lib/cloudflare/kv/namespace.binding.js +15 -0
- package/lib/cloudflare/kv/namespace.binding.js.map +1 -0
- package/lib/cloudflare/kv/namespace.client.d.ts +11 -0
- package/lib/cloudflare/kv/namespace.client.d.ts.map +1 -0
- package/lib/cloudflare/kv/namespace.client.js +31 -0
- package/lib/cloudflare/kv/namespace.client.js.map +1 -0
- package/lib/cloudflare/kv/namespace.d.ts +23 -0
- package/lib/cloudflare/kv/namespace.d.ts.map +1 -0
- package/lib/cloudflare/kv/namespace.js +3 -0
- package/lib/cloudflare/kv/namespace.js.map +1 -0
- package/lib/cloudflare/kv/namespace.provider.d.ts +5 -0
- package/lib/cloudflare/kv/namespace.provider.d.ts.map +1 -0
- package/lib/cloudflare/kv/namespace.provider.js +80 -0
- package/lib/cloudflare/kv/namespace.provider.js.map +1 -0
- package/lib/cloudflare/live.d.ts +11 -0
- package/lib/cloudflare/live.d.ts.map +1 -0
- package/lib/cloudflare/live.js +18 -0
- package/lib/cloudflare/live.js.map +1 -0
- package/lib/cloudflare/r2/bucket.binding.d.ts +8 -0
- package/lib/cloudflare/r2/bucket.binding.d.ts.map +1 -0
- package/lib/cloudflare/r2/bucket.binding.js +18 -0
- package/lib/cloudflare/r2/bucket.binding.js.map +1 -0
- package/lib/cloudflare/r2/bucket.client.d.ts +8 -0
- package/lib/cloudflare/r2/bucket.client.d.ts.map +1 -0
- package/lib/cloudflare/r2/bucket.client.js +9 -0
- package/lib/cloudflare/r2/bucket.client.js.map +1 -0
- package/lib/cloudflare/r2/bucket.d.ts +32 -0
- package/lib/cloudflare/r2/bucket.d.ts.map +1 -0
- package/lib/cloudflare/r2/bucket.del.d.ts +4 -0
- package/lib/cloudflare/r2/bucket.del.d.ts.map +1 -0
- package/lib/cloudflare/r2/bucket.del.js +7 -0
- package/lib/cloudflare/r2/bucket.del.js.map +1 -0
- package/lib/cloudflare/r2/bucket.get.d.ts +5 -0
- package/lib/cloudflare/r2/bucket.get.d.ts.map +1 -0
- package/lib/cloudflare/r2/bucket.get.js +7 -0
- package/lib/cloudflare/r2/bucket.get.js.map +1 -0
- package/lib/cloudflare/r2/bucket.head.d.ts +4 -0
- package/lib/cloudflare/r2/bucket.head.d.ts.map +1 -0
- package/lib/cloudflare/r2/bucket.head.js +7 -0
- package/lib/cloudflare/r2/bucket.head.js.map +1 -0
- package/lib/cloudflare/r2/bucket.js +3 -0
- package/lib/cloudflare/r2/bucket.js.map +1 -0
- package/lib/cloudflare/r2/bucket.list.d.ts +5 -0
- package/lib/cloudflare/r2/bucket.list.d.ts.map +1 -0
- package/lib/cloudflare/r2/bucket.list.js +7 -0
- package/lib/cloudflare/r2/bucket.list.js.map +1 -0
- package/lib/cloudflare/r2/bucket.multipart.d.ts +19 -0
- package/lib/cloudflare/r2/bucket.multipart.d.ts.map +1 -0
- package/lib/cloudflare/r2/bucket.multipart.js +25 -0
- package/lib/cloudflare/r2/bucket.multipart.js.map +1 -0
- package/lib/cloudflare/r2/bucket.provider.d.ts +5 -0
- package/lib/cloudflare/r2/bucket.provider.d.ts.map +1 -0
- package/lib/cloudflare/r2/bucket.provider.js +66 -0
- package/lib/cloudflare/r2/bucket.provider.js.map +1 -0
- package/lib/cloudflare/r2/bucket.put.d.ts +6 -0
- package/lib/cloudflare/r2/bucket.put.d.ts.map +1 -0
- package/lib/cloudflare/r2/bucket.put.js +8 -0
- package/lib/cloudflare/r2/bucket.put.js.map +1 -0
- package/lib/cloudflare/r2/index.d.ts +10 -0
- package/lib/cloudflare/r2/index.d.ts.map +1 -0
- package/lib/cloudflare/r2/index.js +10 -0
- package/lib/cloudflare/r2/index.js.map +1 -0
- package/lib/cloudflare/stream.d.ts +10 -0
- package/lib/cloudflare/stream.d.ts.map +1 -0
- package/lib/cloudflare/stream.js +16 -0
- package/lib/cloudflare/stream.js.map +1 -0
- package/lib/cloudflare/worker/assets.fetch.d.ts +8 -0
- package/lib/cloudflare/worker/assets.fetch.d.ts.map +1 -0
- package/lib/cloudflare/worker/assets.fetch.js +11 -0
- package/lib/cloudflare/worker/assets.fetch.js.map +1 -0
- package/lib/cloudflare/worker/assets.provider.d.ts +66 -0
- package/lib/cloudflare/worker/assets.provider.d.ts.map +1 -0
- package/lib/cloudflare/worker/assets.provider.js +145 -0
- package/lib/cloudflare/worker/assets.provider.js.map +1 -0
- package/lib/cloudflare/worker/index.d.ts +6 -0
- package/lib/cloudflare/worker/index.d.ts.map +1 -0
- package/lib/cloudflare/worker/index.js +5 -0
- package/lib/cloudflare/worker/index.js.map +1 -0
- package/lib/cloudflare/worker/worker.d.ts +67 -0
- package/lib/cloudflare/worker/worker.d.ts.map +1 -0
- package/lib/cloudflare/worker/worker.handler.d.ts +11 -0
- package/lib/cloudflare/worker/worker.handler.d.ts.map +1 -0
- package/lib/cloudflare/worker/worker.handler.js +15 -0
- package/lib/cloudflare/worker/worker.handler.js.map +1 -0
- package/lib/cloudflare/worker/worker.js +4 -0
- package/lib/cloudflare/worker/worker.js.map +1 -0
- package/lib/cloudflare/worker/worker.provider.d.ts +10 -0
- package/lib/cloudflare/worker/worker.provider.d.ts.map +1 -0
- package/lib/cloudflare/worker/worker.provider.js +193 -0
- package/lib/cloudflare/worker/worker.provider.js.map +1 -0
- package/lib/cloudflare/worker/worker.serve.d.ts +39 -0
- package/lib/cloudflare/worker/worker.serve.d.ts.map +1 -0
- package/lib/cloudflare/worker/worker.serve.js +4 -0
- package/lib/cloudflare/worker/worker.serve.js.map +1 -0
- package/lib/destroy.d.ts +1 -3
- package/lib/destroy.d.ts.map +1 -1
- package/lib/destroy.js +5 -0
- package/lib/destroy.js.map +1 -1
- package/lib/dot-alchemy.d.ts +3 -2
- package/lib/dot-alchemy.d.ts.map +1 -1
- package/lib/dot-alchemy.js +3 -2
- package/lib/dot-alchemy.js.map +1 -1
- package/lib/esbuild.d.ts +28 -0
- package/lib/esbuild.d.ts.map +1 -0
- package/lib/esbuild.js +63 -0
- package/lib/esbuild.js.map +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +4 -0
- package/lib/index.js.map +1 -1
- package/lib/plan.d.ts +19 -8
- package/lib/plan.d.ts.map +1 -1
- package/lib/plan.js +144 -72
- package/lib/plan.js.map +1 -1
- package/lib/policy.d.ts +19 -1
- package/lib/policy.d.ts.map +1 -1
- package/lib/policy.js +10 -1
- package/lib/policy.js.map +1 -1
- package/lib/provider.d.ts +2 -2
- package/lib/provider.d.ts.map +1 -1
- package/lib/resource.d.ts +2 -10
- package/lib/resource.d.ts.map +1 -1
- package/lib/resource.js +1 -0
- package/lib/resource.js.map +1 -1
- package/lib/runtime.d.ts +1 -1
- package/lib/runtime.d.ts.map +1 -1
- package/lib/schema.d.ts +37 -0
- package/lib/schema.d.ts.map +1 -0
- package/lib/schema.js +61 -0
- package/lib/schema.js.map +1 -0
- package/lib/sha256.d.ts +5 -0
- package/lib/sha256.d.ts.map +1 -0
- package/lib/sha256.js +16 -0
- package/lib/sha256.js.map +1 -0
- package/lib/state.d.ts +3 -2
- package/lib/state.d.ts.map +1 -1
- package/lib/state.js +3 -2
- package/lib/state.js.map +1 -1
- package/lib/tags.d.ts +17 -0
- package/lib/tags.d.ts.map +1 -0
- package/lib/tags.js +22 -0
- package/lib/tags.js.map +1 -0
- package/lib/test.d.ts +14 -0
- package/lib/test.d.ts.map +1 -0
- package/lib/test.js +28 -0
- package/lib/test.js.map +1 -0
- package/lib/tsconfig.test.tsbuildinfo +1 -0
- package/lib/type.d.ts +3 -0
- package/lib/type.d.ts.map +1 -0
- package/lib/type.js +3 -0
- package/lib/type.js.map +1 -0
- package/package.json +115 -3
- package/src/app.ts +8 -7
- package/src/apply.ts +251 -93
- package/src/aws/account.ts +37 -0
- package/src/aws/arn.ts +1 -0
- package/src/aws/assets.ts +8 -0
- package/src/aws/bundle.ts +5 -0
- package/src/aws/client.ts +47 -0
- package/src/aws/credentials.ts +409 -0
- package/src/aws/dynamodb/attribute-value.ts +240 -0
- package/src/aws/dynamodb/client.ts +20 -0
- package/src/aws/dynamodb/expr.ts +90 -0
- package/src/aws/dynamodb/index.ts +12 -0
- package/src/aws/dynamodb/projection.ts +159 -0
- package/src/aws/dynamodb/secondary-index.ts +45 -0
- package/src/aws/dynamodb/table.get-item.ts +177 -0
- package/src/aws/dynamodb/table.provider.ts +280 -0
- package/src/aws/dynamodb/table.ts +156 -0
- package/src/aws/ec2/client.ts +20 -0
- package/src/aws/ec2/index.ts +3 -0
- package/src/aws/ec2/vpc.provider.ts +285 -0
- package/src/aws/ec2/vpc.ts +152 -0
- package/src/aws/iam.ts +30 -0
- package/src/aws/index.ts +54 -0
- package/src/aws/lambda/client.ts +14 -0
- package/src/aws/lambda/consume.ts +63 -0
- package/src/aws/lambda/function.handler.ts +30 -0
- package/src/aws/lambda/function.invoke.ts +40 -0
- package/src/aws/lambda/function.provider.ts +655 -0
- package/src/aws/lambda/function.ts +45 -0
- package/src/aws/lambda/index.ts +9 -0
- package/src/aws/lambda/serve.ts +29 -0
- package/src/aws/parse-ini.ts +80 -0
- package/src/aws/profile.ts +6 -0
- package/src/aws/region.ts +37 -0
- package/src/aws/s3.ts +10 -0
- package/src/aws/sqs/client.ts +20 -0
- package/src/aws/sqs/index.ts +6 -0
- package/src/aws/sqs/queue.consume.ts +13 -0
- package/src/aws/sqs/queue.event-source.ts +253 -0
- package/src/aws/sqs/queue.provider.ts +94 -0
- package/src/aws/sqs/queue.send-message.ts +51 -0
- package/src/aws/sqs/queue.ts +86 -0
- package/src/aws/sts.ts +13 -0
- package/src/aws/zip.ts +17 -0
- package/src/binding.ts +121 -25
- package/src/capability.ts +44 -0
- package/src/cli/approve.tsx +30 -0
- package/src/cli/clack.ts +22 -0
- package/src/cli/components/ApprovePlan.tsx +44 -0
- package/src/cli/components/Plan.tsx +154 -0
- package/src/cli/components/PlanProgress.tsx +206 -0
- package/src/cli/index.ts +6 -0
- package/src/cli/main.ts +0 -0
- package/src/cli/plan.ts +16 -0
- package/src/cli/progress.tsx +46 -0
- package/src/cli/spinner.ts +14 -0
- package/src/cloudflare/api.ts +152 -0
- package/src/cloudflare/context.ts +49 -0
- package/src/cloudflare/index.ts +6 -0
- package/src/cloudflare/kv/index.ts +3 -0
- package/src/cloudflare/kv/namespace.binding.ts +25 -0
- package/src/cloudflare/kv/namespace.client.ts +70 -0
- package/src/cloudflare/kv/namespace.provider.ts +99 -0
- package/src/cloudflare/kv/namespace.ts +29 -0
- package/src/cloudflare/live.ts +38 -0
- package/src/cloudflare/r2/bucket.binding.ts +27 -0
- package/src/cloudflare/r2/bucket.client.ts +22 -0
- package/src/cloudflare/r2/bucket.del.ts +11 -0
- package/src/cloudflare/r2/bucket.get.ts +13 -0
- package/src/cloudflare/r2/bucket.head.ts +11 -0
- package/src/cloudflare/r2/bucket.list.ts +12 -0
- package/src/cloudflare/r2/bucket.multipart.ts +55 -0
- package/src/cloudflare/r2/bucket.provider.ts +83 -0
- package/src/cloudflare/r2/bucket.put.ts +17 -0
- package/src/cloudflare/r2/bucket.ts +38 -0
- package/src/cloudflare/r2/index.ts +9 -0
- package/src/cloudflare/stream.ts +21 -0
- package/src/cloudflare/worker/assets.fetch.ts +27 -0
- package/src/cloudflare/worker/assets.provider.ts +249 -0
- package/src/cloudflare/worker/index.ts +6 -0
- package/src/cloudflare/worker/worker.handler.ts +39 -0
- package/src/cloudflare/worker/worker.provider.ts +246 -0
- package/src/cloudflare/worker/worker.serve.ts +19 -0
- package/src/cloudflare/worker/worker.ts +76 -0
- package/src/destroy.ts +6 -3
- package/src/dot-alchemy.ts +3 -2
- package/src/esbuild.ts +98 -0
- package/src/index.ts +5 -0
- package/src/plan.ts +233 -120
- package/src/policy.ts +55 -2
- package/src/provider.ts +2 -2
- package/src/resource.ts +3 -2
- package/src/runtime.ts +1 -1
- package/src/schema.ts +102 -0
- package/src/sha256.ts +23 -0
- package/src/state.ts +3 -2
- package/src/tags.ts +38 -0
- package/src/test.ts +71 -0
- package/src/type.ts +2 -0
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Schedule from "effect/Schedule";
|
|
3
|
+
|
|
4
|
+
import { App, type ProviderService } from "alchemy-effect";
|
|
5
|
+
import type { ScopedPlanStatusSession } from "../../apply.ts";
|
|
6
|
+
import { createTagger, createTagsList } from "../../tags.ts";
|
|
7
|
+
import { Account } from "../account.ts";
|
|
8
|
+
import { Region } from "../region.ts";
|
|
9
|
+
import { EC2Client } from "./client.ts";
|
|
10
|
+
import { Vpc, type VpcAttrs, type VpcProps } from "./vpc.ts";
|
|
11
|
+
|
|
12
|
+
import type { EC2 } from "itty-aws/ec2";
|
|
13
|
+
|
|
14
|
+
export const vpcProvider = () =>
|
|
15
|
+
Vpc.provider.effect(
|
|
16
|
+
Effect.gen(function* () {
|
|
17
|
+
const ec2 = yield* EC2Client;
|
|
18
|
+
const app = yield* App;
|
|
19
|
+
const region = yield* Region;
|
|
20
|
+
const accountId = yield* Account;
|
|
21
|
+
const tagged = yield* createTagger();
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
diff: Effect.fn(function* ({ id, news, olds }) {
|
|
25
|
+
// 1. CIDR block changes
|
|
26
|
+
if (olds.cidrBlock !== news.cidrBlock) {
|
|
27
|
+
return { action: "replace" } as const;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// 2. Instance tenancy changes
|
|
31
|
+
if (olds.instanceTenancy !== news.instanceTenancy) {
|
|
32
|
+
return { action: "replace" } as const;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// 3. IPAM pool changes
|
|
36
|
+
if (olds.ipv4IpamPoolId !== news.ipv4IpamPoolId) {
|
|
37
|
+
return { action: "replace" } as const;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (olds.ipv6IpamPoolId !== news.ipv6IpamPoolId) {
|
|
41
|
+
return { action: "replace" } as const;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// 4. IPv6 CIDR block changes
|
|
45
|
+
if (olds.ipv6CidrBlock !== news.ipv6CidrBlock) {
|
|
46
|
+
return { action: "replace" } as const;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// 5. IPv6 pool changes
|
|
50
|
+
if (olds.ipv6Pool !== news.ipv6Pool) {
|
|
51
|
+
return { action: "replace" } as const;
|
|
52
|
+
}
|
|
53
|
+
}),
|
|
54
|
+
|
|
55
|
+
create: Effect.fn(function* ({ id, news, session }) {
|
|
56
|
+
// 1. Prepare tags
|
|
57
|
+
const alchemyTags = tagged(id);
|
|
58
|
+
const userTags = news.tags ?? {};
|
|
59
|
+
const allTags = { ...alchemyTags, ...userTags };
|
|
60
|
+
|
|
61
|
+
// 2. Call CreateVpc
|
|
62
|
+
const createResult = yield* ec2.createVpc({
|
|
63
|
+
// TODO(sam): add all properties
|
|
64
|
+
AmazonProvidedIpv6CidrBlock: news.amazonProvidedIpv6CidrBlock,
|
|
65
|
+
InstanceTenancy: news.instanceTenancy,
|
|
66
|
+
CidrBlock: news.cidrBlock,
|
|
67
|
+
Ipv4IpamPoolId: news.ipv4IpamPoolId,
|
|
68
|
+
Ipv4NetmaskLength: news.ipv4NetmaskLength,
|
|
69
|
+
Ipv6Pool: news.ipv6Pool,
|
|
70
|
+
Ipv6CidrBlock: news.ipv6CidrBlock,
|
|
71
|
+
Ipv6IpamPoolId: news.ipv6IpamPoolId,
|
|
72
|
+
Ipv6NetmaskLength: news.ipv6NetmaskLength,
|
|
73
|
+
Ipv6CidrBlockNetworkBorderGroup:
|
|
74
|
+
news.ipv6CidrBlockNetworkBorderGroup,
|
|
75
|
+
TagSpecifications: [
|
|
76
|
+
{
|
|
77
|
+
ResourceType: "vpc",
|
|
78
|
+
Tags: createTagsList(allTags),
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
DryRun: false,
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
const vpcId = createResult.Vpc!.VpcId!;
|
|
85
|
+
yield* session.note(`VPC created: ${vpcId}`);
|
|
86
|
+
|
|
87
|
+
// 3. Modify DNS attributes if specified (separate API calls)
|
|
88
|
+
yield* ec2.modifyVpcAttribute({
|
|
89
|
+
VpcId: vpcId,
|
|
90
|
+
EnableDnsSupport: { Value: news.enableDnsSupport ?? true },
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
if (news.enableDnsHostnames !== undefined) {
|
|
94
|
+
yield* ec2.modifyVpcAttribute({
|
|
95
|
+
VpcId: vpcId,
|
|
96
|
+
EnableDnsHostnames: { Value: news.enableDnsHostnames },
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// 4. Wait for VPC to be available
|
|
101
|
+
const vpc = yield* waitForVpcAvailable(ec2, vpcId, session);
|
|
102
|
+
|
|
103
|
+
// 6. Return attributes
|
|
104
|
+
return {
|
|
105
|
+
vpcId,
|
|
106
|
+
vpcArn:
|
|
107
|
+
`arn:aws:ec2:${region}:${accountId}:vpc/${vpcId}` as VpcAttrs<VpcProps>["vpcArn"],
|
|
108
|
+
cidrBlock: vpc.CidrBlock!,
|
|
109
|
+
dhcpOptionsId: vpc.DhcpOptionsId!,
|
|
110
|
+
state: vpc.State!,
|
|
111
|
+
isDefault: vpc.IsDefault ?? false,
|
|
112
|
+
ownerId: vpc.OwnerId,
|
|
113
|
+
cidrBlockAssociationSet: vpc.CidrBlockAssociationSet?.map(
|
|
114
|
+
(assoc) => ({
|
|
115
|
+
associationId: assoc.AssociationId!,
|
|
116
|
+
cidrBlock: assoc.CidrBlock!,
|
|
117
|
+
cidrBlockState: {
|
|
118
|
+
state: assoc.CidrBlockState!.State!,
|
|
119
|
+
statusMessage: assoc.CidrBlockState!.StatusMessage,
|
|
120
|
+
},
|
|
121
|
+
}),
|
|
122
|
+
),
|
|
123
|
+
ipv6CidrBlockAssociationSet: vpc.Ipv6CidrBlockAssociationSet?.map(
|
|
124
|
+
(assoc) => ({
|
|
125
|
+
associationId: assoc.AssociationId!,
|
|
126
|
+
ipv6CidrBlock: assoc.Ipv6CidrBlock!,
|
|
127
|
+
ipv6CidrBlockState: {
|
|
128
|
+
state: assoc.Ipv6CidrBlockState!.State!,
|
|
129
|
+
statusMessage: assoc.Ipv6CidrBlockState!.StatusMessage,
|
|
130
|
+
},
|
|
131
|
+
networkBorderGroup: assoc.NetworkBorderGroup,
|
|
132
|
+
ipv6Pool: assoc.Ipv6Pool,
|
|
133
|
+
}),
|
|
134
|
+
),
|
|
135
|
+
} satisfies VpcAttrs<VpcProps>;
|
|
136
|
+
}),
|
|
137
|
+
|
|
138
|
+
update: Effect.fn(function* ({ news, olds, output, session }) {
|
|
139
|
+
const vpcId = output.vpcId;
|
|
140
|
+
|
|
141
|
+
// Only DNS and metrics settings can be updated
|
|
142
|
+
// Everything else requires replacement (handled by diff)
|
|
143
|
+
|
|
144
|
+
if (news.enableDnsSupport !== olds.enableDnsSupport) {
|
|
145
|
+
yield* ec2.modifyVpcAttribute({
|
|
146
|
+
VpcId: vpcId,
|
|
147
|
+
EnableDnsSupport: { Value: news.enableDnsSupport ?? true },
|
|
148
|
+
});
|
|
149
|
+
yield* session.note("Updated DNS support");
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (news.enableDnsHostnames !== olds.enableDnsHostnames) {
|
|
153
|
+
yield* ec2.modifyVpcAttribute({
|
|
154
|
+
VpcId: vpcId,
|
|
155
|
+
EnableDnsHostnames: { Value: news.enableDnsHostnames ?? false },
|
|
156
|
+
});
|
|
157
|
+
yield* session.note("Updated DNS hostnames");
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Note: Tag updates would go here if we support user tag changes
|
|
161
|
+
|
|
162
|
+
return output; // VPC attributes don't change from these updates
|
|
163
|
+
}),
|
|
164
|
+
|
|
165
|
+
delete: Effect.fn(function* ({ output, session }) {
|
|
166
|
+
const vpcId = output.vpcId;
|
|
167
|
+
|
|
168
|
+
yield* session.note(`Deleting VPC: ${vpcId}`);
|
|
169
|
+
|
|
170
|
+
// 1. Attempt to delete VPC
|
|
171
|
+
yield* ec2
|
|
172
|
+
.deleteVpc({
|
|
173
|
+
VpcId: vpcId,
|
|
174
|
+
DryRun: false,
|
|
175
|
+
})
|
|
176
|
+
.pipe(
|
|
177
|
+
Effect.tapError(Effect.logDebug),
|
|
178
|
+
Effect.catchTag("InvalidVpcID.NotFound", () => Effect.void),
|
|
179
|
+
// Retry on dependency violations (resources still being deleted)
|
|
180
|
+
Effect.retry({
|
|
181
|
+
while: (e) => {
|
|
182
|
+
// DependencyViolation means there are still dependent resources
|
|
183
|
+
// This can happen if subnets/IGW are being deleted concurrently
|
|
184
|
+
return (
|
|
185
|
+
e._tag === "ValidationError" &&
|
|
186
|
+
e.message?.includes("DependencyViolation")
|
|
187
|
+
);
|
|
188
|
+
},
|
|
189
|
+
schedule: Schedule.exponential(1000, 1.5).pipe(
|
|
190
|
+
Schedule.intersect(Schedule.recurs(10)), // Try up to 10 times
|
|
191
|
+
Schedule.tapOutput(([, attempt]) =>
|
|
192
|
+
session.note(
|
|
193
|
+
`Waiting for dependencies to clear... (attempt ${attempt + 1})`,
|
|
194
|
+
),
|
|
195
|
+
),
|
|
196
|
+
),
|
|
197
|
+
}),
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
// 2. Wait for VPC to be fully deleted
|
|
201
|
+
yield* waitForVpcDeleted(ec2, vpcId, session);
|
|
202
|
+
|
|
203
|
+
yield* session.note(`VPC ${vpcId} deleted successfully`);
|
|
204
|
+
}),
|
|
205
|
+
} satisfies ProviderService<Vpc>;
|
|
206
|
+
}),
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Wait for VPC to be in available state
|
|
211
|
+
*/
|
|
212
|
+
const waitForVpcAvailable = (
|
|
213
|
+
ec2: EC2,
|
|
214
|
+
vpcId: string,
|
|
215
|
+
session?: ScopedPlanStatusSession,
|
|
216
|
+
) =>
|
|
217
|
+
Effect.retry(
|
|
218
|
+
Effect.gen(function* () {
|
|
219
|
+
const result = yield* ec2
|
|
220
|
+
.describeVpcs({ VpcIds: [vpcId] })
|
|
221
|
+
.pipe(
|
|
222
|
+
Effect.catchTag("InvalidVpcID.NotFound", () =>
|
|
223
|
+
Effect.succeed({ Vpcs: [] }),
|
|
224
|
+
),
|
|
225
|
+
);
|
|
226
|
+
const vpc = result.Vpcs![0];
|
|
227
|
+
|
|
228
|
+
if (vpc.State === "available") {
|
|
229
|
+
return vpc;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Still pending, fail to trigger retry
|
|
233
|
+
return yield* Effect.fail(new Error("VPC not yet available"));
|
|
234
|
+
}),
|
|
235
|
+
{
|
|
236
|
+
schedule: Schedule.fixed(2000).pipe(
|
|
237
|
+
// Check every 2 seconds
|
|
238
|
+
Schedule.intersect(Schedule.recurs(30)), // Max 60 seconds
|
|
239
|
+
Schedule.tapOutput(([, attempt]) =>
|
|
240
|
+
session
|
|
241
|
+
? session.note(
|
|
242
|
+
`Waiting for VPC to be available... (${(attempt + 1) * 2}s)`,
|
|
243
|
+
)
|
|
244
|
+
: Effect.void,
|
|
245
|
+
),
|
|
246
|
+
),
|
|
247
|
+
},
|
|
248
|
+
);
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Wait for VPC to be deleted
|
|
252
|
+
*/
|
|
253
|
+
const waitForVpcDeleted = (
|
|
254
|
+
ec2: EC2,
|
|
255
|
+
vpcId: string,
|
|
256
|
+
session: ScopedPlanStatusSession,
|
|
257
|
+
) =>
|
|
258
|
+
Effect.gen(function* () {
|
|
259
|
+
yield* Effect.retry(
|
|
260
|
+
Effect.gen(function* () {
|
|
261
|
+
const result = yield* ec2.describeVpcs({ VpcIds: [vpcId] }).pipe(
|
|
262
|
+
Effect.tapError(Effect.logDebug),
|
|
263
|
+
Effect.catchTag("InvalidVpcID.NotFound", () =>
|
|
264
|
+
Effect.succeed({ Vpcs: [] }),
|
|
265
|
+
),
|
|
266
|
+
);
|
|
267
|
+
|
|
268
|
+
if (!result.Vpcs || result.Vpcs.length === 0) {
|
|
269
|
+
return; // Successfully deleted
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Still exists, fail to trigger retry
|
|
273
|
+
return yield* Effect.fail(new Error("VPC still exists"));
|
|
274
|
+
}),
|
|
275
|
+
{
|
|
276
|
+
schedule: Schedule.fixed(2000).pipe(
|
|
277
|
+
// Check every 2 seconds
|
|
278
|
+
Schedule.intersect(Schedule.recurs(15)), // Max 30 seconds
|
|
279
|
+
Schedule.tapOutput(([, attempt]) =>
|
|
280
|
+
session.note(`Waiting for VPC deletion... (${(attempt + 1) * 2}s)`),
|
|
281
|
+
),
|
|
282
|
+
),
|
|
283
|
+
},
|
|
284
|
+
);
|
|
285
|
+
});
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import type * as EC2 from "itty-aws/ec2";
|
|
2
|
+
import { Resource } from "../../resource.ts";
|
|
3
|
+
import type { AccountID } from "../account.ts";
|
|
4
|
+
import type { RegionID } from "../region.ts";
|
|
5
|
+
|
|
6
|
+
export const Vpc = Resource<{
|
|
7
|
+
<const ID extends string, const Props extends VpcProps>(
|
|
8
|
+
id: ID,
|
|
9
|
+
props: Props,
|
|
10
|
+
): Vpc<ID, Props>;
|
|
11
|
+
}>("AWS.EC2.VPC");
|
|
12
|
+
|
|
13
|
+
export interface Vpc<
|
|
14
|
+
ID extends string = string,
|
|
15
|
+
Props extends VpcProps = VpcProps,
|
|
16
|
+
> extends Resource<"AWS.EC2.VPC", ID, Props, VpcAttrs<Props>> {}
|
|
17
|
+
|
|
18
|
+
export interface VpcProps {
|
|
19
|
+
/**
|
|
20
|
+
* The IPv4 network range for the VPC, in CIDR notation.
|
|
21
|
+
* Required unless using IPAM.
|
|
22
|
+
* @example "10.0.0.0/16"
|
|
23
|
+
*/
|
|
24
|
+
cidrBlock?: string;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* The ID of an IPv4 IPAM pool you want to use for allocating this VPC's CIDR.
|
|
28
|
+
*/
|
|
29
|
+
ipv4IpamPoolId?: string;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The netmask length of the IPv4 CIDR you want to allocate to this VPC from an IPAM pool.
|
|
33
|
+
*/
|
|
34
|
+
ipv4NetmaskLength?: number;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* The ID of an IPv6 IPAM pool which will be used to allocate this VPC an IPv6 CIDR.
|
|
38
|
+
*/
|
|
39
|
+
ipv6IpamPoolId?: string;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The netmask length of the IPv6 CIDR you want to allocate to this VPC from an IPAM pool.
|
|
43
|
+
*/
|
|
44
|
+
ipv6NetmaskLength?: number;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Requests an Amazon-provided IPv6 CIDR block with a /56 prefix length for the VPC.
|
|
48
|
+
*/
|
|
49
|
+
ipv6CidrBlock?: string;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The ID of an IPv6 address pool from which to allocate the IPv6 CIDR block.
|
|
53
|
+
*/
|
|
54
|
+
ipv6Pool?: string;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The Availability Zone or Local Zone Group name for the IPv6 CIDR block.
|
|
58
|
+
*/
|
|
59
|
+
ipv6CidrBlockNetworkBorderGroup?: string;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* The tenancy options for instances launched into the VPC.
|
|
63
|
+
* @default "default"
|
|
64
|
+
*/
|
|
65
|
+
instanceTenancy?: EC2.Tenancy;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Whether DNS resolution is supported for the VPC.
|
|
69
|
+
* @default true
|
|
70
|
+
*/
|
|
71
|
+
enableDnsSupport?: boolean;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Whether instances launched in the VPC get DNS hostnames.
|
|
75
|
+
* @default true
|
|
76
|
+
*/
|
|
77
|
+
enableDnsHostnames?: boolean;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Requests an Amazon-provided IPv6 CIDR block with a /56 prefix length for the VPC.
|
|
81
|
+
*/
|
|
82
|
+
amazonProvidedIpv6CidrBlock?: boolean;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Tags to assign to the VPC.
|
|
86
|
+
* These will be merged with alchemy auto-tags (alchemy::app, alchemy::stage, alchemy::id).
|
|
87
|
+
*/
|
|
88
|
+
tags?: Record<string, string>;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface VpcAttrs<Props extends VpcProps> {
|
|
92
|
+
/**
|
|
93
|
+
* The ID of the VPC.
|
|
94
|
+
*/
|
|
95
|
+
vpcId: string;
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* The Amazon Resource Name (ARN) of the VPC.
|
|
99
|
+
*/
|
|
100
|
+
vpcArn: `arn:aws:ec2:${RegionID}:${AccountID}:vpc/${this["vpcId"]}`;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* The primary IPv4 CIDR block for the VPC.
|
|
104
|
+
*/
|
|
105
|
+
cidrBlock: string;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* The ID of the set of DHCP options associated with the VPC.
|
|
109
|
+
*/
|
|
110
|
+
dhcpOptionsId: string;
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* The current state of the VPC.
|
|
114
|
+
*/
|
|
115
|
+
state: EC2.VpcState;
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Whether the VPC is the default VPC.
|
|
119
|
+
*/
|
|
120
|
+
isDefault: boolean;
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* The ID of the AWS account that owns the VPC.
|
|
124
|
+
*/
|
|
125
|
+
ownerId?: string;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Information about the IPv4 CIDR blocks associated with the VPC.
|
|
129
|
+
*/
|
|
130
|
+
cidrBlockAssociationSet?: Array<{
|
|
131
|
+
associationId: string;
|
|
132
|
+
cidrBlock: string;
|
|
133
|
+
cidrBlockState: {
|
|
134
|
+
state: EC2.VpcCidrBlockStateCode;
|
|
135
|
+
statusMessage?: string;
|
|
136
|
+
};
|
|
137
|
+
}>;
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Information about the IPv6 CIDR blocks associated with the VPC.
|
|
141
|
+
*/
|
|
142
|
+
ipv6CidrBlockAssociationSet?: Array<{
|
|
143
|
+
associationId: string;
|
|
144
|
+
ipv6CidrBlock: string;
|
|
145
|
+
ipv6CidrBlockState: {
|
|
146
|
+
state: EC2.VpcCidrBlockStateCode;
|
|
147
|
+
statusMessage?: string;
|
|
148
|
+
};
|
|
149
|
+
networkBorderGroup?: string;
|
|
150
|
+
ipv6Pool?: string;
|
|
151
|
+
}>;
|
|
152
|
+
}
|
package/src/aws/iam.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as Context from "effect/Context";
|
|
2
|
+
import { IAM } from "itty-aws/iam";
|
|
3
|
+
import { createAWSServiceClientLayer } from "./client.ts";
|
|
4
|
+
|
|
5
|
+
export class IAMClient extends Context.Tag("AWS::IAM::Client")<
|
|
6
|
+
IAMClient,
|
|
7
|
+
IAM
|
|
8
|
+
>() {}
|
|
9
|
+
|
|
10
|
+
export const client = createAWSServiceClientLayer<typeof IAMClient, IAM>(
|
|
11
|
+
IAMClient,
|
|
12
|
+
IAM,
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
export interface PolicyDocument {
|
|
16
|
+
Version: "2012-10-17";
|
|
17
|
+
Statement: PolicyStatement[];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface PolicyStatement {
|
|
21
|
+
Effect: "Allow" | "Deny";
|
|
22
|
+
Sid?: string;
|
|
23
|
+
Action: string[];
|
|
24
|
+
Resource: string | string[];
|
|
25
|
+
Condition?: Record<string, Record<string, string | string[]>>;
|
|
26
|
+
Principal?: Record<string, string | string[]>;
|
|
27
|
+
NotPrincipal?: Record<string, string | string[]>;
|
|
28
|
+
NotAction?: string[];
|
|
29
|
+
NotResource?: string[];
|
|
30
|
+
}
|
package/src/aws/index.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import * as Layer from "effect/Layer";
|
|
2
|
+
import * as ESBuild from "../esbuild.ts";
|
|
3
|
+
import * as Account from "./account.ts";
|
|
4
|
+
import * as Credentials from "./credentials.ts";
|
|
5
|
+
import * as DynamoDB from "./dynamodb/index.ts";
|
|
6
|
+
import * as EC2 from "./ec2/index.ts";
|
|
7
|
+
import * as IAM from "./iam.ts";
|
|
8
|
+
import * as Lambda from "./lambda/index.ts";
|
|
9
|
+
import * as Region from "./region.ts";
|
|
10
|
+
import * as S3 from "./s3.ts";
|
|
11
|
+
import * as SQS from "./sqs/index.ts";
|
|
12
|
+
import * as STS from "./sts.ts";
|
|
13
|
+
// TODO(sam): should this be named?
|
|
14
|
+
export * from "./profile.ts";
|
|
15
|
+
|
|
16
|
+
export const providers = Layer.mergeAll(
|
|
17
|
+
Layer.provide(
|
|
18
|
+
Layer.provideMerge(Lambda.functionProvider(), ESBuild.layer()),
|
|
19
|
+
Lambda.client(),
|
|
20
|
+
),
|
|
21
|
+
Layer.provide(SQS.queueProvider(), SQS.client()),
|
|
22
|
+
Layer.provide(DynamoDB.tableProvider(), DynamoDB.client()),
|
|
23
|
+
Layer.provide(EC2.vpcProvider(), EC2.client()),
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
export const bindings = Layer.mergeAll(
|
|
27
|
+
//
|
|
28
|
+
SQS.sendMessageFromLambdaFunction(),
|
|
29
|
+
SQS.queueEventSourceProvider(),
|
|
30
|
+
DynamoDB.getItemFromLambdaFunction(),
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
export const clients = Layer.mergeAll(
|
|
34
|
+
STS.client(),
|
|
35
|
+
IAM.client(),
|
|
36
|
+
S3.client(),
|
|
37
|
+
SQS.client(),
|
|
38
|
+
Lambda.client(),
|
|
39
|
+
DynamoDB.client(),
|
|
40
|
+
EC2.client(),
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
export const defaultProviders = providers.pipe(
|
|
44
|
+
Layer.provideMerge(bindings),
|
|
45
|
+
Layer.provideMerge(Account.fromIdentity()),
|
|
46
|
+
Layer.provideMerge(clients),
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
export const live = defaultProviders.pipe(
|
|
50
|
+
Layer.provide(Region.fromEnv()),
|
|
51
|
+
Layer.provide(Credentials.fromSSO()),
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
export default live;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as Context from "effect/Context";
|
|
2
|
+
|
|
3
|
+
import { Lambda } from "itty-aws/lambda";
|
|
4
|
+
import { createAWSServiceClientLayer } from "../client.ts";
|
|
5
|
+
|
|
6
|
+
export class LambdaClient extends Context.Tag("AWS.Lambda.Client")<
|
|
7
|
+
LambdaClient,
|
|
8
|
+
Lambda
|
|
9
|
+
>() {}
|
|
10
|
+
|
|
11
|
+
export const client = createAWSServiceClientLayer<typeof LambdaClient, Lambda>(
|
|
12
|
+
LambdaClient,
|
|
13
|
+
Lambda,
|
|
14
|
+
);
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { From } from "alchemy-effect";
|
|
2
|
+
import { declare } from "alchemy-effect";
|
|
3
|
+
import type {
|
|
4
|
+
Context as LambdaContext,
|
|
5
|
+
SQSBatchResponse,
|
|
6
|
+
SQSEvent,
|
|
7
|
+
} from "aws-lambda";
|
|
8
|
+
import * as Effect from "effect/Effect";
|
|
9
|
+
import * as S from "effect/Schema";
|
|
10
|
+
import * as SQS from "../sqs/index.ts";
|
|
11
|
+
import * as Lambda from "./function.ts";
|
|
12
|
+
|
|
13
|
+
export const consume =
|
|
14
|
+
<Q extends SQS.Queue, ID extends string, Req>(
|
|
15
|
+
id: ID,
|
|
16
|
+
{
|
|
17
|
+
queue,
|
|
18
|
+
handle,
|
|
19
|
+
}: {
|
|
20
|
+
queue: Q;
|
|
21
|
+
handle: (
|
|
22
|
+
event: SQS.QueueEvent<Q["props"]["schema"]["Type"]>,
|
|
23
|
+
context: LambdaContext,
|
|
24
|
+
) => Effect.Effect<SQSBatchResponse | void, never, Req>;
|
|
25
|
+
},
|
|
26
|
+
) =>
|
|
27
|
+
<const Props extends Lambda.FunctionProps<Req>>({
|
|
28
|
+
bindings,
|
|
29
|
+
...props
|
|
30
|
+
}: Props) =>
|
|
31
|
+
Lambda.Function(id, {
|
|
32
|
+
handle: Effect.fn(function* (event: SQSEvent, context: LambdaContext) {
|
|
33
|
+
yield* declare<SQS.Consume<From<Q>>>();
|
|
34
|
+
const records = yield* Effect.all(
|
|
35
|
+
event.Records.map(
|
|
36
|
+
Effect.fn(function* (record) {
|
|
37
|
+
return {
|
|
38
|
+
...record,
|
|
39
|
+
body: yield* S.validate(queue.props.schema)(record.body).pipe(
|
|
40
|
+
Effect.catchAll(() => Effect.void),
|
|
41
|
+
),
|
|
42
|
+
};
|
|
43
|
+
}),
|
|
44
|
+
),
|
|
45
|
+
);
|
|
46
|
+
const response = yield* handle(
|
|
47
|
+
{
|
|
48
|
+
Records: records.filter((record) => record.body !== undefined),
|
|
49
|
+
},
|
|
50
|
+
context,
|
|
51
|
+
);
|
|
52
|
+
return {
|
|
53
|
+
batchItemFailures: [
|
|
54
|
+
...(response?.batchItemFailures ?? []),
|
|
55
|
+
...records
|
|
56
|
+
.filter((record) => record.body === undefined)
|
|
57
|
+
.map((failed) => ({
|
|
58
|
+
itemIdentifier: failed.messageId,
|
|
59
|
+
})),
|
|
60
|
+
],
|
|
61
|
+
} satisfies SQSBatchResponse;
|
|
62
|
+
}),
|
|
63
|
+
})({ ...props, bindings: bindings.and(SQS.QueueEventSource(queue)) });
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Capability } from "alchemy-effect";
|
|
2
|
+
import type { Context as LambdaContext } from "aws-lambda";
|
|
3
|
+
import * as Effect from "effect/Effect";
|
|
4
|
+
|
|
5
|
+
type Handler = (
|
|
6
|
+
event: any,
|
|
7
|
+
context: LambdaContext,
|
|
8
|
+
) => Effect.Effect<any, any, never>;
|
|
9
|
+
|
|
10
|
+
type HandlerEffect<Req = Capability> = Effect.Effect<Handler, any, Req>;
|
|
11
|
+
|
|
12
|
+
const memo = Symbol.for("alchemy::memo");
|
|
13
|
+
|
|
14
|
+
// TODO(sam): is there a better way to lazily evaluate the Effect and cache the result?
|
|
15
|
+
const resolveHandler = async (
|
|
16
|
+
effect: HandlerEffect & {
|
|
17
|
+
[memo]?: Handler;
|
|
18
|
+
},
|
|
19
|
+
) =>
|
|
20
|
+
(effect[memo] ??= await Effect.runPromise(
|
|
21
|
+
// safe to cast away the Capability requirements since they are phantoms
|
|
22
|
+
effect as HandlerEffect<never>,
|
|
23
|
+
));
|
|
24
|
+
|
|
25
|
+
export const toHandler =
|
|
26
|
+
<H extends Handler>(effect: Effect.Effect<H, any, Capability>) =>
|
|
27
|
+
async (event: any, context: LambdaContext) =>
|
|
28
|
+
Effect.runPromise(
|
|
29
|
+
(await resolveHandler(effect))(event, context),
|
|
30
|
+
) as Promise<Effect.Effect.Success<ReturnType<H>>>;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
|
|
3
|
+
import { $, Binding, type Capability, declare, toEnvKey } from "alchemy-effect";
|
|
4
|
+
import { LambdaClient } from "./client.ts";
|
|
5
|
+
import { Function } from "./function.ts";
|
|
6
|
+
|
|
7
|
+
export interface InvokeFunction<Resource = unknown>
|
|
8
|
+
extends Capability<"AWS.Lambda.InvokeFunction", Resource> {}
|
|
9
|
+
|
|
10
|
+
export const InvokeFunction = Binding<
|
|
11
|
+
<F extends Function>(func: F) => Binding<Function, InvokeFunction<$<F>>>
|
|
12
|
+
>(Function, "AWS.Lambda.InvokeFunction");
|
|
13
|
+
|
|
14
|
+
export const invoke = <F extends Function>(func: F, input: any) =>
|
|
15
|
+
Effect.gen(function* () {
|
|
16
|
+
const lambda = yield* LambdaClient;
|
|
17
|
+
const functionArn = process.env[`${func.id}-functionArn`]!;
|
|
18
|
+
yield* declare<InvokeFunction<F>>();
|
|
19
|
+
return yield* lambda.invoke({
|
|
20
|
+
FunctionName: functionArn,
|
|
21
|
+
InvocationType: "RequestResponse",
|
|
22
|
+
Payload: JSON.stringify(input),
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export const invokeFunctionFromLambda = InvokeFunction.provider.succeed({
|
|
27
|
+
attach: ({ source: func }) => ({
|
|
28
|
+
env: {
|
|
29
|
+
[toEnvKey(func.id, "FUNCTION_ARN")]: func.attr.functionArn,
|
|
30
|
+
},
|
|
31
|
+
policyStatements: [
|
|
32
|
+
{
|
|
33
|
+
Sid: "AWS.Lambda.InvokeFunction",
|
|
34
|
+
Effect: "Allow",
|
|
35
|
+
Action: ["lambda:InvokeFunction"],
|
|
36
|
+
Resource: [func.attr.functionArn],
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
}),
|
|
40
|
+
});
|