@mysten-incubation/devstack 0.0.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/LICENSE +189 -0
- package/README.md +94 -0
- package/dist/_virtual/_rolldown/runtime.mjs +13 -0
- package/dist/api/define-capabilities.d.mts +25 -0
- package/dist/api/define-capabilities.mjs +19 -0
- package/dist/api/define-capabilities.mjs.map +1 -0
- package/dist/api/define-devstack-with.d.mts +41 -0
- package/dist/api/define-devstack-with.mjs +24 -0
- package/dist/api/define-devstack-with.mjs.map +1 -0
- package/dist/api/define-devstack.d.mts +62 -0
- package/dist/api/define-devstack.mjs +108 -0
- package/dist/api/define-devstack.mjs.map +1 -0
- package/dist/api/define-plugin.d.mts +1 -0
- package/dist/api/inference-network.mjs +122 -0
- package/dist/api/inference-network.mjs.map +1 -0
- package/dist/api/mode-narrowed-factory.d.mts +26 -0
- package/dist/api/mode-narrowed-factory.mjs +8 -0
- package/dist/api/mode-narrowed-factory.mjs.map +1 -0
- package/dist/api/plugin-errors.mjs +10 -0
- package/dist/api/plugin-errors.mjs.map +1 -0
- package/dist/api/run-stack.d.mts +82 -0
- package/dist/api/run-stack.mjs +127 -0
- package/dist/api/run-stack.mjs.map +1 -0
- package/dist/build-integrations/playwright/config.d.mts +92 -0
- package/dist/build-integrations/playwright/config.mjs +71 -0
- package/dist/build-integrations/playwright/config.mjs.map +1 -0
- package/dist/build-integrations/playwright/errors.d.mts +82 -0
- package/dist/build-integrations/playwright/errors.mjs +43 -0
- package/dist/build-integrations/playwright/errors.mjs.map +1 -0
- package/dist/build-integrations/playwright/global-setup.d.mts +64 -0
- package/dist/build-integrations/playwright/global-setup.mjs +44 -0
- package/dist/build-integrations/playwright/global-setup.mjs.map +1 -0
- package/dist/build-integrations/playwright/index.d.mts +6 -0
- package/dist/build-integrations/playwright/index.mjs +6 -0
- package/dist/build-integrations/playwright/stack-context.d.mts +95 -0
- package/dist/build-integrations/playwright/stack-context.mjs +277 -0
- package/dist/build-integrations/playwright/stack-context.mjs.map +1 -0
- package/dist/build-integrations/playwright/wallet-context.d.mts +87 -0
- package/dist/build-integrations/playwright/wallet-context.mjs +148 -0
- package/dist/build-integrations/playwright/wallet-context.mjs.map +1 -0
- package/dist/build-integrations/runtime/cold-start-url.d.mts +67 -0
- package/dist/build-integrations/runtime/cold-start-url.mjs +56 -0
- package/dist/build-integrations/runtime/cold-start-url.mjs.map +1 -0
- package/dist/build-integrations/runtime/dapp-kit-slot.mjs +10 -0
- package/dist/build-integrations/runtime/dapp-kit-slot.mjs.map +1 -0
- package/dist/build-integrations/runtime/discover.d.mts +78 -0
- package/dist/build-integrations/runtime/discover.mjs +124 -0
- package/dist/build-integrations/runtime/discover.mjs.map +1 -0
- package/dist/build-integrations/runtime/endpoint-registry.d.mts +26 -0
- package/dist/build-integrations/runtime/endpoint-registry.mjs +41 -0
- package/dist/build-integrations/runtime/endpoint-registry.mjs.map +1 -0
- package/dist/build-integrations/runtime/errors.d.mts +64 -0
- package/dist/build-integrations/runtime/errors.mjs +51 -0
- package/dist/build-integrations/runtime/errors.mjs.map +1 -0
- package/dist/build-integrations/runtime/index.d.mts +7 -0
- package/dist/build-integrations/runtime/index.mjs +6 -0
- package/dist/build-integrations/runtime/read-stack-context.d.mts +38 -0
- package/dist/build-integrations/runtime/read-stack-context.mjs +130 -0
- package/dist/build-integrations/runtime/read-stack-context.mjs.map +1 -0
- package/dist/build-integrations/runtime/stack-context.d.mts +53 -0
- package/dist/build-integrations/vitest/config.d.mts +62 -0
- package/dist/build-integrations/vitest/config.mjs +80 -0
- package/dist/build-integrations/vitest/config.mjs.map +1 -0
- package/dist/build-integrations/vitest/env.d.mts +48 -0
- package/dist/build-integrations/vitest/env.mjs +50 -0
- package/dist/build-integrations/vitest/env.mjs.map +1 -0
- package/dist/build-integrations/vitest/errors.d.mts +44 -0
- package/dist/build-integrations/vitest/errors.mjs +18 -0
- package/dist/build-integrations/vitest/errors.mjs.map +1 -0
- package/dist/build-integrations/vitest/index.d.mts +6 -0
- package/dist/build-integrations/vitest/index.mjs +6 -0
- package/dist/build-integrations/vitest/setup.d.mts +53 -0
- package/dist/build-integrations/vitest/setup.mjs +56 -0
- package/dist/build-integrations/vitest/setup.mjs.map +1 -0
- package/dist/build-integrations/vitest/stack-context.d.mts +58 -0
- package/dist/build-integrations/vitest/stack-context.mjs +67 -0
- package/dist/build-integrations/vitest/stack-context.mjs.map +1 -0
- package/dist/cli/main.d.mts +5 -0
- package/dist/cli/main.mjs +586 -0
- package/dist/cli/main.mjs.map +1 -0
- package/dist/cli/prune-direct.mjs +216 -0
- package/dist/cli/prune-direct.mjs.map +1 -0
- package/dist/cli/snapshot-reader.mjs +73 -0
- package/dist/cli/snapshot-reader.mjs.map +1 -0
- package/dist/cli/up-lifecycle.mjs +28 -0
- package/dist/cli/up-lifecycle.mjs.map +1 -0
- package/dist/contracts/capability-decl.d.mts +42 -0
- package/dist/contracts/chain-probe.d.mts +26 -0
- package/dist/contracts/chain-probe.mjs +8 -0
- package/dist/contracts/chain-probe.mjs.map +1 -0
- package/dist/contracts/codegenable.d.mts +43 -0
- package/dist/contracts/container-runtime.d.mts +245 -0
- package/dist/contracts/liveness-classifier.d.mts +19 -0
- package/dist/contracts/network-resolver.d.mts +15 -0
- package/dist/contracts/network-resolver.mjs +7 -0
- package/dist/contracts/network-resolver.mjs.map +1 -0
- package/dist/contracts/projection.d.mts +15 -0
- package/dist/contracts/routable.d.mts +53 -0
- package/dist/contracts/snapshotable.d.mts +39 -0
- package/dist/contracts/strategy-contributor.d.mts +26 -0
- package/dist/index.d.mts +89 -0
- package/dist/index.mjs +37 -0
- package/dist/orchestrators/codegen/bindings.d.mts +2 -0
- package/dist/orchestrators/codegen/bindings.mjs +340 -0
- package/dist/orchestrators/codegen/bindings.mjs.map +1 -0
- package/dist/orchestrators/codegen/emit.mjs +56 -0
- package/dist/orchestrators/codegen/emit.mjs.map +1 -0
- package/dist/orchestrators/codegen/errors.d.mts +1 -0
- package/dist/orchestrators/codegen/errors.mjs +66 -0
- package/dist/orchestrators/codegen/errors.mjs.map +1 -0
- package/dist/orchestrators/codegen/extras.mjs +16 -0
- package/dist/orchestrators/codegen/extras.mjs.map +1 -0
- package/dist/orchestrators/codegen/format.mjs +109 -0
- package/dist/orchestrators/codegen/format.mjs.map +1 -0
- package/dist/orchestrators/codegen/gitignore.mjs +67 -0
- package/dist/orchestrators/codegen/gitignore.mjs.map +1 -0
- package/dist/orchestrators/codegen/paths.d.mts +1 -0
- package/dist/orchestrators/codegen/paths.mjs +33 -0
- package/dist/orchestrators/codegen/paths.mjs.map +1 -0
- package/dist/orchestrators/codegen/permissions.mjs +6 -0
- package/dist/orchestrators/codegen/permissions.mjs.map +1 -0
- package/dist/orchestrators/codegen/service.d.mts +1 -0
- package/dist/orchestrators/codegen/service.mjs +276 -0
- package/dist/orchestrators/codegen/service.mjs.map +1 -0
- package/dist/orchestrators/router/cleanup.mjs +58 -0
- package/dist/orchestrators/router/cleanup.mjs.map +1 -0
- package/dist/orchestrators/router/cors.mjs +31 -0
- package/dist/orchestrators/router/cors.mjs.map +1 -0
- package/dist/orchestrators/router/entrypoints.d.mts +1 -0
- package/dist/orchestrators/router/entrypoints.mjs +80 -0
- package/dist/orchestrators/router/entrypoints.mjs.map +1 -0
- package/dist/orchestrators/router/errors.d.mts +1 -0
- package/dist/orchestrators/router/errors.mjs +103 -0
- package/dist/orchestrators/router/errors.mjs.map +1 -0
- package/dist/orchestrators/router/file-provider.d.mts +1 -0
- package/dist/orchestrators/router/file-provider.mjs +320 -0
- package/dist/orchestrators/router/file-provider.mjs.map +1 -0
- package/dist/orchestrators/router/hostname.d.mts +1 -0
- package/dist/orchestrators/router/hostname.mjs +107 -0
- package/dist/orchestrators/router/hostname.mjs.map +1 -0
- package/dist/orchestrators/router/index.d.mts +1 -0
- package/dist/orchestrators/router/profile.d.mts +1 -0
- package/dist/orchestrators/router/profile.mjs +109 -0
- package/dist/orchestrators/router/profile.mjs.map +1 -0
- package/dist/orchestrators/router/service.d.mts +3 -0
- package/dist/orchestrators/router/service.mjs +421 -0
- package/dist/orchestrators/router/service.mjs.map +1 -0
- package/dist/orchestrators/router/traefik-container.d.mts +1 -0
- package/dist/orchestrators/router/traefik-container.mjs +229 -0
- package/dist/orchestrators/router/traefik-container.mjs.map +1 -0
- package/dist/orchestrators/runtime-composition.d.mts +10 -0
- package/dist/orchestrators/runtime-composition.mjs +168 -0
- package/dist/orchestrators/runtime-composition.mjs.map +1 -0
- package/dist/orchestrators/snapshot/capture.d.mts +1 -0
- package/dist/orchestrators/snapshot/capture.mjs +350 -0
- package/dist/orchestrators/snapshot/capture.mjs.map +1 -0
- package/dist/orchestrators/snapshot/descriptor.d.mts +1 -0
- package/dist/orchestrators/snapshot/descriptor.mjs +109 -0
- package/dist/orchestrators/snapshot/descriptor.mjs.map +1 -0
- package/dist/orchestrators/snapshot/identity-guard.d.mts +1 -0
- package/dist/orchestrators/snapshot/identity-guard.mjs +132 -0
- package/dist/orchestrators/snapshot/identity-guard.mjs.map +1 -0
- package/dist/orchestrators/snapshot/image-bundle-tags.mjs +207 -0
- package/dist/orchestrators/snapshot/image-bundle-tags.mjs.map +1 -0
- package/dist/orchestrators/snapshot/index.d.mts +1 -0
- package/dist/orchestrators/snapshot/integrity.d.mts +1 -0
- package/dist/orchestrators/snapshot/integrity.mjs +74 -0
- package/dist/orchestrators/snapshot/integrity.mjs.map +1 -0
- package/dist/orchestrators/snapshot/prune.d.mts +1 -0
- package/dist/orchestrators/snapshot/prune.mjs +110 -0
- package/dist/orchestrators/snapshot/prune.mjs.map +1 -0
- package/dist/orchestrators/snapshot/restore.d.mts +1 -0
- package/dist/orchestrators/snapshot/restore.mjs +404 -0
- package/dist/orchestrators/snapshot/restore.mjs.map +1 -0
- package/dist/orchestrators/snapshot/service.d.mts +1 -0
- package/dist/orchestrators/snapshot/service.mjs +296 -0
- package/dist/orchestrators/snapshot/service.mjs.map +1 -0
- package/dist/orchestrators/snapshot/state-document.mjs +18 -0
- package/dist/orchestrators/snapshot/state-document.mjs.map +1 -0
- package/dist/orchestrators/snapshot/wipe.d.mts +1 -0
- package/dist/orchestrators/snapshot/wipe.mjs +59 -0
- package/dist/orchestrators/snapshot/wipe.mjs.map +1 -0
- package/dist/plugins/account/codegen.d.mts +12 -0
- package/dist/plugins/account/codegen.mjs +22 -0
- package/dist/plugins/account/codegen.mjs.map +1 -0
- package/dist/plugins/account/errors.d.mts +44 -0
- package/dist/plugins/account/errors.mjs +16 -0
- package/dist/plugins/account/errors.mjs.map +1 -0
- package/dist/plugins/account/funding.d.mts +94 -0
- package/dist/plugins/account/funding.mjs +199 -0
- package/dist/plugins/account/funding.mjs.map +1 -0
- package/dist/plugins/account/index.d.mts +54 -0
- package/dist/plugins/account/index.mjs +151 -0
- package/dist/plugins/account/index.mjs.map +1 -0
- package/dist/plugins/account/keypair.d.mts +32 -0
- package/dist/plugins/account/keypair.mjs +99 -0
- package/dist/plugins/account/keypair.mjs.map +1 -0
- package/dist/plugins/account/lease.mjs +21 -0
- package/dist/plugins/account/lease.mjs.map +1 -0
- package/dist/plugins/account/registry.d.mts +33 -0
- package/dist/plugins/account/registry.mjs +36 -0
- package/dist/plugins/account/registry.mjs.map +1 -0
- package/dist/plugins/account/service.d.mts +104 -0
- package/dist/plugins/account/service.mjs +405 -0
- package/dist/plugins/account/service.mjs.map +1 -0
- package/dist/plugins/account/snapshot.mjs +33 -0
- package/dist/plugins/account/snapshot.mjs.map +1 -0
- package/dist/plugins/account/variants/env.mjs +24 -0
- package/dist/plugins/account/variants/env.mjs.map +1 -0
- package/dist/plugins/account/variants/ephemeral.mjs +72 -0
- package/dist/plugins/account/variants/ephemeral.mjs.map +1 -0
- package/dist/plugins/account/variants/impersonate.d.mts +16 -0
- package/dist/plugins/account/variants/impersonate.mjs +48 -0
- package/dist/plugins/account/variants/impersonate.mjs.map +1 -0
- package/dist/plugins/account/variants/inline.mjs +13 -0
- package/dist/plugins/account/variants/inline.mjs.map +1 -0
- package/dist/plugins/account/variants/keystore.mjs +93 -0
- package/dist/plugins/account/variants/keystore.mjs.map +1 -0
- package/dist/plugins/account/variants/signer.mjs +31 -0
- package/dist/plugins/account/variants/signer.mjs.map +1 -0
- package/dist/plugins/action/build-context.d.mts +41 -0
- package/dist/plugins/action/discriminator.d.mts +20 -0
- package/dist/plugins/action/discriminator.mjs +13 -0
- package/dist/plugins/action/discriminator.mjs.map +1 -0
- package/dist/plugins/action/errors.d.mts +31 -0
- package/dist/plugins/action/errors.mjs +13 -0
- package/dist/plugins/action/errors.mjs.map +1 -0
- package/dist/plugins/action/execute.d.mts +2 -0
- package/dist/plugins/action/execute.mjs +145 -0
- package/dist/plugins/action/execute.mjs.map +1 -0
- package/dist/plugins/action/index.d.mts +56 -0
- package/dist/plugins/action/index.mjs +82 -0
- package/dist/plugins/action/index.mjs.map +1 -0
- package/dist/plugins/action/service.d.mts +26 -0
- package/dist/plugins/action/service.mjs +84 -0
- package/dist/plugins/action/service.mjs.map +1 -0
- package/dist/plugins/coin/address-resolution.d.mts +34 -0
- package/dist/plugins/coin/address-resolution.mjs +80 -0
- package/dist/plugins/coin/address-resolution.mjs.map +1 -0
- package/dist/plugins/coin/codegen.d.mts +16 -0
- package/dist/plugins/coin/codegen.mjs +21 -0
- package/dist/plugins/coin/codegen.mjs.map +1 -0
- package/dist/plugins/coin/discovery.d.mts +26 -0
- package/dist/plugins/coin/discovery.mjs +112 -0
- package/dist/plugins/coin/discovery.mjs.map +1 -0
- package/dist/plugins/coin/errors.d.mts +48 -0
- package/dist/plugins/coin/errors.mjs +13 -0
- package/dist/plugins/coin/errors.mjs.map +1 -0
- package/dist/plugins/coin/index.d.mts +95 -0
- package/dist/plugins/coin/index.mjs +172 -0
- package/dist/plugins/coin/index.mjs.map +1 -0
- package/dist/plugins/coin/metadata.d.mts +15 -0
- package/dist/plugins/coin/metadata.mjs +99 -0
- package/dist/plugins/coin/metadata.mjs.map +1 -0
- package/dist/plugins/coin/mint.d.mts +34 -0
- package/dist/plugins/coin/mint.mjs +164 -0
- package/dist/plugins/coin/mint.mjs.map +1 -0
- package/dist/plugins/coin/registry.d.mts +1 -0
- package/dist/plugins/coin/registry.mjs +37 -0
- package/dist/plugins/coin/registry.mjs.map +1 -0
- package/dist/plugins/coin/service.d.mts +47 -0
- package/dist/plugins/coin/service.mjs +51 -0
- package/dist/plugins/coin/service.mjs.map +1 -0
- package/dist/plugins/coin/snapshot.mjs +19 -0
- package/dist/plugins/coin/snapshot.mjs.map +1 -0
- package/dist/plugins/coin/type-strings.mjs +49 -0
- package/dist/plugins/coin/type-strings.mjs.map +1 -0
- package/dist/plugins/deepbook/codegen.d.mts +39 -0
- package/dist/plugins/deepbook/codegen.mjs +15 -0
- package/dist/plugins/deepbook/codegen.mjs.map +1 -0
- package/dist/plugins/deepbook/deploy.mjs +437 -0
- package/dist/plugins/deepbook/deploy.mjs.map +1 -0
- package/dist/plugins/deepbook/errors.d.mts +29 -0
- package/dist/plugins/deepbook/errors.mjs +26 -0
- package/dist/plugins/deepbook/errors.mjs.map +1 -0
- package/dist/plugins/deepbook/faucet-strategy.d.mts +8 -0
- package/dist/plugins/deepbook/faucet-strategy.mjs +81 -0
- package/dist/plugins/deepbook/faucet-strategy.mjs.map +1 -0
- package/dist/plugins/deepbook/index.d.mts +171 -0
- package/dist/plugins/deepbook/index.mjs +359 -0
- package/dist/plugins/deepbook/index.mjs.map +1 -0
- package/dist/plugins/deepbook/plugin-key.mjs +7 -0
- package/dist/plugins/deepbook/plugin-key.mjs.map +1 -0
- package/dist/plugins/deepbook/pyth/index.mjs +226 -0
- package/dist/plugins/deepbook/pyth/index.mjs.map +1 -0
- package/dist/plugins/deepbook/routable.mjs +21 -0
- package/dist/plugins/deepbook/routable.mjs.map +1 -0
- package/dist/plugins/deepbook/snapshot.mjs +49 -0
- package/dist/plugins/deepbook/snapshot.mjs.map +1 -0
- package/dist/plugins/deepbook/types.d.mts +125 -0
- package/dist/plugins/deepbook/types.mjs +12 -0
- package/dist/plugins/deepbook/types.mjs.map +1 -0
- package/dist/plugins/faucet/dispatcher.d.mts +9 -0
- package/dist/plugins/faucet/dispatcher.mjs +13 -0
- package/dist/plugins/faucet/dispatcher.mjs.map +1 -0
- package/dist/plugins/faucet/errors.d.mts +86 -0
- package/dist/plugins/faucet/errors.mjs +19 -0
- package/dist/plugins/faucet/errors.mjs.map +1 -0
- package/dist/plugins/faucet/http.mjs +127 -0
- package/dist/plugins/faucet/http.mjs.map +1 -0
- package/dist/plugins/faucet/index.d.mts +43 -0
- package/dist/plugins/faucet/index.mjs +42 -0
- package/dist/plugins/faucet/index.mjs.map +1 -0
- package/dist/plugins/faucet/service.d.mts +20 -0
- package/dist/plugins/faucet/strategies/sui-local.d.mts +23 -0
- package/dist/plugins/faucet/strategies/sui-local.mjs +29 -0
- package/dist/plugins/faucet/strategies/sui-local.mjs.map +1 -0
- package/dist/plugins/host-service/errors.d.mts +27 -0
- package/dist/plugins/host-service/errors.mjs +14 -0
- package/dist/plugins/host-service/errors.mjs.map +1 -0
- package/dist/plugins/host-service/index.d.mts +10 -0
- package/dist/plugins/host-service/index.mjs +48 -0
- package/dist/plugins/host-service/index.mjs.map +1 -0
- package/dist/plugins/host-service/routable.mjs +24 -0
- package/dist/plugins/host-service/routable.mjs.map +1 -0
- package/dist/plugins/host-service/service.d.mts +49 -0
- package/dist/plugins/host-service/service.mjs +375 -0
- package/dist/plugins/host-service/service.mjs.map +1 -0
- package/dist/plugins/package/build.d.mts +1 -0
- package/dist/plugins/package/build.mjs +24 -0
- package/dist/plugins/package/build.mjs.map +1 -0
- package/dist/plugins/package/codegen.d.mts +19 -0
- package/dist/plugins/package/codegen.mjs +41 -0
- package/dist/plugins/package/codegen.mjs.map +1 -0
- package/dist/plugins/package/dep-resolution.mjs +10 -0
- package/dist/plugins/package/dep-resolution.mjs.map +1 -0
- package/dist/plugins/package/errors.d.mts +34 -0
- package/dist/plugins/package/errors.mjs +13 -0
- package/dist/plugins/package/errors.mjs.map +1 -0
- package/dist/plugins/package/index.d.mts +109 -0
- package/dist/plugins/package/index.mjs +207 -0
- package/dist/plugins/package/index.mjs.map +1 -0
- package/dist/plugins/package/mode-known.mjs +41 -0
- package/dist/plugins/package/mode-known.mjs.map +1 -0
- package/dist/plugins/package/mode-local.d.mts +1 -0
- package/dist/plugins/package/mode-local.mjs +183 -0
- package/dist/plugins/package/mode-local.mjs.map +1 -0
- package/dist/plugins/package/publish-executor.mjs +202 -0
- package/dist/plugins/package/publish-executor.mjs.map +1 -0
- package/dist/plugins/package/publish-output.d.mts +28 -0
- package/dist/plugins/package/publish-output.mjs +45 -0
- package/dist/plugins/package/publish-output.mjs.map +1 -0
- package/dist/plugins/package/registry.d.mts +25 -0
- package/dist/plugins/package/registry.mjs +30 -0
- package/dist/plugins/package/registry.mjs.map +1 -0
- package/dist/plugins/package/service.mjs +20 -0
- package/dist/plugins/package/service.mjs.map +1 -0
- package/dist/plugins/package/snapshot.mjs +25 -0
- package/dist/plugins/package/snapshot.mjs.map +1 -0
- package/dist/plugins/postgres/codegen.mjs +42 -0
- package/dist/plugins/postgres/codegen.mjs.map +1 -0
- package/dist/plugins/postgres/connection.d.mts +33 -0
- package/dist/plugins/postgres/connection.mjs +19 -0
- package/dist/plugins/postgres/connection.mjs.map +1 -0
- package/dist/plugins/postgres/db-ensure.mjs +100 -0
- package/dist/plugins/postgres/db-ensure.mjs.map +1 -0
- package/dist/plugins/postgres/errors.d.mts +55 -0
- package/dist/plugins/postgres/errors.mjs +29 -0
- package/dist/plugins/postgres/errors.mjs.map +1 -0
- package/dist/plugins/postgres/index.d.mts +37 -0
- package/dist/plugins/postgres/index.mjs +75 -0
- package/dist/plugins/postgres/index.mjs.map +1 -0
- package/dist/plugins/postgres/routable.mjs +33 -0
- package/dist/plugins/postgres/routable.mjs.map +1 -0
- package/dist/plugins/postgres/service.d.mts +50 -0
- package/dist/plugins/postgres/service.mjs +145 -0
- package/dist/plugins/postgres/service.mjs.map +1 -0
- package/dist/plugins/postgres/snapshot.d.mts +1 -0
- package/dist/plugins/postgres/snapshot.mjs +32 -0
- package/dist/plugins/postgres/snapshot.mjs.map +1 -0
- package/dist/plugins/router-entrypoints.mjs +21 -0
- package/dist/plugins/router-entrypoints.mjs.map +1 -0
- package/dist/plugins/seal/bootstrap-assets/cargo-image.mjs +59 -0
- package/dist/plugins/seal/bootstrap-assets/cargo-image.mjs.map +1 -0
- package/dist/plugins/seal/bootstrap-assets/source-fetch.mjs +132 -0
- package/dist/plugins/seal/bootstrap-assets/source-fetch.mjs.map +1 -0
- package/dist/plugins/seal/codegen.d.mts +19 -0
- package/dist/plugins/seal/codegen.mjs +16 -0
- package/dist/plugins/seal/codegen.mjs.map +1 -0
- package/dist/plugins/seal/config-render.mjs +82 -0
- package/dist/plugins/seal/config-render.mjs.map +1 -0
- package/dist/plugins/seal/deploy.mjs +198 -0
- package/dist/plugins/seal/deploy.mjs.map +1 -0
- package/dist/plugins/seal/errors.d.mts +52 -0
- package/dist/plugins/seal/errors.mjs +19 -0
- package/dist/plugins/seal/errors.mjs.map +1 -0
- package/dist/plugins/seal/index.d.mts +161 -0
- package/dist/plugins/seal/index.mjs +235 -0
- package/dist/plugins/seal/index.mjs.map +1 -0
- package/dist/plugins/seal/key-manager.d.mts +22 -0
- package/dist/plugins/seal/key-manager.mjs +22 -0
- package/dist/plugins/seal/key-manager.mjs.map +1 -0
- package/dist/plugins/seal/key-server.mjs +175 -0
- package/dist/plugins/seal/key-server.mjs.map +1 -0
- package/dist/plugins/seal/keygen.mjs +96 -0
- package/dist/plugins/seal/keygen.mjs.map +1 -0
- package/dist/plugins/seal/mode/fork-known.d.mts +8 -0
- package/dist/plugins/seal/mode/fork-known.mjs +23 -0
- package/dist/plugins/seal/mode/fork-known.mjs.map +1 -0
- package/dist/plugins/seal/mode/live.d.mts +18 -0
- package/dist/plugins/seal/mode/live.mjs +64 -0
- package/dist/plugins/seal/mode/live.mjs.map +1 -0
- package/dist/plugins/seal/mode/local-keygen.mjs +180 -0
- package/dist/plugins/seal/mode/local-keygen.mjs.map +1 -0
- package/dist/plugins/seal/plugin-key.mjs +7 -0
- package/dist/plugins/seal/plugin-key.mjs.map +1 -0
- package/dist/plugins/seal/registry-publish.d.mts +43 -0
- package/dist/plugins/seal/registry-publish.mjs +9 -0
- package/dist/plugins/seal/registry-publish.mjs.map +1 -0
- package/dist/plugins/seal/routable.mjs +57 -0
- package/dist/plugins/seal/routable.mjs.map +1 -0
- package/dist/plugins/seal/service.mjs +17 -0
- package/dist/plugins/seal/service.mjs.map +1 -0
- package/dist/plugins/seal/snapshot.mjs +51 -0
- package/dist/plugins/seal/snapshot.mjs.map +1 -0
- package/dist/plugins/sui/auto-tick.mjs +45 -0
- package/dist/plugins/sui/auto-tick.mjs.map +1 -0
- package/dist/plugins/sui/chain-build-container.d.mts +1 -0
- package/dist/plugins/sui/chain-probe.d.mts +85 -0
- package/dist/plugins/sui/chain-probe.mjs +104 -0
- package/dist/plugins/sui/chain-probe.mjs.map +1 -0
- package/dist/plugins/sui/codegen.d.mts +14 -0
- package/dist/plugins/sui/codegen.mjs +26 -0
- package/dist/plugins/sui/codegen.mjs.map +1 -0
- package/dist/plugins/sui/errors.d.mts +74 -0
- package/dist/plugins/sui/errors.mjs +28 -0
- package/dist/plugins/sui/errors.mjs.map +1 -0
- package/dist/plugins/sui/fork-orchestration.mjs +24 -0
- package/dist/plugins/sui/fork-orchestration.mjs.map +1 -0
- package/dist/plugins/sui/fork-transaction.mjs +96 -0
- package/dist/plugins/sui/fork-transaction.mjs.map +1 -0
- package/dist/plugins/sui/index.d.mts +318 -0
- package/dist/plugins/sui/index.mjs +182 -0
- package/dist/plugins/sui/index.mjs.map +1 -0
- package/dist/plugins/sui/mode/external.mjs +60 -0
- package/dist/plugins/sui/mode/external.mjs.map +1 -0
- package/dist/plugins/sui/mode/fork.mjs +283 -0
- package/dist/plugins/sui/mode/fork.mjs.map +1 -0
- package/dist/plugins/sui/mode/live.mjs +103 -0
- package/dist/plugins/sui/mode/live.mjs.map +1 -0
- package/dist/plugins/sui/mode/local.mjs +293 -0
- package/dist/plugins/sui/mode/local.mjs.map +1 -0
- package/dist/plugins/sui/mode/shared-boot.mjs +254 -0
- package/dist/plugins/sui/mode/shared-boot.mjs.map +1 -0
- package/dist/plugins/sui/mode/shared.d.mts +103 -0
- package/dist/plugins/sui/mode/shared.mjs +12 -0
- package/dist/plugins/sui/mode/shared.mjs.map +1 -0
- package/dist/plugins/sui/mode/spec.d.mts +94 -0
- package/dist/plugins/sui/network-resolver.d.mts +23 -0
- package/dist/plugins/sui/routable.mjs +88 -0
- package/dist/plugins/sui/routable.mjs.map +1 -0
- package/dist/plugins/sui/seed-objects.d.mts +18 -0
- package/dist/plugins/sui/seed-objects.mjs +25 -0
- package/dist/plugins/sui/seed-objects.mjs.map +1 -0
- package/dist/plugins/sui/service.mjs +38 -0
- package/dist/plugins/sui/service.mjs.map +1 -0
- package/dist/plugins/sui/snapshot.mjs +53 -0
- package/dist/plugins/sui/snapshot.mjs.map +1 -0
- package/dist/plugins/wallet/codegen.d.mts +33 -0
- package/dist/plugins/wallet/codegen.mjs +34 -0
- package/dist/plugins/wallet/codegen.mjs.map +1 -0
- package/dist/plugins/wallet/errors.d.mts +66 -0
- package/dist/plugins/wallet/errors.mjs +16 -0
- package/dist/plugins/wallet/errors.mjs.map +1 -0
- package/dist/plugins/wallet/index.d.mts +63 -0
- package/dist/plugins/wallet/index.mjs +126 -0
- package/dist/plugins/wallet/index.mjs.map +1 -0
- package/dist/plugins/wallet/origin-policy.d.mts +1 -0
- package/dist/plugins/wallet/origin-policy.mjs +65 -0
- package/dist/plugins/wallet/origin-policy.mjs.map +1 -0
- package/dist/plugins/wallet/pairing.d.mts +11 -0
- package/dist/plugins/wallet/pairing.mjs +125 -0
- package/dist/plugins/wallet/pairing.mjs.map +1 -0
- package/dist/plugins/wallet/protocol.d.mts +1 -0
- package/dist/plugins/wallet/protocol.mjs +96 -0
- package/dist/plugins/wallet/protocol.mjs.map +1 -0
- package/dist/plugins/wallet/routable.mjs +32 -0
- package/dist/plugins/wallet/routable.mjs.map +1 -0
- package/dist/plugins/wallet/server.d.mts +12 -0
- package/dist/plugins/wallet/server.mjs +317 -0
- package/dist/plugins/wallet/server.mjs.map +1 -0
- package/dist/plugins/wallet/service.d.mts +68 -0
- package/dist/plugins/wallet/service.mjs +97 -0
- package/dist/plugins/wallet/service.mjs.map +1 -0
- package/dist/plugins/wallet/snapshot.d.mts +1 -0
- package/dist/plugins/wallet/snapshot.mjs +14 -0
- package/dist/plugins/wallet/snapshot.mjs.map +1 -0
- package/dist/plugins/walrus/bootstrap-assets/cargo-image.mjs +42 -0
- package/dist/plugins/walrus/bootstrap-assets/cargo-image.mjs.map +1 -0
- package/dist/plugins/walrus/codegen.d.mts +38 -0
- package/dist/plugins/walrus/codegen.mjs +34 -0
- package/dist/plugins/walrus/codegen.mjs.map +1 -0
- package/dist/plugins/walrus/deploy-paths.mjs +14 -0
- package/dist/plugins/walrus/deploy-paths.mjs.map +1 -0
- package/dist/plugins/walrus/deploy.d.mts +1 -0
- package/dist/plugins/walrus/deploy.mjs +224 -0
- package/dist/plugins/walrus/deploy.mjs.map +1 -0
- package/dist/plugins/walrus/errors.d.mts +38 -0
- package/dist/plugins/walrus/errors.mjs +26 -0
- package/dist/plugins/walrus/errors.mjs.map +1 -0
- package/dist/plugins/walrus/faucet-strategy.d.mts +12 -0
- package/dist/plugins/walrus/faucet-strategy.mjs +62 -0
- package/dist/plugins/walrus/faucet-strategy.mjs.map +1 -0
- package/dist/plugins/walrus/index.d.mts +177 -0
- package/dist/plugins/walrus/index.mjs +284 -0
- package/dist/plugins/walrus/index.mjs.map +1 -0
- package/dist/plugins/walrus/mode/known-deploy.d.mts +25 -0
- package/dist/plugins/walrus/mode/known-deploy.mjs +71 -0
- package/dist/plugins/walrus/mode/known-deploy.mjs.map +1 -0
- package/dist/plugins/walrus/mode/local-cluster.d.mts +34 -0
- package/dist/plugins/walrus/mode/local-cluster.mjs +153 -0
- package/dist/plugins/walrus/mode/local-cluster.mjs.map +1 -0
- package/dist/plugins/walrus/plugin-key.mjs +7 -0
- package/dist/plugins/walrus/plugin-key.mjs.map +1 -0
- package/dist/plugins/walrus/registry-publish.d.mts +24 -0
- package/dist/plugins/walrus/registry-publish.mjs +7 -0
- package/dist/plugins/walrus/registry-publish.mjs.map +1 -0
- package/dist/plugins/walrus/routable.mjs +99 -0
- package/dist/plugins/walrus/routable.mjs.map +1 -0
- package/dist/plugins/walrus/service.mjs +20 -0
- package/dist/plugins/walrus/service.mjs.map +1 -0
- package/dist/plugins/walrus/snapshot.mjs +53 -0
- package/dist/plugins/walrus/snapshot.mjs.map +1 -0
- package/dist/plugins/walrus/storage-nodes.d.mts +15 -0
- package/dist/plugins/walrus/storage-nodes.mjs +154 -0
- package/dist/plugins/walrus/storage-nodes.mjs.map +1 -0
- package/dist/plugins/walrus/wal-swap.d.mts +2 -0
- package/dist/plugins/walrus/wal-swap.mjs +58 -0
- package/dist/plugins/walrus/wal-swap.mjs.map +1 -0
- package/dist/primitives/artifact-publisher.d.mts +12 -0
- package/dist/primitives/cache.d.mts +1 -0
- package/dist/runtime/built-in-plugin-layers.mjs +49 -0
- package/dist/runtime/built-in-plugin-layers.mjs.map +1 -0
- package/dist/runtime/docker/client.d.mts +2 -0
- package/dist/runtime/docker/client.mjs +54 -0
- package/dist/runtime/docker/client.mjs.map +1 -0
- package/dist/runtime/docker/container.d.mts +1 -0
- package/dist/runtime/docker/container.mjs +562 -0
- package/dist/runtime/docker/container.mjs.map +1 -0
- package/dist/runtime/docker/errors.d.mts +1 -0
- package/dist/runtime/docker/errors.mjs +187 -0
- package/dist/runtime/docker/errors.mjs.map +1 -0
- package/dist/runtime/docker/exec.d.mts +1 -0
- package/dist/runtime/docker/exec.mjs +63 -0
- package/dist/runtime/docker/exec.mjs.map +1 -0
- package/dist/runtime/docker/image.d.mts +1 -0
- package/dist/runtime/docker/image.mjs +278 -0
- package/dist/runtime/docker/image.mjs.map +1 -0
- package/dist/runtime/docker/index.d.mts +1 -0
- package/dist/runtime/docker/inventory.d.mts +1 -0
- package/dist/runtime/docker/inventory.mjs +167 -0
- package/dist/runtime/docker/inventory.mjs.map +1 -0
- package/dist/runtime/docker/labels.d.mts +1 -0
- package/dist/runtime/docker/labels.mjs +97 -0
- package/dist/runtime/docker/labels.mjs.map +1 -0
- package/dist/runtime/docker/logs.d.mts +1 -0
- package/dist/runtime/docker/logs.mjs +34 -0
- package/dist/runtime/docker/logs.mjs.map +1 -0
- package/dist/runtime/docker/network.d.mts +1 -0
- package/dist/runtime/docker/network.mjs +168 -0
- package/dist/runtime/docker/network.mjs.map +1 -0
- package/dist/runtime/docker/service.d.mts +9 -0
- package/dist/runtime/docker/service.mjs +266 -0
- package/dist/runtime/docker/service.mjs.map +1 -0
- package/dist/runtime/docker/sweep.d.mts +1 -0
- package/dist/runtime/docker/sweep.mjs +220 -0
- package/dist/runtime/docker/sweep.mjs.map +1 -0
- package/dist/runtime/docker/volume.d.mts +1 -0
- package/dist/runtime/docker/volume.mjs +24 -0
- package/dist/runtime/docker/volume.mjs.map +1 -0
- package/dist/runtime/docker/wrap.d.mts +1 -0
- package/dist/runtime/docker/wrap.mjs +131 -0
- package/dist/runtime/docker/wrap.mjs.map +1 -0
- package/dist/substrate/brand.d.mts +24 -0
- package/dist/substrate/brand.mjs +14 -0
- package/dist/substrate/brand.mjs.map +1 -0
- package/dist/substrate/cross-process.d.mts +1 -0
- package/dist/substrate/cross-process.mjs +28 -0
- package/dist/substrate/cross-process.mjs.map +1 -0
- package/dist/substrate/events.d.mts +117 -0
- package/dist/substrate/identity.d.mts +13 -0
- package/dist/substrate/lifecycle.d.mts +12 -0
- package/dist/substrate/manifest.d.mts +39 -0
- package/dist/substrate/manifest.mjs +33 -0
- package/dist/substrate/manifest.mjs.map +1 -0
- package/dist/substrate/network.d.mts +34 -0
- package/dist/substrate/options.d.mts +23 -0
- package/dist/substrate/plugin.d.mts +101 -0
- package/dist/substrate/plugin.mjs +61 -0
- package/dist/substrate/plugin.mjs.map +1 -0
- package/dist/substrate/projection.d.mts +100 -0
- package/dist/substrate/runtime/artifact-publisher/index.mjs +76 -0
- package/dist/substrate/runtime/artifact-publisher/index.mjs.map +1 -0
- package/dist/substrate/runtime/atomic-write.mjs +106 -0
- package/dist/substrate/runtime/atomic-write.mjs.map +1 -0
- package/dist/substrate/runtime/cache/index.d.mts +1 -0
- package/dist/substrate/runtime/cache/schema.d.mts +1 -0
- package/dist/substrate/runtime/cache/schema.mjs +22 -0
- package/dist/substrate/runtime/cache/schema.mjs.map +1 -0
- package/dist/substrate/runtime/cache/service.d.mts +1 -0
- package/dist/substrate/runtime/cache/service.mjs +89 -0
- package/dist/substrate/runtime/cache/service.mjs.map +1 -0
- package/dist/substrate/runtime/capability-sinks/index.d.mts +1 -0
- package/dist/substrate/runtime/capability-sinks/layer.d.mts +1 -0
- package/dist/substrate/runtime/capability-sinks/layer.mjs +31 -0
- package/dist/substrate/runtime/capability-sinks/layer.mjs.map +1 -0
- package/dist/substrate/runtime/capability-sinks/service.d.mts +36 -0
- package/dist/substrate/runtime/capability-sinks/service.mjs +74 -0
- package/dist/substrate/runtime/capability-sinks/service.mjs.map +1 -0
- package/dist/substrate/runtime/config-validation.d.mts +38 -0
- package/dist/substrate/runtime/config-validation.mjs +137 -0
- package/dist/substrate/runtime/config-validation.mjs.map +1 -0
- package/dist/substrate/runtime/context-helpers.mjs +32 -0
- package/dist/substrate/runtime/context-helpers.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/command-channel/channel.mjs +128 -0
- package/dist/substrate/runtime/cross-process/command-channel/channel.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/command-channel/file-channel.mjs +136 -0
- package/dist/substrate/runtime/cross-process/command-channel/file-channel.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/command-channel/protocol.mjs +49 -0
- package/dist/substrate/runtime/cross-process/command-channel/protocol.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/command-channel/runtime-control-lock.mjs +9 -0
- package/dist/substrate/runtime/cross-process/command-channel/runtime-control-lock.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/liveness.mjs +119 -0
- package/dist/substrate/runtime/cross-process/liveness.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/roster.mjs +275 -0
- package/dist/substrate/runtime/cross-process/roster.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/snapshot-reservation.d.mts +1 -0
- package/dist/substrate/runtime/cross-process/snapshot-reservation.mjs +117 -0
- package/dist/substrate/runtime/cross-process/snapshot-reservation.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/stack-lock.d.mts +1 -0
- package/dist/substrate/runtime/cross-process/stack-lock.mjs +142 -0
- package/dist/substrate/runtime/cross-process/stack-lock.mjs.map +1 -0
- package/dist/substrate/runtime/current-plugin.mjs +15 -0
- package/dist/substrate/runtime/current-plugin.mjs.map +1 -0
- package/dist/substrate/runtime/errors.d.mts +1 -0
- package/dist/substrate/runtime/errors.mjs +76 -0
- package/dist/substrate/runtime/errors.mjs.map +1 -0
- package/dist/substrate/runtime/host-tree-tar/index.mjs +364 -0
- package/dist/substrate/runtime/host-tree-tar/index.mjs.map +1 -0
- package/dist/substrate/runtime/http-probe.d.mts +35 -0
- package/dist/substrate/runtime/http-probe.mjs +65 -0
- package/dist/substrate/runtime/http-probe.mjs.map +1 -0
- package/dist/substrate/runtime/lease-broker/index.d.mts +1 -0
- package/dist/substrate/runtime/lease-broker/service.d.mts +64 -0
- package/dist/substrate/runtime/lease-broker/service.mjs +155 -0
- package/dist/substrate/runtime/lease-broker/service.mjs.map +1 -0
- package/dist/substrate/runtime/lifecycle/dep-graph.d.mts +1 -0
- package/dist/substrate/runtime/lifecycle/dep-graph.mjs +138 -0
- package/dist/substrate/runtime/lifecycle/dep-graph.mjs.map +1 -0
- package/dist/substrate/runtime/lifecycle/index.d.mts +1 -0
- package/dist/substrate/runtime/lifecycle/lifecycle-fact.mjs +31 -0
- package/dist/substrate/runtime/lifecycle/lifecycle-fact.mjs.map +1 -0
- package/dist/substrate/runtime/lifecycle/plugin-registry.d.mts +1 -0
- package/dist/substrate/runtime/lifecycle/plugin-registry.mjs +133 -0
- package/dist/substrate/runtime/lifecycle/plugin-registry.mjs.map +1 -0
- package/dist/substrate/runtime/lifecycle/ready-gate.d.mts +1 -0
- package/dist/substrate/runtime/lifecycle/ready-gate.mjs +34 -0
- package/dist/substrate/runtime/lifecycle/ready-gate.mjs.map +1 -0
- package/dist/substrate/runtime/lifecycle/selective-restart.d.mts +1 -0
- package/dist/substrate/runtime/lifecycle/selective-restart.mjs +43 -0
- package/dist/substrate/runtime/lifecycle/selective-restart.mjs.map +1 -0
- package/dist/substrate/runtime/lifecycle/signals.d.mts +1 -0
- package/dist/substrate/runtime/lifecycle/signals.mjs +64 -0
- package/dist/substrate/runtime/lifecycle/signals.mjs.map +1 -0
- package/dist/substrate/runtime/lifecycle/state-machine.d.mts +1 -0
- package/dist/substrate/runtime/lifecycle/state-machine.mjs +38 -0
- package/dist/substrate/runtime/lifecycle/state-machine.mjs.map +1 -0
- package/dist/substrate/runtime/lifecycle/watch-attribution.d.mts +1 -0
- package/dist/substrate/runtime/lifecycle/watch-attribution.mjs +27 -0
- package/dist/substrate/runtime/lifecycle/watch-attribution.mjs.map +1 -0
- package/dist/substrate/runtime/managed-container.d.mts +30 -0
- package/dist/substrate/runtime/managed-container.mjs +32 -0
- package/dist/substrate/runtime/managed-container.mjs.map +1 -0
- package/dist/substrate/runtime/manifest/manifest.mjs +73 -0
- package/dist/substrate/runtime/manifest/manifest.mjs.map +1 -0
- package/dist/substrate/runtime/mode-errors.d.mts +36 -0
- package/dist/substrate/runtime/observability/cascade-formatter.d.mts +1 -0
- package/dist/substrate/runtime/observability/cascade-formatter.mjs +135 -0
- package/dist/substrate/runtime/observability/cascade-formatter.mjs.map +1 -0
- package/dist/substrate/runtime/observability/formatter-registry.d.mts +1 -0
- package/dist/substrate/runtime/observability/formatter-registry.mjs +65 -0
- package/dist/substrate/runtime/observability/formatter-registry.mjs.map +1 -0
- package/dist/substrate/runtime/observability/index.d.mts +3 -0
- package/dist/substrate/runtime/observability/logger.d.mts +58 -0
- package/dist/substrate/runtime/observability/logger.mjs +89 -0
- package/dist/substrate/runtime/observability/logger.mjs.map +1 -0
- package/dist/substrate/runtime/observability/pretty-error.d.mts +1 -0
- package/dist/substrate/runtime/observability/pretty-error.mjs +119 -0
- package/dist/substrate/runtime/observability/pretty-error.mjs.map +1 -0
- package/dist/substrate/runtime/observability/process-lines.d.mts +31 -0
- package/dist/substrate/runtime/observability/process-lines.mjs +40 -0
- package/dist/substrate/runtime/observability/process-lines.mjs.map +1 -0
- package/dist/substrate/runtime/observability/redaction.d.mts +28 -0
- package/dist/substrate/runtime/observability/redaction.mjs +45 -0
- package/dist/substrate/runtime/observability/redaction.mjs.map +1 -0
- package/dist/substrate/runtime/observability/spans.d.mts +1 -0
- package/dist/substrate/runtime/observability/spans.mjs +87 -0
- package/dist/substrate/runtime/observability/spans.mjs.map +1 -0
- package/dist/substrate/runtime/observability/subprocess-capture.d.mts +2 -0
- package/dist/substrate/runtime/observability/subprocess-capture.mjs +82 -0
- package/dist/substrate/runtime/observability/subprocess-capture.mjs.map +1 -0
- package/dist/substrate/runtime/paths.d.mts +17 -0
- package/dist/substrate/runtime/paths.mjs +61 -0
- package/dist/substrate/runtime/paths.mjs.map +1 -0
- package/dist/substrate/runtime/port-broker/index.d.mts +1 -0
- package/dist/substrate/runtime/port-broker/service.d.mts +1 -0
- package/dist/substrate/runtime/port-broker/service.mjs +319 -0
- package/dist/substrate/runtime/port-broker/service.mjs.map +1 -0
- package/dist/substrate/runtime/post-acquire-tasks.d.mts +1 -0
- package/dist/substrate/runtime/post-acquire-tasks.mjs +34 -0
- package/dist/substrate/runtime/post-acquire-tasks.mjs.map +1 -0
- package/dist/substrate/runtime/probes.d.mts +51 -0
- package/dist/substrate/runtime/probes.mjs +84 -0
- package/dist/substrate/runtime/probes.mjs.map +1 -0
- package/dist/substrate/runtime/process-supervisor.d.mts +57 -0
- package/dist/substrate/runtime/process-supervisor.mjs +73 -0
- package/dist/substrate/runtime/process-supervisor.mjs.map +1 -0
- package/dist/substrate/runtime/projection/operational-endpoints.mjs +44 -0
- package/dist/substrate/runtime/projection/operational-endpoints.mjs.map +1 -0
- package/dist/substrate/runtime/projection/persisted.mjs +195 -0
- package/dist/substrate/runtime/projection/persisted.mjs.map +1 -0
- package/dist/substrate/runtime/projection/state-ref.mjs +48 -0
- package/dist/substrate/runtime/projection/state-ref.mjs.map +1 -0
- package/dist/substrate/runtime/projection/update.mjs +200 -0
- package/dist/substrate/runtime/projection/update.mjs.map +1 -0
- package/dist/substrate/runtime/retry-policy.d.mts +18 -0
- package/dist/substrate/runtime/retry-policy.mjs +16 -0
- package/dist/substrate/runtime/retry-policy.mjs.map +1 -0
- package/dist/substrate/runtime/run.mjs +86 -0
- package/dist/substrate/runtime/run.mjs.map +1 -0
- package/dist/substrate/runtime/runtime-decode.d.mts +32 -0
- package/dist/substrate/runtime/runtime-decode.mjs +53 -0
- package/dist/substrate/runtime/runtime-decode.mjs.map +1 -0
- package/dist/substrate/runtime/scoped-http-server.mjs +36 -0
- package/dist/substrate/runtime/scoped-http-server.mjs.map +1 -0
- package/dist/substrate/runtime/scoped-ref-map/service.mjs +83 -0
- package/dist/substrate/runtime/scoped-ref-map/service.mjs.map +1 -0
- package/dist/substrate/runtime/stage-and-swap/index.d.mts +1 -0
- package/dist/substrate/runtime/stage-and-swap/index.mjs +131 -0
- package/dist/substrate/runtime/stage-and-swap/index.mjs.map +1 -0
- package/dist/substrate/runtime/state-store/schema.mjs +36 -0
- package/dist/substrate/runtime/state-store/schema.mjs.map +1 -0
- package/dist/substrate/runtime/strategy-registry/chain-probe-for.d.mts +1 -0
- package/dist/substrate/runtime/strategy-registry/chain-probe-for.mjs +22 -0
- package/dist/substrate/runtime/strategy-registry/chain-probe-for.mjs.map +1 -0
- package/dist/substrate/runtime/strategy-registry/faucet-capability-for.d.mts +1 -0
- package/dist/substrate/runtime/strategy-registry/faucet-capability-for.mjs +30 -0
- package/dist/substrate/runtime/strategy-registry/faucet-capability-for.mjs.map +1 -0
- package/dist/substrate/runtime/strategy-registry/index.d.mts +1 -0
- package/dist/substrate/runtime/strategy-registry/service.d.mts +1 -0
- package/dist/substrate/runtime/strategy-registry/service.mjs +67 -0
- package/dist/substrate/runtime/strategy-registry/service.mjs.map +1 -0
- package/dist/substrate/runtime/sui-execute/index.d.mts +11 -0
- package/dist/substrate/runtime/sui-execute/index.mjs +144 -0
- package/dist/substrate/runtime/sui-execute/index.mjs.map +1 -0
- package/dist/substrate/runtime/sui-move-build/index.d.mts +1 -0
- package/dist/substrate/runtime/sui-move-build/index.mjs +283 -0
- package/dist/substrate/runtime/sui-move-build/index.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor.d.mts +1 -0
- package/dist/substrate/runtime/supervisor.mjs +831 -0
- package/dist/substrate/runtime/supervisor.mjs.map +1 -0
- package/dist/surfaces/cli/command-tree.mjs +276 -0
- package/dist/surfaces/cli/command-tree.mjs.map +1 -0
- package/dist/surfaces/cli/commands/config.mjs +31 -0
- package/dist/surfaces/cli/commands/config.mjs.map +1 -0
- package/dist/surfaces/cli/commands/confirm-node.mjs +26 -0
- package/dist/surfaces/cli/commands/confirm-node.mjs.map +1 -0
- package/dist/surfaces/cli/commands/confirm.mjs +26 -0
- package/dist/surfaces/cli/commands/confirm.mjs.map +1 -0
- package/dist/surfaces/cli/commands/doctor-probes.mjs +452 -0
- package/dist/surfaces/cli/commands/doctor-probes.mjs.map +1 -0
- package/dist/surfaces/cli/commands/doctor.mjs +38 -0
- package/dist/surfaces/cli/commands/doctor.mjs.map +1 -0
- package/dist/surfaces/cli/commands/prune-picker.mjs +347 -0
- package/dist/surfaces/cli/commands/prune-picker.mjs.map +1 -0
- package/dist/surfaces/cli/commands/prune.mjs +178 -0
- package/dist/surfaces/cli/commands/prune.mjs.map +1 -0
- package/dist/surfaces/cli/commands/snapshot.mjs +141 -0
- package/dist/surfaces/cli/commands/snapshot.mjs.map +1 -0
- package/dist/surfaces/cli/commands/status.mjs +95 -0
- package/dist/surfaces/cli/commands/status.mjs.map +1 -0
- package/dist/surfaces/cli/commands/supervisor-presence.mjs +33 -0
- package/dist/surfaces/cli/commands/supervisor-presence.mjs.map +1 -0
- package/dist/surfaces/cli/commands/wipe.mjs +28 -0
- package/dist/surfaces/cli/commands/wipe.mjs.map +1 -0
- package/dist/surfaces/cli/envelope.mjs +43 -0
- package/dist/surfaces/cli/envelope.mjs.map +1 -0
- package/dist/surfaces/cli/errors.mjs +110 -0
- package/dist/surfaces/cli/errors.mjs.map +1 -0
- package/dist/surfaces/cli/flags.mjs +56 -0
- package/dist/surfaces/cli/flags.mjs.map +1 -0
- package/dist/surfaces/cli/index.mjs +418 -0
- package/dist/surfaces/cli/index.mjs.map +1 -0
- package/dist/surfaces/cli/output.mjs +115 -0
- package/dist/surfaces/cli/output.mjs.map +1 -0
- package/dist/surfaces/cli/sysexits.mjs +139 -0
- package/dist/surfaces/cli/sysexits.mjs.map +1 -0
- package/dist/surfaces/tui/app.mjs +104 -0
- package/dist/surfaces/tui/app.mjs.map +1 -0
- package/dist/surfaces/tui/dashboard.mjs +261 -0
- package/dist/surfaces/tui/dashboard.mjs.map +1 -0
- package/dist/surfaces/tui/display-derivation.mjs +395 -0
- package/dist/surfaces/tui/display-derivation.mjs.map +1 -0
- package/dist/surfaces/tui/errors.mjs +11 -0
- package/dist/surfaces/tui/errors.mjs.map +1 -0
- package/dist/surfaces/tui/event-log.mjs +155 -0
- package/dist/surfaces/tui/event-log.mjs.map +1 -0
- package/dist/surfaces/tui/heartbeat.mjs +33 -0
- package/dist/surfaces/tui/heartbeat.mjs.map +1 -0
- package/dist/surfaces/tui/index.mjs +50 -0
- package/dist/surfaces/tui/index.mjs.map +1 -0
- package/dist/surfaces/tui/input.mjs +104 -0
- package/dist/surfaces/tui/input.mjs.map +1 -0
- package/dist/surfaces/tui/mode-detect.mjs +32 -0
- package/dist/surfaces/tui/mode-detect.mjs.map +1 -0
- package/dist/surfaces/tui/mount-ink.mjs +31 -0
- package/dist/surfaces/tui/mount-ink.mjs.map +1 -0
- package/dist/surfaces/tui/plain-renderer.mjs +170 -0
- package/dist/surfaces/tui/plain-renderer.mjs.map +1 -0
- package/dist/surfaces/tui/resource-table.mjs +507 -0
- package/dist/surfaces/tui/resource-table.mjs.map +1 -0
- package/images/_shared/signal-forward.sh +77 -0
- package/images/postgres/Dockerfile +32 -0
- package/images/seal/Dockerfile +68 -0
- package/images/seal/entrypoint.sh +65 -0
- package/images/sui/Dockerfile +73 -0
- package/images/sui/entrypoint.sh +244 -0
- package/images/sui-fork/Dockerfile +53 -0
- package/images/sui-fork/entrypoint.sh +51 -0
- package/images/walrus/Dockerfile +122 -0
- package/images/walrus/deploy-walrus.sh +305 -0
- package/images/walrus/run-walrus.sh +53 -0
- package/package.json +94 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-provider.mjs","names":[],"sources":["../../../src/orchestrators/router/file-provider.ts"],"sourcesContent":["// File-provider config generator.\n//\n// Architecture invariant #1: file-provider ONLY, never docker-provider.\n// We materialize per-backend dispatch entries as YAML files in a\n// watched directory; Traefik's file-provider polls + reloads on\n// change. The docker-provider was rejected because the container IP\n// we need is the *shared-network* IP that lands AFTER `network connect`,\n// and the docker-provider captures the per-stack IP at first event\n// and never refreshes.\n//\n// One file per canonical route identity. Each file carries exactly\n// one router + one service (and references the shared CORS middleware\n// when `cors: true`). This layout means atomic add/remove of a route\n// is one file create/unlink — no merge step, no race.\n//\n// Two YAML shapes live under this renderer, discriminated by the\n// resolved route's `wireProtocol`:\n//\n// HTTP / h2c (Host-header dispatch on a shared port):\n//\n// http:\n// routers:\n// <id>-router:\n// rule: \"Host(`<hostname>`)\"\n// entryPoints: [\"<entrypointName>\"]\n// service: \"<id>-svc\"\n// middlewares: [\"devstack-cors\"] # when cors: true\n// services:\n// <id>-svc:\n// loadBalancer:\n// servers:\n// - url: \"http://<upstream-host>:<upstream-port>\"\n//\n// TCP (per-entrypoint-port dispatch; ONE backend per entrypoint):\n//\n// tcp:\n// routers:\n// <id>-router:\n// rule: \"HostSNI(`*`)\"\n// entryPoints: [\"<entrypointName>\"]\n// service: \"<id>-svc\"\n// services:\n// <id>-svc:\n// loadBalancer:\n// servers:\n// - address: \"<upstream-host>:<upstream-port>\"\n//\n// HostSNI(`*`) matches any incoming TCP connection on the entrypoint\n// (Traefik requires every TCP router to have a rule; `*` is the wildcard\n// that means \"any client\"). No CORS section — TCP isn't HTTP and the\n// shared CORS middleware lives under `http.middlewares`.\n\nimport { Effect } from 'effect';\n\nimport type { RoutableDecl } from '../../contracts/routable.ts';\nimport type { RosterHolder } from '../../substrate/cross-process.ts';\nimport type { Identity } from '../../substrate/identity.ts';\nimport { CORS_MIDDLEWARE_NAME } from './cors.ts';\nimport type { EntrypointRegistryShape } from './entrypoints.ts';\nimport { RouteCollision, RouterValidationError, type UnknownEntrypoint } from './errors.ts';\nimport { dispatchFileId, renderUrl, routerHostname } from './hostname.ts';\n\nexport const ROUTE_READINESS_HEADER = 'X-Devstack-Route-Id';\n\n// ---------------------------------------------------------------------------\n// Resolved-route data structure\n// ---------------------------------------------------------------------------\n\n/** Resolved wire-protocol. `'tcp'` carries no hostname matcher and no\n * CORS. The router orchestrator's renderer + collision-detector branch\n * on this. */\nexport type ResolvedWireProtocol = 'http' | 'h2c' | 'tcp';\n\n/** A `RoutableDecl` resolved by the orchestrator: hostname minted,\n * dispatch-id stringified, entrypoint port resolved, upstream URL\n * resolved. This is the shape the file-provider renderer consumes —\n * decoupled from the resolution path so testing the renderer is\n * pure. */\nexport interface ResolvedRoute {\n\treadonly dispatchFileId: string;\n\t/** Minted hostname for HTTP routes. For TCP routes this is still\n\t * computed (it's the host string the URL surfaces to consumers),\n\t * but the Traefik router rule is `HostSNI(\\`*\\`)` — TCP dispatches\n\t * by entrypoint port, not Host. */\n\treadonly hostname: string;\n\treadonly entrypointName: string;\n\treadonly entrypointPort: number;\n\t/** Upstream URL string. For HTTP this is `http://<host>:<port>`; for\n\t * TCP it's still rendered as `tcp://<host>:<port>` so the renderer\n\t * can pull host+port back out for the `address:` field. */\n\treadonly upstreamUrl: string;\n\treadonly cors: boolean;\n\treadonly wireProtocol: ResolvedWireProtocol;\n}\n\nexport interface RouteCollisionMetadata {\n\treadonly dispatchFileId: string;\n\treadonly hostname: string;\n\treadonly entrypointName: string;\n\treadonly entrypointPort: number | null;\n\treadonly wireProtocol: ResolvedWireProtocol;\n}\n\nexport const ROUTER_ROUTE_LEASE_VERSION = 1;\n\nexport interface RouteLeaseMetadata {\n\treadonly version: typeof ROUTER_ROUTE_LEASE_VERSION;\n\treadonly routerProfileId: string;\n\treadonly app: string;\n\treadonly stack: string;\n\treadonly owner: RosterHolder;\n}\n\nexport interface DispatchRouteMetadata extends RouteCollisionMetadata {\n\treadonly lease: RouteLeaseMetadata | null;\n}\n\nexport type DispatchRouteDecodeReason =\n\t| 'missing-required-route-metadata'\n\t| 'unknown-route-lease-version'\n\t| 'invalid-route-lease-metadata';\n\nexport interface DispatchRouteDecodeDiagnostic {\n\treadonly _tag: 'DispatchRouteDecodeDiagnostic';\n\treadonly dispatchFileId: string;\n\treadonly reason: DispatchRouteDecodeReason;\n\treadonly detail: string;\n}\n\nexport type DispatchRouteParseResult =\n\t| {\n\t\t\treadonly _tag: 'valid';\n\t\t\treadonly route: DispatchRouteMetadata;\n\t\t\treadonly diagnostics: ReadonlyArray<DispatchRouteDecodeDiagnostic>;\n\t }\n\t| {\n\t\t\treadonly _tag: 'invalid';\n\t\t\treadonly dispatchFileId: string;\n\t\t\treadonly diagnostics: ReadonlyArray<DispatchRouteDecodeDiagnostic>;\n\t };\n\n/** Filename within the dispatch directory for a given file-id. The\n * `10-` prefix sorts behind the shared CORS middleware (`00-`) so\n * Traefik picks up the middleware before any router referencing it. */\nexport const dispatchFilename = (fileId: string): string => `10-${fileId}.yml`;\n\n// ---------------------------------------------------------------------------\n// Resolution — Routable + Identity + EntrypointRegistry + upstream → ResolvedRoute\n// ---------------------------------------------------------------------------\n\n/** Upstream-resolution interface the file-provider needs. The\n * orchestrator threads in concrete resolvers (`runtime/docker` for\n * containers, the port broker for host-loopback) without leaking\n * service knowledge. Architecture: \"router has no compiled-in\n * awareness of which services exist.\" */\nexport interface UpstreamResolver {\n\t/** For a container-kind upstream, return `(host, port)` where host\n\t * is the container's shared-network IP and port is the container\n\t * port from the plugin. Bounded retry lives inside the resolver\n\t * (architecture invariant #3). */\n\treadonly resolveContainer: (target: {\n\t\treadonly containerName: string;\n\t\treadonly containerPort: number;\n\t}) => Effect.Effect<{ readonly host: string; readonly port: number }, RouterValidationError>;\n\t/** For a host-loopback-kind upstream, return the bound loopback\n\t * port. The plugin owns port allocation and stamps the resolved\n\t * port into its Routable decl after acquire. */\n\treadonly resolveHostLoopback: (target: {\n\t\treadonly port: number;\n\t}) => Effect.Effect<{ readonly host: string; readonly port: number }, RouterValidationError>;\n}\n\n/** Resolve a single Routable into a ResolvedRoute. Pure-ish: the only\n * effectful bit is the upstream resolver (which talks to docker /\n * the port broker) and the entrypoint lookup.\n *\n * Takes the registry as a parameter rather than yielding the service\n * tag so the calling orchestrator can pre-bind it once at layer-\n * construction time, keeping the per-Routable hot path free of\n * Context lookups. */\nexport const resolveRoute = (\n\tidentity: Identity,\n\tdecl: RoutableDecl,\n\tregistry: EntrypointRegistryShape,\n\tupstreams: UpstreamResolver,\n): Effect.Effect<ResolvedRoute, RouterValidationError | UnknownEntrypoint> =>\n\tEffect.gen(function* () {\n\t\tconst entrypoint = yield* registry.byName(decl.endpointName);\n\t\tconst hostname = yield* routerHostname(identity, decl.dispatchId.role);\n\t\tconst fileId = yield* dispatchFileId({ identity, dispatch: decl.dispatchId });\n\t\tconst upstream =\n\t\t\tdecl.upstream.type === 'container'\n\t\t\t\t? yield* upstreams.resolveContainer({\n\t\t\t\t\t\tcontainerName: decl.upstream.containerName,\n\t\t\t\t\t\tcontainerPort: decl.upstream.containerPort,\n\t\t\t\t\t})\n\t\t\t\t: yield* upstreams.resolveHostLoopback({ port: decl.upstream.port });\n\t\tconst wireProtocol: ResolvedWireProtocol =\n\t\t\tdecl.wireProtocol === 'tcp' ? 'tcp' : decl.wireProtocol === 'h2c' ? 'h2c' : 'http';\n\t\t// The router contract says: a `wireProtocol: 'tcp'` decl MUST\n\t\t// reference an entrypoint whose protocol is also `'tcp'`. The\n\t\t// converse holds — HTTP/h2c decls must reference HTTP-family\n\t\t// entrypoints. Mismatch is a programming error in the plugin\n\t\t// author (caught here once, not at every render).\n\t\tconst expectFamily: 'tcp' | 'http' = wireProtocol === 'tcp' ? 'tcp' : 'http';\n\t\tconst entrypointFamily: 'tcp' | 'http' = entrypoint.protocol === 'tcp' ? 'tcp' : 'http';\n\t\tif (expectFamily !== entrypointFamily) {\n\t\t\treturn yield* Effect.fail(\n\t\t\t\tnew RouterValidationError({\n\t\t\t\t\tfield: 'entrypointName',\n\t\t\t\t\tvalue: entrypoint.name,\n\t\t\t\t\tdetail:\n\t\t\t\t\t\t`wireProtocol family mismatch: decl is '${wireProtocol}' but ` +\n\t\t\t\t\t\t`entrypoint '${entrypoint.name}' is '${entrypoint.protocol}'`,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\t// Validate the upstream URL — defense in depth (the resolvers\n\t\t// already produce safe values, but this stops a future resolver\n\t\t// that returns junk from corrupting the YAML). TCP carries the\n\t\t// `tcp://` scheme so we differentiate from the HTTP path; the\n\t\t// renderer pulls host+port back out either way.\n\t\tconst upstreamUrl = renderUrl({\n\t\t\tprotocol: wireProtocol === 'tcp' ? 'tcp' : 'http',\n\t\t\thostname: upstream.host,\n\t\t\tport: upstream.port,\n\t\t});\n\t\tif (!/^(?:http|tcp):\\/\\/[A-Za-z0-9_.:-]+:\\d+$/.test(upstreamUrl)) {\n\t\t\treturn yield* Effect.fail(\n\t\t\t\tnew RouterValidationError({\n\t\t\t\t\tfield: 'upstreamUrl',\n\t\t\t\t\tvalue: upstreamUrl,\n\t\t\t\t\tdetail: 'expected http://<host>:<port> or tcp://<host>:<port>',\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\t// CORS is HTTP-only — TCP decls don't carry the field. Render\n\t\t// uses this; the resolved shape carries `false` for TCP.\n\t\tconst cors = decl.wireProtocol === 'tcp' ? false : decl.cors;\n\t\treturn {\n\t\t\tdispatchFileId: fileId,\n\t\t\thostname,\n\t\t\tentrypointName: entrypoint.name,\n\t\t\tentrypointPort: entrypoint.port,\n\t\t\tupstreamUrl,\n\t\t\tcors,\n\t\t\twireProtocol,\n\t\t};\n\t});\n\n// ---------------------------------------------------------------------------\n// Render — ResolvedRoute → YAML body\n// ---------------------------------------------------------------------------\n\n/** Pull host+port out of an `<scheme>://<host>:<port>` URL. Used by the\n * TCP renderer to write the `address:` field. Safe because\n * `resolveRoute` validates the URL shape before we get here. */\nconst splitUpstream = (url: string): { host: string; port: string } => {\n\tconst stripped = url.replace(/^(?:http|tcp):\\/\\//, '');\n\tconst lastColon = stripped.lastIndexOf(':');\n\treturn {\n\t\thost: stripped.slice(0, lastColon),\n\t\tport: stripped.slice(lastColon + 1),\n\t};\n};\n\nconst renderLeaseHeader = (lease: RouteLeaseMetadata): ReadonlyArray<string> => [\n\t`# routeLeaseVersion: ${lease.version}`,\n\t`# routerProfileId: ${lease.routerProfileId}`,\n\t`# ownerApp: ${lease.app}`,\n\t`# ownerStack: ${lease.stack}`,\n\t`# ownerPid: ${lease.owner.pid}`,\n\t`# ownerStartTime: ${lease.owner.startTime}`,\n\t`# ownerHostname: ${lease.owner.hostname}`,\n\t`# ownerClaimedAt: ${lease.owner.claimedAt}`,\n\t`# ownerHeartbeatAt: ${lease.owner.heartbeatAt}`,\n\t`# ownerIntent: ${lease.owner.intent}`,\n];\n\n/** Render the YAML body for a single resolved route. Hand-rolled\n * (same rationale as `cors.ts`): static, controlled, byte-stable so\n * no-op rewrites don't wake the watcher. */\nexport const renderRouteYaml = (route: ResolvedRoute, lease: RouteLeaseMetadata): string => {\n\tif (route.wireProtocol === 'tcp') return renderTcpRouteYaml(route, lease);\n\treturn renderHttpRouteYaml(route, lease);\n};\n\nconst routeReadinessMiddlewareName = (route: ResolvedRoute): string =>\n\t`${route.dispatchFileId}-route-ready`;\n\nconst renderHttpRouteYaml = (route: ResolvedRoute, lease: RouteLeaseMetadata): string => {\n\tconst middlewares = [\n\t\trouteReadinessMiddlewareName(route),\n\t\t...(route.cors ? [CORS_MIDDLEWARE_NAME] : []),\n\t];\n\tconst schemeHint =\n\t\troute.wireProtocol === 'h2c'\n\t\t\t? ` # h2c upstream — gRPC-friendly cleartext HTTP/2.\\n`\n\t\t\t: '';\n\treturn [\n\t\t`# Auto-generated by devstack router orchestrator. Do not edit by hand.`,\n\t\t`# dispatchFileId: ${route.dispatchFileId}`,\n\t\t`# wireProtocol: ${route.wireProtocol}`,\n\t\t`# entrypointName: ${route.entrypointName}`,\n\t\t`# entrypointPort: ${route.entrypointPort}`,\n\t\t`# hostname: ${route.hostname}`,\n\t\t...renderLeaseHeader(lease),\n\t\t`http:`,\n\t\t` routers:`,\n\t\t` ${route.dispatchFileId}-router:`,\n\t\t` rule: \"Host(\\`${route.hostname}\\`)\"`,\n\t\t` entryPoints: [\"${route.entrypointName}\"]`,\n\t\t` service: \"${route.dispatchFileId}-svc\"`,\n\t\t` middlewares: [${middlewares.map((name) => `\"${name}\"`).join(', ')}]`,\n\t\t` middlewares:`,\n\t\t` ${routeReadinessMiddlewareName(route)}:`,\n\t\t` headers:`,\n\t\t` customResponseHeaders:`,\n\t\t` ${ROUTE_READINESS_HEADER}: \"${route.dispatchFileId}\"`,\n\t\t` services:`,\n\t\t` ${route.dispatchFileId}-svc:`,\n\t\t` loadBalancer:`,\n\t\tschemeHint.length > 0 ? schemeHint.trimEnd() : null,\n\t\t` servers:`,\n\t\t` - url: \"${route.upstreamUrl}\"`,\n\t\t``,\n\t]\n\t\t.filter((line): line is string => line !== null)\n\t\t.join('\\n');\n};\n\nconst renderTcpRouteYaml = (route: ResolvedRoute, lease: RouteLeaseMetadata): string => {\n\tconst { host, port } = splitUpstream(route.upstreamUrl);\n\treturn [\n\t\t`# Auto-generated by devstack router orchestrator. Do not edit by hand.`,\n\t\t`# dispatchFileId: ${route.dispatchFileId}`,\n\t\t`# wireProtocol: tcp`,\n\t\t`# entrypointName: ${route.entrypointName}`,\n\t\t`# entrypointPort: ${route.entrypointPort}`,\n\t\t`# hostname: ${route.hostname}`,\n\t\t`# tcpDispatch: entrypoint-port dispatch; HostSNI wildcard`,\n\t\t...renderLeaseHeader(lease),\n\t\t`tcp:`,\n\t\t` routers:`,\n\t\t` ${route.dispatchFileId}-router:`,\n\t\t` rule: \"HostSNI(\\`*\\`)\"`,\n\t\t` entryPoints: [\"${route.entrypointName}\"]`,\n\t\t` service: \"${route.dispatchFileId}-svc\"`,\n\t\t` services:`,\n\t\t` ${route.dispatchFileId}-svc:`,\n\t\t` loadBalancer:`,\n\t\t` servers:`,\n\t\t` - address: \"${host}:${port}\"`,\n\t\t``,\n\t].join('\\n');\n};\n\nexport const dispatchFileIdFromFilename = (filename: string): string | null => {\n\tconst match = /^10-(.+)\\.yml$/.exec(filename);\n\treturn match?.[1] ?? null;\n};\n\nconst commentValue = (body: string, key: string): string | null => {\n\tconst escaped = key.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\tconst match = new RegExp(`^# ${escaped}: (.*)$`, 'm').exec(body);\n\treturn match?.[1]?.trim() ?? null;\n};\n\nconst matchValue = (body: string, pattern: RegExp): string | null =>\n\tpattern.exec(body)?.[1]?.trim() ?? null;\n\nconst commentNumber = (body: string, key: string): number | null => {\n\tconst raw = commentValue(body, key);\n\tif (raw === null || !/^\\d+$/.test(raw)) return null;\n\treturn Number.parseInt(raw, 10);\n};\n\nconst parseWireProtocol = (body: string): ResolvedWireProtocol | null => {\n\tconst fromComment = commentValue(body, 'wireProtocol');\n\tif (fromComment === 'http' || fromComment === 'h2c' || fromComment === 'tcp') {\n\t\treturn fromComment;\n\t}\n\tif (/^tcp:/m.test(body)) return 'tcp';\n\tif (/^http:/m.test(body)) return 'http';\n\treturn null;\n};\n\nconst hasRouteLeaseMetadata = (body: string): boolean =>\n\t[\n\t\t'routeLeaseVersion',\n\t\t'routerProfileId',\n\t\t'ownerApp',\n\t\t'ownerStack',\n\t\t'ownerPid',\n\t\t'ownerStartTime',\n\t\t'ownerHostname',\n\t\t'ownerClaimedAt',\n\t\t'ownerHeartbeatAt',\n\t\t'ownerIntent',\n\t].some((key) => commentValue(body, key) !== null);\n\nconst parseRouteLeaseMetadata = (\n\tbody: string,\n\tdispatchFileId: string,\n): {\n\treadonly lease: RouteLeaseMetadata | null;\n\treadonly diagnostic: DispatchRouteDecodeDiagnostic | null;\n} => {\n\tif (!hasRouteLeaseMetadata(body)) return { lease: null, diagnostic: null };\n\tconst rawVersion = commentValue(body, 'routeLeaseVersion');\n\tconst version = commentNumber(body, 'routeLeaseVersion');\n\tconst routerProfileId = commentValue(body, 'routerProfileId');\n\tconst app = commentValue(body, 'ownerApp');\n\tconst stack = commentValue(body, 'ownerStack');\n\tconst pid = commentNumber(body, 'ownerPid');\n\tconst startTime = commentNumber(body, 'ownerStartTime');\n\tconst hostname = commentValue(body, 'ownerHostname');\n\tconst claimedAt = commentNumber(body, 'ownerClaimedAt');\n\tconst heartbeatAt = commentNumber(body, 'ownerHeartbeatAt');\n\tconst intent = commentValue(body, 'ownerIntent');\n\tif (version !== ROUTER_ROUTE_LEASE_VERSION) {\n\t\treturn {\n\t\t\tlease: null,\n\t\t\tdiagnostic: {\n\t\t\t\t_tag: 'DispatchRouteDecodeDiagnostic',\n\t\t\t\tdispatchFileId,\n\t\t\t\treason: 'unknown-route-lease-version',\n\t\t\t\tdetail: `expected routeLeaseVersion ${ROUTER_ROUTE_LEASE_VERSION}, got ${rawVersion ?? '<missing>'}`,\n\t\t\t},\n\t\t};\n\t}\n\tif (\n\t\trouterProfileId === null ||\n\t\tapp === null ||\n\t\tstack === null ||\n\t\tpid === null ||\n\t\tstartTime === null ||\n\t\thostname === null ||\n\t\tclaimedAt === null ||\n\t\theartbeatAt === null ||\n\t\t(intent !== 'normal' && intent !== 'snapshot')\n\t) {\n\t\treturn {\n\t\t\tlease: null,\n\t\t\tdiagnostic: {\n\t\t\t\t_tag: 'DispatchRouteDecodeDiagnostic',\n\t\t\t\tdispatchFileId,\n\t\t\t\treason: 'invalid-route-lease-metadata',\n\t\t\t\tdetail: 'route lease metadata is incomplete or malformed',\n\t\t\t},\n\t\t};\n\t}\n\treturn {\n\t\tlease: {\n\t\t\tversion: ROUTER_ROUTE_LEASE_VERSION,\n\t\t\trouterProfileId,\n\t\t\tapp,\n\t\t\tstack,\n\t\t\towner: {\n\t\t\t\tpid,\n\t\t\t\tstartTime,\n\t\t\t\thostname,\n\t\t\t\tclaimedAt,\n\t\t\t\theartbeatAt,\n\t\t\t\tintent,\n\t\t\t},\n\t\t},\n\t\tdiagnostic: null,\n\t};\n};\n\nexport const parseDispatchRouteFile = (\n\tbody: string,\n\tfallbackDispatchFileId: string | null = null,\n): DispatchRouteParseResult => {\n\tconst dispatchFileId = commentValue(body, 'dispatchFileId') ?? fallbackDispatchFileId;\n\tconst wireProtocol = parseWireProtocol(body);\n\tconst entrypointName =\n\t\tcommentValue(body, 'entrypointName') ?? matchValue(body, /entryPoints: \\[\"([^\"]+)\"\\]/);\n\tconst hostname =\n\t\tcommentValue(body, 'hostname') ??\n\t\tmatchValue(body, /Host\\(`([^`]+)`\\)/) ??\n\t\t(wireProtocol === 'tcp' ? '' : null);\n\tconst portRaw = commentValue(body, 'entrypointPort');\n\tconst entrypointPort =\n\t\tportRaw === null || !/^\\d+$/.test(portRaw) ? null : Number.parseInt(portRaw, 10);\n\n\tif (\n\t\tdispatchFileId === null ||\n\t\twireProtocol === null ||\n\t\tentrypointName === null ||\n\t\thostname === null\n\t) {\n\t\tconst protectedDispatchFileId = dispatchFileId ?? '<unknown>';\n\t\treturn {\n\t\t\t_tag: 'invalid',\n\t\t\tdispatchFileId: protectedDispatchFileId,\n\t\t\tdiagnostics: [\n\t\t\t\t{\n\t\t\t\t\t_tag: 'DispatchRouteDecodeDiagnostic',\n\t\t\t\t\tdispatchFileId: protectedDispatchFileId,\n\t\t\t\t\treason: 'missing-required-route-metadata',\n\t\t\t\t\tdetail:\n\t\t\t\t\t\t'route file is missing dispatchFileId, wireProtocol/http|tcp block, entrypointName, or hostname metadata',\n\t\t\t\t},\n\t\t\t],\n\t\t};\n\t}\n\tconst leaseResult = parseRouteLeaseMetadata(body, dispatchFileId);\n\n\treturn {\n\t\t_tag: 'valid',\n\t\troute: {\n\t\t\tdispatchFileId,\n\t\t\thostname,\n\t\t\tentrypointName,\n\t\t\tentrypointPort,\n\t\t\twireProtocol,\n\t\t\tlease: leaseResult.lease,\n\t\t},\n\t\tdiagnostics: leaseResult.diagnostic === null ? [] : [leaseResult.diagnostic],\n\t};\n};\n\nexport const parseDispatchRouteMetadata = (\n\tbody: string,\n\tfallbackDispatchFileId: string | null = null,\n): DispatchRouteMetadata | null => {\n\tconst parsed = parseDispatchRouteFile(body, fallbackDispatchFileId);\n\treturn parsed._tag === 'valid' ? parsed.route : null;\n};\n\n// ---------------------------------------------------------------------------\n// Collision detection\n// ---------------------------------------------------------------------------\n\n/** Assert no two resolved routes share dispatch keys.\n *\n * - HTTP routes collide on `(entrypoint, hostname)` — two HTTP backends\n * on the same entrypoint port can coexist via different Host headers,\n * so the Host *is* part of the key.\n * - TCP routes collide on `entrypoint` alone — TCP has no Host header,\n * so an entrypoint can serve exactly ONE backend. Two TCP decls on\n * the same entrypoint are an unambiguous error (parallel stacks of\n * a TCP service share the host port and would clobber each other).\n *\n * Architecture invariant #7 — distinct identity → distinct dispatch\n * URL. The TCP arm is the new clause; HTTP arm unchanged. */\nexport const detectCollisions = (\n\troutes: ReadonlyArray<RouteCollisionMetadata>,\n): RouteCollision | null => {\n\tconst seen = new Map<string, Array<RouteCollisionMetadata>>();\n\tfor (const r of routes) {\n\t\tconst portKey =\n\t\t\tr.entrypointPort === null ? `entrypoint:${r.entrypointName}` : `port:${r.entrypointPort}`;\n\t\tconst key = r.wireProtocol === 'tcp' ? `tcp@${portKey}` : `http@${portKey}@${r.hostname}`;\n\t\tconst acc = seen.get(key);\n\t\tif (acc) acc.push(r);\n\t\telse seen.set(key, [r]);\n\t}\n\tfor (const [key, colliding] of seen) {\n\t\tif (colliding.length > 1) {\n\t\t\tconst ids = colliding.map((route) => route.dispatchFileId);\n\t\t\tconst first = colliding[0];\n\t\t\tif (key.startsWith('tcp@')) {\n\t\t\t\treturn new RouteCollision({\n\t\t\t\t\tmessage: routeCollisionMessage({\n\t\t\t\t\t\thostname: '',\n\t\t\t\t\t\tentrypoint: first?.entrypointName ?? '',\n\t\t\t\t\t\tdispatchIds: ids,\n\t\t\t\t\t\twireProtocol: 'tcp',\n\t\t\t\t\t}),\n\t\t\t\t\thostname: '',\n\t\t\t\t\tentrypoint: first?.entrypointName ?? '',\n\t\t\t\t\tdispatchIds: ids,\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn new RouteCollision({\n\t\t\t\tmessage: routeCollisionMessage({\n\t\t\t\t\thostname: first?.hostname ?? '',\n\t\t\t\t\tentrypoint: first?.entrypointName ?? '',\n\t\t\t\t\tdispatchIds: ids,\n\t\t\t\t\twireProtocol: 'http',\n\t\t\t\t}),\n\t\t\t\thostname: first?.hostname ?? '',\n\t\t\t\tentrypoint: first?.entrypointName ?? '',\n\t\t\t\tdispatchIds: ids,\n\t\t\t});\n\t\t}\n\t}\n\treturn null;\n};\n\nconst routeCollisionMessage = (collision: {\n\treadonly hostname: string;\n\treadonly entrypoint: string;\n\treadonly dispatchIds: ReadonlyArray<string>;\n\treadonly wireProtocol: ResolvedWireProtocol;\n}): string => {\n\tconst ids = collision.dispatchIds.join(', ');\n\tif (collision.wireProtocol === 'tcp') {\n\t\treturn `router TCP route collision on entrypoint '${collision.entrypoint}' for dispatch ids: ${ids}`;\n\t}\n\treturn (\n\t\t`router route collision on entrypoint '${collision.entrypoint}' ` +\n\t\t`and hostname '${collision.hostname}' for dispatch ids: ${ids}`\n\t);\n};\n\n// ---------------------------------------------------------------------------\n// Static base file — Traefik provider directive\n// ---------------------------------------------------------------------------\n\n/** Filename for the file-provider static config. Traefik is launched\n * with `--providers.file.directory=/etc/traefik/dispatch` so it\n * reads from there directly; this static file is OPTIONAL polish\n * and currently unused. Reserved for future provider tuning. */\nexport const STATIC_PROVIDER_FILENAME = '00-providers.yml';\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { RouterValidationError } from "./errors.mjs";
|
|
2
|
+
import { Effect } from "effect";
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
const LABEL = /^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
5
|
+
const MAX_DISPATCH_ID_LEN = 140;
|
|
6
|
+
const MAX_DISPATCH_ID_READABLE_LEN = 48;
|
|
7
|
+
const MAX_HOSTNAME_LEN = 200;
|
|
8
|
+
/** Validate a single label-shaped string. Returns the input or fails
|
|
9
|
+
* with a typed `RouterValidationError`. */
|
|
10
|
+
const validateLabel = (field, value) => {
|
|
11
|
+
if (!LABEL.test(value)) return Effect.fail(new RouterValidationError({
|
|
12
|
+
field,
|
|
13
|
+
value,
|
|
14
|
+
detail: "expected lower-case RFC-1035 label (alphanumeric + internal hyphens, 1-63 chars)"
|
|
15
|
+
}));
|
|
16
|
+
return Effect.succeed(value);
|
|
17
|
+
};
|
|
18
|
+
/** Fold dots → hyphens (architecture invariant #8) and lower-case.
|
|
19
|
+
* Pure, no validation. The output is fed to `validateLabel`. */
|
|
20
|
+
const normalizeServiceSegment = (raw) => raw.toLowerCase().replace(/\./g, "-");
|
|
21
|
+
/** Build the human-readable prefix of a dispatch id. This is not the
|
|
22
|
+
* identity key; uniqueness comes from the hash over the canonical
|
|
23
|
+
* tuple in `dispatchFileId`. */
|
|
24
|
+
const normalizeDispatchSegment = (raw) => raw.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "") || "route";
|
|
25
|
+
/** Mint the per-Routable hostname from `(identity, role)`.
|
|
26
|
+
*
|
|
27
|
+
* Default stack: `<role>.<app>.localhost`
|
|
28
|
+
* Other stacks: `<role>.<stack>.<app>.localhost`
|
|
29
|
+
*
|
|
30
|
+
* The `role` segment is folded + validated; the `app` and `stack`
|
|
31
|
+
* segments are also validated (they come from `Identity`, which the
|
|
32
|
+
* substrate has already validated once at boot, but defense-in-depth
|
|
33
|
+
* is cheap and the failure mode is a programming error).
|
|
34
|
+
*
|
|
35
|
+
* Architecture invariant #7: this MUST embed the stack dimension for
|
|
36
|
+
* non-default stacks. Distinct identities → distinct hostnames. */
|
|
37
|
+
const routerHostname = (identity, role) => Effect.gen(function* () {
|
|
38
|
+
const app = yield* validateLabel("hostname", identity.app);
|
|
39
|
+
const roleSafe = yield* validateLabel("hostname", normalizeServiceSegment(role));
|
|
40
|
+
const host = (() => {
|
|
41
|
+
if (identity.stack === "main") return `${roleSafe}.${app}.localhost`;
|
|
42
|
+
return `${roleSafe}.${identity.stack.toLowerCase()}.${app}.localhost`;
|
|
43
|
+
})();
|
|
44
|
+
if (host.length > MAX_HOSTNAME_LEN) return yield* Effect.fail(new RouterValidationError({
|
|
45
|
+
field: "hostname",
|
|
46
|
+
value: host,
|
|
47
|
+
detail: `exceeds ${MAX_HOSTNAME_LEN}-char limit`
|
|
48
|
+
}));
|
|
49
|
+
if (identity.stack !== "main") yield* validateLabel("hostname", identity.stack.toLowerCase());
|
|
50
|
+
return host;
|
|
51
|
+
});
|
|
52
|
+
const canonicalDispatchTuple = (inputs) => JSON.stringify([
|
|
53
|
+
"devstack-router-dispatch-v1",
|
|
54
|
+
inputs.identity.app,
|
|
55
|
+
inputs.identity.stack,
|
|
56
|
+
inputs.dispatch.serviceKey,
|
|
57
|
+
inputs.dispatch.role
|
|
58
|
+
]);
|
|
59
|
+
const truncateReadable = (value) => (value.length <= MAX_DISPATCH_ID_READABLE_LEN ? value : value.slice(0, MAX_DISPATCH_ID_READABLE_LEN).replace(/-+$/g, "")) || "route";
|
|
60
|
+
/** Mint a dispatch-file id from the full route identity tuple. The id
|
|
61
|
+
* is used as the file name in the global file-provider directory
|
|
62
|
+
* (one file per backend), and as the Traefik router/service name
|
|
63
|
+
* inside the file.
|
|
64
|
+
*
|
|
65
|
+
* Format: `r1-<readable-prefix>-<sha256>`.
|
|
66
|
+
*
|
|
67
|
+
* The readable prefix is intentionally lossy; it exists only to make
|
|
68
|
+
* directory listings diagnosable. The SHA-256 suffix is over the
|
|
69
|
+
* canonical `(version, app, stack, serviceKey, role)` tuple, so
|
|
70
|
+
* raw underscores, separator strings, case, and dot/hyphen folding do
|
|
71
|
+
* not affect identity. */
|
|
72
|
+
const dispatchFileId = (inputs) => Effect.gen(function* () {
|
|
73
|
+
const id = `r1-${truncateReadable(normalizeDispatchSegment([
|
|
74
|
+
inputs.identity.app,
|
|
75
|
+
inputs.identity.stack,
|
|
76
|
+
inputs.dispatch.serviceKey,
|
|
77
|
+
inputs.dispatch.role
|
|
78
|
+
].join("-")))}-${createHash("sha256").update(canonicalDispatchTuple(inputs)).digest("hex")}`;
|
|
79
|
+
if (id.length > MAX_DISPATCH_ID_LEN) return yield* Effect.fail(new RouterValidationError({
|
|
80
|
+
field: "dispatchId",
|
|
81
|
+
value: id,
|
|
82
|
+
detail: `exceeds ${MAX_DISPATCH_ID_LEN}-char limit`
|
|
83
|
+
}));
|
|
84
|
+
if (!/^r1-[a-z0-9][a-z0-9-]*-[a-f0-9]{64}$/.test(id)) return yield* Effect.fail(new RouterValidationError({
|
|
85
|
+
field: "dispatchId",
|
|
86
|
+
value: id,
|
|
87
|
+
detail: "expected r1-<lower-case-slug>-<sha256-hex>"
|
|
88
|
+
}));
|
|
89
|
+
return id;
|
|
90
|
+
});
|
|
91
|
+
/** URL-construction helper: `<scheme>://<hostname>:<port>`.
|
|
92
|
+
*
|
|
93
|
+
* - `http` / `h2c` → `http://…` (h2c is HTTP/2 cleartext; Traefik
|
|
94
|
+
* handles upstream selection internally, the URL scheme is still
|
|
95
|
+
* `http`).
|
|
96
|
+
* - `tcp` → `tcp://…` — used by the file-provider renderer to
|
|
97
|
+
* distinguish from HTTP at YAML-emit time. Consumers of the
|
|
98
|
+
* resolved URL (manifest, codegen) translate back to whatever
|
|
99
|
+
* scheme their protocol expects (e.g. `postgres://`, `redis://`). */
|
|
100
|
+
const renderUrl = (parts) => {
|
|
101
|
+
if (parts.protocol === "tcp") return `tcp://${parts.hostname}:${parts.port}`;
|
|
102
|
+
return `http://${parts.hostname}:${parts.port}`;
|
|
103
|
+
};
|
|
104
|
+
//#endregion
|
|
105
|
+
export { dispatchFileId, renderUrl, routerHostname };
|
|
106
|
+
|
|
107
|
+
//# sourceMappingURL=hostname.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hostname.mjs","names":[],"sources":["../../../src/orchestrators/router/hostname.ts"],"sourcesContent":["// Hostname + dispatch-id minting helpers.\n//\n// Architecture distilled-doc §\"Outputs / capabilities provided\":\n//\n// - default (\"main\") stack: `<service>.<app>.localhost`\n// - every other stack: `<service>.<stack>.<app>.localhost`\n//\n// \"service\" here is the dispatch-id's `role` segment — NOT the\n// plugin's name. Plugins emit a `(serviceKey, role)` DispatchId; we\n// fold the role into the hostname, since the role is the\n// user-meaningful side (\"api\", \"key-server\", \"indexer-metrics\") and\n// the service key already encodes plugin + app + stack on the\n// dispatch-file side.\n//\n// Architecture invariants:\n// #7 — Distinct `(app, stack, service)` triples MUST produce\n// distinct hostnames AND distinct dispatch ids. The default-\n// stack omission is intentional UX; every other stack\n// includes the stack segment so parallel stacks of the same\n// app never collide.\n// #8 — Hostname service labels fold dots to a label-safe separator.\n// Dispatch ids are minted from a canonical source tuple plus a\n// SHA-256 digest, so lossy readable folding cannot collide.\n// #13 — User-influenceable strings are validated against a\n// conservative character set before render.\n\nimport { createHash } from 'node:crypto';\n\nimport { Effect } from 'effect';\nimport type { DispatchId } from '../../contracts/routable.ts';\nimport type { Identity } from '../../substrate/identity.ts';\nimport { RouterValidationError } from './errors.ts';\n\n/** The conventional \"default\" stack name. Hostnames for this stack\n * omit the stack segment per the architecture's UX rule. */\nexport const DEFAULT_STACK = 'main';\n\n// RFC-1035 single-label regex: starts/ends with alphanumeric, allows\n// internal hyphens, length 1-63. We use the same shape for app, role,\n// and (post-fold) the stack segment.\nconst LABEL = /^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/;\n// The readable prefix is capped, and the SHA-256 suffix is fixed size.\nconst MAX_DISPATCH_ID_LEN = 140;\nconst MAX_DISPATCH_ID_READABLE_LEN = 48;\n// 253 chars is the RFC-1035 full-name max. We stay well below.\nconst MAX_HOSTNAME_LEN = 200;\n\n/** Validate a single label-shaped string. Returns the input or fails\n * with a typed `RouterValidationError`. */\nconst validateLabel = (\n\tfield: RouterValidationError['field'],\n\tvalue: string,\n): Effect.Effect<string, RouterValidationError> => {\n\tif (!LABEL.test(value)) {\n\t\treturn Effect.fail(\n\t\t\tnew RouterValidationError({\n\t\t\t\tfield,\n\t\t\t\tvalue,\n\t\t\t\tdetail: 'expected lower-case RFC-1035 label (alphanumeric + internal hyphens, 1-63 chars)',\n\t\t\t}),\n\t\t);\n\t}\n\treturn Effect.succeed(value);\n};\n\n/** Fold dots → hyphens (architecture invariant #8) and lower-case.\n * Pure, no validation. The output is fed to `validateLabel`. */\nexport const normalizeServiceSegment = (raw: string): string =>\n\traw.toLowerCase().replace(/\\./g, '-');\n\n/** Build the human-readable prefix of a dispatch id. This is not the\n * identity key; uniqueness comes from the hash over the canonical\n * tuple in `dispatchFileId`. */\nexport const normalizeDispatchSegment = (raw: string): string =>\n\traw\n\t\t.toLowerCase()\n\t\t.replace(/[^a-z0-9]+/g, '-')\n\t\t.replace(/-+/g, '-')\n\t\t.replace(/^-|-$/g, '') || 'route';\n\n// ---------------------------------------------------------------------------\n// Hostname minting\n// ---------------------------------------------------------------------------\n\n/** Mint the per-Routable hostname from `(identity, role)`.\n *\n * Default stack: `<role>.<app>.localhost`\n * Other stacks: `<role>.<stack>.<app>.localhost`\n *\n * The `role` segment is folded + validated; the `app` and `stack`\n * segments are also validated (they come from `Identity`, which the\n * substrate has already validated once at boot, but defense-in-depth\n * is cheap and the failure mode is a programming error).\n *\n * Architecture invariant #7: this MUST embed the stack dimension for\n * non-default stacks. Distinct identities → distinct hostnames. */\nexport const routerHostname = (\n\tidentity: Identity,\n\trole: string,\n): Effect.Effect<string, RouterValidationError> =>\n\tEffect.gen(function* () {\n\t\tconst app = yield* validateLabel('hostname', identity.app);\n\t\tconst folded = normalizeServiceSegment(role);\n\t\tconst roleSafe = yield* validateLabel('hostname', folded);\n\t\tconst host = (() => {\n\t\t\tif (identity.stack === DEFAULT_STACK) {\n\t\t\t\treturn `${roleSafe}.${app}.localhost`;\n\t\t\t}\n\t\t\tconst stackSafe = identity.stack.toLowerCase();\n\t\t\t// `validateLabel` runs *after* lower-casing so the stack name\n\t\t\t// (Identity brand) is held to the same character set as the\n\t\t\t// role and the app. Boot validation should already enforce\n\t\t\t// this; we re-check defensively.\n\t\t\treturn `${roleSafe}.${stackSafe}.${app}.localhost`;\n\t\t})();\n\t\tif (host.length > MAX_HOSTNAME_LEN) {\n\t\t\treturn yield* Effect.fail(\n\t\t\t\tnew RouterValidationError({\n\t\t\t\t\tfield: 'hostname',\n\t\t\t\t\tvalue: host,\n\t\t\t\t\tdetail: `exceeds ${MAX_HOSTNAME_LEN}-char limit`,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\t// Re-validate the stack segment for non-default stacks now that\n\t\t// it's part of a composed hostname.\n\t\tif (identity.stack !== DEFAULT_STACK) {\n\t\t\tyield* validateLabel('hostname', identity.stack.toLowerCase());\n\t\t}\n\t\treturn host;\n\t});\n\n// ---------------------------------------------------------------------------\n// Dispatch-file id minting\n// ---------------------------------------------------------------------------\n\nexport interface DispatchFileIdInputs {\n\treadonly identity: Identity;\n\treadonly dispatch: DispatchId;\n}\n\nconst canonicalDispatchTuple = (inputs: DispatchFileIdInputs): string =>\n\tJSON.stringify([\n\t\t'devstack-router-dispatch-v1',\n\t\tinputs.identity.app,\n\t\tinputs.identity.stack,\n\t\tinputs.dispatch.serviceKey,\n\t\tinputs.dispatch.role,\n\t]);\n\nconst truncateReadable = (value: string): string =>\n\t(value.length <= MAX_DISPATCH_ID_READABLE_LEN\n\t\t? value\n\t\t: value.slice(0, MAX_DISPATCH_ID_READABLE_LEN).replace(/-+$/g, '')) || 'route';\n\n/** Mint a dispatch-file id from the full route identity tuple. The id\n * is used as the file name in the global file-provider directory\n * (one file per backend), and as the Traefik router/service name\n * inside the file.\n *\n * Format: `r1-<readable-prefix>-<sha256>`.\n *\n * The readable prefix is intentionally lossy; it exists only to make\n * directory listings diagnosable. The SHA-256 suffix is over the\n * canonical `(version, app, stack, serviceKey, role)` tuple, so\n * raw underscores, separator strings, case, and dot/hyphen folding do\n * not affect identity. */\nexport const dispatchFileId = (\n\tinputs: DispatchFileIdInputs,\n): Effect.Effect<string, RouterValidationError> =>\n\tEffect.gen(function* () {\n\t\tconst readable = truncateReadable(\n\t\t\tnormalizeDispatchSegment(\n\t\t\t\t[\n\t\t\t\t\tinputs.identity.app,\n\t\t\t\t\tinputs.identity.stack,\n\t\t\t\t\tinputs.dispatch.serviceKey,\n\t\t\t\t\tinputs.dispatch.role,\n\t\t\t\t].join('-'),\n\t\t\t),\n\t\t);\n\t\tconst hash = createHash('sha256').update(canonicalDispatchTuple(inputs)).digest('hex');\n\t\tconst id = `r1-${readable}-${hash}`;\n\t\tif (id.length > MAX_DISPATCH_ID_LEN) {\n\t\t\treturn yield* Effect.fail(\n\t\t\t\tnew RouterValidationError({\n\t\t\t\t\tfield: 'dispatchId',\n\t\t\t\t\tvalue: id,\n\t\t\t\t\tdetail: `exceeds ${MAX_DISPATCH_ID_LEN}-char limit`,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\tif (!/^r1-[a-z0-9][a-z0-9-]*-[a-f0-9]{64}$/.test(id)) {\n\t\t\treturn yield* Effect.fail(\n\t\t\t\tnew RouterValidationError({\n\t\t\t\t\tfield: 'dispatchId',\n\t\t\t\t\tvalue: id,\n\t\t\t\t\tdetail: 'expected r1-<lower-case-slug>-<sha256-hex>',\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\treturn id;\n\t});\n\n/** URL-construction helper: `<scheme>://<hostname>:<port>`.\n *\n * - `http` / `h2c` → `http://…` (h2c is HTTP/2 cleartext; Traefik\n * handles upstream selection internally, the URL scheme is still\n * `http`).\n * - `tcp` → `tcp://…` — used by the file-provider renderer to\n * distinguish from HTTP at YAML-emit time. Consumers of the\n * resolved URL (manifest, codegen) translate back to whatever\n * scheme their protocol expects (e.g. `postgres://`, `redis://`). */\nexport const renderUrl = (parts: {\n\treadonly protocol: 'http' | 'h2c' | 'tcp';\n\treadonly hostname: string;\n\treadonly port: number;\n}): string => {\n\tif (parts.protocol === 'tcp') return `tcp://${parts.hostname}:${parts.port}`;\n\treturn `http://${parts.hostname}:${parts.port}`;\n};\n"],"mappings":";;;AAwCA,MAAM,QAAQ;AAEd,MAAM,sBAAsB;AAC5B,MAAM,+BAA+B;AAErC,MAAM,mBAAmB;;;AAIzB,MAAM,iBACL,OACA,UACkD;AAClD,KAAI,CAAC,MAAM,KAAK,MAAM,CACrB,QAAO,OAAO,KACb,IAAI,sBAAsB;EACzB;EACA;EACA,QAAQ;EACR,CAAC,CACF;AAEF,QAAO,OAAO,QAAQ,MAAM;;;;AAK7B,MAAa,2BAA2B,QACvC,IAAI,aAAa,CAAC,QAAQ,OAAO,IAAI;;;;AAKtC,MAAa,4BAA4B,QACxC,IACE,aAAa,CACb,QAAQ,eAAe,IAAI,CAC3B,QAAQ,OAAO,IAAI,CACnB,QAAQ,UAAU,GAAG,IAAI;;;;;;;;;;;;;AAkB5B,MAAa,kBACZ,UACA,SAEA,OAAO,IAAI,aAAa;CACvB,MAAM,MAAM,OAAO,cAAc,YAAY,SAAS,IAAI;CAE1D,MAAM,WAAW,OAAO,cAAc,YADvB,wBAAwB,KACiB,CAAC;CACzD,MAAM,cAAc;AACnB,MAAI,SAAS,UAAA,OACZ,QAAO,GAAG,SAAS,GAAG,IAAI;AAO3B,SAAO,GAAG,SAAS,GALD,SAAS,MAAM,aAKF,CAAC,GAAG,IAAI;KACpC;AACJ,KAAI,KAAK,SAAS,iBACjB,QAAO,OAAO,OAAO,KACpB,IAAI,sBAAsB;EACzB,OAAO;EACP,OAAO;EACP,QAAQ,WAAW,iBAAiB;EACpC,CAAC,CACF;AAIF,KAAI,SAAS,UAAA,OACZ,QAAO,cAAc,YAAY,SAAS,MAAM,aAAa,CAAC;AAE/D,QAAO;EACN;AAWH,MAAM,0BAA0B,WAC/B,KAAK,UAAU;CACd;CACA,OAAO,SAAS;CAChB,OAAO,SAAS;CAChB,OAAO,SAAS;CAChB,OAAO,SAAS;CAChB,CAAC;AAEH,MAAM,oBAAoB,WACxB,MAAM,UAAU,+BACd,QACA,MAAM,MAAM,GAAG,6BAA6B,CAAC,QAAQ,QAAQ,GAAG,KAAK;;;;;;;;;;;;;AAczE,MAAa,kBACZ,WAEA,OAAO,IAAI,aAAa;CAYvB,MAAM,KAAK,MAXM,iBAChB,yBACC;EACC,OAAO,SAAS;EAChB,OAAO,SAAS;EAChB,OAAO,SAAS;EAChB,OAAO,SAAS;EAChB,CAAC,KAAK,IAAI,CACX,CAGuB,CAAC,GADb,WAAW,SAAS,CAAC,OAAO,uBAAuB,OAAO,CAAC,CAAC,OAAO,MAC/C;AACjC,KAAI,GAAG,SAAS,oBACf,QAAO,OAAO,OAAO,KACpB,IAAI,sBAAsB;EACzB,OAAO;EACP,OAAO;EACP,QAAQ,WAAW,oBAAoB;EACvC,CAAC,CACF;AAEF,KAAI,CAAC,uCAAuC,KAAK,GAAG,CACnD,QAAO,OAAO,OAAO,KACpB,IAAI,sBAAsB;EACzB,OAAO;EACP,OAAO;EACP,QAAQ;EACR,CAAC,CACF;AAEF,QAAO;EACN;;;;;;;;;;AAWH,MAAa,aAAa,UAIZ;AACb,KAAI,MAAM,aAAa,MAAO,QAAO,SAAS,MAAM,SAAS,GAAG,MAAM;AACtE,QAAO,UAAU,MAAM,SAAS,GAAG,MAAM"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { execFileSync } from "node:child_process";
|
|
5
|
+
import { homedir, userInfo } from "node:os";
|
|
6
|
+
const shortHash = (input) => createHash("sha256").update(input).digest("hex").slice(0, 12);
|
|
7
|
+
const safeSegment = (input) => input.toLowerCase().replace(/[^a-z0-9_.-]+/g, "-").replace(/^[^a-z0-9]+/, "").slice(0, 24).replace(/[-_.]+$/, "");
|
|
8
|
+
const makeRouterProfile = (options) => {
|
|
9
|
+
const prefix = options.namePrefix ?? "devstack";
|
|
10
|
+
const fingerprint = shortHash(`${options.userId}\0${options.dockerContextId}`);
|
|
11
|
+
const id = `${safeSegment(options.userId) || "user"}-${fingerprint}`;
|
|
12
|
+
const stateDir = join(options.stateRoot ?? join(homedir(), ".devstack", "router"), id);
|
|
13
|
+
return {
|
|
14
|
+
version: 1,
|
|
15
|
+
id,
|
|
16
|
+
userId: options.userId,
|
|
17
|
+
dockerContextId: options.dockerContextId,
|
|
18
|
+
stateDir,
|
|
19
|
+
dispatchDir: join(stateDir, "dispatch"),
|
|
20
|
+
containerName: `${prefix}-router-${fingerprint}`,
|
|
21
|
+
networkName: `${prefix}-router-${fingerprint}`,
|
|
22
|
+
bootstrapLockFile: join(stateDir, "locks", "bootstrap.lock"),
|
|
23
|
+
dispatchLockFile: join(stateDir, "locks", "dispatch.lock")
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
const currentRouterUserId = () => {
|
|
27
|
+
if (typeof process.getuid === "function") return `uid-${process.getuid()}`;
|
|
28
|
+
try {
|
|
29
|
+
return `user-${userInfo().username}`;
|
|
30
|
+
} catch {
|
|
31
|
+
return `user-${process.env.USER ?? "unknown"}`;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
const dockerContextFromCli = (bin, env) => {
|
|
35
|
+
try {
|
|
36
|
+
const trimmed = execFileSync(bin, ["context", "show"], {
|
|
37
|
+
encoding: "utf8",
|
|
38
|
+
timeout: 1e3,
|
|
39
|
+
stdio: [
|
|
40
|
+
"ignore",
|
|
41
|
+
"pipe",
|
|
42
|
+
"ignore"
|
|
43
|
+
],
|
|
44
|
+
env: {
|
|
45
|
+
...process.env,
|
|
46
|
+
...env
|
|
47
|
+
}
|
|
48
|
+
}).trim();
|
|
49
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
50
|
+
} catch {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
const dockerContextFromConfig = (env) => {
|
|
55
|
+
const configDir = env.DOCKER_CONFIG ?? join(homedir(), ".docker");
|
|
56
|
+
try {
|
|
57
|
+
const raw = JSON.parse(readFileSync(join(configDir, "config.json"), "utf8"));
|
|
58
|
+
return typeof raw.currentContext === "string" && raw.currentContext.trim().length > 0 ? raw.currentContext.trim() : null;
|
|
59
|
+
} catch {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
const dockerDaemonIdFromCli = (bin, env) => {
|
|
64
|
+
try {
|
|
65
|
+
const trimmed = execFileSync(bin, [
|
|
66
|
+
"info",
|
|
67
|
+
"--format",
|
|
68
|
+
"{{.ID}}"
|
|
69
|
+
], {
|
|
70
|
+
encoding: "utf8",
|
|
71
|
+
timeout: 1e3,
|
|
72
|
+
stdio: [
|
|
73
|
+
"ignore",
|
|
74
|
+
"pipe",
|
|
75
|
+
"ignore"
|
|
76
|
+
],
|
|
77
|
+
env: {
|
|
78
|
+
...process.env,
|
|
79
|
+
...env
|
|
80
|
+
}
|
|
81
|
+
}).trim();
|
|
82
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
83
|
+
} catch {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
const resolveDockerContextId = (dockerHost = {}, env = process.env) => {
|
|
88
|
+
const bin = dockerHost.bin ?? "docker";
|
|
89
|
+
const host = dockerHost.dockerHost ?? env.DOCKER_HOST ?? "default";
|
|
90
|
+
const dockerEnv = {
|
|
91
|
+
...env.DOCKER_CONTEXT === void 0 ? {} : { DOCKER_CONTEXT: env.DOCKER_CONTEXT },
|
|
92
|
+
...host === "default" ? {} : { DOCKER_HOST: host }
|
|
93
|
+
};
|
|
94
|
+
const envContext = env.DOCKER_CONTEXT?.trim();
|
|
95
|
+
const context = envContext && envContext.length > 0 ? envContext : dockerContextFromConfig(env) ?? dockerContextFromCli(bin, dockerEnv);
|
|
96
|
+
if (context !== null) return `context:${context}|host:${host}`;
|
|
97
|
+
const daemonId = dockerDaemonIdFromCli(bin, dockerEnv);
|
|
98
|
+
if (daemonId !== null) return `daemon:${daemonId}`;
|
|
99
|
+
return `context:default|host:${host}`;
|
|
100
|
+
};
|
|
101
|
+
const makeDefaultRouterProfile = (options = {}) => makeRouterProfile({
|
|
102
|
+
userId: currentRouterUserId(),
|
|
103
|
+
dockerContextId: resolveDockerContextId(options.dockerHost, options.env),
|
|
104
|
+
...options.stateRoot === void 0 ? {} : { stateRoot: options.stateRoot }
|
|
105
|
+
});
|
|
106
|
+
//#endregion
|
|
107
|
+
export { makeDefaultRouterProfile };
|
|
108
|
+
|
|
109
|
+
//# sourceMappingURL=profile.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile.mjs","names":[],"sources":["../../../src/orchestrators/router/profile.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport { execFileSync } from 'node:child_process';\nimport { readFileSync } from 'node:fs';\nimport { homedir, userInfo } from 'node:os';\nimport { join } from 'node:path';\n\nimport type { DockerHostShape } from '../../runtime/docker/client.ts';\n\nexport const ROUTER_PROFILE_VERSION = 1;\n\nexport interface RouterProfile {\n\treadonly version: typeof ROUTER_PROFILE_VERSION;\n\treadonly id: string;\n\treadonly userId: string;\n\treadonly dockerContextId: string;\n\treadonly stateDir: string;\n\treadonly dispatchDir: string;\n\treadonly containerName: string;\n\treadonly networkName: string;\n\treadonly bootstrapLockFile: string;\n\treadonly dispatchLockFile: string;\n}\n\nexport interface RouterProfileOptions {\n\treadonly userId: string;\n\treadonly dockerContextId: string;\n\treadonly stateRoot?: string;\n\treadonly namePrefix?: string;\n}\n\nexport interface DefaultRouterProfileOptions {\n\treadonly dockerHost?: DockerHostShape;\n\treadonly env?: Readonly<Record<string, string | undefined>>;\n\treadonly stateRoot?: string;\n}\n\nconst shortHash = (input: string): string =>\n\tcreateHash('sha256').update(input).digest('hex').slice(0, 12);\n\nconst safeSegment = (input: string): string =>\n\tinput\n\t\t.toLowerCase()\n\t\t.replace(/[^a-z0-9_.-]+/g, '-')\n\t\t.replace(/^[^a-z0-9]+/, '')\n\t\t.slice(0, 24)\n\t\t.replace(/[-_.]+$/, '');\n\nexport const makeRouterProfile = (options: RouterProfileOptions): RouterProfile => {\n\tconst prefix = options.namePrefix ?? 'devstack';\n\tconst fingerprint = shortHash(`${options.userId}\\0${options.dockerContextId}`);\n\tconst userSegment = safeSegment(options.userId) || 'user';\n\tconst id = `${userSegment}-${fingerprint}`;\n\tconst stateRoot = options.stateRoot ?? join(homedir(), '.devstack', 'router');\n\tconst stateDir = join(stateRoot, id);\n\treturn {\n\t\tversion: ROUTER_PROFILE_VERSION,\n\t\tid,\n\t\tuserId: options.userId,\n\t\tdockerContextId: options.dockerContextId,\n\t\tstateDir,\n\t\tdispatchDir: join(stateDir, 'dispatch'),\n\t\tcontainerName: `${prefix}-router-${fingerprint}`,\n\t\tnetworkName: `${prefix}-router-${fingerprint}`,\n\t\tbootstrapLockFile: join(stateDir, 'locks', 'bootstrap.lock'),\n\t\tdispatchLockFile: join(stateDir, 'locks', 'dispatch.lock'),\n\t};\n};\n\nexport const currentRouterUserId = (): string => {\n\tif (typeof process.getuid === 'function') return `uid-${process.getuid()}`;\n\ttry {\n\t\treturn `user-${userInfo().username}`;\n\t} catch {\n\t\treturn `user-${process.env.USER ?? 'unknown'}`;\n\t}\n};\n\nconst dockerContextFromCli = (\n\tbin: string,\n\tenv: Readonly<Record<string, string | undefined>>,\n): string | null => {\n\ttry {\n\t\tconst out = execFileSync(bin, ['context', 'show'], {\n\t\t\tencoding: 'utf8',\n\t\t\ttimeout: 1000,\n\t\t\tstdio: ['ignore', 'pipe', 'ignore'],\n\t\t\tenv: { ...process.env, ...env },\n\t\t});\n\t\tconst trimmed = out.trim();\n\t\treturn trimmed.length > 0 ? trimmed : null;\n\t} catch {\n\t\treturn null;\n\t}\n};\n\nconst dockerContextFromConfig = (\n\tenv: Readonly<Record<string, string | undefined>>,\n): string | null => {\n\tconst configDir = env.DOCKER_CONFIG ?? join(homedir(), '.docker');\n\ttry {\n\t\tconst raw = JSON.parse(readFileSync(join(configDir, 'config.json'), 'utf8')) as {\n\t\t\treadonly currentContext?: unknown;\n\t\t};\n\t\treturn typeof raw.currentContext === 'string' && raw.currentContext.trim().length > 0\n\t\t\t? raw.currentContext.trim()\n\t\t\t: null;\n\t} catch {\n\t\treturn null;\n\t}\n};\n\nconst dockerDaemonIdFromCli = (\n\tbin: string,\n\tenv: Readonly<Record<string, string | undefined>>,\n): string | null => {\n\ttry {\n\t\tconst out = execFileSync(bin, ['info', '--format', '{{.ID}}'], {\n\t\t\tencoding: 'utf8',\n\t\t\ttimeout: 1000,\n\t\t\tstdio: ['ignore', 'pipe', 'ignore'],\n\t\t\tenv: { ...process.env, ...env },\n\t\t});\n\t\tconst trimmed = out.trim();\n\t\treturn trimmed.length > 0 ? trimmed : null;\n\t} catch {\n\t\treturn null;\n\t}\n};\n\nexport const resolveDockerContextId = (\n\tdockerHost: DockerHostShape = {},\n\tenv: Readonly<Record<string, string | undefined>> = process.env,\n): string => {\n\tconst bin = dockerHost.bin ?? 'docker';\n\tconst host = dockerHost.dockerHost ?? env.DOCKER_HOST ?? 'default';\n\tconst dockerEnv: Record<string, string | undefined> = {\n\t\t...(env.DOCKER_CONTEXT === undefined ? {} : { DOCKER_CONTEXT: env.DOCKER_CONTEXT }),\n\t\t...(host === 'default' ? {} : { DOCKER_HOST: host }),\n\t};\n\tconst envContext = env.DOCKER_CONTEXT?.trim();\n\tconst context =\n\t\tenvContext && envContext.length > 0\n\t\t\t? envContext\n\t\t\t: (dockerContextFromConfig(env) ?? dockerContextFromCli(bin, dockerEnv));\n\tif (context !== null) return `context:${context}|host:${host}`;\n\tconst daemonId = dockerDaemonIdFromCli(bin, dockerEnv);\n\tif (daemonId !== null) return `daemon:${daemonId}`;\n\treturn `context:default|host:${host}`;\n};\n\nexport const makeDefaultRouterProfile = (\n\toptions: DefaultRouterProfileOptions = {},\n): RouterProfile =>\n\tmakeRouterProfile({\n\t\tuserId: currentRouterUserId(),\n\t\tdockerContextId: resolveDockerContextId(options.dockerHost, options.env),\n\t\t...(options.stateRoot === undefined ? {} : { stateRoot: options.stateRoot }),\n\t});\n"],"mappings":"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"}
|