alchemy-effect 0.1.0 → 0.3.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 +55038 -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 +7 -15
- package/lib/app.d.ts.map +1 -1
- package/lib/app.js +1 -20
- package/lib/app.js.map +1 -1
- package/lib/apply.d.ts +15 -19
- package/lib/apply.d.ts.map +1 -1
- package/lib/apply.js +173 -82
- 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 +13 -3
- package/lib/aws/account.d.ts.map +1 -1
- package/lib/aws/account.js +19 -4
- package/lib/aws/account.js.map +1 -1
- package/lib/aws/arn.d.ts +1 -5
- package/lib/aws/arn.d.ts.map +1 -1
- package/lib/aws/client.d.ts.map +1 -1
- package/lib/aws/client.js +8 -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 +11 -1
- 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/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/{sqs/queue.client.js → dynamodb/client.js} +6 -6
- 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 +10 -0
- package/lib/aws/dynamodb/index.d.ts.map +1 -0
- package/lib/aws/dynamodb/index.js +9 -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 +26 -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 +59 -0
- package/lib/aws/dynamodb/table.d.ts.map +1 -0
- package/lib/aws/dynamodb/table.get-item.d.ts +57 -0
- package/lib/aws/dynamodb/table.get-item.d.ts.map +1 -0
- package/lib/aws/dynamodb/table.get-item.js +77 -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 +7 -0
- package/lib/aws/dynamodb/table.provider.d.ts.map +1 -0
- package/lib/aws/dynamodb/table.provider.js +187 -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 +7 -0
- package/lib/aws/ec2/index.d.ts.map +1 -0
- package/lib/aws/ec2/index.js +7 -0
- package/lib/aws/ec2/index.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 +135 -0
- package/lib/aws/ec2/vpc.d.ts.map +1 -0
- package/lib/aws/ec2/vpc.js +4 -0
- package/lib/aws/ec2/vpc.js.map +1 -0
- package/lib/aws/ec2/vpc.provider.d.ts +6 -0
- package/lib/aws/ec2/vpc.provider.d.ts.map +1 -0
- package/lib/aws/ec2/vpc.provider.js +183 -0
- package/lib/aws/ec2/vpc.provider.js.map +1 -0
- package/lib/aws/index.d.ts +23 -16
- package/lib/aws/index.d.ts.map +1 -1
- package/lib/aws/index.js +10 -18
- package/lib/aws/index.js.map +1 -1
- 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 +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 +18 -15
- 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 +7 -5
- package/lib/aws/lambda/function.invoke.d.ts.map +1 -1
- package/lib/aws/lambda/function.invoke.js +5 -3
- 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 +6 -5
- package/lib/aws/lambda/function.provider.d.ts.map +1 -1
- package/lib/aws/lambda/function.provider.js +150 -58
- package/lib/aws/lambda/function.provider.js.map +1 -1
- package/lib/aws/lambda/index.d.ts +2 -2
- package/lib/aws/lambda/index.d.ts.map +1 -1
- package/lib/aws/lambda/index.js +2 -1
- 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/lambda/serve.js.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 -1
- 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 +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 +3 -1
- package/lib/aws/sqs/index.d.ts.map +1 -1
- package/lib/aws/sqs/index.js +3 -1
- package/lib/aws/sqs/index.js.map +1 -1
- package/lib/aws/sqs/queue.consume.d.ts +1 -10
- package/lib/aws/sqs/queue.consume.d.ts.map +1 -1
- package/lib/aws/sqs/queue.consume.js +0 -19
- package/lib/aws/sqs/queue.consume.js.map +1 -1
- package/lib/aws/sqs/queue.d.ts +6 -12
- package/lib/aws/sqs/queue.d.ts.map +1 -1
- package/lib/aws/sqs/queue.event-source.d.ts +22 -0
- package/lib/aws/sqs/queue.event-source.d.ts.map +1 -0
- package/lib/aws/sqs/queue.event-source.js +130 -0
- package/lib/aws/sqs/queue.event-source.js.map +1 -0
- 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 +5 -4
- package/lib/aws/sqs/queue.provider.d.ts.map +1 -1
- package/lib/aws/sqs/queue.provider.js +6 -6
- package/lib/aws/sqs/queue.provider.js.map +1 -1
- package/lib/aws/sqs/queue.send-message.d.ts +8 -6
- package/lib/aws/sqs/queue.send-message.d.ts.map +1 -1
- package/lib/aws/sqs/queue.send-message.js +6 -4
- package/lib/aws/sqs/queue.send-message.js.map +1 -1
- package/lib/binding.d.ts +74 -26
- 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/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 +3 -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 +342 -213
- package/lib/cli/index.d.ts.map +1 -1
- package/lib/cli/index.js +26047 -11403
- 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 +31 -19
- package/lib/cloudflare/api.d.ts.map +1 -1
- package/lib/cloudflare/api.js +95 -29
- 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/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 +7 -4
- package/lib/cloudflare/index.d.ts.map +1 -1
- package/lib/cloudflare/index.js +7 -4
- package/lib/cloudflare/index.js.map +1 -1
- 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 +10 -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 +24 -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 +6 -0
- package/lib/cloudflare/kv/namespace.provider.d.ts.map +1 -0
- package/lib/cloudflare/kv/namespace.provider.js +81 -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 +15 -0
- package/lib/cloudflare/live.js.map +1 -0
- package/lib/cloudflare/r2/bucket.binding.d.ts +10 -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 +33 -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 +6 -0
- package/lib/cloudflare/r2/bucket.provider.d.ts.map +1 -0
- package/lib/cloudflare/r2/bucket.provider.js +67 -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 +9 -0
- package/lib/cloudflare/worker/assets.fetch.d.ts.map +1 -0
- package/lib/cloudflare/worker/assets.fetch.js +12 -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 +5 -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 +66 -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 +11 -0
- package/lib/cloudflare/worker/worker.provider.d.ts.map +1 -0
- package/lib/cloudflare/worker/worker.provider.js +194 -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/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 -3
- package/lib/destroy.d.ts.map +1 -1
- package/lib/destroy.js +2 -0
- package/lib/destroy.js.map +1 -1
- package/lib/diff.d.ts +16 -0
- package/lib/diff.d.ts.map +1 -0
- package/lib/diff.js +9 -0
- package/lib/diff.js.map +1 -0
- 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/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/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/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 +11 -5
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +11 -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/output.d.ts +143 -0
- package/lib/output.d.ts.map +1 -0
- package/lib/output.js +269 -0
- package/lib/output.js.map +1 -0
- package/lib/plan.d.ts +59 -29
- package/lib/plan.d.ts.map +1 -1
- package/lib/plan.js +347 -169
- package/lib/plan.js.map +1 -1
- package/lib/policy.d.ts +22 -5
- package/lib/policy.d.ts.map +1 -1
- package/lib/policy.js +10 -2
- package/lib/policy.js.map +1 -1
- package/lib/provider.d.ts +16 -18
- package/lib/provider.d.ts.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 -16
- 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 +8 -7
- package/lib/runtime.d.ts.map +1 -1
- package/lib/runtime.js.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/service.d.ts +9 -6
- package/lib/service.d.ts.map +1 -1
- package/lib/service.js.map +1 -1
- 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/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 +53 -11
- package/lib/state.d.ts.map +1 -1
- package/lib/state.js +33 -31
- 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 +35 -0
- package/lib/test.d.ts.map +1 -0
- package/lib/test.js +68 -0
- package/lib/test.js.map +1 -0
- package/lib/tsconfig.test.tsbuildinfo +1 -0
- package/lib/type.d.ts +6 -0
- package/lib/type.d.ts.map +1 -0
- package/lib/type.js +3 -0
- package/lib/type.js.map +1 -0
- 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 +58 -7
- package/src/$.ts +17 -0
- package/src/app.ts +9 -37
- package/src/apply.ts +435 -289
- package/src/assert-never.ts +18 -0
- package/src/aws/account.ts +29 -7
- package/src/aws/arn.ts +1 -7
- package/src/aws/client.ts +14 -1
- package/src/aws/config.ts +16 -0
- package/src/aws/credentials.ts +213 -177
- package/src/aws/dynamodb/attribute-value.ts +240 -0
- package/src/aws/{sqs/queue.client.ts → dynamodb/client.ts} +9 -9
- 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 +173 -0
- package/src/aws/dynamodb/table.provider.ts +276 -0
- package/src/aws/dynamodb/table.ts +101 -0
- package/src/aws/ec2/client.ts +20 -0
- package/src/aws/ec2/index.ts +7 -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 +269 -0
- package/src/aws/ec2/vpc.ts +163 -0
- package/src/aws/index.ts +50 -45
- package/src/aws/lambda/client.ts +14 -0
- package/src/aws/lambda/consume.ts +8 -8
- package/src/aws/lambda/function.handler.ts +1 -1
- package/src/aws/lambda/function.invoke.ts +8 -4
- package/src/aws/lambda/function.provider.ts +208 -109
- package/src/aws/lambda/function.ts +21 -12
- package/src/aws/lambda/index.ts +3 -4
- package/src/aws/lambda/serve.ts +1 -1
- package/src/aws/profile.ts +1 -4
- package/src/aws/region.ts +43 -2
- package/src/aws/sqs/client.ts +20 -0
- package/src/aws/sqs/index.ts +4 -1
- package/src/aws/sqs/queue.consume.ts +1 -34
- package/src/aws/sqs/queue.event-source.ts +227 -0
- package/src/aws/sqs/queue.provider.ts +14 -7
- package/src/aws/sqs/queue.send-message.ts +7 -10
- package/src/aws/sqs/queue.ts +9 -4
- package/src/binding.ts +130 -34
- package/src/capability.ts +44 -0
- package/src/cli/components/ApprovePlan.tsx +2 -2
- package/src/cli/components/Plan.tsx +6 -3
- 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 +147 -63
- package/src/cloudflare/config.ts +7 -0
- package/src/cloudflare/context.ts +49 -0
- package/src/cloudflare/index.ts +8 -4
- package/src/cloudflare/kv/index.ts +3 -0
- package/src/cloudflare/kv/namespace.binding.ts +27 -0
- package/src/cloudflare/kv/namespace.client.ts +70 -0
- package/src/cloudflare/kv/namespace.provider.ts +100 -0
- package/src/cloudflare/kv/namespace.ts +30 -0
- package/src/cloudflare/live.ts +32 -0
- package/src/cloudflare/r2/bucket.binding.ts +29 -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 +84 -0
- package/src/cloudflare/r2/bucket.put.ts +17 -0
- package/src/cloudflare/r2/bucket.ts +44 -0
- package/src/cloudflare/r2/index.ts +9 -0
- package/src/cloudflare/stream.ts +21 -0
- package/src/cloudflare/worker/assets.fetch.ts +29 -0
- package/src/cloudflare/worker/assets.provider.ts +249 -0
- package/src/cloudflare/worker/index.ts +4 -0
- package/src/cloudflare/worker/worker.handler.ts +39 -0
- package/src/cloudflare/worker/worker.provider.ts +249 -0
- package/src/cloudflare/worker/worker.serve.ts +22 -0
- package/src/cloudflare/worker/worker.ts +77 -0
- package/src/data.ts +18 -0
- package/src/destroy.ts +2 -3
- package/src/diff.ts +30 -0
- package/src/dot-alchemy.ts +3 -2
- package/src/env.ts +20 -32
- package/src/esbuild.ts +98 -0
- package/src/exports.ts +21 -0
- package/src/index.ts +12 -6
- package/src/input.ts +81 -0
- package/src/output.ts +518 -0
- package/src/plan.ts +544 -243
- package/src/policy.ts +58 -7
- package/src/provider.ts +27 -25
- package/src/ref.ts +48 -0
- package/src/resource.ts +23 -8
- package/src/runtime.ts +16 -9
- package/src/schema.ts +102 -0
- package/src/service.ts +11 -7
- package/src/sha256.ts +23 -0
- package/src/stack.ts +116 -0
- package/src/stage.ts +85 -0
- package/src/state.ts +141 -62
- package/src/tags.ts +38 -0
- package/src/test.ts +172 -0
- package/src/type.ts +6 -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/aws/lambda/function.client.d.ts +0 -8
- package/lib/aws/lambda/function.client.d.ts.map +0 -1
- package/lib/aws/lambda/function.client.js +0 -7
- package/lib/aws/lambda/function.client.js.map +0 -1
- package/lib/aws/sqs/queue.client.d.ts +0 -12
- package/lib/aws/sqs/queue.client.d.ts.map +0 -1
- package/lib/aws/sqs/queue.client.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 -29
- 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/lib/cloudflare/kv.d.ts +0 -29
- package/lib/cloudflare/kv.d.ts.map +0 -1
- package/lib/cloudflare/kv.js +0 -3
- package/lib/cloudflare/kv.js.map +0 -1
- package/lib/cloudflare/kv.provider.d.ts +0 -4
- package/lib/cloudflare/kv.provider.d.ts.map +0 -1
- package/lib/cloudflare/kv.provider.js +0 -39
- package/lib/cloudflare/kv.provider.js.map +0 -1
- package/lib/cloudflare/worker.d.ts +0 -33
- package/lib/cloudflare/worker.d.ts.map +0 -1
- package/lib/cloudflare/worker.js +0 -4
- package/lib/cloudflare/worker.js.map +0 -1
- package/src/approve.ts +0 -13
- package/src/aws/lambda/function.client.ts +0 -14
- 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 -45
- package/src/cli/spinner.ts +0 -14
- package/src/cloudflare/kv.provider.ts +0 -51
- package/src/cloudflare/kv.ts +0 -20
- package/src/cloudflare/worker.ts +0 -34
package/src/plan.ts
CHANGED
|
@@ -1,13 +1,22 @@
|
|
|
1
|
+
import * as Context from "effect/Context";
|
|
2
|
+
import { App } from "./app.ts";
|
|
1
3
|
import * as Data from "effect/Data";
|
|
2
4
|
import * as Effect from "effect/Effect";
|
|
3
|
-
import
|
|
5
|
+
import { omit } from "effect/Struct";
|
|
6
|
+
import type {
|
|
7
|
+
AnyBinding,
|
|
8
|
+
BindingDiffProps,
|
|
9
|
+
BindingService,
|
|
10
|
+
} from "./binding.ts";
|
|
4
11
|
import type { Capability } from "./capability.ts";
|
|
5
|
-
import type {
|
|
12
|
+
import type { Diff } from "./diff.ts";
|
|
13
|
+
import * as Output from "./output.ts";
|
|
6
14
|
import type { Instance } from "./policy.ts";
|
|
15
|
+
import type { Provider } from "./provider.ts";
|
|
7
16
|
import { type ProviderService } from "./provider.ts";
|
|
8
|
-
import type { Resource, ResourceTags } from "./resource.ts";
|
|
9
|
-
import { isService, type Service } from "./service.ts";
|
|
10
|
-
import { State, type ResourceState } from "./state.ts";
|
|
17
|
+
import type { AnyResource, Resource, ResourceTags } from "./resource.ts";
|
|
18
|
+
import { isService, type IService, type Service } from "./service.ts";
|
|
19
|
+
import { State, StateStoreError, type ResourceState } from "./state.ts";
|
|
11
20
|
|
|
12
21
|
export type PlanError = never;
|
|
13
22
|
|
|
@@ -26,23 +35,34 @@ export const isBindNode = (node: any): node is BindNode => {
|
|
|
26
35
|
*/
|
|
27
36
|
export type BindNode<B extends AnyBinding = AnyBinding> =
|
|
28
37
|
| Attach<B>
|
|
38
|
+
| Reattach<B>
|
|
29
39
|
| Detach<B>
|
|
30
40
|
| NoopBind<B>;
|
|
31
41
|
|
|
32
42
|
export type Attach<B extends AnyBinding = AnyBinding> = {
|
|
33
43
|
action: "attach";
|
|
34
44
|
binding: B;
|
|
35
|
-
olds
|
|
45
|
+
olds: BindNode | undefined;
|
|
46
|
+
attr: B["attr"] | undefined;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export type Reattach<B extends AnyBinding = AnyBinding> = {
|
|
50
|
+
action: "reattach";
|
|
51
|
+
binding: B;
|
|
52
|
+
olds: BindNode;
|
|
53
|
+
attr: B["attr"];
|
|
36
54
|
};
|
|
37
55
|
|
|
38
56
|
export type Detach<B extends AnyBinding = AnyBinding> = {
|
|
39
57
|
action: "detach";
|
|
40
58
|
binding: B;
|
|
59
|
+
attr: B["attr"] | undefined;
|
|
41
60
|
};
|
|
42
61
|
|
|
43
62
|
export type NoopBind<B extends AnyBinding = AnyBinding> = {
|
|
44
63
|
action: "noop";
|
|
45
64
|
binding: B;
|
|
65
|
+
attr: B["attr"];
|
|
46
66
|
};
|
|
47
67
|
|
|
48
68
|
export const isCRUD = (node: any): node is CRUD => {
|
|
@@ -59,14 +79,14 @@ export const isCRUD = (node: any): node is CRUD => {
|
|
|
59
79
|
/**
|
|
60
80
|
* A node in the plan that represents a resource CRUD operation.
|
|
61
81
|
*/
|
|
62
|
-
export type CRUD<R extends Resource =
|
|
82
|
+
export type CRUD<R extends Resource = AnyResource> =
|
|
63
83
|
| Create<R>
|
|
64
84
|
| Update<R>
|
|
65
85
|
| Delete<R>
|
|
66
86
|
| Replace<R>
|
|
67
87
|
| NoopUpdate<R>;
|
|
68
88
|
|
|
69
|
-
export type Apply<R extends Resource =
|
|
89
|
+
export type Apply<R extends Resource = AnyResource> =
|
|
70
90
|
| Create<R>
|
|
71
91
|
| Update<R>
|
|
72
92
|
| Replace<R>
|
|
@@ -82,104 +102,170 @@ const Node = <T extends Apply>(node: T) => ({
|
|
|
82
102
|
},
|
|
83
103
|
});
|
|
84
104
|
|
|
85
|
-
export type Create<R extends Resource> = {
|
|
105
|
+
export type Create<R extends Resource = AnyResource> = {
|
|
86
106
|
action: "create";
|
|
87
107
|
resource: R;
|
|
88
108
|
news: any;
|
|
89
|
-
provider: ProviderService
|
|
109
|
+
provider: ProviderService<R>;
|
|
90
110
|
attributes: R["attr"];
|
|
91
111
|
bindings: BindNode[];
|
|
92
112
|
};
|
|
93
113
|
|
|
94
|
-
export type Update<R extends Resource> = {
|
|
114
|
+
export type Update<R extends Resource = AnyResource> = {
|
|
95
115
|
action: "update";
|
|
96
116
|
resource: R;
|
|
97
117
|
olds: any;
|
|
98
118
|
news: any;
|
|
99
119
|
output: any;
|
|
100
|
-
provider: ProviderService
|
|
120
|
+
provider: ProviderService<R>;
|
|
101
121
|
attributes: R["attr"];
|
|
102
122
|
bindings: BindNode[];
|
|
103
123
|
};
|
|
104
124
|
|
|
105
|
-
export type Delete<R extends Resource> = {
|
|
125
|
+
export type Delete<R extends Resource = AnyResource> = {
|
|
106
126
|
action: "delete";
|
|
107
127
|
resource: R;
|
|
108
128
|
olds: any;
|
|
109
129
|
output: any;
|
|
110
|
-
provider: ProviderService
|
|
130
|
+
provider: ProviderService<R>;
|
|
111
131
|
bindings: BindNode[];
|
|
112
132
|
attributes: R["attr"];
|
|
113
133
|
downstream: string[];
|
|
114
134
|
};
|
|
115
135
|
|
|
116
|
-
export type NoopUpdate<R extends Resource> = {
|
|
136
|
+
export type NoopUpdate<R extends Resource = AnyResource> = {
|
|
117
137
|
action: "noop";
|
|
118
138
|
resource: R;
|
|
119
139
|
attributes: R["attr"];
|
|
120
140
|
bindings: BindNode[];
|
|
121
141
|
};
|
|
122
142
|
|
|
123
|
-
export type Replace<R extends Resource> = {
|
|
143
|
+
export type Replace<R extends Resource = AnyResource> = {
|
|
124
144
|
action: "replace";
|
|
125
145
|
resource: R;
|
|
126
146
|
olds: any;
|
|
127
147
|
news: any;
|
|
128
148
|
output: any;
|
|
129
|
-
provider: ProviderService
|
|
149
|
+
provider: ProviderService<R>;
|
|
130
150
|
bindings: BindNode[];
|
|
131
151
|
attributes: R["attr"];
|
|
132
152
|
deleteFirst?: boolean;
|
|
133
153
|
};
|
|
134
154
|
|
|
135
|
-
export type
|
|
136
|
-
|
|
155
|
+
export type ResourceGraph<Resources extends Service | Resource> = ToGraph<
|
|
156
|
+
TraverseResources<Resources>
|
|
157
|
+
>;
|
|
158
|
+
|
|
159
|
+
export type TraverseResources<Resources extends Service | Resource> =
|
|
160
|
+
| Resources
|
|
161
|
+
| BoundResources<Resources>
|
|
162
|
+
| TransitiveResources<Resources>;
|
|
163
|
+
|
|
164
|
+
type ToGraph<Resources extends Service | Resource> = {
|
|
165
|
+
[ID in Resources["id"]]: Apply<Extract<Resources, { id: ID }>>;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
export type BoundResources<Resources extends Service | Resource> = NeverUnknown<
|
|
169
|
+
Extract<
|
|
170
|
+
Resources,
|
|
171
|
+
IService
|
|
172
|
+
>["props"]["bindings"]["capabilities"][number]["resource"]
|
|
173
|
+
>;
|
|
174
|
+
|
|
175
|
+
// finds transitive dependencies at most two levels deep
|
|
176
|
+
// TODO(sam): figure out an efficient way to do arbitrary depth
|
|
177
|
+
export type TransitiveResources<
|
|
178
|
+
Resources extends Service | Resource,
|
|
179
|
+
Found extends Service | Resource = never,
|
|
180
|
+
> = Extract<
|
|
181
|
+
| Found
|
|
182
|
+
| {
|
|
183
|
+
[prop in keyof Resources["props"]]: IsAny<
|
|
184
|
+
Resources["props"][prop]
|
|
185
|
+
> extends true
|
|
186
|
+
? Found
|
|
187
|
+
: Resources["props"][prop] extends { kind: "alchemy/Policy" }
|
|
188
|
+
? Found
|
|
189
|
+
: Resources["props"][prop] extends Output.Output<any, infer Src, any>
|
|
190
|
+
? Src extends Found
|
|
191
|
+
? Found
|
|
192
|
+
: TransitiveResources<Src, Src | Found>
|
|
193
|
+
: {
|
|
194
|
+
[p in keyof Resources["props"][prop]]: IsAny<
|
|
195
|
+
Resources["props"][prop][p]
|
|
196
|
+
> extends true
|
|
197
|
+
? Found
|
|
198
|
+
: Resources["props"][prop][p] extends Output.Output<
|
|
199
|
+
any,
|
|
200
|
+
infer Src,
|
|
201
|
+
any
|
|
202
|
+
>
|
|
203
|
+
? Src extends Found
|
|
204
|
+
? Found
|
|
205
|
+
: TransitiveResources<Src, Src | Found>
|
|
206
|
+
: Found;
|
|
207
|
+
}[keyof Resources["props"][prop]];
|
|
208
|
+
}[keyof Resources["props"]],
|
|
209
|
+
Service | Resource
|
|
210
|
+
>;
|
|
211
|
+
|
|
212
|
+
export type Providers<Resources extends Service | Resource> =
|
|
213
|
+
| ResourceProviders<Resources>
|
|
214
|
+
| BindingTags<Resources>;
|
|
215
|
+
|
|
216
|
+
export type ResourceProviders<Res extends Service | Resource> = Res extends any
|
|
217
|
+
? Provider<Extract<Res["base"], Service | Resource>>
|
|
218
|
+
: never;
|
|
219
|
+
|
|
220
|
+
export type BindingTags<Resources extends Service | Resource> = NeverUnknown<
|
|
221
|
+
Extract<Resources, Service>["props"]["bindings"]["tags"][number]
|
|
222
|
+
>;
|
|
223
|
+
|
|
224
|
+
type NeverUnknown<T> = unknown extends T ? never : T;
|
|
225
|
+
|
|
226
|
+
type IsAny<T> = 0 extends 1 & T ? true : false;
|
|
227
|
+
|
|
228
|
+
export type DerivePlan<Resources extends Service | Resource> = {
|
|
137
229
|
resources: {
|
|
138
|
-
[
|
|
230
|
+
[ID in keyof ResourceGraph<Resources>]: ResourceGraph<Resources>[ID];
|
|
139
231
|
};
|
|
140
232
|
deletions: {
|
|
141
|
-
[
|
|
233
|
+
[ID in string]: Delete<AnyResource>;
|
|
142
234
|
};
|
|
143
235
|
};
|
|
144
236
|
|
|
145
|
-
export
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
>({
|
|
149
|
-
phase,
|
|
150
|
-
services,
|
|
151
|
-
}: {
|
|
152
|
-
phase: Phase;
|
|
153
|
-
services: Services;
|
|
154
|
-
}) => {
|
|
155
|
-
type ServiceIDs = Services[number]["id"];
|
|
156
|
-
type ServiceHosts = {
|
|
157
|
-
[ID in ServiceIDs]: Extract<Services[number], Service<Extract<ID, string>>>;
|
|
237
|
+
export type IPlan = {
|
|
238
|
+
resources: {
|
|
239
|
+
[id in string]: CRUD<any>;
|
|
158
240
|
};
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
[ID in ServiceIDs]: ServiceHosts[ID]["props"]["bindings"]["tags"][number];
|
|
162
|
-
}[ServiceIDs];
|
|
163
|
-
type UpstreamResources = {
|
|
164
|
-
[ID in ServiceIDs]: Extract<
|
|
165
|
-
ServiceHosts[ID]["props"]["bindings"]["capabilities"][number]["resource"],
|
|
166
|
-
Resource
|
|
167
|
-
>;
|
|
168
|
-
}[ServiceIDs];
|
|
169
|
-
type Resources = {
|
|
170
|
-
[ID in ServiceIDs]: Apply<Extract<Instance<ServiceHosts[ID]>, Resource>>;
|
|
171
|
-
} & {
|
|
172
|
-
[ID in UpstreamResources["id"]]: Apply<
|
|
173
|
-
Extract<UpstreamResources, { id: ID }>
|
|
174
|
-
>;
|
|
241
|
+
deletions: {
|
|
242
|
+
[id in string]?: Delete<Resource>;
|
|
175
243
|
};
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
export type Plan<Resources extends Service | Resource> = Effect.Effect<
|
|
247
|
+
DerivePlan<Resources>,
|
|
248
|
+
never,
|
|
249
|
+
Providers<Resources> | State
|
|
250
|
+
>;
|
|
176
251
|
|
|
177
|
-
|
|
252
|
+
export const plan = <const Resources extends (Service | Resource)[]>(
|
|
253
|
+
...resources: Resources
|
|
254
|
+
): Plan<Instance<Resources[number]>> =>
|
|
255
|
+
Effect.gen(function* () {
|
|
178
256
|
const state = yield* State;
|
|
179
257
|
|
|
180
|
-
|
|
258
|
+
// TODO(sam): rename terminology to Stack
|
|
259
|
+
const app = yield* App;
|
|
260
|
+
|
|
261
|
+
const resourceIds = yield* state.list({
|
|
262
|
+
stack: app.name,
|
|
263
|
+
stage: app.stage,
|
|
264
|
+
});
|
|
181
265
|
const resourcesState = yield* Effect.all(
|
|
182
|
-
resourceIds.map((id) =>
|
|
266
|
+
resourceIds.map((id) =>
|
|
267
|
+
state.get({ stack: app.name, stage: app.stage, resourceId: id }),
|
|
268
|
+
),
|
|
183
269
|
);
|
|
184
270
|
// map of resource ID -> its downstream dependencies (resources that depend on it)
|
|
185
271
|
const downstream = resourcesState
|
|
@@ -190,21 +276,10 @@ export const plan = <
|
|
|
190
276
|
bindings: BindNode[];
|
|
191
277
|
} => !!resource?.bindings,
|
|
192
278
|
)
|
|
193
|
-
.flatMap(
|
|
194
|
-
(
|
|
195
|
-
resource.
|
|
196
|
-
|
|
197
|
-
]),
|
|
198
|
-
// resource.bindings.flatMap(({ binding }) => {
|
|
199
|
-
// const capability: Capability = binding.capability;
|
|
200
|
-
// const resource = capability.resource;
|
|
201
|
-
// if (!resource) {
|
|
202
|
-
// return [];
|
|
203
|
-
// }
|
|
204
|
-
// return [
|
|
205
|
-
// [binding.capability.resource.id, binding.capability.resource],
|
|
206
|
-
// ];
|
|
207
|
-
// }),
|
|
279
|
+
.flatMap((resource) =>
|
|
280
|
+
resource.bindings.flatMap(({ binding }) => [
|
|
281
|
+
[binding.capability.resource.id, binding.capability.resource],
|
|
282
|
+
]),
|
|
208
283
|
)
|
|
209
284
|
.reduce(
|
|
210
285
|
(acc, [id, resourceId]) => ({
|
|
@@ -214,131 +289,273 @@ export const plan = <
|
|
|
214
289
|
{} as Record<string, string[]>,
|
|
215
290
|
);
|
|
216
291
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
292
|
+
type ResolveEffect<T> = Effect.Effect<T, ResolveErr, ResolveReq>;
|
|
293
|
+
type ResolveErr = StateStoreError;
|
|
294
|
+
type ResolveReq =
|
|
295
|
+
| Context.TagClass<
|
|
296
|
+
Provider<Resource<string, string, any, any>>,
|
|
297
|
+
string,
|
|
298
|
+
ProviderService<Resource<string, string, any, any>>
|
|
299
|
+
>
|
|
300
|
+
| State;
|
|
301
|
+
|
|
302
|
+
const resolvedResources: Record<
|
|
303
|
+
string,
|
|
304
|
+
ResolveEffect<{
|
|
305
|
+
[attr in string]: any;
|
|
306
|
+
}>
|
|
307
|
+
> = {};
|
|
308
|
+
|
|
309
|
+
const resolveResource = (
|
|
310
|
+
resourceExpr: Output.ResourceExpr<any, any, any>,
|
|
311
|
+
) =>
|
|
312
|
+
Effect.gen(function* () {
|
|
313
|
+
return yield* (resolvedResources[resourceExpr.src.id] ??=
|
|
314
|
+
yield* Effect.cached(
|
|
315
|
+
Effect.gen(function* () {
|
|
316
|
+
const resource = resourceExpr.src as Resource & {
|
|
317
|
+
provider: ResourceTags<Resource<string, string, any, any>>;
|
|
318
|
+
};
|
|
319
|
+
const provider = yield* resource.provider.tag;
|
|
320
|
+
const props = yield* resolveInput(resource.props);
|
|
321
|
+
const oldState = yield* state.get({
|
|
322
|
+
stack: app.name,
|
|
323
|
+
stage: app.stage,
|
|
324
|
+
resourceId: resource.id,
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
if (!oldState) {
|
|
328
|
+
return resourceExpr;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
const diff = yield* provider.diff
|
|
332
|
+
? provider.diff({
|
|
333
|
+
id: resource.id,
|
|
334
|
+
olds: oldState.props,
|
|
335
|
+
news: props,
|
|
336
|
+
output: oldState.output,
|
|
337
|
+
})
|
|
338
|
+
: Effect.succeed(undefined);
|
|
339
|
+
|
|
340
|
+
if (diff == null) {
|
|
341
|
+
if (arePropsChanged(oldState, props)) {
|
|
342
|
+
// the props have changed but the provider did not provide any hints as to what is stable
|
|
343
|
+
// so we must assume everything has changed
|
|
344
|
+
return resourceExpr;
|
|
345
|
+
}
|
|
346
|
+
} else if (diff.action === "update") {
|
|
347
|
+
const output = oldState?.output;
|
|
348
|
+
if (diff.stables) {
|
|
349
|
+
return new Output.ResourceExpr(
|
|
350
|
+
resourceExpr.src,
|
|
351
|
+
Object.fromEntries(
|
|
352
|
+
diff.stables.map((stable) => [stable, output?.[stable]]),
|
|
353
|
+
),
|
|
354
|
+
);
|
|
355
|
+
} else {
|
|
356
|
+
// if there are no stable properties, treat every property as changed
|
|
357
|
+
return resourceExpr;
|
|
358
|
+
}
|
|
359
|
+
} else if (diff.action === "replace") {
|
|
360
|
+
}
|
|
361
|
+
return oldState?.output;
|
|
362
|
+
}),
|
|
363
|
+
));
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
const resolveInput = (input: any): ResolveEffect<any> =>
|
|
367
|
+
Effect.gen(function* () {
|
|
368
|
+
if (!input) {
|
|
369
|
+
return input;
|
|
370
|
+
} else if (Output.isExpr(input)) {
|
|
371
|
+
return yield* resolveOutput(input);
|
|
372
|
+
} else if (Array.isArray(input)) {
|
|
373
|
+
return yield* Effect.all(input.map(resolveInput));
|
|
374
|
+
} else if (typeof input === "object") {
|
|
375
|
+
return Object.fromEntries(
|
|
376
|
+
yield* Effect.all(
|
|
377
|
+
Object.entries(input).map(([key, value]) =>
|
|
378
|
+
resolveInput(value).pipe(Effect.map((value) => [key, value])),
|
|
379
|
+
),
|
|
380
|
+
),
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
return input;
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
const resolveOutput = (expr: Output.Expr<any>): ResolveEffect<any> =>
|
|
387
|
+
Effect.gen(function* () {
|
|
388
|
+
if (Output.isResourceExpr(expr)) {
|
|
389
|
+
return yield* resolveResource(expr);
|
|
390
|
+
} else if (Output.isPropExpr(expr)) {
|
|
391
|
+
const upstream = yield* resolveOutput(expr.expr);
|
|
392
|
+
return upstream?.[expr.identifier];
|
|
393
|
+
} else if (Output.isApplyExpr(expr)) {
|
|
394
|
+
const upstream = yield* resolveOutput(expr.expr);
|
|
395
|
+
return Output.isOutput(upstream) ? expr : expr.f(upstream);
|
|
396
|
+
} else if (Output.isEffectExpr(expr)) {
|
|
397
|
+
const upstream = yield* resolveOutput(expr.expr);
|
|
398
|
+
return Output.isOutput(upstream) ? expr : yield* expr.f(upstream);
|
|
399
|
+
} else if (Output.isAllExpr(expr)) {
|
|
400
|
+
return yield* Effect.all(expr.outs.map(resolveOutput));
|
|
401
|
+
}
|
|
402
|
+
return yield* Effect.die(new Error("Not implemented yet"));
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
const resolveUpstream = (
|
|
406
|
+
value: any,
|
|
407
|
+
): {
|
|
408
|
+
[ID in string]: Resource;
|
|
409
|
+
} => {
|
|
410
|
+
if (Output.isExpr(value)) {
|
|
411
|
+
return Output.upstream(value);
|
|
412
|
+
} else if (Array.isArray(value)) {
|
|
413
|
+
return Object.assign({}, ...value.map(resolveUpstream));
|
|
414
|
+
} else if (
|
|
415
|
+
value &&
|
|
416
|
+
(typeof value === "object" || typeof value === "function")
|
|
417
|
+
) {
|
|
418
|
+
return Object.assign(
|
|
419
|
+
{},
|
|
420
|
+
...Object.values(value).map((value) => resolveUpstream(value)),
|
|
421
|
+
);
|
|
422
|
+
}
|
|
423
|
+
return {};
|
|
424
|
+
};
|
|
425
|
+
|
|
426
|
+
const resourceGraph = Object.fromEntries(
|
|
427
|
+
(yield* Effect.all(
|
|
428
|
+
resources
|
|
429
|
+
.flatMap((resource) => [
|
|
430
|
+
...(isService(resource)
|
|
431
|
+
? resource.props.bindings.capabilities.map(
|
|
432
|
+
(cap: Capability) => cap.resource as Resource,
|
|
231
433
|
)
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
news,
|
|
261
|
-
provider,
|
|
262
|
-
resource,
|
|
263
|
-
bindings,
|
|
264
|
-
// phantom
|
|
265
|
-
attributes: undefined!,
|
|
266
|
-
});
|
|
267
|
-
} else if (provider.diff) {
|
|
268
|
-
const diff = yield* provider.diff({
|
|
269
|
-
id,
|
|
270
|
-
olds: oldState.props,
|
|
271
|
-
news,
|
|
272
|
-
output: oldState.output,
|
|
273
|
-
});
|
|
274
|
-
if (diff.action === "noop") {
|
|
275
|
-
return Node<NoopUpdate<Resource>>({
|
|
276
|
-
action: "noop",
|
|
277
|
-
resource,
|
|
278
|
-
bindings,
|
|
279
|
-
// phantom
|
|
280
|
-
attributes: undefined!,
|
|
281
|
-
});
|
|
282
|
-
} else if (diff.action === "replace") {
|
|
283
|
-
return Node<Replace<Resource>>({
|
|
284
|
-
action: "replace",
|
|
285
|
-
olds: oldState.props,
|
|
286
|
-
news,
|
|
287
|
-
output: oldState.output,
|
|
288
|
-
provider,
|
|
289
|
-
resource,
|
|
290
|
-
bindings,
|
|
291
|
-
// phantom
|
|
292
|
-
attributes: undefined!,
|
|
293
|
-
});
|
|
294
|
-
} else {
|
|
295
|
-
return Node<Update<Resource>>({
|
|
296
|
-
action: "update",
|
|
297
|
-
olds: oldState.props,
|
|
298
|
-
news,
|
|
299
|
-
output: oldState.output,
|
|
300
|
-
provider,
|
|
301
|
-
resource,
|
|
302
|
-
bindings,
|
|
303
|
-
// phantom
|
|
304
|
-
attributes: undefined!,
|
|
305
|
-
});
|
|
434
|
+
: []),
|
|
435
|
+
...Object.values(resolveUpstream(resource.props)),
|
|
436
|
+
resource,
|
|
437
|
+
])
|
|
438
|
+
.filter(
|
|
439
|
+
(node, i, arr) => arr.findIndex((n) => n.id === node.id) === i,
|
|
440
|
+
)
|
|
441
|
+
.map(
|
|
442
|
+
Effect.fn(function* (node) {
|
|
443
|
+
const id = node.id;
|
|
444
|
+
const resource = node as Resource & {
|
|
445
|
+
provider: ResourceTags<Resource<string, string, any, any>>;
|
|
446
|
+
};
|
|
447
|
+
const news = yield* resolveInput(resource.props);
|
|
448
|
+
|
|
449
|
+
const oldState = yield* state.get({
|
|
450
|
+
stack: app.name,
|
|
451
|
+
stage: app.stage,
|
|
452
|
+
resourceId: id,
|
|
453
|
+
});
|
|
454
|
+
const provider = yield* resource.provider.tag;
|
|
455
|
+
|
|
456
|
+
const bindings = isService(node)
|
|
457
|
+
? yield* diffBindings({
|
|
458
|
+
oldState,
|
|
459
|
+
bindings: (
|
|
460
|
+
node.props.bindings as unknown as {
|
|
461
|
+
bindings: AnyBinding[];
|
|
306
462
|
}
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
463
|
+
).bindings,
|
|
464
|
+
target: {
|
|
465
|
+
id: node.id,
|
|
466
|
+
props: node.props,
|
|
467
|
+
oldAttr: oldState?.output,
|
|
468
|
+
oldProps: oldState?.props,
|
|
469
|
+
},
|
|
470
|
+
})
|
|
471
|
+
: []; // TODO(sam): return undefined instead of empty array
|
|
472
|
+
|
|
473
|
+
if (oldState === undefined || oldState.status === "creating") {
|
|
474
|
+
return Node<Create<Resource>>({
|
|
475
|
+
action: "create",
|
|
476
|
+
news,
|
|
477
|
+
provider,
|
|
478
|
+
resource,
|
|
479
|
+
bindings,
|
|
480
|
+
// phantom
|
|
481
|
+
attributes: undefined!,
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
const diff = provider.diff
|
|
486
|
+
? yield* (() => {
|
|
487
|
+
const diff = provider.diff({
|
|
488
|
+
id,
|
|
489
|
+
olds: oldState.props,
|
|
490
|
+
news,
|
|
491
|
+
output: oldState.output,
|
|
492
|
+
});
|
|
493
|
+
return Effect.isEffect(diff) ? diff : Effect.succeed(diff);
|
|
494
|
+
})()
|
|
495
|
+
: undefined;
|
|
496
|
+
|
|
497
|
+
if (!diff && arePropsChanged(oldState, news)) {
|
|
498
|
+
return Node<Update<Resource>>({
|
|
499
|
+
action: "update",
|
|
500
|
+
olds: oldState.props,
|
|
501
|
+
news,
|
|
502
|
+
output: oldState.output,
|
|
503
|
+
provider,
|
|
504
|
+
resource,
|
|
505
|
+
bindings,
|
|
506
|
+
// phantom
|
|
507
|
+
attributes: undefined!,
|
|
508
|
+
});
|
|
509
|
+
} else if (diff?.action === "replace") {
|
|
510
|
+
return Node<Replace<Resource>>({
|
|
511
|
+
action: "replace",
|
|
512
|
+
olds: oldState.props,
|
|
513
|
+
news,
|
|
514
|
+
output: oldState.output,
|
|
515
|
+
provider,
|
|
516
|
+
resource,
|
|
517
|
+
bindings,
|
|
518
|
+
// phantom
|
|
519
|
+
attributes: undefined!,
|
|
520
|
+
});
|
|
521
|
+
} else if (diff?.action === "update") {
|
|
522
|
+
return Node<Update<Resource>>({
|
|
523
|
+
action: "update",
|
|
524
|
+
olds: oldState.props,
|
|
525
|
+
news,
|
|
526
|
+
output: oldState.output,
|
|
527
|
+
provider,
|
|
528
|
+
resource,
|
|
529
|
+
bindings,
|
|
530
|
+
// phantom
|
|
531
|
+
attributes: undefined!,
|
|
532
|
+
});
|
|
533
|
+
} else {
|
|
534
|
+
return Node<NoopUpdate<Resource>>({
|
|
535
|
+
action: "noop",
|
|
536
|
+
resource,
|
|
537
|
+
bindings,
|
|
538
|
+
// phantom
|
|
539
|
+
attributes: undefined!,
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
}),
|
|
543
|
+
),
|
|
544
|
+
)).map((update) => [update.resource.id, update]),
|
|
545
|
+
) as IPlan["resources"];
|
|
333
546
|
|
|
334
547
|
const deletions = Object.fromEntries(
|
|
335
548
|
(yield* Effect.all(
|
|
336
|
-
(yield* state.list()).map(
|
|
549
|
+
(yield* state.list({ stack: app.name, stage: app.stage })).map(
|
|
337
550
|
Effect.fn(function* (id) {
|
|
338
|
-
if (id in
|
|
551
|
+
if (id in resourceGraph) {
|
|
339
552
|
return;
|
|
340
553
|
}
|
|
341
|
-
const oldState = yield* state.get(
|
|
554
|
+
const oldState = yield* state.get({
|
|
555
|
+
stack: app.name,
|
|
556
|
+
stage: app.stage,
|
|
557
|
+
resourceId: id,
|
|
558
|
+
});
|
|
342
559
|
const context = yield* Effect.context<never>();
|
|
343
560
|
if (oldState) {
|
|
344
561
|
const provider: ProviderService = context.unsafeMap.get(
|
|
@@ -361,7 +578,6 @@ export const plan = <
|
|
|
361
578
|
bindings: [],
|
|
362
579
|
resource: {
|
|
363
580
|
id: id,
|
|
364
|
-
parent: undefined,
|
|
365
581
|
type: oldState.type,
|
|
366
582
|
attr: oldState.output,
|
|
367
583
|
props: oldState.props,
|
|
@@ -376,7 +592,9 @@ export const plan = <
|
|
|
376
592
|
);
|
|
377
593
|
|
|
378
594
|
for (const [resourceId, deletion] of Object.entries(deletions)) {
|
|
379
|
-
const dependencies = deletion.downstream.filter(
|
|
595
|
+
const dependencies = deletion.downstream.filter(
|
|
596
|
+
(d) => d in resourceGraph,
|
|
597
|
+
);
|
|
380
598
|
if (dependencies.length > 0) {
|
|
381
599
|
return yield* Effect.fail(
|
|
382
600
|
new DeleteResourceHasDownstreamDependencies({
|
|
@@ -389,24 +607,10 @@ export const plan = <
|
|
|
389
607
|
}
|
|
390
608
|
|
|
391
609
|
return {
|
|
392
|
-
|
|
393
|
-
resources,
|
|
610
|
+
resources: resourceGraph,
|
|
394
611
|
deletions,
|
|
395
|
-
} satisfies
|
|
396
|
-
}) as
|
|
397
|
-
{
|
|
398
|
-
phase: Phase;
|
|
399
|
-
resources: {
|
|
400
|
-
[ID in keyof Resources]: Resources[ID];
|
|
401
|
-
};
|
|
402
|
-
deletions: {
|
|
403
|
-
[id in Exclude<string, keyof Resources>]?: Delete<Resource>;
|
|
404
|
-
};
|
|
405
|
-
},
|
|
406
|
-
never,
|
|
407
|
-
UpstreamTags | State
|
|
408
|
-
>;
|
|
409
|
-
};
|
|
612
|
+
} satisfies IPlan as IPlan;
|
|
613
|
+
}) as any;
|
|
410
614
|
|
|
411
615
|
class DeleteResourceHasDownstreamDependencies extends Data.TaggedError(
|
|
412
616
|
"DeleteResourceHasDownstreamDependencies",
|
|
@@ -416,55 +620,152 @@ class DeleteResourceHasDownstreamDependencies extends Data.TaggedError(
|
|
|
416
620
|
dependencies: string[];
|
|
417
621
|
}> {}
|
|
418
622
|
|
|
419
|
-
const
|
|
623
|
+
const arePropsChanged = <R extends Resource>(
|
|
420
624
|
oldState: ResourceState | undefined,
|
|
421
|
-
|
|
422
|
-
) => JSON.stringify(oldState?.props) === JSON.stringify(newState);
|
|
423
|
-
|
|
424
|
-
const diffBindings = (
|
|
425
|
-
oldState: ResourceState | undefined,
|
|
426
|
-
bindings: AnyBinding[],
|
|
625
|
+
newProps: R["props"],
|
|
427
626
|
) => {
|
|
428
|
-
|
|
627
|
+
return (
|
|
628
|
+
JSON.stringify(omit(oldState?.props ?? {}, "bindings")) !==
|
|
629
|
+
JSON.stringify(omit((newProps ?? {}) as any, "bindings"))
|
|
630
|
+
);
|
|
631
|
+
};
|
|
632
|
+
|
|
633
|
+
const diffBindings = Effect.fn(function* ({
|
|
634
|
+
oldState,
|
|
635
|
+
bindings,
|
|
636
|
+
target,
|
|
637
|
+
}: {
|
|
638
|
+
oldState: ResourceState | undefined;
|
|
639
|
+
bindings: AnyBinding[];
|
|
640
|
+
target: BindingDiffProps["target"];
|
|
641
|
+
}) {
|
|
642
|
+
// const actions: BindNode[] = [];
|
|
429
643
|
const oldBindings = oldState?.bindings;
|
|
430
644
|
const oldSids = new Set(
|
|
431
645
|
oldBindings?.map(({ binding }) => binding.capability.sid),
|
|
432
646
|
);
|
|
433
|
-
for (const binding of bindings) {
|
|
434
|
-
const cap = binding.capability;
|
|
435
|
-
const sid = cap.sid ?? `${cap.action}:${cap.resource.ID}`;
|
|
436
|
-
oldSids.delete(sid);
|
|
437
647
|
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
648
|
+
const diffBinding: (
|
|
649
|
+
binding: AnyBinding,
|
|
650
|
+
) => Effect.Effect<BindNode, StateStoreError, State> = Effect.fn(
|
|
651
|
+
function* (binding) {
|
|
652
|
+
const cap = binding.capability;
|
|
653
|
+
const sid = cap.sid ?? `${cap.action}:${cap.resource.ID}`;
|
|
654
|
+
// Find potential oldBinding for this sid
|
|
655
|
+
const oldBinding = oldBindings?.find(
|
|
656
|
+
({ binding }) => binding.capability.sid === sid,
|
|
657
|
+
);
|
|
658
|
+
if (!oldBinding) {
|
|
659
|
+
return {
|
|
660
|
+
action: "attach",
|
|
661
|
+
binding,
|
|
662
|
+
attr: undefined,
|
|
663
|
+
olds: undefined,
|
|
664
|
+
} satisfies Attach<AnyBinding>;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
const diff = yield* isBindingDiff({
|
|
668
|
+
target,
|
|
669
|
+
oldBinding,
|
|
670
|
+
newBinding: binding,
|
|
445
671
|
});
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
672
|
+
// if (diff === false) {
|
|
673
|
+
// } else if (diff === true) {
|
|
674
|
+
// return {
|
|
675
|
+
// action: "attach",
|
|
676
|
+
// binding,
|
|
677
|
+
// olds: oldBinding,
|
|
678
|
+
// } satisfies Attach<AnyBinding>;
|
|
679
|
+
// }
|
|
680
|
+
if (diff.action === "replace") {
|
|
681
|
+
return yield* Effect.die(
|
|
682
|
+
new Error("Replace binding not yet supported"),
|
|
683
|
+
);
|
|
684
|
+
// TODO(sam): implement support for replacing bindings
|
|
685
|
+
// return {
|
|
686
|
+
// action: "replace",
|
|
687
|
+
// binding,
|
|
688
|
+
// olds: oldBinding,
|
|
689
|
+
// };
|
|
690
|
+
} else if (diff?.action === "update") {
|
|
691
|
+
return {
|
|
692
|
+
action: "reattach",
|
|
693
|
+
binding,
|
|
694
|
+
olds: oldBinding,
|
|
695
|
+
attr: oldBinding.attr,
|
|
696
|
+
} satisfies Reattach<AnyBinding>;
|
|
697
|
+
}
|
|
698
|
+
return {
|
|
699
|
+
action: "noop",
|
|
449
700
|
binding,
|
|
450
|
-
|
|
451
|
-
}
|
|
452
|
-
}
|
|
701
|
+
attr: oldBinding.attr,
|
|
702
|
+
} satisfies NoopBind<AnyBinding>;
|
|
703
|
+
},
|
|
704
|
+
);
|
|
705
|
+
|
|
706
|
+
return (yield* Effect.all(bindings.map(diffBinding))).filter(
|
|
707
|
+
(action): action is BindNode => action !== null,
|
|
708
|
+
);
|
|
709
|
+
});
|
|
710
|
+
|
|
711
|
+
const isBindingDiff = Effect.fn(function* ({
|
|
712
|
+
target,
|
|
713
|
+
oldBinding: { binding: oldBinding },
|
|
714
|
+
newBinding,
|
|
715
|
+
}: {
|
|
716
|
+
// TODO(sam): support binding to other Resources
|
|
717
|
+
target: BindingDiffProps["target"];
|
|
718
|
+
oldBinding: BindNode;
|
|
719
|
+
newBinding: AnyBinding;
|
|
720
|
+
}) {
|
|
721
|
+
const oldCap = oldBinding.capability;
|
|
722
|
+
const newCap = newBinding.capability;
|
|
723
|
+
if (
|
|
724
|
+
// if the binding provider has changed
|
|
725
|
+
oldBinding.tag !== newBinding.tag ||
|
|
726
|
+
// if it points to a totally different resource, we should replace
|
|
727
|
+
oldCap?.resource?.id !== newCap?.resource?.id ||
|
|
728
|
+
// if it is a different action
|
|
729
|
+
oldCap.action !== newCap.action
|
|
730
|
+
) {
|
|
731
|
+
// then we must replace (we need to detach and attach with different bindings or to different resources)
|
|
732
|
+
return {
|
|
733
|
+
action: "replace",
|
|
734
|
+
} satisfies Diff;
|
|
453
735
|
}
|
|
454
|
-
// for (const sid of oldSids) {
|
|
455
|
-
// actions.push({
|
|
456
|
-
// action: "detach",
|
|
457
|
-
// cap: oldBindings?.find((binding) => binding.sid === sid)!,
|
|
458
|
-
// });
|
|
459
|
-
// }
|
|
460
|
-
return actions;
|
|
461
|
-
};
|
|
462
736
|
|
|
463
|
-
const
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
737
|
+
const binding = newBinding as AnyBinding & {
|
|
738
|
+
// smuggled property (because it interacts poorly with inference)
|
|
739
|
+
Tag: Context.Tag<never, BindingService>;
|
|
740
|
+
};
|
|
741
|
+
const provider = yield* binding.Tag;
|
|
742
|
+
if (provider.diff) {
|
|
743
|
+
const state = yield* State;
|
|
744
|
+
const oldState = yield* state.get(oldCap.resource.id);
|
|
745
|
+
const diff = yield* provider.diff({
|
|
746
|
+
source: {
|
|
747
|
+
id: oldCap.resource.id,
|
|
748
|
+
props: newCap.resource.props,
|
|
749
|
+
oldProps: oldState?.props,
|
|
750
|
+
oldAttr: oldState?.output,
|
|
751
|
+
},
|
|
752
|
+
props: newBinding.props,
|
|
753
|
+
attr: oldBinding.attr,
|
|
754
|
+
target,
|
|
755
|
+
});
|
|
756
|
+
|
|
757
|
+
if (diff?.action === "update" || diff?.action === "replace") {
|
|
758
|
+
return diff;
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
return {
|
|
762
|
+
action:
|
|
763
|
+
oldBinding.capability.action !== newBinding.capability.action ||
|
|
764
|
+
oldBinding.capability?.resource?.id !==
|
|
765
|
+
newBinding.capability?.resource?.id
|
|
766
|
+
? "update"
|
|
767
|
+
: "noop",
|
|
768
|
+
} as const;
|
|
769
|
+
});
|
|
469
770
|
// TODO(sam): compare props
|
|
470
771
|
// oldBinding.props !== newBinding.props;
|