alchemy 2.0.0-beta.84 → 2.0.0-beta.85
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/THIRD_PARTY_LICENSES.md +2 -2
- package/bin/cli.js +14 -6
- package/bin/register-oxc.js +16 -12
- package/lib/AdoptPolicy.d.ts +73 -0
- package/lib/AdoptPolicy.d.ts.map +1 -1
- package/lib/AdoptPolicy.js +54 -0
- package/lib/AdoptPolicy.js.map +1 -1
- package/lib/Alchemist/AuthRegistry.d.ts +31 -0
- package/lib/Alchemist/AuthRegistry.d.ts.map +1 -0
- package/lib/Alchemist/AuthRegistry.js +95 -0
- package/lib/Alchemist/AuthRegistry.js.map +1 -0
- package/lib/Alchemist/Drift.d.ts +70 -0
- package/lib/Alchemist/Drift.d.ts.map +1 -0
- package/lib/Alchemist/Drift.js +54 -0
- package/lib/Alchemist/Drift.js.map +1 -0
- package/lib/Alchemist/Entrypoint.d.ts +27 -3
- package/lib/Alchemist/Entrypoint.d.ts.map +1 -1
- package/lib/Alchemist/Entrypoint.js +34 -3
- package/lib/Alchemist/Entrypoint.js.map +1 -1
- package/lib/Alchemist/Errors.d.ts +1 -1
- package/lib/Alchemist/Errors.d.ts.map +1 -1
- package/lib/Alchemist/Errors.js +1 -1
- package/lib/Alchemist/Errors.js.map +1 -1
- package/lib/Alchemist/Logs.d.ts +46 -0
- package/lib/Alchemist/Logs.d.ts.map +1 -0
- package/lib/Alchemist/{routes/logs.js → Logs.js} +21 -26
- package/lib/Alchemist/Logs.js.map +1 -0
- package/lib/Alchemist/Nuke.d.ts +69 -0
- package/lib/Alchemist/Nuke.d.ts.map +1 -0
- package/lib/Alchemist/Nuke.js +35 -0
- package/lib/Alchemist/Nuke.js.map +1 -0
- package/lib/Alchemist/Operations.d.ts +168 -0
- package/lib/Alchemist/Operations.d.ts.map +1 -0
- package/lib/Alchemist/Operations.js +165 -0
- package/lib/Alchemist/Operations.js.map +1 -0
- package/lib/Alchemist/Profile.d.ts +132 -0
- package/lib/Alchemist/Profile.d.ts.map +1 -0
- package/lib/Alchemist/{routes/profile.js → Profile.js} +20 -21
- package/lib/Alchemist/Profile.js.map +1 -0
- package/lib/Alchemist/{routes/provider.d.ts → Provider.d.ts} +4 -4
- package/lib/Alchemist/Provider.d.ts.map +1 -0
- package/lib/Alchemist/{routes/provider.js → Provider.js} +7 -6
- package/lib/Alchemist/Provider.js.map +1 -0
- package/lib/Alchemist/Runtime.d.ts +10 -6
- package/lib/Alchemist/Runtime.d.ts.map +1 -1
- package/lib/Alchemist/Runtime.js +38 -2
- package/lib/Alchemist/Runtime.js.map +1 -1
- package/lib/Alchemist/{routes/state.d.ts → State.d.ts} +36 -16
- package/lib/Alchemist/State.d.ts.map +1 -0
- package/lib/Alchemist/{routes/state.js → State.js} +50 -15
- package/lib/Alchemist/State.js.map +1 -0
- package/lib/Alchemist/index.d.ts +11 -10
- package/lib/Alchemist/index.d.ts.map +1 -1
- package/lib/Alchemist/index.js +10 -9
- package/lib/Alchemist/index.js.map +1 -1
- package/lib/Apply.d.ts +2 -8
- package/lib/Apply.d.ts.map +1 -1
- package/lib/Apply.js +364 -184
- package/lib/Apply.js.map +1 -1
- package/lib/Auth/AuthProvider.d.ts +24 -11
- package/lib/Auth/AuthProvider.d.ts.map +1 -1
- package/lib/Auth/AuthProvider.js +28 -12
- package/lib/Auth/AuthProvider.js.map +1 -1
- package/lib/Auth/BrowserOAuth.d.ts +6 -8
- package/lib/Auth/BrowserOAuth.d.ts.map +1 -1
- package/lib/Auth/BrowserOAuth.js +25 -41
- package/lib/Auth/BrowserOAuth.js.map +1 -1
- package/lib/Auth/Credentials.d.ts.map +1 -1
- package/lib/Auth/Credentials.js +2 -2
- package/lib/Auth/Credentials.js.map +1 -1
- package/lib/Auth/Demand.d.ts +4 -4
- package/lib/Auth/Demand.d.ts.map +1 -1
- package/lib/Auth/Demand.js +16 -10
- package/lib/Auth/Demand.js.map +1 -1
- package/lib/Auth/Env.d.ts +2 -1
- package/lib/Auth/Env.d.ts.map +1 -1
- package/lib/Auth/Env.js +4 -2
- package/lib/Auth/Env.js.map +1 -1
- package/lib/Auth/Inspect.d.ts +2 -2
- package/lib/Auth/Inspect.d.ts.map +1 -1
- package/lib/Auth/Inspect.js +3 -1
- package/lib/Auth/Inspect.js.map +1 -1
- package/lib/Auth/Lock.d.ts.map +1 -1
- package/lib/Auth/Lock.js +4 -8
- package/lib/Auth/Lock.js.map +1 -1
- package/lib/Auth/OAuthFlow.d.ts +3 -12
- package/lib/Auth/OAuthFlow.d.ts.map +1 -1
- package/lib/Auth/OAuthFlow.js +7 -17
- package/lib/Auth/OAuthFlow.js.map +1 -1
- package/lib/Auth/Paths.d.ts +2 -1
- package/lib/Auth/Paths.d.ts.map +1 -1
- package/lib/Auth/Paths.js +3 -2
- package/lib/Auth/Paths.js.map +1 -1
- package/lib/Auth/Profile.d.ts +10 -0
- package/lib/Auth/Profile.d.ts.map +1 -1
- package/lib/Auth/Profile.js +19 -2
- package/lib/Auth/Profile.js.map +1 -1
- package/lib/Auth/Registry.d.ts +20 -0
- package/lib/Auth/Registry.d.ts.map +1 -0
- package/lib/Auth/Registry.js +17 -0
- package/lib/Auth/Registry.js.map +1 -0
- package/lib/Auth/Resolve.d.ts +34 -2
- package/lib/Auth/Resolve.d.ts.map +1 -1
- package/lib/Auth/Resolve.js +51 -3
- package/lib/Auth/Resolve.js.map +1 -1
- package/lib/Auth/StoredAuthProvider.d.ts +1 -1
- package/lib/Auth/StoredAuthProvider.d.ts.map +1 -1
- package/lib/Auth/StoredAuthProvider.js +1 -2
- package/lib/Auth/StoredAuthProvider.js.map +1 -1
- package/lib/Binding.d.ts.map +1 -1
- package/lib/Binding.js +3 -1
- package/lib/Binding.js.map +1 -1
- package/lib/Bundle/Bundle.d.ts +5 -0
- package/lib/Bundle/Bundle.d.ts.map +1 -1
- package/lib/Bundle/Bundle.js +36 -6
- package/lib/Bundle/Bundle.js.map +1 -1
- package/lib/Bundle/NamespaceImportPlugin.d.ts +55 -0
- package/lib/Bundle/NamespaceImportPlugin.d.ts.map +1 -0
- package/lib/Bundle/NamespaceImportPlugin.js +226 -0
- package/lib/Bundle/NamespaceImportPlugin.js.map +1 -0
- package/lib/Bundle/index.d.ts +1 -0
- package/lib/Bundle/index.d.ts.map +1 -1
- package/lib/Bundle/index.js +1 -0
- package/lib/Bundle/index.js.map +1 -1
- package/lib/Cli/Format.d.ts.map +1 -1
- package/lib/Cli/Format.js +2 -1
- package/lib/Cli/Format.js.map +1 -1
- package/lib/Cli/GlobalLog.d.ts +72 -26
- package/lib/Cli/GlobalLog.d.ts.map +1 -1
- package/lib/Cli/GlobalLog.js +151 -59
- package/lib/Cli/GlobalLog.js.map +1 -1
- package/lib/Cli/LoggingCli.d.ts.map +1 -1
- package/lib/Cli/LoggingCli.js +24 -18
- package/lib/Cli/LoggingCli.js.map +1 -1
- package/lib/Cli/PlainCliFormatter.d.ts.map +1 -1
- package/lib/Cli/PlainCliFormatter.js +4 -1
- package/lib/Cli/PlainCliFormatter.js.map +1 -1
- package/lib/Cli/Present.d.ts +14 -0
- package/lib/Cli/Present.d.ts.map +1 -0
- package/lib/Cli/Present.js +22 -0
- package/lib/Cli/Present.js.map +1 -0
- package/lib/Cli/SigilRenderer.d.ts +58 -0
- package/lib/Cli/SigilRenderer.d.ts.map +1 -0
- package/lib/Cli/SigilRenderer.js +39 -0
- package/lib/Cli/SigilRenderer.js.map +1 -0
- package/lib/Cli/checkVersion.d.ts +11 -14
- package/lib/Cli/checkVersion.d.ts.map +1 -1
- package/lib/Cli/checkVersion.js +19 -77
- package/lib/Cli/checkVersion.js.map +1 -1
- package/lib/Cli/commands/confirm.d.ts +2 -2
- package/lib/Cli/commands/confirm.d.ts.map +1 -1
- package/lib/Cli/commands/confirm.js +3 -3
- package/lib/Cli/commands/confirm.js.map +1 -1
- package/lib/Cli/commands/deploy.d.ts +4 -4
- package/lib/Cli/commands/deploy.d.ts.map +1 -1
- package/lib/Cli/commands/deploy.js +40 -39
- package/lib/Cli/commands/deploy.js.map +1 -1
- package/lib/Cli/commands/dev.d.ts.map +1 -1
- package/lib/Cli/commands/dev.js +41 -3
- package/lib/Cli/commands/dev.js.map +1 -1
- package/lib/Cli/commands/drift.d.ts +2 -2
- package/lib/Cli/commands/drift.d.ts.map +1 -1
- package/lib/Cli/commands/drift.js +14 -13
- package/lib/Cli/commands/drift.js.map +1 -1
- package/lib/Cli/commands/errors.d.ts.map +1 -1
- package/lib/Cli/commands/errors.js +2 -1
- package/lib/Cli/commands/errors.js.map +1 -1
- package/lib/Cli/commands/instrument.d.ts +15 -5
- package/lib/Cli/commands/instrument.d.ts.map +1 -1
- package/lib/Cli/commands/instrument.js +33 -8
- package/lib/Cli/commands/instrument.js.map +1 -1
- package/lib/Cli/commands/logs.d.ts +1 -1
- package/lib/Cli/commands/logs.d.ts.map +1 -1
- package/lib/Cli/commands/logs.js +22 -22
- package/lib/Cli/commands/logs.js.map +1 -1
- package/lib/Cli/commands/nuke.d.ts +3 -2
- package/lib/Cli/commands/nuke.d.ts.map +1 -1
- package/lib/Cli/commands/nuke.js +19 -17
- package/lib/Cli/commands/nuke.js.map +1 -1
- package/lib/Cli/commands/profile/commands.d.ts +3 -2
- package/lib/Cli/commands/profile/commands.d.ts.map +1 -1
- package/lib/Cli/commands/profile/commands.js +26 -27
- package/lib/Cli/commands/profile/commands.js.map +1 -1
- package/lib/Cli/commands/profile/flows.d.ts +6 -5
- package/lib/Cli/commands/profile/flows.d.ts.map +1 -1
- package/lib/Cli/commands/profile/flows.js +19 -17
- package/lib/Cli/commands/profile/flows.js.map +1 -1
- package/lib/Cli/commands/profile/hub.d.ts +1 -2
- package/lib/Cli/commands/profile/hub.d.ts.map +1 -1
- package/lib/Cli/commands/profile/hub.js +15 -17
- package/lib/Cli/commands/profile/hub.js.map +1 -1
- package/lib/Cli/commands/provider.d.ts +3 -1
- package/lib/Cli/commands/provider.d.ts.map +1 -1
- package/lib/Cli/commands/provider.js +4 -4
- package/lib/Cli/commands/provider.js.map +1 -1
- package/lib/Cli/commands/render.d.ts +2 -4
- package/lib/Cli/commands/render.d.ts.map +1 -1
- package/lib/Cli/commands/render.js +33 -56
- package/lib/Cli/commands/render.js.map +1 -1
- package/lib/Cli/commands/state.d.ts +1 -2
- package/lib/Cli/commands/state.d.ts.map +1 -1
- package/lib/Cli/commands/state.js +74 -27
- package/lib/Cli/commands/state.js.map +1 -1
- package/lib/Cli/components/capabilities.d.ts +4 -0
- package/lib/Cli/components/capabilities.d.ts.map +1 -0
- package/lib/Cli/components/capabilities.js +18 -0
- package/lib/Cli/components/capabilities.js.map +1 -0
- package/lib/Cli/components/types.d.ts +2 -81
- package/lib/Cli/components/types.d.ts.map +1 -1
- package/lib/Cli/components/types.js +1 -3
- package/lib/Cli/components/types.js.map +1 -1
- package/lib/Cli/components/ui/Environment.d.ts +3 -3
- package/lib/Cli/components/ui/Environment.d.ts.map +1 -1
- package/lib/Cli/components/ui/Environment.js.map +1 -1
- package/lib/Cli/components/ui/Interactive.d.ts +17 -4
- package/lib/Cli/components/ui/Interactive.d.ts.map +1 -1
- package/lib/Cli/components/ui/Interactive.js +7 -11
- package/lib/Cli/components/ui/Interactive.js.map +1 -1
- package/lib/Cli/components/ui/Layout.d.ts +1 -1
- package/lib/Cli/components/ui/Layout.d.ts.map +1 -1
- package/lib/Cli/components/ui/Layout.js +1 -1
- package/lib/Cli/components/ui/Layout.js.map +1 -1
- package/lib/Cli/components/ui/Typography.d.ts +1 -1
- package/lib/Cli/components/ui/Typography.d.ts.map +1 -1
- package/lib/Cli/components/ui/Typography.js +1 -1
- package/lib/Cli/components/ui/Typography.js.map +1 -1
- package/lib/Cli/components/ui/index.d.ts +2 -2
- package/lib/Cli/components/ui/index.js +2 -2
- package/lib/Cli/components/view/ApprovePlan.d.ts +1 -1
- package/lib/Cli/components/view/ApprovePlan.d.ts.map +1 -1
- package/lib/Cli/components/view/ApprovePlan.js +2 -1
- package/lib/Cli/components/view/ApprovePlan.js.map +1 -1
- package/lib/Cli/components/view/Format.d.ts +5 -0
- package/lib/Cli/components/view/Format.d.ts.map +1 -0
- package/lib/Cli/components/view/Format.js +39 -0
- package/lib/Cli/components/view/Format.js.map +1 -0
- package/lib/Cli/components/view/Help.d.ts +2 -2
- package/lib/Cli/components/view/Help.d.ts.map +1 -1
- package/lib/Cli/components/view/Help.js +7 -5
- package/lib/Cli/components/view/Help.js.map +1 -1
- package/lib/Cli/components/view/Logo.js +1 -1
- package/lib/Cli/components/view/Logo.js.map +1 -1
- package/lib/Cli/components/view/Nuke.d.ts +8 -9
- package/lib/Cli/components/view/Nuke.d.ts.map +1 -1
- package/lib/Cli/components/view/Nuke.js +49 -52
- package/lib/Cli/components/view/Nuke.js.map +1 -1
- package/lib/Cli/components/view/PlanDecision.d.ts +1 -1
- package/lib/Cli/components/view/PlanDecision.d.ts.map +1 -1
- package/lib/Cli/components/view/PlanDecision.js +1 -1
- package/lib/Cli/components/view/PlanDecision.js.map +1 -1
- package/lib/Cli/components/view/PlanRow.js +1 -1
- package/lib/Cli/components/view/PlanRow.js.map +1 -1
- package/lib/Cli/components/view/PlanTree.d.ts +1 -1
- package/lib/Cli/components/view/PlanTree.d.ts.map +1 -1
- package/lib/Cli/components/view/PlanTree.js +1 -1
- package/lib/Cli/components/view/PlanView.js +1 -1
- package/lib/Cli/components/view/PlanView.js.map +1 -1
- package/lib/Cli/components/view/Profile.d.ts +1 -1
- package/lib/Cli/components/view/Profile.js +2 -2
- package/lib/Cli/components/view/Profile.js.map +1 -1
- package/lib/Cli/components/view/ProfileDashboard.d.ts +4 -4
- package/lib/Cli/components/view/ProfileDashboard.d.ts.map +1 -1
- package/lib/Cli/components/view/ProfileDashboard.js +9 -8
- package/lib/Cli/components/view/ProfileDashboard.js.map +1 -1
- package/lib/Cli/components/view/Prompts.d.ts +3 -3
- package/lib/Cli/components/view/Prompts.d.ts.map +1 -1
- package/lib/Cli/components/view/Prompts.js +11 -18
- package/lib/Cli/components/view/Prompts.js.map +1 -1
- package/lib/Cli/components/view/Runtime.d.ts +5 -5
- package/lib/Cli/components/view/Runtime.d.ts.map +1 -1
- package/lib/Cli/components/view/Runtime.js +136 -219
- package/lib/Cli/components/view/Runtime.js.map +1 -1
- package/lib/Cli/components/view/SigilCli.d.ts +2 -2
- package/lib/Cli/components/view/SigilCli.d.ts.map +1 -1
- package/lib/Cli/components/view/SigilCli.js +7 -7
- package/lib/Cli/components/view/SigilCli.js.map +1 -1
- package/lib/Cli/components/view/StateExplorer.d.ts +1 -1
- package/lib/Cli/components/view/StateExplorer.d.ts.map +1 -1
- package/lib/Cli/components/view/StateExplorer.js +2 -1
- package/lib/Cli/components/view/StateExplorer.js.map +1 -1
- package/lib/Cli/components/view/statusStyle.d.ts +2 -2
- package/lib/Cli/components/view/statusStyle.d.ts.map +1 -1
- package/lib/Cli/components/view/statusStyle.js +1 -1
- package/lib/Cli/components/view/statusStyle.js.map +1 -1
- package/lib/Cli/exec.d.ts +6 -1
- package/lib/Cli/exec.d.ts.map +1 -1
- package/lib/Cli/exec.js +29 -34
- package/lib/Cli/exec.js.map +1 -1
- package/lib/Cli/main.d.ts.map +1 -1
- package/lib/Cli/main.js +35 -26
- package/lib/Cli/main.js.map +1 -1
- package/lib/Cli/selectCli.d.ts +2 -2
- package/lib/Cli/selectCli.d.ts.map +1 -1
- package/lib/Cli/selectCli.js +2 -2
- package/lib/Cli/selectCli.js.map +1 -1
- package/lib/Command/Command.js +1 -1
- package/lib/Command/Command.js.map +1 -1
- package/lib/Command/Dev.d.ts +58 -4
- package/lib/Command/Dev.d.ts.map +1 -1
- package/lib/Command/Dev.js +87 -30
- package/lib/Command/Dev.js.map +1 -1
- package/lib/Command/Local.d.ts +1 -1
- package/lib/Command/Memo.js +1 -1
- package/lib/Command/Memo.js.map +1 -1
- package/lib/Command/Providers.d.ts +1 -1
- package/lib/Command/Providers.d.ts.map +1 -1
- package/lib/Contributions.d.ts +2 -3
- package/lib/Contributions.d.ts.map +1 -1
- package/lib/Contributions.js +38 -6
- package/lib/Contributions.js.map +1 -1
- package/lib/DNS/Adapter.d.ts +204 -0
- package/lib/DNS/Adapter.d.ts.map +1 -0
- package/lib/DNS/Adapter.js +112 -0
- package/lib/DNS/Adapter.js.map +1 -0
- package/lib/DNS/index.d.ts +2 -0
- package/lib/DNS/index.d.ts.map +1 -0
- package/lib/DNS/index.js +2 -0
- package/lib/DNS/index.js.map +1 -0
- package/lib/Deploy.d.ts +7 -2
- package/lib/Deploy.d.ts.map +1 -1
- package/lib/Deploy.js +8 -3
- package/lib/Deploy.js.map +1 -1
- package/lib/Destroy.d.ts +5 -8
- package/lib/Destroy.d.ts.map +1 -1
- package/lib/Destroy.js +10 -7
- package/lib/Destroy.js.map +1 -1
- package/lib/Diff.d.ts.map +1 -1
- package/lib/Diff.js +14 -4
- package/lib/Diff.js.map +1 -1
- package/lib/Drift.d.ts +7 -7
- package/lib/Drift.d.ts.map +1 -1
- package/lib/Drift.js +184 -101
- package/lib/Drift.js.map +1 -1
- package/lib/EvalStack.d.ts +23 -0
- package/lib/EvalStack.d.ts.map +1 -0
- package/lib/EvalStack.js +47 -0
- package/lib/EvalStack.js.map +1 -0
- package/lib/Events.d.ts +210 -0
- package/lib/Events.d.ts.map +1 -0
- package/lib/Events.js +244 -0
- package/lib/Events.js.map +1 -0
- package/lib/Interaction.d.ts +159 -48
- package/lib/Interaction.d.ts.map +1 -1
- package/lib/Interaction.js +139 -58
- package/lib/Interaction.js.map +1 -1
- package/lib/Local/LocalProvider.d.ts.map +1 -1
- package/lib/Local/LocalProvider.js +31 -9
- package/lib/Local/LocalProvider.js.map +1 -1
- package/lib/Local/RpcProvider.d.ts.map +1 -1
- package/lib/Local/RpcProvider.js +10 -1
- package/lib/Local/RpcProvider.js.map +1 -1
- package/lib/Local/RpcProviderProxy.d.ts +16 -0
- package/lib/Local/RpcProviderProxy.d.ts.map +1 -1
- package/lib/Local/RpcProviderProxy.js +19 -10
- package/lib/Local/RpcProviderProxy.js.map +1 -1
- package/lib/Local/RpcSerialization.d.ts +3 -2
- package/lib/Local/RpcSerialization.d.ts.map +1 -1
- package/lib/Local/RpcSerialization.js +13 -10
- package/lib/Local/RpcSerialization.js.map +1 -1
- package/lib/Local/RpcServer.d.ts +2 -1
- package/lib/Local/RpcServer.d.ts.map +1 -1
- package/lib/Local/RpcServer.js +19 -14
- package/lib/Local/RpcServer.js.map +1 -1
- package/lib/Local/RpcServerBun.d.ts.map +1 -1
- package/lib/Local/RpcServerBun.js +8 -4
- package/lib/Local/RpcServerBun.js.map +1 -1
- package/lib/Local/RpcServerEnvironment.d.ts +2 -3
- package/lib/Local/RpcServerEnvironment.d.ts.map +1 -1
- package/lib/Local/RpcServerEnvironment.js +2 -2
- package/lib/Local/RpcServerEnvironment.js.map +1 -1
- package/lib/Local/RpcServerNode.d.ts.map +1 -1
- package/lib/Local/RpcServerNode.js +5 -1
- package/lib/Local/RpcServerNode.js.map +1 -1
- package/lib/Local/RpcServerSession.d.ts +1 -1
- package/lib/Local/RpcServerSession.d.ts.map +1 -1
- package/lib/Local/RpcServerSession.js.map +1 -1
- package/lib/Local/RpcSpawner.d.ts +6 -8
- package/lib/Local/RpcSpawner.d.ts.map +1 -1
- package/lib/Local/RpcSpawner.js +45 -36
- package/lib/Local/RpcSpawner.js.map +1 -1
- package/lib/Local/Sidecar.d.ts +23 -0
- package/lib/Local/Sidecar.d.ts.map +1 -1
- package/lib/Local/Sidecar.js +14 -9
- package/lib/Local/Sidecar.js.map +1 -1
- package/lib/Nuke.d.ts +5 -23
- package/lib/Nuke.d.ts.map +1 -1
- package/lib/Nuke.js +48 -13
- package/lib/Nuke.js.map +1 -1
- package/lib/Output.d.ts +19 -1
- package/lib/Output.d.ts.map +1 -1
- package/lib/Output.js +96 -3
- package/lib/Output.js.map +1 -1
- package/lib/Plan.d.ts +5 -1
- package/lib/Plan.d.ts.map +1 -1
- package/lib/Plan.js +111 -33
- package/lib/Plan.js.map +1 -1
- package/lib/Platform.d.ts.map +1 -1
- package/lib/Platform.js +31 -7
- package/lib/Platform.js.map +1 -1
- package/lib/Provider.d.ts +45 -0
- package/lib/Provider.d.ts.map +1 -1
- package/lib/Provider.js +2 -2
- package/lib/Provider.js.map +1 -1
- package/lib/Report.d.ts +17 -195
- package/lib/Report.d.ts.map +1 -1
- package/lib/Report.js +39 -12
- package/lib/Report.js.map +1 -1
- package/lib/Runtime/ManagedHttpShutdown.d.ts +17 -0
- package/lib/Runtime/ManagedHttpShutdown.d.ts.map +1 -1
- package/lib/Runtime/ManagedHttpShutdown.js +11 -2
- package/lib/Runtime/ManagedHttpShutdown.js.map +1 -1
- package/lib/RuntimeContext.js +1 -1
- package/lib/RuntimeContext.js.map +1 -1
- package/lib/Stack.d.ts +49 -29
- package/lib/Stack.d.ts.map +1 -1
- package/lib/Stack.js +25 -31
- package/lib/Stack.js.map +1 -1
- package/lib/State/BucketState.d.ts.map +1 -1
- package/lib/State/BucketState.js +43 -14
- package/lib/State/BucketState.js.map +1 -1
- package/lib/State/LocalState.d.ts.map +1 -1
- package/lib/State/LocalState.js +3 -3
- package/lib/State/LocalState.js.map +1 -1
- package/lib/State/Provisioning.d.ts +5 -0
- package/lib/State/Provisioning.d.ts.map +1 -1
- package/lib/State/Provisioning.js +3 -1
- package/lib/State/Provisioning.js.map +1 -1
- package/lib/State/ResourceState.d.ts +2 -0
- package/lib/State/ResourceState.d.ts.map +1 -1
- package/lib/State/State.d.ts +26 -0
- package/lib/State/State.d.ts.map +1 -1
- package/lib/State/StateEncoding.d.ts +7 -0
- package/lib/State/StateEncoding.d.ts.map +1 -1
- package/lib/State/StateEncoding.js +19 -0
- package/lib/State/StateEncoding.js.map +1 -1
- package/lib/State/index.js +2 -2
- package/lib/State/index.js.map +1 -1
- package/lib/Telemetry/Layer.d.ts +2 -5
- package/lib/Telemetry/Layer.d.ts.map +1 -1
- package/lib/Telemetry/Layer.js +3 -23
- package/lib/Telemetry/Layer.js.map +1 -1
- package/lib/Telemetry/Metrics.d.ts +1 -1
- package/lib/Telemetry/Metrics.d.ts.map +1 -1
- package/lib/TelemetryRelay.js +1 -1
- package/lib/TelemetryRelay.js.map +1 -1
- package/lib/TelemetryRuntime.d.ts +1 -1
- package/lib/TelemetryRuntime.d.ts.map +1 -1
- package/lib/TelemetryRuntime.js +4 -3
- package/lib/TelemetryRuntime.js.map +1 -1
- package/lib/Util/ConsoleSink.d.ts +23 -2
- package/lib/Util/ConsoleSink.d.ts.map +1 -1
- package/lib/Util/ConsoleSink.js +54 -14
- package/lib/Util/ConsoleSink.js.map +1 -1
- package/lib/Util/LogAnnotation.d.ts +19 -0
- package/lib/Util/LogAnnotation.d.ts.map +1 -0
- package/lib/Util/LogAnnotation.js +19 -0
- package/lib/Util/LogAnnotation.js.map +1 -0
- package/lib/Util/LogRecord.d.ts +281 -0
- package/lib/Util/LogRecord.d.ts.map +1 -0
- package/lib/Util/LogRecord.js +267 -0
- package/lib/Util/LogRecord.js.map +1 -0
- package/lib/Util/Node.d.ts +9 -0
- package/lib/Util/Node.d.ts.map +1 -1
- package/lib/Util/Node.js +10 -6
- package/lib/Util/Node.js.map +1 -1
- package/lib/Util/PlatformServices.d.ts +3 -2
- package/lib/Util/PlatformServices.d.ts.map +1 -1
- package/lib/Util/PlatformServices.js +6 -2
- package/lib/Util/PlatformServices.js.map +1 -1
- package/lib/Util/ResourceOutput.d.ts +18 -10
- package/lib/Util/ResourceOutput.d.ts.map +1 -1
- package/lib/Util/ResourceOutput.js +22 -23
- package/lib/Util/ResourceOutput.js.map +1 -1
- package/lib/Util/Shutdown.d.ts +10 -0
- package/lib/Util/Shutdown.d.ts.map +1 -0
- package/lib/Util/Shutdown.js +32 -0
- package/lib/Util/Shutdown.js.map +1 -0
- package/lib/Util/Terminal.d.ts +2 -4
- package/lib/Util/Terminal.d.ts.map +1 -1
- package/lib/Util/Terminal.js +3 -11
- package/lib/Util/Terminal.js.map +1 -1
- package/lib/Util/TraceParent.d.ts +32 -0
- package/lib/Util/TraceParent.d.ts.map +1 -0
- package/lib/Util/TraceParent.js +42 -0
- package/lib/Util/TraceParent.js.map +1 -0
- package/lib/Util/base64.d.ts +7 -0
- package/lib/Util/base64.d.ts.map +1 -0
- package/lib/Util/base64.js +24 -0
- package/lib/Util/base64.js.map +1 -0
- package/lib/Util/cached-function.d.ts +5 -0
- package/lib/Util/cached-function.d.ts.map +1 -1
- package/lib/Util/cached-function.js +13 -8
- package/lib/Util/cached-function.js.map +1 -1
- package/lib/Util/data.d.ts +1 -1
- package/lib/Util/data.d.ts.map +1 -1
- package/lib/Util/data.js +1 -1
- package/lib/Util/data.js.map +1 -1
- package/lib/Util/equal.d.ts.map +1 -1
- package/lib/Util/equal.js +3 -2
- package/lib/Util/equal.js.map +1 -1
- package/lib/Util/extraFiles.d.ts.map +1 -1
- package/lib/Util/extraFiles.js +5 -5
- package/lib/Util/extraFiles.js.map +1 -1
- package/lib/Util/interactive.js +1 -1
- package/lib/Website/AstroOutput.d.ts +42 -0
- package/lib/Website/AstroOutput.d.ts.map +1 -0
- package/lib/Website/AstroOutput.js +34 -0
- package/lib/Website/AstroOutput.js.map +1 -0
- package/lib/Website/FrontendCore.d.ts +1 -1
- package/lib/Workflows.d.ts +9 -0
- package/lib/Workflows.d.ts.map +1 -1
- package/lib/Workflows.js +8 -0
- package/lib/Workflows.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/package.json +21 -28
- package/src/AdoptPolicy.ts +76 -0
- package/src/Alchemist/AuthRegistry.ts +164 -0
- package/src/Alchemist/Drift.ts +103 -0
- package/src/Alchemist/Entrypoint.ts +51 -3
- package/src/Alchemist/Errors.ts +1 -1
- package/src/Alchemist/{routes/logs.ts → Logs.ts} +28 -30
- package/src/Alchemist/Nuke.ts +90 -0
- package/src/Alchemist/Operations.ts +309 -0
- package/src/Alchemist/{routes/profile.ts → Profile.ts} +22 -22
- package/src/Alchemist/{routes/provider.ts → Provider.ts} +7 -6
- package/src/Alchemist/Runtime.ts +46 -12
- package/src/Alchemist/{routes/state.ts → State.ts} +78 -21
- package/src/Alchemist/index.ts +32 -15
- package/src/Apply.ts +513 -274
- package/src/Auth/AuthProvider.ts +76 -23
- package/src/Auth/BrowserOAuth.ts +37 -60
- package/src/Auth/Credentials.ts +2 -4
- package/src/Auth/Demand.ts +27 -18
- package/src/Auth/Env.ts +13 -8
- package/src/Auth/Inspect.ts +5 -2
- package/src/Auth/Lock.ts +4 -8
- package/src/Auth/OAuthFlow.ts +12 -26
- package/src/Auth/Paths.ts +3 -2
- package/src/Auth/Profile.ts +30 -2
- package/src/Auth/Registry.ts +27 -0
- package/src/Auth/Resolve.ts +75 -3
- package/src/Auth/StoredAuthProvider.ts +1 -2
- package/src/Binding.ts +3 -4
- package/src/Bundle/Bundle.ts +58 -7
- package/src/Bundle/NamespaceImportPlugin.ts +259 -0
- package/src/Bundle/index.ts +1 -0
- package/src/Cli/Format.ts +2 -1
- package/src/Cli/GlobalLog.ts +206 -68
- package/src/Cli/LoggingCli.ts +33 -20
- package/src/Cli/PlainCliFormatter.ts +4 -1
- package/src/Cli/Present.ts +34 -0
- package/src/Cli/SigilRenderer.ts +75 -0
- package/src/Cli/checkVersion.ts +25 -78
- package/src/Cli/commands/confirm.ts +3 -3
- package/src/Cli/commands/deploy.ts +53 -44
- package/src/Cli/commands/dev.ts +65 -7
- package/src/Cli/commands/drift.ts +20 -16
- package/src/Cli/commands/errors.ts +2 -3
- package/src/Cli/commands/instrument.ts +39 -8
- package/src/Cli/commands/logs.ts +22 -30
- package/src/Cli/commands/nuke.ts +25 -26
- package/src/Cli/commands/profile/commands.ts +34 -34
- package/src/Cli/commands/profile/flows.ts +26 -20
- package/src/Cli/commands/profile/hub.ts +16 -18
- package/src/Cli/commands/provider.ts +4 -4
- package/src/Cli/commands/render.ts +43 -71
- package/src/Cli/commands/state.ts +113 -33
- package/src/Cli/components/capabilities.ts +20 -0
- package/src/Cli/components/types.ts +13 -99
- package/src/Cli/components/ui/Environment.tsx +5 -5
- package/src/Cli/components/ui/Interactive.tsx +24 -15
- package/src/Cli/components/ui/Layout.tsx +1 -1
- package/src/Cli/components/ui/Typography.tsx +1 -1
- package/src/Cli/components/ui/index.ts +2 -2
- package/src/Cli/components/view/ApprovePlan.tsx +2 -1
- package/src/Cli/components/view/Format.tsx +58 -0
- package/src/Cli/components/view/Help.tsx +14 -17
- package/src/Cli/components/view/Logo.tsx +1 -1
- package/src/Cli/components/view/Nuke.tsx +74 -49
- package/src/Cli/components/view/PlanDecision.tsx +1 -1
- package/src/Cli/components/view/PlanRow.tsx +1 -1
- package/src/Cli/components/view/PlanTree.ts +2 -2
- package/src/Cli/components/view/PlanView.tsx +2 -2
- package/src/Cli/components/view/Profile.tsx +2 -2
- package/src/Cli/components/view/ProfileDashboard.tsx +12 -11
- package/src/Cli/components/view/Prompts.tsx +37 -75
- package/src/Cli/components/view/Runtime.tsx +132 -238
- package/src/Cli/components/view/SigilCli.tsx +12 -12
- package/src/Cli/components/view/StateExplorer.tsx +2 -1
- package/src/Cli/components/view/statusStyle.ts +2 -2
- package/src/Cli/exec.ts +48 -41
- package/src/Cli/main.ts +52 -33
- package/src/Cli/selectCli.ts +3 -3
- package/src/Command/Command.ts +1 -1
- package/src/Command/Dev.ts +129 -36
- package/src/Command/Memo.ts +1 -1
- package/src/Contributions.ts +42 -8
- package/src/DNS/Adapter.ts +289 -0
- package/src/DNS/index.ts +1 -0
- package/src/Deploy.ts +11 -3
- package/src/Destroy.ts +19 -13
- package/src/Diff.ts +17 -4
- package/src/Drift.ts +256 -127
- package/src/EvalStack.ts +97 -0
- package/src/Events.ts +296 -0
- package/src/Interaction.ts +332 -97
- package/src/Local/LocalProvider.ts +40 -9
- package/src/Local/RpcProvider.ts +11 -1
- package/src/Local/RpcProviderProxy.ts +29 -21
- package/src/Local/RpcSerialization.ts +32 -17
- package/src/Local/RpcServer.ts +25 -17
- package/src/Local/RpcServerBun.ts +10 -6
- package/src/Local/RpcServerEnvironment.ts +2 -2
- package/src/Local/RpcServerNode.ts +8 -1
- package/src/Local/RpcServerSession.ts +2 -2
- package/src/Local/RpcSpawner.ts +61 -37
- package/src/Local/Sidecar.ts +10 -1
- package/src/Nuke.ts +66 -43
- package/src/Output.ts +120 -7
- package/src/Plan.ts +140 -52
- package/src/Platform.ts +47 -18
- package/src/Provider.ts +48 -3
- package/src/Report.ts +77 -275
- package/src/Runtime/ManagedHttpShutdown.ts +21 -4
- package/src/RuntimeContext.ts +1 -1
- package/src/Stack.ts +113 -135
- package/src/State/BucketState.ts +53 -21
- package/src/State/LocalState.ts +7 -9
- package/src/State/Provisioning.ts +8 -1
- package/src/State/ResourceState.ts +2 -0
- package/src/State/State.ts +30 -0
- package/src/State/StateEncoding.ts +22 -0
- package/src/State/index.ts +2 -2
- package/src/Telemetry/Layer.ts +3 -24
- package/src/Telemetry/Metrics.ts +1 -1
- package/src/TelemetryRelay.ts +1 -1
- package/src/TelemetryRuntime.ts +8 -8
- package/src/Util/ConsoleSink.ts +76 -13
- package/src/Util/LogAnnotation.ts +18 -0
- package/src/Util/LogRecord.ts +386 -0
- package/src/Util/Node.ts +20 -6
- package/src/Util/PlatformServices.ts +17 -4
- package/src/Util/ResourceOutput.ts +26 -25
- package/src/Util/Shutdown.ts +52 -0
- package/src/Util/Terminal.ts +3 -20
- package/src/Util/TraceParent.ts +70 -0
- package/src/Util/base64.ts +22 -0
- package/src/Util/cached-function.ts +30 -19
- package/src/Util/data.ts +2 -2
- package/src/Util/equal.ts +3 -2
- package/src/Util/extraFiles.ts +9 -8
- package/src/Util/interactive.ts +1 -1
- package/src/Website/AstroOutput.ts +83 -0
- package/src/Workflows.ts +11 -0
- package/src/index.ts +1 -0
- package/lib/Alchemist/Progress.d.ts +0 -16
- package/lib/Alchemist/Progress.d.ts.map +0 -1
- package/lib/Alchemist/Progress.js +0 -123
- package/lib/Alchemist/Progress.js.map +0 -1
- package/lib/Alchemist/Session.d.ts +0 -116
- package/lib/Alchemist/Session.d.ts.map +0 -1
- package/lib/Alchemist/Session.js +0 -212
- package/lib/Alchemist/Session.js.map +0 -1
- package/lib/Alchemist/routes/drift.d.ts +0 -55
- package/lib/Alchemist/routes/drift.d.ts.map +0 -1
- package/lib/Alchemist/routes/drift.js +0 -52
- package/lib/Alchemist/routes/drift.js.map +0 -1
- package/lib/Alchemist/routes/logs.d.ts +0 -41
- package/lib/Alchemist/routes/logs.d.ts.map +0 -1
- package/lib/Alchemist/routes/logs.js.map +0 -1
- package/lib/Alchemist/routes/nuke.d.ts +0 -46
- package/lib/Alchemist/routes/nuke.d.ts.map +0 -1
- package/lib/Alchemist/routes/nuke.js +0 -80
- package/lib/Alchemist/routes/nuke.js.map +0 -1
- package/lib/Alchemist/routes/profile.d.ts +0 -133
- package/lib/Alchemist/routes/profile.d.ts.map +0 -1
- package/lib/Alchemist/routes/profile.js.map +0 -1
- package/lib/Alchemist/routes/provider.d.ts.map +0 -1
- package/lib/Alchemist/routes/provider.js.map +0 -1
- package/lib/Alchemist/routes/stack.d.ts +0 -95
- package/lib/Alchemist/routes/stack.d.ts.map +0 -1
- package/lib/Alchemist/routes/stack.js +0 -73
- package/lib/Alchemist/routes/stack.js.map +0 -1
- package/lib/Alchemist/routes/state.d.ts.map +0 -1
- package/lib/Alchemist/routes/state.js.map +0 -1
- package/lib/Cli/CliKit/CliKit.d.ts +0 -92
- package/lib/Cli/CliKit/CliKit.d.ts.map +0 -1
- package/lib/Cli/CliKit/CliKit.js +0 -27
- package/lib/Cli/CliKit/CliKit.js.map +0 -1
- package/lib/Cli/CliKit/index.d.ts +0 -9
- package/lib/Cli/CliKit/index.d.ts.map +0 -1
- package/lib/Cli/CliKit/index.js +0 -9
- package/lib/Cli/CliKit/index.js.map +0 -1
- package/lib/Cli/CliKit/interaction.d.ts +0 -13
- package/lib/Cli/CliKit/interaction.d.ts.map +0 -1
- package/lib/Cli/CliKit/interaction.js +0 -17
- package/lib/Cli/CliKit/interaction.js.map +0 -1
- package/lib/Cli/CliKit/layer.d.ts +0 -7
- package/lib/Cli/CliKit/layer.d.ts.map +0 -1
- package/lib/Cli/CliKit/layer.js +0 -33
- package/lib/Cli/CliKit/layer.js.map +0 -1
- package/lib/Local/DevLog.d.ts +0 -32
- package/lib/Local/DevLog.d.ts.map +0 -1
- package/lib/Local/DevLog.js +0 -112
- package/lib/Local/DevLog.js.map +0 -1
- package/lib/Test/Alchemy.d.ts +0 -79
- package/lib/Test/Alchemy.d.ts.map +0 -1
- package/lib/Test/Alchemy.js +0 -193
- package/lib/Test/Alchemy.js.map +0 -1
- package/lib/Test/Bun.d.ts +0 -69
- package/lib/Test/Bun.d.ts.map +0 -1
- package/lib/Test/Bun.js +0 -126
- package/lib/Test/Bun.js.map +0 -1
- package/lib/Test/Core.d.ts +0 -277
- package/lib/Test/Core.d.ts.map +0 -1
- package/lib/Test/Core.js +0 -362
- package/lib/Test/Core.js.map +0 -1
- package/lib/Test/Http.d.ts +0 -109
- package/lib/Test/Http.d.ts.map +0 -1
- package/lib/Test/Http.js +0 -123
- package/lib/Test/Http.js.map +0 -1
- package/lib/Test/TestState.d.ts +0 -12
- package/lib/Test/TestState.d.ts.map +0 -1
- package/lib/Test/TestState.js +0 -15
- package/lib/Test/TestState.js.map +0 -1
- package/lib/Test/Vitest.d.ts +0 -60
- package/lib/Test/Vitest.d.ts.map +0 -1
- package/lib/Test/Vitest.js +0 -132
- package/lib/Test/Vitest.js.map +0 -1
- package/lib/Test/index.d.ts +0 -3
- package/lib/Test/index.d.ts.map +0 -1
- package/lib/Test/index.js +0 -3
- package/lib/Test/index.js.map +0 -1
- package/lib/Util/FileLogger.d.ts +0 -7
- package/lib/Util/FileLogger.d.ts.map +0 -1
- package/lib/Util/FileLogger.js +0 -16
- package/lib/Util/FileLogger.js.map +0 -1
- package/src/Alchemist/Progress.ts +0 -167
- package/src/Alchemist/Session.ts +0 -415
- package/src/Alchemist/routes/drift.ts +0 -87
- package/src/Alchemist/routes/nuke.ts +0 -131
- package/src/Alchemist/routes/stack.ts +0 -173
- package/src/Cli/CliKit/CliKit.ts +0 -159
- package/src/Cli/CliKit/index.ts +0 -41
- package/src/Cli/CliKit/interaction.ts +0 -19
- package/src/Cli/CliKit/layer.ts +0 -44
- package/src/Local/DevLog.ts +0 -122
- package/src/Test/Alchemy.ts +0 -334
- package/src/Test/Bun.ts +0 -230
- package/src/Test/Core.ts +0 -785
- package/src/Test/Http.ts +0 -201
- package/src/Test/TestState.ts +0 -35
- package/src/Test/Vitest.ts +0 -239
- package/src/Test/index.ts +0 -2
- package/src/Util/FileLogger.ts +0 -20
package/src/Apply.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { ConfigError } from "effect/Config";
|
|
|
3
3
|
import * as Data from "effect/Data";
|
|
4
4
|
import * as Deferred from "effect/Deferred";
|
|
5
5
|
import * as Effect from "effect/Effect";
|
|
6
|
-
import * as
|
|
6
|
+
import * as Formatter from "effect/Formatter";
|
|
7
7
|
import * as Layer from "effect/Layer";
|
|
8
8
|
import * as Option from "effect/Option";
|
|
9
9
|
import type { PlatformError } from "effect/PlatformError";
|
|
@@ -11,7 +11,13 @@ import * as Predicate from "effect/Predicate";
|
|
|
11
11
|
import type { Simplify } from "effect/Types";
|
|
12
12
|
import type { ActionLike } from "./Action.ts";
|
|
13
13
|
import { makeResolveContext } from "./ActionRuntimeContext.ts";
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
OwnedBySomeoneElse,
|
|
16
|
+
stripUnowned,
|
|
17
|
+
Unowned,
|
|
18
|
+
Unresolved,
|
|
19
|
+
UnverifiableReplacement,
|
|
20
|
+
} from "./AdoptPolicy.ts";
|
|
15
21
|
import { AlchemyContext } from "./AlchemyContext.ts";
|
|
16
22
|
import {
|
|
17
23
|
Artifacts,
|
|
@@ -26,26 +32,21 @@ import {
|
|
|
26
32
|
failCredentialsRequired,
|
|
27
33
|
demandPlanCredentials,
|
|
28
34
|
} from "./Auth/Demand.ts";
|
|
29
|
-
import { havePropsChanged, stripUnresolved } from "./Diff.ts";
|
|
35
|
+
import { havePropsChanged, isResolved, stripEffects, stripUnresolved } from "./Diff.ts";
|
|
36
|
+
import { captureEmit, type ApplyEvent, type ApplyStatus } from "./Events.ts";
|
|
30
37
|
import type { Input } from "./Input.ts";
|
|
31
38
|
import { generateInstanceId } from "./InstanceId.ts";
|
|
32
39
|
import * as Output from "./Output.ts";
|
|
33
40
|
import { type ActionApply, type Apply, type Delete, type Plan } from "./Plan.ts";
|
|
34
41
|
import {
|
|
35
42
|
type DeleteInProgress,
|
|
43
|
+
type ProviderService,
|
|
36
44
|
findProviderByType,
|
|
37
45
|
missingProviderError,
|
|
38
46
|
tryFindProviderByType,
|
|
39
47
|
} from "./Provider.ts";
|
|
40
48
|
import { stampedMode, type ProviderMode } from "./ProviderMode.ts";
|
|
41
|
-
import {
|
|
42
|
-
type PlanDisplayOptions,
|
|
43
|
-
type PlanStatusSession,
|
|
44
|
-
type ScopedPlanStatusSession,
|
|
45
|
-
Cli,
|
|
46
|
-
noopSession,
|
|
47
|
-
} from "./Report.ts";
|
|
48
|
-
import type { ApplyStatus } from "./Report.ts";
|
|
49
|
+
import { resourceSession } from "./Report.ts";
|
|
49
50
|
import type { ResourceBinding } from "./Resource.ts";
|
|
50
51
|
import { ResourceContext } from "./ResourceContext.ts";
|
|
51
52
|
import { RuntimeContext } from "./RuntimeContext.ts";
|
|
@@ -70,19 +71,20 @@ import {
|
|
|
70
71
|
StateStoreError,
|
|
71
72
|
} from "./State/index.ts";
|
|
72
73
|
import { type ResourceOp, recordResourceOp } from "./Telemetry/Metrics.ts";
|
|
74
|
+
import { LogAnnotation } from "./Util/LogAnnotation.ts";
|
|
73
75
|
import { hashInput } from "./Util/sha256.ts";
|
|
74
76
|
|
|
75
77
|
export type AppliedPlan<P extends Plan> = {
|
|
76
|
-
[id in keyof P["resources"]]: P["resources"][id] extends Delete | undefined
|
|
78
|
+
[id in keyof P["resources"]]: P["resources"][id] extends Delete | undefined
|
|
77
79
|
? never
|
|
78
80
|
: Simplify<P["resources"][id]["resource"]["attr"]>;
|
|
79
81
|
};
|
|
80
82
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
/**
|
|
84
|
+
* Where the engine reports apply progress. Every event goes out as a log
|
|
85
|
+
* record; renderers observe them with `onEvent`.
|
|
86
|
+
*/
|
|
87
|
+
type Reporter = (event: ApplyEvent) => Effect.Effect<void>;
|
|
86
88
|
|
|
87
89
|
interface ResourceTracker {
|
|
88
90
|
output: any;
|
|
@@ -107,6 +109,26 @@ const track = (
|
|
|
107
109
|
outputs[fqn] = entry.output;
|
|
108
110
|
};
|
|
109
111
|
|
|
112
|
+
/**
|
|
113
|
+
* Whether an attr-less checkpoint lost props to `stripUnresolved`. Its stored
|
|
114
|
+
* props no longer identify the physical resource it was creating (e.g. a
|
|
115
|
+
* stripped namespace makes a name match a different resource), so recovery
|
|
116
|
+
* must not look the resource up from them.
|
|
117
|
+
*
|
|
118
|
+
* Effect-valued props don't count: `Output.evaluate` passes them through
|
|
119
|
+
* untouched, so even fully resolved props carry them (a Function's runtime
|
|
120
|
+
* wiring). They never name a physical resource, and treating them as holes
|
|
121
|
+
* would mark every create of such a resource and orphan it on interruption.
|
|
122
|
+
*/
|
|
123
|
+
const propsIncomplete = (value: {
|
|
124
|
+
attr?: unknown;
|
|
125
|
+
props?: unknown;
|
|
126
|
+
propsIncomplete?: true;
|
|
127
|
+
}): true | undefined =>
|
|
128
|
+
value.attr === undefined && (value.propsIncomplete || !isResolved(stripEffects(value.props)))
|
|
129
|
+
? true
|
|
130
|
+
: undefined;
|
|
131
|
+
|
|
110
132
|
const provideLifecycleScope =
|
|
111
133
|
(resource: ResourceContext["Service"]) =>
|
|
112
134
|
<A, E, R>(effect: Effect.Effect<A, E, R>) =>
|
|
@@ -138,6 +160,8 @@ const instrumentLifecycle =
|
|
|
138
160
|
<A, E, R>(effect: Effect.Effect<A, E, R>) =>
|
|
139
161
|
effect.pipe(
|
|
140
162
|
provideLifecycleScope({ logicalId, fqn, instanceId, type: resourceType }),
|
|
163
|
+
// Every log a provider writes during the op carries its resource.
|
|
164
|
+
Effect.annotateLogs(LogAnnotation.fqn, fqn),
|
|
141
165
|
recordResourceOp(resourceType, op),
|
|
142
166
|
Effect.withSpan(`provider.${op}`, {
|
|
143
167
|
attributes: {
|
|
@@ -150,9 +174,92 @@ const instrumentLifecycle =
|
|
|
150
174
|
}),
|
|
151
175
|
);
|
|
152
176
|
|
|
177
|
+
type AdmissionNode = {
|
|
178
|
+
provider: Pick<ProviderService<any>, "observe" | "read">;
|
|
179
|
+
props: any;
|
|
180
|
+
deferredAdoption?: { adopt: boolean };
|
|
181
|
+
resource: { Type: string };
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* A dependency cycle precreates on raw props, before `read` can check
|
|
186
|
+
* ownership. Ask the provider's `observe` what exists at the identity
|
|
187
|
+
* precreate would claim, and refuse a foreign resource unless adoption is
|
|
188
|
+
* allowed. A provider without `observe` precreates `unchecked`; one whose
|
|
189
|
+
* identity has not resolved yet reports it `unresolved`, so the engine must
|
|
190
|
+
* check the resolved identity before reconcile claims it.
|
|
191
|
+
*/
|
|
192
|
+
const observeBeforePrecreate = Effect.fn(function* (
|
|
193
|
+
node: AdmissionNode,
|
|
194
|
+
news: any,
|
|
195
|
+
fqn: string,
|
|
196
|
+
logicalId: string,
|
|
197
|
+
instanceId: string,
|
|
198
|
+
previous?: any,
|
|
199
|
+
) {
|
|
200
|
+
if (node.provider.observe === undefined || node.deferredAdoption === undefined) {
|
|
201
|
+
return "unchecked" as const;
|
|
202
|
+
}
|
|
203
|
+
const observed = yield* node.provider
|
|
204
|
+
.observe({ id: logicalId, fqn, instanceId, news, previous })
|
|
205
|
+
.pipe(instrumentLifecycle("observe", fqn, node.resource.Type, logicalId, instanceId));
|
|
206
|
+
if (observed === Unresolved) return "unresolved" as const;
|
|
207
|
+
if (observed !== undefined && Unowned.is(observed) && !node.deferredAdoption.adopt) {
|
|
208
|
+
return yield* new OwnedBySomeoneElse({
|
|
209
|
+
message:
|
|
210
|
+
`Cannot pre-create resource '${fqn}' (${node.resource.Type}): ` +
|
|
211
|
+
"it exists in the cloud but is not owned by this " +
|
|
212
|
+
"stack/stage/logical-id. Re-run with `--adopt` (or " +
|
|
213
|
+
"wrap the effect in `adopt(true)`) to take it over.",
|
|
214
|
+
resourceType: node.resource.Type,
|
|
215
|
+
logicalId,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
return "admitted" as const;
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
/** A provider's `observe` reported `Unresolved` for fully resolved props. */
|
|
222
|
+
class UnresolvedObservation extends Data.TaggedError("UnresolvedObservation")<{
|
|
223
|
+
message: string;
|
|
224
|
+
}> {}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Reports what exists at the resolved identity reconcile will claim: `read`
|
|
228
|
+
* when the provider implements it, `observe` otherwise. A replacement passes
|
|
229
|
+
* its `previous` generation's attributes, so the provider can recognize it.
|
|
230
|
+
*/
|
|
231
|
+
const observeResolved = Effect.fn(function* (
|
|
232
|
+
node: AdmissionNode,
|
|
233
|
+
news: Record<string, any>,
|
|
234
|
+
fqn: string,
|
|
235
|
+
logicalId: string,
|
|
236
|
+
instanceId: string,
|
|
237
|
+
previous?: any,
|
|
238
|
+
) {
|
|
239
|
+
if (node.provider.read) {
|
|
240
|
+
return yield* node.provider
|
|
241
|
+
.read({ id: logicalId, fqn, instanceId, olds: news, output: undefined, previous })
|
|
242
|
+
.pipe(instrumentLifecycle("read", fqn, node.resource.Type, logicalId, instanceId));
|
|
243
|
+
}
|
|
244
|
+
const observed = yield* node.provider.observe!({
|
|
245
|
+
id: logicalId,
|
|
246
|
+
fqn,
|
|
247
|
+
instanceId,
|
|
248
|
+
news,
|
|
249
|
+
previous,
|
|
250
|
+
}).pipe(instrumentLifecycle("observe", fqn, node.resource.Type, logicalId, instanceId));
|
|
251
|
+
if (observed === Unresolved) {
|
|
252
|
+
return yield* Effect.die(
|
|
253
|
+
new UnresolvedObservation({
|
|
254
|
+
message: `The provider for '${fqn}' (${node.resource.Type}) reported its identity as Unresolved, but its props are resolved.`,
|
|
255
|
+
}),
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
return observed;
|
|
259
|
+
});
|
|
260
|
+
|
|
153
261
|
export const apply = <P extends Plan>(
|
|
154
262
|
plan: P,
|
|
155
|
-
options: ApplyOptions = {},
|
|
156
263
|
): Effect.Effect<
|
|
157
264
|
Input.Resolve<P["output"]>,
|
|
158
265
|
| Output.InvalidReferenceError
|
|
@@ -181,144 +288,146 @@ export const apply = <P extends Plan>(
|
|
|
181
288
|
yield* demandPlanCredentials(plan);
|
|
182
289
|
}
|
|
183
290
|
|
|
184
|
-
|
|
185
|
-
//
|
|
186
|
-
//
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
(
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
.
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
renamedFrom.filter((formerFqn) => !migrationTargets.has(formerFqn)),
|
|
250
|
-
(formerFqn) => state.delete({ stack: stackName, stage, fqn: formerFqn }),
|
|
251
|
-
{ concurrency: "unbounded" },
|
|
252
|
-
);
|
|
253
|
-
});
|
|
254
|
-
},
|
|
255
|
-
{ concurrency: "unbounded" },
|
|
256
|
-
);
|
|
291
|
+
const emitEvent = yield* captureEmit;
|
|
292
|
+
// The last status each resource announced, so the post-convergence
|
|
293
|
+
// flush below re-emits only what is still unannounced (cycle members).
|
|
294
|
+
const announced = new Map<string, ApplyStatus>();
|
|
295
|
+
const reportEvent: Reporter = (event) => {
|
|
296
|
+
if (event.type === "apply.resource.status") announced.set(event.fqn, event.status);
|
|
297
|
+
return emitEvent(event);
|
|
298
|
+
};
|
|
299
|
+
// No Effect.scoped around apply: local dev providers start long-running
|
|
300
|
+
// processes in the AMBIENT scope during reconcile, which a scope here
|
|
301
|
+
// would kill when apply returns.
|
|
302
|
+
const state = yield* yield* State;
|
|
303
|
+
const stack = yield* Stack;
|
|
304
|
+
const stage = yield* Stage;
|
|
305
|
+
const stackName = stack.name;
|
|
306
|
+
|
|
307
|
+
const tracker: Record<string, ResourceTracker> = {};
|
|
308
|
+
const outputs: Record<string, any> = {};
|
|
309
|
+
const terminalStatuses = new Map<
|
|
310
|
+
string,
|
|
311
|
+
{
|
|
312
|
+
fqn: string;
|
|
313
|
+
id: string;
|
|
314
|
+
type: string;
|
|
315
|
+
status: Extract<ApplyStatus, "created" | "updated" | "adopted" | "ran" | "skipped">;
|
|
316
|
+
providerMode?: ProviderMode;
|
|
317
|
+
}
|
|
318
|
+
>();
|
|
319
|
+
|
|
320
|
+
// ── FQN migrations (renamedFrom) ──
|
|
321
|
+
// Persist renames before any lifecycle operation runs: a node whose row
|
|
322
|
+
// was found under a former FQN carries that row pre-remapped in
|
|
323
|
+
// `node.state` (see Plan's rename resolution). Commit it at the current
|
|
324
|
+
// FQN FIRST, then drop the former row — in that order, so an
|
|
325
|
+
// interruption leaves rows at both FQNs with the same instanceId, which
|
|
326
|
+
// the next plan recognizes as an in-flight migration (and never as an
|
|
327
|
+
// orphan to delete).
|
|
328
|
+
//
|
|
329
|
+
// In a same-deploy shift (A→B while B→C), C's former FQN `B` is
|
|
330
|
+
// simultaneously B's migration TARGET. C must NOT delete it: B's own
|
|
331
|
+
// `state.set` supersedes the stale copy, and the migrations run
|
|
332
|
+
// concurrently — the delete could land after B's write and destroy the
|
|
333
|
+
// freshly migrated row.
|
|
334
|
+
const migrationTargets = new Set(
|
|
335
|
+
Object.values(plan.resources)
|
|
336
|
+
.filter((node) => node.renamedFrom?.length && node.state !== undefined)
|
|
337
|
+
.map((node) => node.resource.FQN),
|
|
338
|
+
);
|
|
339
|
+
yield* Effect.forEach(
|
|
340
|
+
Object.values(plan.resources),
|
|
341
|
+
(node) => {
|
|
342
|
+
const { renamedFrom, state: row } = node;
|
|
343
|
+
return renamedFrom === undefined || renamedFrom.length === 0 || row === undefined
|
|
344
|
+
? Effect.void
|
|
345
|
+
: Effect.gen(function* () {
|
|
346
|
+
yield* state.set({ stack: stackName, stage, fqn: node.resource.FQN, value: row });
|
|
347
|
+
yield* Effect.forEach(
|
|
348
|
+
renamedFrom.filter((formerFqn) => !migrationTargets.has(formerFqn)),
|
|
349
|
+
(formerFqn) => state.delete({ stack: stackName, stage, fqn: formerFqn }),
|
|
350
|
+
{ concurrency: "unbounded" },
|
|
351
|
+
);
|
|
352
|
+
});
|
|
353
|
+
},
|
|
354
|
+
{ concurrency: "unbounded" },
|
|
355
|
+
);
|
|
257
356
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
357
|
+
yield* executePlan(
|
|
358
|
+
plan,
|
|
359
|
+
tracker,
|
|
360
|
+
outputs,
|
|
361
|
+
terminalStatuses,
|
|
362
|
+
reportEvent,
|
|
363
|
+
state,
|
|
364
|
+
stackName,
|
|
365
|
+
stage,
|
|
366
|
+
);
|
|
268
367
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
368
|
+
// TODO(sam): support roll back to previous state if errors occur during expansion
|
|
369
|
+
// -> RISK: some UPDATEs may not be reversible (i.e. trigger replacements)
|
|
370
|
+
// TODO(sam): should pivot be done separately? E.g shift traffic?
|
|
272
371
|
|
|
273
|
-
|
|
372
|
+
yield* collectGarbage(plan, reportEvent);
|
|
274
373
|
|
|
275
|
-
|
|
374
|
+
yield* converge(plan, tracker, outputs, terminalStatuses, reportEvent, state, stackName, stage);
|
|
276
375
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
{
|
|
282
|
-
)
|
|
376
|
+
// Cycle members hold their terminal status until `converge` settles
|
|
377
|
+
// it; everything else announced it as it finished.
|
|
378
|
+
yield* Effect.forEach(
|
|
379
|
+
Array.from(terminalStatuses.values()).filter(
|
|
380
|
+
({ fqn, status }) => announced.get(fqn) !== status,
|
|
381
|
+
),
|
|
382
|
+
({ fqn, id, type, status, providerMode }) =>
|
|
383
|
+
reportEvent({
|
|
384
|
+
type: "apply.resource.status",
|
|
385
|
+
fqn,
|
|
386
|
+
id,
|
|
387
|
+
resourceType: type,
|
|
388
|
+
status,
|
|
389
|
+
providerMode,
|
|
390
|
+
}),
|
|
391
|
+
{ concurrency: "unbounded" },
|
|
392
|
+
);
|
|
283
393
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
}
|
|
306
|
-
return undefined;
|
|
394
|
+
if (plan.destroy) {
|
|
395
|
+
// The destroy converged: every resource row was deleted above. Drop
|
|
396
|
+
// the rest of the stage's persisted state — notably the stack output
|
|
397
|
+
// record written by the last deploy — so `getOutput` returns
|
|
398
|
+
// undefined and `listStages` no longer reports the stage.
|
|
399
|
+
// https://github.com/alchemy-run/alchemy/issues/961
|
|
400
|
+
yield* state.deleteStack({ stack: stackName, stage });
|
|
401
|
+
// Invariant: a successful destroy leaves the stage EMPTY. If rows
|
|
402
|
+
// survive, this destroy session could not actually see (or delete)
|
|
403
|
+
// the stack's state — e.g. its plan listed an empty store while
|
|
404
|
+
// committed rows existed — and reporting success here would silently
|
|
405
|
+
// leak every cloud resource those rows track. Fail loudly instead so
|
|
406
|
+
// the leak surfaces in the run that caused it.
|
|
407
|
+
const remaining = yield* state.list({ stack: stackName, stage });
|
|
408
|
+
if (remaining.length > 0) {
|
|
409
|
+
return yield* new StateStoreError({
|
|
410
|
+
message:
|
|
411
|
+
`destroy of ${stackName}/${stage} reported success but ${remaining.length} ` +
|
|
412
|
+
`state row(s) remain (${remaining.join(", ")}) — the destroy session could ` +
|
|
413
|
+
`not see the stack's persisted state, so its cloud resources were NOT deleted`,
|
|
414
|
+
});
|
|
307
415
|
}
|
|
416
|
+
return undefined;
|
|
417
|
+
}
|
|
308
418
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
419
|
+
if (plan.selectedFqns !== undefined || !plan.output) {
|
|
420
|
+
return undefined;
|
|
421
|
+
}
|
|
312
422
|
|
|
313
|
-
|
|
423
|
+
const resolved = yield* Output.evaluate(plan.output, outputs);
|
|
314
424
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
425
|
+
// Persist the stack's evaluated outputs so cross-stack references
|
|
426
|
+
// (`yield* OtherStack` / `OtherStack.stage.<name>` / `Output.stackRef`)
|
|
427
|
+
// can read them back out of the state store.
|
|
428
|
+
yield* state.setOutput({ stack: stackName, stage, value: resolved });
|
|
319
429
|
|
|
320
|
-
|
|
321
|
-
}).pipe(Effect.onExit((exit) => session.done(Exit.isSuccess(exit) ? "success" : "failure")));
|
|
430
|
+
return resolved;
|
|
322
431
|
}).pipe(
|
|
323
432
|
ensureArtifactStore,
|
|
324
433
|
Effect.withSpan("apply", {
|
|
@@ -350,7 +459,7 @@ const executePlan = Effect.fn(function* (
|
|
|
350
459
|
providerMode?: ProviderMode;
|
|
351
460
|
}
|
|
352
461
|
>,
|
|
353
|
-
|
|
462
|
+
reportEvent: Reporter,
|
|
354
463
|
state: {
|
|
355
464
|
set: <V extends PersistedState>(req: {
|
|
356
465
|
stack: string;
|
|
@@ -368,10 +477,8 @@ const executePlan = Effect.fn(function* (
|
|
|
368
477
|
const allNodes: Record<string, Apply | ActionApply> = { ...plan.resources, ...plan.actions };
|
|
369
478
|
|
|
370
479
|
const ready = Object.fromEntries(
|
|
371
|
-
yield* Effect.
|
|
372
|
-
|
|
373
|
-
Effect.map(Deferred.make<void>(), (d) => [fqn, d] as const),
|
|
374
|
-
),
|
|
480
|
+
yield* Effect.forEach(Object.keys(allNodes), (fqn) =>
|
|
481
|
+
Effect.map(Deferred.make<void>(), (d) => [fqn, d] as const),
|
|
375
482
|
),
|
|
376
483
|
) as Record<string, Deferred.Deferred<void>>;
|
|
377
484
|
|
|
@@ -380,50 +487,48 @@ const executePlan = Effect.fn(function* (
|
|
|
380
487
|
// precreate stubs do NOT signal `readyStable`, so any consumer that
|
|
381
488
|
// requires stable inputs (e.g. Tasks) waits past the precreate phase.
|
|
382
489
|
const readyStable = Object.fromEntries(
|
|
383
|
-
yield* Effect.
|
|
384
|
-
|
|
385
|
-
Effect.map(Deferred.make<void>(), (d) => [fqn, d] as const),
|
|
386
|
-
),
|
|
490
|
+
yield* Effect.forEach(Object.keys(allNodes), (fqn) =>
|
|
491
|
+
Effect.map(Deferred.make<void>(), (d) => [fqn, d] as const),
|
|
387
492
|
),
|
|
388
493
|
) as Record<string, Deferred.Deferred<void>>;
|
|
389
494
|
|
|
390
495
|
const waitForDeps = (downstreamFqn: string, fqns: string[]) =>
|
|
391
|
-
Effect.
|
|
392
|
-
fqns
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
: Deferred.await(readyStable[fqn]),
|
|
413
|
-
),
|
|
496
|
+
Effect.forEach(
|
|
497
|
+
fqns.filter((fqn) => fqn in ready),
|
|
498
|
+
(fqn) =>
|
|
499
|
+
// Non-cycle upstreams must be observed at their TERMINAL output
|
|
500
|
+
// (`readyStable`), not their early precreate signal (`ready`). This
|
|
501
|
+
// is what makes a failed upstream actually interrupt its downstream:
|
|
502
|
+
// a resource with `precreate` resolves `ready` before its real
|
|
503
|
+
// `reconcile` runs, so a downstream waiting on `ready` would proceed
|
|
504
|
+
// (and even finish) even though the upstream's reconcile later
|
|
505
|
+
// failed. Waiting on `readyStable` means the downstream's
|
|
506
|
+
// `waitForDeps` short-circuits with the upstream's failure cause.
|
|
507
|
+
//
|
|
508
|
+
// Cycle members are the exception: peers in an SCC depend on each
|
|
509
|
+
// other, so they must rendezvous on the early `ready`/precreate
|
|
510
|
+
// signal to break the deadlock. Phase 3 (`converge`) re-runs them
|
|
511
|
+
// against final outputs once the cycle settles. A downstream
|
|
512
|
+
// outside the cycle must still wait for reconcile: e.g. a queue
|
|
513
|
+
// consumer cannot attach to a Worker's fetch-only precreate stub.
|
|
514
|
+
plan.cycleMembers.has(downstreamFqn) && plan.cycleMembers.has(fqn)
|
|
515
|
+
? Deferred.await(ready[fqn])
|
|
516
|
+
: Deferred.await(readyStable[fqn]),
|
|
414
517
|
{ concurrency: "unbounded" },
|
|
415
518
|
);
|
|
416
519
|
|
|
417
520
|
const waitForStableDeps = (fqns: string[]) =>
|
|
418
|
-
Effect.
|
|
419
|
-
fqns.filter((fqn) => fqn in readyStable)
|
|
521
|
+
Effect.forEach(
|
|
522
|
+
fqns.filter((fqn) => fqn in readyStable),
|
|
523
|
+
(fqn) => Deferred.await(readyStable[fqn]),
|
|
420
524
|
{ concurrency: "unbounded" },
|
|
421
525
|
);
|
|
422
526
|
|
|
423
527
|
const failures: LifecycleFailure[] = [];
|
|
424
528
|
|
|
425
|
-
yield* Effect.
|
|
426
|
-
Object.entries(allNodes)
|
|
529
|
+
yield* Effect.forEach(
|
|
530
|
+
Object.entries(allNodes),
|
|
531
|
+
([fqn, node]) =>
|
|
427
532
|
(node as ActionApply).kind === "action"
|
|
428
533
|
? executeActionNode(
|
|
429
534
|
fqn,
|
|
@@ -433,7 +538,7 @@ const executePlan = Effect.fn(function* (
|
|
|
433
538
|
ready,
|
|
434
539
|
readyStable,
|
|
435
540
|
terminalStatuses,
|
|
436
|
-
|
|
541
|
+
reportEvent,
|
|
437
542
|
state,
|
|
438
543
|
stackName,
|
|
439
544
|
stage,
|
|
@@ -448,15 +553,14 @@ const executePlan = Effect.fn(function* (
|
|
|
448
553
|
ready,
|
|
449
554
|
readyStable,
|
|
450
555
|
terminalStatuses as any,
|
|
451
|
-
|
|
556
|
+
reportEvent,
|
|
452
557
|
state,
|
|
453
558
|
stackName,
|
|
454
559
|
stage,
|
|
455
560
|
(fqns) => waitForDeps(fqn, fqns),
|
|
456
561
|
failures,
|
|
457
|
-
plan.cycleMembers
|
|
562
|
+
plan.cycleMembers,
|
|
458
563
|
),
|
|
459
|
-
),
|
|
460
564
|
{ concurrency: "unbounded" },
|
|
461
565
|
);
|
|
462
566
|
|
|
@@ -498,7 +602,9 @@ const failureMessage = (cause: Cause.Cause<unknown>): string | undefined => {
|
|
|
498
602
|
const message =
|
|
499
603
|
Predicate.hasProperty(error, "message") && typeof error.message === "string"
|
|
500
604
|
? error.message
|
|
501
|
-
:
|
|
605
|
+
: typeof error === "string"
|
|
606
|
+
? error
|
|
607
|
+
: Formatter.format(error);
|
|
502
608
|
const line = message.split("\n", 1)[0]!;
|
|
503
609
|
return tag !== undefined && !line.includes(tag) ? `${tag}: ${line}` : line;
|
|
504
610
|
}
|
|
@@ -522,7 +628,7 @@ const executeNode = (
|
|
|
522
628
|
providerMode?: ProviderMode;
|
|
523
629
|
}
|
|
524
630
|
>,
|
|
525
|
-
|
|
631
|
+
reportEvent: Reporter,
|
|
526
632
|
state: {
|
|
527
633
|
set: <V extends ResourceState>(req: {
|
|
528
634
|
stack: string;
|
|
@@ -535,9 +641,10 @@ const executeNode = (
|
|
|
535
641
|
stage: string,
|
|
536
642
|
waitForDeps: (fqns: string[]) => Effect.Effect<void[], never, never>,
|
|
537
643
|
failures: LifecycleFailure[],
|
|
538
|
-
|
|
644
|
+
cycleMembers: ReadonlySet<string>,
|
|
539
645
|
): Effect.Effect<void, never, never> =>
|
|
540
646
|
Effect.gen(function* () {
|
|
647
|
+
const inCycle = cycleMembers.has(fqn);
|
|
541
648
|
const logicalId = node.resource.LogicalId;
|
|
542
649
|
const namespace = node.resource.Namespace;
|
|
543
650
|
|
|
@@ -562,23 +669,14 @@ const executeNode = (
|
|
|
562
669
|
value: {
|
|
563
670
|
...value,
|
|
564
671
|
adoptionBlocked: value.adoptionBlocked ?? node.adoptionBlocked,
|
|
672
|
+
propsIncomplete: propsIncomplete(value),
|
|
565
673
|
props: stripUnresolved(value.props),
|
|
566
674
|
bindings: stripUnresolved(value.bindings),
|
|
567
675
|
namespace,
|
|
568
676
|
} as S,
|
|
569
677
|
});
|
|
570
678
|
|
|
571
|
-
const scopedSession =
|
|
572
|
-
...session,
|
|
573
|
-
note: (note, options?) =>
|
|
574
|
-
session.emit({
|
|
575
|
-
fqn,
|
|
576
|
-
id: logicalId,
|
|
577
|
-
_tag: "apply.resource.note",
|
|
578
|
-
message: note,
|
|
579
|
-
kind: options?.kind,
|
|
580
|
-
}),
|
|
581
|
-
} satisfies ScopedPlanStatusSession;
|
|
679
|
+
const scopedSession = resourceSession(reportEvent, fqn, logicalId);
|
|
582
680
|
|
|
583
681
|
// On a mode-switch replacement (local ⇄ live) surface the transition:
|
|
584
682
|
// the old generation's stamped mode → the mode resolved for this run.
|
|
@@ -591,11 +689,11 @@ const executeNode = (
|
|
|
591
689
|
: undefined;
|
|
592
690
|
|
|
593
691
|
const report = (status: ApplyStatus) =>
|
|
594
|
-
|
|
595
|
-
|
|
692
|
+
reportEvent({
|
|
693
|
+
type: "apply.resource.status",
|
|
596
694
|
fqn,
|
|
597
695
|
id: logicalId,
|
|
598
|
-
|
|
696
|
+
resourceType: node.resource.Type,
|
|
599
697
|
status,
|
|
600
698
|
providerMode: node.mode,
|
|
601
699
|
fromProviderMode,
|
|
@@ -633,11 +731,11 @@ const executeNode = (
|
|
|
633
731
|
// terminal status is known. Their final status is flushed from
|
|
634
732
|
// `terminalStatuses` after `converge` completes.
|
|
635
733
|
if (inCycle) return;
|
|
636
|
-
yield*
|
|
637
|
-
|
|
734
|
+
yield* reportEvent({
|
|
735
|
+
type: "apply.resource.status",
|
|
638
736
|
fqn,
|
|
639
737
|
id: logicalId,
|
|
640
|
-
|
|
738
|
+
resourceType: node.resource.Type,
|
|
641
739
|
status,
|
|
642
740
|
providerMode: node.mode,
|
|
643
741
|
});
|
|
@@ -712,6 +810,23 @@ const executeNode = (
|
|
|
712
810
|
return [...new Set([...propDeps, ...bindingDeps])];
|
|
713
811
|
};
|
|
714
812
|
|
|
813
|
+
// A cycle precreates before its peers reconcile. An upstream outside the
|
|
814
|
+
// cycle cannot depend on it, so wait for those upstreams and resolve the
|
|
815
|
+
// props they determine: only values derived from cycle peers stay
|
|
816
|
+
// unresolved when precreate and `observe` run.
|
|
817
|
+
const resolvePrecreateProps = Effect.gen(function* () {
|
|
818
|
+
const outside = allUpstreamFqns().filter((upstream) => !cycleMembers.has(upstream));
|
|
819
|
+
yield* waitForDeps(outside);
|
|
820
|
+
return yield* Output.evaluateAvailable(
|
|
821
|
+
node.props,
|
|
822
|
+
Object.fromEntries(
|
|
823
|
+
outside
|
|
824
|
+
.filter((upstream) => Object.hasOwn(outputs, upstream))
|
|
825
|
+
.map((upstream) => [upstream, outputs[upstream]]),
|
|
826
|
+
),
|
|
827
|
+
);
|
|
828
|
+
});
|
|
829
|
+
|
|
715
830
|
// ── instance ID ──
|
|
716
831
|
|
|
717
832
|
const resolveInstanceId = Effect.gen(function* () {
|
|
@@ -793,6 +908,8 @@ const executeNode = (
|
|
|
793
908
|
}
|
|
794
909
|
|
|
795
910
|
let attr: any = node.state?.attr;
|
|
911
|
+
// Whether the identity reconcile claims has passed the ownership check.
|
|
912
|
+
let admitted = node.deferredAdoption === undefined;
|
|
796
913
|
|
|
797
914
|
if (attr !== undefined) {
|
|
798
915
|
// Precreate/read may already have produced a usable output snapshot. Publish
|
|
@@ -806,6 +923,10 @@ const executeNode = (
|
|
|
806
923
|
// Durable Object classes are empty) can serve traffic while the real
|
|
807
924
|
// version propagates.
|
|
808
925
|
if (inCycle && node.provider.precreate && attr === undefined) {
|
|
926
|
+
const props = yield* resolvePrecreateProps;
|
|
927
|
+
// Without `observe`, precreate and reconcile claim the identity unchecked.
|
|
928
|
+
admitted =
|
|
929
|
+
(yield* observeBeforePrecreate(node, props, fqn, logicalId, instanceId)) !== "unresolved";
|
|
809
930
|
// Some resources need a placeholder physical resource before their real
|
|
810
931
|
// create can finish. Persist that stub so downstream evaluation can proceed.
|
|
811
932
|
yield* report("pre-creating");
|
|
@@ -813,7 +934,7 @@ const executeNode = (
|
|
|
813
934
|
.precreate({
|
|
814
935
|
id: logicalId,
|
|
815
936
|
fqn,
|
|
816
|
-
news:
|
|
937
|
+
news: props,
|
|
817
938
|
session: scopedSession,
|
|
818
939
|
instanceId,
|
|
819
940
|
bindings: excludeDeletedBindings(node.bindings),
|
|
@@ -826,7 +947,9 @@ const executeNode = (
|
|
|
826
947
|
instanceId,
|
|
827
948
|
resourceType: node.resource.Type,
|
|
828
949
|
props: node.props,
|
|
829
|
-
|
|
950
|
+
// A stub for an unresolved identity claims nothing. Leave the
|
|
951
|
+
// checkpoint without it, so a retry checks the identity again.
|
|
952
|
+
attr: admitted ? attr : undefined,
|
|
830
953
|
providerVersion: node.provider.version ?? 0,
|
|
831
954
|
bindings: excludeDeletedBindings(node.bindings),
|
|
832
955
|
downstream: node.downstream,
|
|
@@ -852,8 +975,8 @@ const executeNode = (
|
|
|
852
975
|
|
|
853
976
|
const bindingOutputs = excludeDeletedBindings(yield* Output.evaluate(node.bindings, outputs));
|
|
854
977
|
|
|
855
|
-
if (
|
|
856
|
-
const checkpoint = () =>
|
|
978
|
+
if (!admitted) {
|
|
979
|
+
const checkpoint = (attr: any) =>
|
|
857
980
|
commit<CreatingResourceState>({
|
|
858
981
|
status: "creating",
|
|
859
982
|
fqn,
|
|
@@ -869,13 +992,12 @@ const executeNode = (
|
|
|
869
992
|
providerMode: node.mode,
|
|
870
993
|
adoptionBlocked: node.adoptionBlocked,
|
|
871
994
|
});
|
|
872
|
-
// Refusal or interruption must retain identity, never foreign
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
.pipe(instrumentLifecycle("read", fqn, node.resource.Type, logicalId, instanceId));
|
|
995
|
+
// Refusal or interruption must retain identity, never foreign
|
|
996
|
+
// attributes, nor a stub for an identity not yet checked.
|
|
997
|
+
yield* checkpoint(undefined);
|
|
998
|
+
const observed = yield* observeResolved(node, news, fqn, logicalId, instanceId);
|
|
877
999
|
if (observed !== undefined) {
|
|
878
|
-
if (Unowned.is(observed) && !node.deferredAdoption
|
|
1000
|
+
if (Unowned.is(observed) && !node.deferredAdoption?.adopt) {
|
|
879
1001
|
return yield* new OwnedBySomeoneElse({
|
|
880
1002
|
message:
|
|
881
1003
|
`Cannot adopt resource '${fqn}' (${node.resource.Type}): ` +
|
|
@@ -886,9 +1008,10 @@ const executeNode = (
|
|
|
886
1008
|
logicalId,
|
|
887
1009
|
});
|
|
888
1010
|
}
|
|
889
|
-
|
|
1011
|
+
// Reconcile keeps a precreated stub as its output.
|
|
1012
|
+
attr ??= stripUnowned(observed);
|
|
890
1013
|
// A creating checkpoint retains olds: undefined on retry.
|
|
891
|
-
yield* checkpoint();
|
|
1014
|
+
yield* checkpoint(attr);
|
|
892
1015
|
}
|
|
893
1016
|
}
|
|
894
1017
|
|
|
@@ -1173,15 +1296,99 @@ const executeNode = (
|
|
|
1173
1296
|
}
|
|
1174
1297
|
});
|
|
1175
1298
|
|
|
1176
|
-
|
|
1299
|
+
const deleteFirst = Effect.fn(function* () {
|
|
1177
1300
|
yield* scopedSession.note(
|
|
1178
1301
|
"Deleting previous resource before creating its replacement (deleteFirst)...",
|
|
1179
1302
|
);
|
|
1180
1303
|
yield* deleteOldGenerations(replState.old);
|
|
1181
|
-
}
|
|
1304
|
+
});
|
|
1182
1305
|
|
|
1183
1306
|
let attr: any = replState.attr;
|
|
1184
1307
|
|
|
1308
|
+
// ── replacement admission ──
|
|
1309
|
+
//
|
|
1310
|
+
// The replacement may resolve to a physical identity that already
|
|
1311
|
+
// exists and belongs to someone else (e.g. a renamed Worker pointing at
|
|
1312
|
+
// a foreign script). Read it before anything is mutated — before
|
|
1313
|
+
// precreate, reconcile, and delete-first cleanup of the previous
|
|
1314
|
+
// generation — and refuse an unowned target unless adoption is allowed,
|
|
1315
|
+
// exactly like a fresh create.
|
|
1316
|
+
let admitted = attr !== undefined || node.deferredAdoption === undefined;
|
|
1317
|
+
const admit = Effect.fn(function* (props: Record<string, any>) {
|
|
1318
|
+
admitted = true;
|
|
1319
|
+
const observed = yield* observeResolved(
|
|
1320
|
+
node,
|
|
1321
|
+
props,
|
|
1322
|
+
fqn,
|
|
1323
|
+
logicalId,
|
|
1324
|
+
instanceId,
|
|
1325
|
+
replState.old?.attr,
|
|
1326
|
+
);
|
|
1327
|
+
if (observed === undefined) return;
|
|
1328
|
+
if (Unowned.is(observed) && !node.deferredAdoption?.adopt) {
|
|
1329
|
+
return yield* new OwnedBySomeoneElse({
|
|
1330
|
+
message:
|
|
1331
|
+
`Cannot replace resource '${fqn}' (${node.resource.Type}): ` +
|
|
1332
|
+
"its replacement exists in the cloud but is not owned by this " +
|
|
1333
|
+
"stack/stage/logical-id. Re-run with `--adopt` (or " +
|
|
1334
|
+
"wrap the effect in `adopt(true)`) to take it over.",
|
|
1335
|
+
resourceType: node.resource.Type,
|
|
1336
|
+
logicalId,
|
|
1337
|
+
});
|
|
1338
|
+
}
|
|
1339
|
+
// A delete-first target may be the previous generation itself, which
|
|
1340
|
+
// is about to be deleted — never hand its attributes to reconcile.
|
|
1341
|
+
// Reconcile keeps a precreated stub as its output.
|
|
1342
|
+
if (!node.deleteFirst) attr ??= stripUnowned(observed);
|
|
1343
|
+
});
|
|
1344
|
+
|
|
1345
|
+
// A cycle precreates on the props its upstreams outside the cycle
|
|
1346
|
+
// determine; anything else waits for every upstream.
|
|
1347
|
+
const precreateProps = inCycle ? yield* resolvePrecreateProps : node.props;
|
|
1348
|
+
|
|
1349
|
+
if (!admitted && isResolved(precreateProps)) {
|
|
1350
|
+
yield* admit(precreateProps);
|
|
1351
|
+
}
|
|
1352
|
+
|
|
1353
|
+
// A cycle precreates before its props resolve, so `observe` admits the
|
|
1354
|
+
// identity precreate will claim — before delete-first, too. Without
|
|
1355
|
+
// `observe`, precreate and reconcile claim it unchecked. An unresolved
|
|
1356
|
+
// identity is admitted once it resolves, before reconcile.
|
|
1357
|
+
if (!admitted && inCycle) {
|
|
1358
|
+
const observation = yield* observeBeforePrecreate(
|
|
1359
|
+
node,
|
|
1360
|
+
precreateProps,
|
|
1361
|
+
fqn,
|
|
1362
|
+
logicalId,
|
|
1363
|
+
instanceId,
|
|
1364
|
+
replState.old?.attr,
|
|
1365
|
+
);
|
|
1366
|
+
admitted = observation !== "unresolved";
|
|
1367
|
+
if (!admitted && node.deleteFirst && !node.deferredAdoption?.adopt) {
|
|
1368
|
+
return yield* new UnverifiableReplacement({
|
|
1369
|
+
message:
|
|
1370
|
+
`Cannot replace resource '${fqn}' (${node.resource.Type}): ` +
|
|
1371
|
+
"it must be deleted before its replacement is pre-created, but " +
|
|
1372
|
+
"the replacement's identity depends on outputs that are not " +
|
|
1373
|
+
"resolved yet, so its ownership cannot be checked first. Re-run " +
|
|
1374
|
+
"with `--adopt` (or wrap the effect in `adopt(true)`) to replace it anyway.",
|
|
1375
|
+
resourceType: node.resource.Type,
|
|
1376
|
+
logicalId,
|
|
1377
|
+
});
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
|
|
1381
|
+
// A cycle must delete before precreate claims the identity. Plan has
|
|
1382
|
+
// already refused one whose identity could not be admitted first
|
|
1383
|
+
// without `observe`; the check above refuses an unresolved one.
|
|
1384
|
+
// Otherwise the previous generation survives until reconcile is
|
|
1385
|
+
// about to run, so a failed upstream never leaves the resource missing.
|
|
1386
|
+
let deletedFirst = false;
|
|
1387
|
+
if (node.deleteFirst && inCycle) {
|
|
1388
|
+
yield* deleteFirst();
|
|
1389
|
+
deletedFirst = true;
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1185
1392
|
if (attr !== undefined) {
|
|
1186
1393
|
// If precreate already ran, expose that intermediate output immediately so
|
|
1187
1394
|
// downstream resources can resolve against the same in-flight replacement.
|
|
@@ -1194,7 +1401,7 @@ const executeNode = (
|
|
|
1194
1401
|
.precreate({
|
|
1195
1402
|
id: logicalId,
|
|
1196
1403
|
fqn,
|
|
1197
|
-
news:
|
|
1404
|
+
news: precreateProps,
|
|
1198
1405
|
session: scopedSession,
|
|
1199
1406
|
instanceId,
|
|
1200
1407
|
bindings: excludeDeletedBindings(node.bindings),
|
|
@@ -1207,7 +1414,9 @@ const executeNode = (
|
|
|
1207
1414
|
instanceId,
|
|
1208
1415
|
resourceType: node.resource.Type,
|
|
1209
1416
|
props: node.props,
|
|
1210
|
-
|
|
1417
|
+
// A stub for an unresolved identity claims nothing. Leave the
|
|
1418
|
+
// checkpoint without it, so a retry checks the identity again.
|
|
1419
|
+
attr: admitted ? attr : undefined,
|
|
1211
1420
|
providerVersion: node.provider.version ?? 0,
|
|
1212
1421
|
bindings: excludeDeletedBindings(node.bindings),
|
|
1213
1422
|
downstream: node.downstream,
|
|
@@ -1233,6 +1442,13 @@ const executeNode = (
|
|
|
1233
1442
|
|
|
1234
1443
|
const bindingOutputs = excludeDeletedBindings(yield* Output.evaluate(node.bindings, outputs));
|
|
1235
1444
|
|
|
1445
|
+
if (!admitted) {
|
|
1446
|
+
yield* admit(news);
|
|
1447
|
+
}
|
|
1448
|
+
if (node.deleteFirst && !deletedFirst) {
|
|
1449
|
+
yield* deleteFirst();
|
|
1450
|
+
}
|
|
1451
|
+
|
|
1236
1452
|
attr = yield* node.provider
|
|
1237
1453
|
.reconcile({
|
|
1238
1454
|
id: logicalId,
|
|
@@ -1304,23 +1520,23 @@ const executeNode = (
|
|
|
1304
1520
|
return;
|
|
1305
1521
|
}
|
|
1306
1522
|
|
|
1307
|
-
return yield* Effect.die(`Unknown action: ${node.action}`);
|
|
1523
|
+
return yield* Effect.die(`Unknown action: ${(node as { action: string }).action}`);
|
|
1308
1524
|
}).pipe(
|
|
1309
1525
|
Effect.catchCause((cause) =>
|
|
1310
1526
|
// Record the failure, propagate it to any downstream resources waiting on
|
|
1311
1527
|
// our Deferred (so their waitForDeps short-circuits instead of deadlocking),
|
|
1312
|
-
// emit a "fail" status
|
|
1528
|
+
// emit a "fail" status, and resolve to void so Effect.all
|
|
1313
1529
|
// does not interrupt sibling fibers. The aggregated cause is raised at
|
|
1314
1530
|
// the end of executePlan.
|
|
1315
1531
|
Effect.gen(function* () {
|
|
1316
1532
|
failures.push({ fqn, logicalId: node.resource.LogicalId, type: node.resource.Type, cause });
|
|
1317
1533
|
yield* Deferred.failCause(ready[fqn], cause as Cause.Cause<never>);
|
|
1318
1534
|
yield* Deferred.failCause(readyStable[fqn], cause as Cause.Cause<never>);
|
|
1319
|
-
yield*
|
|
1320
|
-
|
|
1535
|
+
yield* reportEvent({
|
|
1536
|
+
type: "apply.resource.status",
|
|
1321
1537
|
fqn,
|
|
1322
1538
|
id: node.resource.LogicalId,
|
|
1323
|
-
|
|
1539
|
+
resourceType: node.resource.Type,
|
|
1324
1540
|
status: "fail",
|
|
1325
1541
|
message: failureMessage(cause),
|
|
1326
1542
|
providerMode: node.mode,
|
|
@@ -1380,7 +1596,7 @@ const executeActionNode = (
|
|
|
1380
1596
|
providerMode?: ProviderMode;
|
|
1381
1597
|
}
|
|
1382
1598
|
>,
|
|
1383
|
-
|
|
1599
|
+
reportEvent: Reporter,
|
|
1384
1600
|
state: {
|
|
1385
1601
|
set: <V extends PersistedState>(req: {
|
|
1386
1602
|
stack: string;
|
|
@@ -1403,7 +1619,13 @@ const executeActionNode = (
|
|
|
1403
1619
|
state.set({ stack: stackName, stage, fqn, value: { ...value, namespace } as S });
|
|
1404
1620
|
|
|
1405
1621
|
const report = (status: ApplyStatus) =>
|
|
1406
|
-
|
|
1622
|
+
reportEvent({
|
|
1623
|
+
type: "apply.resource.status",
|
|
1624
|
+
fqn,
|
|
1625
|
+
id: logicalId,
|
|
1626
|
+
resourceType: task.Type,
|
|
1627
|
+
status,
|
|
1628
|
+
});
|
|
1407
1629
|
|
|
1408
1630
|
const signalReady = Deferred.succeed(ready[fqn], void 0);
|
|
1409
1631
|
const signalReadyStable = Deferred.succeed(readyStable[fqn], void 0);
|
|
@@ -1494,11 +1716,11 @@ const executeActionNode = (
|
|
|
1494
1716
|
failures.push({ fqn, logicalId: node.def.LogicalId, type: node.def.Type, cause });
|
|
1495
1717
|
yield* Deferred.failCause(ready[fqn], cause as Cause.Cause<never>);
|
|
1496
1718
|
yield* Deferred.failCause(readyStable[fqn], cause as Cause.Cause<never>);
|
|
1497
|
-
yield*
|
|
1498
|
-
|
|
1719
|
+
yield* reportEvent({
|
|
1720
|
+
type: "apply.resource.status",
|
|
1499
1721
|
fqn,
|
|
1500
1722
|
id: node.def.LogicalId,
|
|
1501
|
-
|
|
1723
|
+
resourceType: node.def.Type,
|
|
1502
1724
|
status: "fail",
|
|
1503
1725
|
message: failureMessage(cause),
|
|
1504
1726
|
});
|
|
@@ -1537,7 +1759,7 @@ const converge = Effect.fn(function* (
|
|
|
1537
1759
|
providerMode?: ProviderMode;
|
|
1538
1760
|
}
|
|
1539
1761
|
>,
|
|
1540
|
-
|
|
1762
|
+
reportEvent: Reporter,
|
|
1541
1763
|
state: {
|
|
1542
1764
|
set: <V extends PersistedState>(req: {
|
|
1543
1765
|
stack: string;
|
|
@@ -1574,17 +1796,33 @@ const converge = Effect.fn(function* (
|
|
|
1574
1796
|
const namespace = node.resource.Namespace;
|
|
1575
1797
|
const instanceId = tracker[fqn].instanceId;
|
|
1576
1798
|
|
|
1577
|
-
const scopedSession =
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1799
|
+
const scopedSession = resourceSession(reportEvent, fqn, logicalId);
|
|
1800
|
+
|
|
1801
|
+
// A cycle peer resolves against its peers' first outputs, so an
|
|
1802
|
+
// identity checked then may resolve differently now. Check the identity
|
|
1803
|
+
// these props resolve to before reconcile claims it.
|
|
1804
|
+
const deferredAdoption = "deferredAdoption" in node ? node.deferredAdoption : undefined;
|
|
1805
|
+
if (propsChanged && deferredAdoption !== undefined) {
|
|
1806
|
+
const observed = yield* observeResolved(
|
|
1807
|
+
node,
|
|
1808
|
+
newProps,
|
|
1809
|
+
fqn,
|
|
1810
|
+
logicalId,
|
|
1811
|
+
instanceId,
|
|
1812
|
+
tracker[fqn].output,
|
|
1813
|
+
);
|
|
1814
|
+
if (observed !== undefined && Unowned.is(observed) && !deferredAdoption.adopt) {
|
|
1815
|
+
return yield* new OwnedBySomeoneElse({
|
|
1816
|
+
message:
|
|
1817
|
+
`Cannot converge resource '${fqn}' (${node.resource.Type}): ` +
|
|
1818
|
+
"its final identity exists in the cloud but is not owned by this " +
|
|
1819
|
+
"stack/stage/logical-id. Re-run with `--adopt` (or " +
|
|
1820
|
+
"wrap the effect in `adopt(true)`) to take it over.",
|
|
1821
|
+
resourceType: node.resource.Type,
|
|
1822
|
+
logicalId,
|
|
1823
|
+
});
|
|
1824
|
+
}
|
|
1825
|
+
}
|
|
1588
1826
|
|
|
1589
1827
|
const attr = yield* node.provider
|
|
1590
1828
|
.reconcile({
|
|
@@ -1764,7 +2002,7 @@ export class DestroyError extends Data.TaggedError("DestroyError")<{
|
|
|
1764
2002
|
}
|
|
1765
2003
|
}
|
|
1766
2004
|
|
|
1767
|
-
const collectGarbage = Effect.fn(function* (plan: Plan,
|
|
2005
|
+
const collectGarbage = Effect.fn(function* (plan: Plan, reportEvent: Reporter) {
|
|
1768
2006
|
const state = yield* yield* State;
|
|
1769
2007
|
const stack = yield* Stack;
|
|
1770
2008
|
const stackName = stack.name;
|
|
@@ -1773,28 +2011,28 @@ const collectGarbage = Effect.fn(function* (plan: Plan, session: PlanStatusSessi
|
|
|
1773
2011
|
// Task deletions are pure state drops — no body is invoked. Run them in
|
|
1774
2012
|
// parallel before resource GC; tasks never have provider-side dependencies
|
|
1775
2013
|
// to wait on.
|
|
1776
|
-
yield* Effect.
|
|
1777
|
-
Object.entries(plan.actionDeletions ?? {})
|
|
2014
|
+
yield* Effect.forEach(
|
|
2015
|
+
Object.entries(plan.actionDeletions ?? {}),
|
|
2016
|
+
([fqn, node]) =>
|
|
1778
2017
|
node === undefined
|
|
1779
2018
|
? Effect.void
|
|
1780
2019
|
: Effect.gen(function* () {
|
|
1781
|
-
yield*
|
|
1782
|
-
|
|
2020
|
+
yield* reportEvent({
|
|
2021
|
+
type: "apply.resource.status",
|
|
1783
2022
|
fqn,
|
|
1784
2023
|
id: node.def.LogicalId,
|
|
1785
|
-
|
|
2024
|
+
resourceType: node.def.Type,
|
|
1786
2025
|
status: "deleting",
|
|
1787
2026
|
});
|
|
1788
2027
|
yield* state.delete({ stack: stackName, stage, fqn });
|
|
1789
|
-
yield*
|
|
1790
|
-
|
|
2028
|
+
yield* reportEvent({
|
|
2029
|
+
type: "apply.resource.status",
|
|
1791
2030
|
fqn,
|
|
1792
2031
|
id: node.def.LogicalId,
|
|
1793
|
-
|
|
2032
|
+
resourceType: node.def.Type,
|
|
1794
2033
|
status: "deleted",
|
|
1795
2034
|
});
|
|
1796
2035
|
}),
|
|
1797
|
-
),
|
|
1798
2036
|
{ concurrency: "unbounded" },
|
|
1799
2037
|
);
|
|
1800
2038
|
|
|
@@ -1897,6 +2135,9 @@ const collectGarbage = Effect.fn(function* (plan: Plan, session: PlanStatusSessi
|
|
|
1897
2135
|
const adoptionBlocked = isDeleteNode(node)
|
|
1898
2136
|
? node.state.adoptionBlocked
|
|
1899
2137
|
: generation.adoptionBlocked;
|
|
2138
|
+
const incompleteProps = isDeleteNode(node)
|
|
2139
|
+
? node.state.propsIncomplete
|
|
2140
|
+
: generation.propsIncomplete;
|
|
1900
2141
|
// Mutable: an attr-less row (interrupted create) may recover its
|
|
1901
2142
|
// attributes from `provider.read` below, right before deletion.
|
|
1902
2143
|
let attr = persistedAttr;
|
|
@@ -1922,26 +2163,16 @@ const collectGarbage = Effect.fn(function* (plan: Plan, session: PlanStatusSessi
|
|
|
1922
2163
|
});
|
|
1923
2164
|
|
|
1924
2165
|
const report = (status: ApplyStatus) =>
|
|
1925
|
-
|
|
1926
|
-
|
|
2166
|
+
reportEvent({
|
|
2167
|
+
type: "apply.resource.status",
|
|
1927
2168
|
fqn,
|
|
1928
2169
|
id: logicalId,
|
|
1929
|
-
|
|
2170
|
+
resourceType,
|
|
1930
2171
|
status,
|
|
1931
2172
|
providerMode,
|
|
1932
2173
|
});
|
|
1933
2174
|
|
|
1934
|
-
const scopedSession =
|
|
1935
|
-
...session,
|
|
1936
|
-
note: (note, options?) =>
|
|
1937
|
-
session.emit({
|
|
1938
|
-
fqn,
|
|
1939
|
-
id: logicalId,
|
|
1940
|
-
_tag: "apply.resource.note",
|
|
1941
|
-
message: note,
|
|
1942
|
-
kind: options?.kind,
|
|
1943
|
-
}),
|
|
1944
|
-
} satisfies ScopedPlanStatusSession;
|
|
2175
|
+
const scopedSession = resourceSession(reportEvent, fqn, logicalId);
|
|
1945
2176
|
|
|
1946
2177
|
return yield* (deletions[fqn] ??= yield* Effect.cached(
|
|
1947
2178
|
Effect.gen(function* () {
|
|
@@ -1950,8 +2181,9 @@ const collectGarbage = Effect.fn(function* (plan: Plan, session: PlanStatusSessi
|
|
|
1950
2181
|
// this resource legitimately undeletable (dependency violation),
|
|
1951
2182
|
// so it is skipped with a "blocked by" note instead of surfacing
|
|
1952
2183
|
// a spurious second error.
|
|
1953
|
-
const dependents = yield* Effect.
|
|
1954
|
-
downstream
|
|
2184
|
+
const dependents = yield* Effect.forEach(
|
|
2185
|
+
downstream,
|
|
2186
|
+
(dep) =>
|
|
1955
2187
|
dep !== fqn && !ancestors.has(dep)
|
|
1956
2188
|
? dep in deletionGraph
|
|
1957
2189
|
? deleteResource(
|
|
@@ -1965,7 +2197,6 @@ const collectGarbage = Effect.fn(function* (plan: Plan, session: PlanStatusSessi
|
|
|
1965
2197
|
outcome: unresolved.has(dep) ? ("failed" as const) : ("deleted" as const),
|
|
1966
2198
|
}))
|
|
1967
2199
|
: Effect.succeed({ dep, outcome: "deleted" as const }),
|
|
1968
|
-
),
|
|
1969
2200
|
{ concurrency: "unbounded" },
|
|
1970
2201
|
);
|
|
1971
2202
|
|
|
@@ -2050,6 +2281,13 @@ const collectGarbage = Effect.fn(function* (plan: Plan, session: PlanStatusSessi
|
|
|
2050
2281
|
"migrated predecessor. Any interrupted new physical " +
|
|
2051
2282
|
"resource must be identified and cleaned up manually.",
|
|
2052
2283
|
);
|
|
2284
|
+
} else if (incompleteProps) {
|
|
2285
|
+
yield* scopedSession.note(
|
|
2286
|
+
"Skipping recovery: unresolved properties were omitted from " +
|
|
2287
|
+
"this interrupted create's state, so they cannot identify it. " +
|
|
2288
|
+
"Any interrupted physical resource must be identified and " +
|
|
2289
|
+
"cleaned up manually.",
|
|
2290
|
+
);
|
|
2053
2291
|
} else if (provider.read) {
|
|
2054
2292
|
const recovered = yield* provider
|
|
2055
2293
|
.read({ id: logicalId, fqn, instanceId, olds: props as never, output: undefined })
|
|
@@ -2111,6 +2349,7 @@ const collectGarbage = Effect.fn(function* (plan: Plan, session: PlanStatusSessi
|
|
|
2111
2349
|
removalPolicy: node.resource.RemovalPolicy,
|
|
2112
2350
|
providerMode,
|
|
2113
2351
|
adoptionBlocked,
|
|
2352
|
+
propsIncomplete: incompleteProps,
|
|
2114
2353
|
});
|
|
2115
2354
|
}
|
|
2116
2355
|
|
|
@@ -2181,6 +2420,7 @@ const collectGarbage = Effect.fn(function* (plan: Plan, session: PlanStatusSessi
|
|
|
2181
2420
|
bindings: excludeDeletedBindings(node.bindings),
|
|
2182
2421
|
removalPolicy: node.removalPolicy,
|
|
2183
2422
|
providerMode: node.providerMode,
|
|
2423
|
+
propsIncomplete: node.propsIncomplete,
|
|
2184
2424
|
});
|
|
2185
2425
|
}
|
|
2186
2426
|
yield* scopedSession.note(
|
|
@@ -2206,10 +2446,9 @@ const collectGarbage = Effect.fn(function* (plan: Plan, session: PlanStatusSessi
|
|
|
2206
2446
|
// retained) inside each node's delete effect — the effects resolve to
|
|
2207
2447
|
// outcomes and never fail, so one bad resource never interrupts sibling
|
|
2208
2448
|
// deletions mid-flight.
|
|
2209
|
-
yield* Effect.
|
|
2210
|
-
Object.values(deletionGraph)
|
|
2211
|
-
|
|
2212
|
-
.map((node) => deleteResource(node)),
|
|
2449
|
+
yield* Effect.forEach(
|
|
2450
|
+
Object.values(deletionGraph).filter((node) => node !== undefined),
|
|
2451
|
+
(node) => deleteResource(node),
|
|
2213
2452
|
{ concurrency: "unbounded" },
|
|
2214
2453
|
);
|
|
2215
2454
|
});
|