everything-dev 2.0.0-rc.6 → 2.0.0-rc.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/api/auth-middleware.cjs +14 -1
- package/dist/api/auth-middleware.cjs.map +1 -1
- package/dist/api/auth-middleware.d.cts +9 -0
- package/dist/api/auth-middleware.d.mts +9 -0
- package/dist/api/auth-middleware.mjs +14 -1
- package/dist/api/auth-middleware.mjs.map +1 -1
- package/dist/build.cjs +1 -1
- package/dist/build.mjs +1 -1
- package/dist/bundle-cache.cjs +1 -1
- package/dist/bundle-cache.cjs.map +1 -1
- package/dist/bundle-cache.mjs +1 -1
- package/dist/bundle-cache.mjs.map +1 -1
- package/dist/cli/init.cjs +22 -10
- package/dist/cli/init.cjs.map +1 -1
- package/dist/cli/init.mjs +22 -10
- package/dist/cli/init.mjs.map +1 -1
- package/dist/cli.cjs +6 -5
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs +5 -4
- package/dist/cli.mjs.map +1 -1
- package/dist/commands/deploy.cjs +111 -1
- package/dist/commands/deploy.cjs.map +1 -1
- package/dist/commands/deploy.mjs +112 -2
- package/dist/commands/deploy.mjs.map +1 -1
- package/dist/commands/keys.cjs +1 -1
- package/dist/commands/keys.cjs.map +1 -1
- package/dist/commands/keys.mjs +1 -1
- package/dist/commands/keys.mjs.map +1 -1
- package/dist/commands/smoke.cjs +41 -0
- package/dist/commands/smoke.cjs.map +1 -0
- package/dist/commands/smoke.mjs +41 -0
- package/dist/commands/smoke.mjs.map +1 -0
- package/dist/commands/upgrade.cjs +2 -2
- package/dist/commands/upgrade.cjs.map +1 -1
- package/dist/commands/upgrade.mjs +1 -1
- package/dist/commands/upgrade.mjs.map +1 -1
- package/dist/contract.cjs +27 -1
- package/dist/contract.cjs.map +1 -1
- package/dist/contract.d.cts +65 -1
- package/dist/contract.d.mts +65 -1
- package/dist/contract.meta.cjs +14 -2
- package/dist/contract.meta.cjs.map +1 -1
- package/dist/contract.meta.d.cts +24 -2
- package/dist/contract.meta.d.mts +24 -2
- package/dist/contract.meta.mjs +14 -2
- package/dist/contract.meta.mjs.map +1 -1
- package/dist/contract.mjs +26 -2
- package/dist/contract.mjs.map +1 -1
- package/dist/db/core.cjs +22 -4
- package/dist/db/core.cjs.map +1 -1
- package/dist/db/core.mjs +22 -4
- package/dist/db/core.mjs.map +1 -1
- package/dist/dev-log-pipeline.cjs +6 -0
- package/dist/dev-log-pipeline.cjs.map +1 -1
- package/dist/dev-log-pipeline.mjs +6 -0
- package/dist/dev-log-pipeline.mjs.map +1 -1
- package/dist/dev-program.cjs +20 -3
- package/dist/dev-program.cjs.map +1 -1
- package/dist/dev-program.mjs +20 -4
- package/dist/dev-program.mjs.map +1 -1
- package/dist/dev-session.cjs +1 -0
- package/dist/dev-session.cjs.map +1 -1
- package/dist/dev-session.mjs +1 -0
- package/dist/dev-session.mjs.map +1 -1
- package/dist/fastkv.cjs +21 -3
- package/dist/fastkv.cjs.map +1 -1
- package/dist/fastkv.d.cts +14 -1
- package/dist/fastkv.d.mts +14 -1
- package/dist/fastkv.mjs +21 -5
- package/dist/fastkv.mjs.map +1 -1
- package/dist/{mf.cjs → federation.cjs} +6 -13
- package/dist/federation.cjs.map +1 -0
- package/dist/{mf.d.cts → federation.d.cts} +2 -2
- package/dist/{mf.d.mts → federation.d.mts} +2 -2
- package/dist/{mf.mjs → federation.mjs} +6 -13
- package/dist/federation.mjs.map +1 -0
- package/dist/http-client.cjs +84 -57
- package/dist/http-client.cjs.map +1 -1
- package/dist/http-client.mjs +84 -58
- package/dist/http-client.mjs.map +1 -1
- package/dist/image-deploy.cjs +9 -0
- package/dist/image-deploy.cjs.map +1 -1
- package/dist/image-deploy.mjs +9 -1
- package/dist/image-deploy.mjs.map +1 -1
- package/dist/index.cjs +4 -0
- package/dist/index.d.cts +3 -3
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +3 -3
- package/dist/infra/planner.cjs +6 -2
- package/dist/infra/planner.cjs.map +1 -1
- package/dist/infra/planner.mjs +6 -2
- package/dist/infra/planner.mjs.map +1 -1
- package/dist/orchestrator.cjs +39 -35
- package/dist/orchestrator.cjs.map +1 -1
- package/dist/orchestrator.mjs +39 -35
- package/dist/orchestrator.mjs.map +1 -1
- package/dist/plugin.cjs +2 -0
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.cts +24 -0
- package/dist/plugin.d.mts +24 -0
- package/dist/plugin.mjs +2 -0
- package/dist/plugin.mjs.map +1 -1
- package/dist/process-registry.cjs +1 -1
- package/dist/process-registry.mjs +1 -1
- package/dist/publish.cjs +3 -3
- package/dist/publish.cjs.map +1 -1
- package/dist/publish.mjs +4 -4
- package/dist/publish.mjs.map +1 -1
- package/dist/resolver.cjs +293 -0
- package/dist/resolver.cjs.map +1 -0
- package/dist/resolver.d.cts +99 -0
- package/dist/resolver.d.mts +99 -0
- package/dist/resolver.mjs +284 -0
- package/dist/resolver.mjs.map +1 -0
- package/dist/smoke.cjs +262 -0
- package/dist/smoke.cjs.map +1 -0
- package/dist/smoke.mjs +260 -0
- package/dist/smoke.mjs.map +1 -0
- package/dist/ui/auth.d.cts +217 -123
- package/dist/ui/auth.d.mts +217 -123
- package/dist/ui/router-client.cjs +2 -1
- package/dist/ui/router-client.cjs.map +1 -1
- package/dist/ui/router-client.mjs +2 -1
- package/dist/ui/router-client.mjs.map +1 -1
- package/dist/version-manifest-resolve.cjs +3 -3
- package/dist/version-manifest-resolve.cjs.map +1 -1
- package/dist/version-manifest-resolve.mjs +1 -1
- package/dist/version-manifest-resolve.mjs.map +1 -1
- package/dist/workspace.cjs +1 -1
- package/dist/workspace.mjs +1 -1
- package/package.json +18 -18
- package/skills/api-and-auth/SKILL.md +12 -9
- package/skills/api-and-auth/references/middleware.md +38 -0
- package/skills/cli-reference/SKILL.md +22 -6
- package/skills/talk-to-the-app/SKILL.md +32 -5
- package/dist/bundle-fs-resolve.cjs +0 -235
- package/dist/bundle-fs-resolve.cjs.map +0 -1
- package/dist/bundle-fs-resolve.d.cts +0 -82
- package/dist/bundle-fs-resolve.d.mts +0 -82
- package/dist/bundle-fs-resolve.mjs +0 -228
- package/dist/bundle-fs-resolve.mjs.map +0 -1
- package/dist/bundle-path.cjs +0 -48
- package/dist/bundle-path.cjs.map +0 -1
- package/dist/bundle-path.mjs +0 -45
- package/dist/bundle-path.mjs.map +0 -1
- package/dist/mf.cjs.map +0 -1
- package/dist/mf.mjs.map +0 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ApiPluginConfig, ApiPluginConfigSchema, BosConfig, BosConfigInput, BosConfigInputAppEntry, BosConfigInputSchema, BosConfigSchema, BosPluginRef, BosPluginRefSchema, BosStaging, BosStagingSchema, CdnConfig, CdnConfigSchema, CiConfig, CiConfigSchema, ClientRuntimeConfig, ClientRuntimeConfigSchema, ClientRuntimeInfo, ClientRuntimeInfoSchema, ComposableAppEntry, ComposableAppEntrySchema, DependencyNodeKind, DependencyNodeKindSchema, Extends, ExtendsConfig, ExtendsSchema, FederationEntry, FederationEntrySchema, HostConfig, HostConfigSchema, JsonObject, JsonObjectSchema, JsonPrimitive, JsonValue, JsonValueSchema, ParentStarterConfig, ParentStarterConfigSchema, PluginEntries, PluginEntryValue, PluginRuntimeUi, PluginUiConfig, PluginUiConfigSchema, PublishAuth, PublishAuthSchema, PublishConfig, PublishConfigSchema, RailwayCi, RailwayCiSchema, RuntimeConfig, RuntimeConfigSchema, RuntimeDependencyNode, RuntimeDependencyNodeSchema, RuntimeLineage, RuntimeLineageSchema, RuntimePluginConfig, RuntimePluginConfigSchema, SharedConfig, SharedConfigSchema, SharedDepConfig, SharedDepConfigSchema, SharedDepMapSchema, SlotPin, SlotPinSchema, SourceMode, SourceModeSchema, StarterLevel, StarterLevelConfig, StarterLevelConfigSchema, StarterLevelSchema, UiConfig, UiConfigSchema } from "./types.mjs";
|
|
2
|
-
import { BosConfigResult, BuildOptions, BuildOptionsSchema, BuildResultSchema, ConfigOptionsSchema, ConfigResultSchema, DbDoctorOptions, DbDoctorOptionsSchema, DbDoctorResult, DbDoctorResultSchema, DbRepairOptions, DbRepairOptionsSchema, DbRepairResult, DbRepairResultSchema, DbStudioOptions, DbStudioOptionsSchema, DbStudioResult, DbStudioResultSchema, DeployManifestListEntrySchema, DeployOptions, DeployOptionsSchema, DeployResult, DeployResultSchema, DeployedVersionStatusSchema, DevOptions, DevOptionsSchema, DevResult, DevResultSchema, InfraExportOptions, InfraExportOptionsSchema, InfraExportResult, InfraExportResultSchema, InfraExportService, InfraExportServiceSchema, InitOptions, InitOptionsSchema, InitResult, InitResultSchema, KeyPublishOptions, KeyPublishOptionsSchema, KeyPublishResult, KeyPublishResultSchema, KillOptions, KillOptionsSchema, KillResult, KillResultSchema, LoginOptions, LoginOptionsSchema, LoginResult, LoginResultSchema, LogoutOptions, LogoutOptionsSchema, LogoutResult, LogoutResultSchema, LogsOptions, LogsOptionsSchema, LogsResult, LogsResultSchema, MfCheckOptions, MfCheckOptionsSchema, MfCheckRemoteResultSchema, MfCheckResult, MfCheckResultSchema, OverrideSection, OverrideSectionSchema, PhaseTiming, PhaseTimingSchema, PidEntry, PidEntrySchema, PluginAddOptions, PluginAddOptionsSchema, PluginAddResult, PluginAddResultSchema, PluginListResult, PluginListResultSchema, PluginPublishOptions, PluginPublishOptionsSchema, PluginPublishResult, PluginPublishResultSchema, PluginRemoveOptions, PluginRemoveOptionsSchema, PluginRemoveResult, PluginRemoveResultSchema, ProcessRole, ProcessRoleSchema, PsResult, PsResultSchema, PublishOptions, PublishOptionsSchema, PublishResult, PublishResultSchema, RegistryUseOptionsSchema, RegistryUseResultSchema, RollbackHistoryEntrySchema, RollbackOptionsSchema, RollbackResultSchema, RollbackSlotCheckSchema, RuntimeOverrideTarget, RuntimeOverrideTargetBaseSchema, RuntimeOverrideTargetSchema, StartOptions, StartOptionsSchema, StartResult, StartResultSchema, StatusResult, StatusResultSchema, SyncOptions, SyncOptionsSchema, SyncResult, SyncResultSchema, TypecheckOptions, TypecheckOptionsSchema, TypecheckResult, TypecheckResultSchema, TypecheckWorkspaceResult, TypecheckWorkspaceResultSchema, TypesGenOptions, TypesGenOptionsSchema, TypesGenResult, TypesGenResultSchema, UpgradeOptions, UpgradeOptionsSchema, UpgradeResult, UpgradeResultSchema, WorkspaceDeployResult, WorkspaceDeployResultSchema, bosContract, commandOptionSchemas } from "./contract.mjs";
|
|
2
|
+
import { BosConfigResult, BuildOptions, BuildOptionsSchema, BuildResultSchema, ConfigOptionsSchema, ConfigResultSchema, DbDoctorOptions, DbDoctorOptionsSchema, DbDoctorResult, DbDoctorResultSchema, DbRepairOptions, DbRepairOptionsSchema, DbRepairResult, DbRepairResultSchema, DbStudioOptions, DbStudioOptionsSchema, DbStudioResult, DbStudioResultSchema, DeployManifestListEntrySchema, DeployOptions, DeployOptionsSchema, DeployResult, DeployResultSchema, DeployedVersionStatusSchema, DevOptions, DevOptionsSchema, DevResult, DevResultSchema, InfraExportOptions, InfraExportOptionsSchema, InfraExportResult, InfraExportResultSchema, InfraExportService, InfraExportServiceSchema, InitOptions, InitOptionsSchema, InitResult, InitResultSchema, KeyPublishOptions, KeyPublishOptionsSchema, KeyPublishResult, KeyPublishResultSchema, KillOptions, KillOptionsSchema, KillResult, KillResultSchema, LoginOptions, LoginOptionsSchema, LoginResult, LoginResultSchema, LogoutOptions, LogoutOptionsSchema, LogoutResult, LogoutResultSchema, LogsOptions, LogsOptionsSchema, LogsResult, LogsResultSchema, MfCheckOptions, MfCheckOptionsSchema, MfCheckRemoteResultSchema, MfCheckResult, MfCheckResultSchema, OverrideSection, OverrideSectionSchema, PhaseTiming, PhaseTimingSchema, PidEntry, PidEntrySchema, PluginAddOptions, PluginAddOptionsSchema, PluginAddResult, PluginAddResultSchema, PluginListResult, PluginListResultSchema, PluginPublishOptions, PluginPublishOptionsSchema, PluginPublishResult, PluginPublishResultSchema, PluginRemoveOptions, PluginRemoveOptionsSchema, PluginRemoveResult, PluginRemoveResultSchema, ProcessRole, ProcessRoleSchema, PsResult, PsResultSchema, PublishOptions, PublishOptionsSchema, PublishResult, PublishResultSchema, RegistryUseOptionsSchema, RegistryUseResultSchema, RollbackHistoryEntrySchema, RollbackOptionsSchema, RollbackResultSchema, RollbackSlotCheckSchema, RuntimeOverrideTarget, RuntimeOverrideTargetBaseSchema, RuntimeOverrideTargetSchema, SmokeOptionsSchema, SmokeResultSchema, StartOptions, StartOptionsSchema, StartResult, StartResultSchema, StatusResult, StatusResultSchema, SyncOptions, SyncOptionsSchema, SyncResult, SyncResultSchema, TypecheckOptions, TypecheckOptionsSchema, TypecheckResult, TypecheckResultSchema, TypecheckWorkspaceResult, TypecheckWorkspaceResultSchema, TypesGenOptions, TypesGenOptionsSchema, TypesGenResult, TypesGenResultSchema, UpgradeOptions, UpgradeOptionsSchema, UpgradeResult, UpgradeResultSchema, WorkspaceDeployResult, WorkspaceDeployResultSchema, bosContract, commandOptionSchemas } from "./contract.mjs";
|
|
3
3
|
import { CliCommandMeta, cliCommandMeta } from "./contract.meta.mjs";
|
|
4
|
-
import { ConfigHistoryEntry, DeployManifestEntry, NetworkId, PluginManifest, buildRegistryConfigUrl, buildRegistryConfigUrlForNetwork, fetchBosConfigFromFastKv, fetchConfigHistory, fetchDeployManifests, fetchRemotePluginManifest, getFastKvBaseUrlForNetwork, getRegistryNamespaceForAccount, getRegistryNamespaceForNetwork, parseBosUrl } from "./fastkv.mjs";
|
|
4
|
+
import { ConfigHistoryEntry, DeployManifestEntry, NetworkId, PluginManifest, buildRegistryConfigUrl, buildRegistryConfigUrlForNetwork, fetchBosConfigFromFastKv, fetchConfigHistory, fetchDeployManifests, fetchPublishedConfigFromFastKv, fetchRemotePluginManifest, getFastKvBaseUrlForNetwork, getRegistryNamespaceForAccount, getRegistryNamespaceForNetwork, parseBosUrl, parseFastKvConfigValue } from "./fastkv.mjs";
|
|
5
5
|
import { AnySchema, Context, Effect, Layer, LoadedPluginWithBinding, Plugin, PluginRuntime, RouterContract, Scope, createPlugin, createPluginRuntime, oc, z } from "./sdk.mjs";
|
|
6
6
|
import { StartConfigSource, isRegistryStart, resolveStartConfigSource } from "./start-config-source.mjs";
|
|
7
7
|
import { BOS_CONFIG_ORDER, BosEnv, mergeBosConfigWithExtends, rebuildOrderedConfig, resolveExtendsRef } from "./merge.mjs";
|
|
8
8
|
import { BuildRuntimeConfigOptions, CircularExtendsError, ConfigExtendsError, ConfigLoadError, ConfigNotfoundError, ConfigVersionManifestError, DEV_OVERLAY_FILENAME, DevOverlayError, MISSING_CONFIG_MESSAGE, ResolvedComposableReference, buildRuntimeConfig, buildRuntimeConfigEffect, buildRuntimePluginsForConfig, defaultConfigEnv, findConfigPath, getConfigBaseDir, getHostDevelopmentPort, getResolvedConfigPath, isAppDescriptorPath, isLocalDevelopmentTarget, isRuntimeOverrideAllowed, loadAppDescriptorConfig, loadGeneratedResolvedConfig, localConfigEntryPath, parseAppDescriptorModule, parseDevOverlayModule, parseExtendsTarget, parsePort, parseRuntimeOverrideTargets, readAuthoredConfigInput, readBosConfigForBuild, readLocalAuthoredConfigInput, resetConfigPathCache, resolveBosConfigPath, resolveComposableReference, resolveConfigComposableEntries, resolveDevelopmentHostUrl, resolveLocalDevelopmentPath, resolvePluginRuntimeName, resolveUiRuntimeName, runWithConfigWarningSink, writeResolvedConfig } from "./config.mjs";
|
|
9
|
-
export { type AnySchema, ApiPluginConfig, ApiPluginConfigSchema, BOS_CONFIG_ORDER, BosConfig, BosConfigInput, BosConfigInputAppEntry, BosConfigInputSchema, BosConfigResult, BosConfigSchema, type BosEnv, BosPluginRef, BosPluginRefSchema, BosStaging, BosStagingSchema, BuildOptions, BuildOptionsSchema, BuildResultSchema, BuildRuntimeConfigOptions, CdnConfig, CdnConfigSchema, CiConfig, CiConfigSchema, CircularExtendsError, CliCommandMeta, ClientRuntimeConfig, ClientRuntimeConfigSchema, ClientRuntimeInfo, ClientRuntimeInfoSchema, ComposableAppEntry, ComposableAppEntrySchema, ConfigExtendsError, ConfigHistoryEntry, ConfigLoadError, ConfigNotfoundError, ConfigOptionsSchema, ConfigResultSchema, ConfigVersionManifestError, Context, DEV_OVERLAY_FILENAME, DbDoctorOptions, DbDoctorOptionsSchema, DbDoctorResult, DbDoctorResultSchema, DbRepairOptions, DbRepairOptionsSchema, DbRepairResult, DbRepairResultSchema, DbStudioOptions, DbStudioOptionsSchema, DbStudioResult, DbStudioResultSchema, DependencyNodeKind, DependencyNodeKindSchema, DeployManifestEntry, DeployManifestListEntrySchema, DeployOptions, DeployOptionsSchema, DeployResult, DeployResultSchema, DeployedVersionStatusSchema, DevOptions, DevOptionsSchema, DevOverlayError, DevResult, DevResultSchema, Effect, Extends, ExtendsConfig, ExtendsSchema, FederationEntry, FederationEntrySchema, HostConfig, HostConfigSchema, InfraExportOptions, InfraExportOptionsSchema, InfraExportResult, InfraExportResultSchema, InfraExportService, InfraExportServiceSchema, InitOptions, InitOptionsSchema, InitResult, InitResultSchema, JsonObject, JsonObjectSchema, JsonPrimitive, JsonValue, JsonValueSchema, KeyPublishOptions, KeyPublishOptionsSchema, KeyPublishResult, KeyPublishResultSchema, KillOptions, KillOptionsSchema, KillResult, KillResultSchema, Layer, type LoadedPluginWithBinding, LoginOptions, LoginOptionsSchema, LoginResult, LoginResultSchema, LogoutOptions, LogoutOptionsSchema, LogoutResult, LogoutResultSchema, LogsOptions, LogsOptionsSchema, LogsResult, LogsResultSchema, MISSING_CONFIG_MESSAGE, MfCheckOptions, MfCheckOptionsSchema, MfCheckRemoteResultSchema, MfCheckResult, MfCheckResultSchema, NetworkId, OverrideSection, OverrideSectionSchema, ParentStarterConfig, ParentStarterConfigSchema, PhaseTiming, PhaseTimingSchema, PidEntry, PidEntrySchema, type Plugin, PluginAddOptions, PluginAddOptionsSchema, PluginAddResult, PluginAddResultSchema, PluginEntries, PluginEntryValue, PluginListResult, PluginListResultSchema, PluginManifest, PluginPublishOptions, PluginPublishOptionsSchema, PluginPublishResult, PluginPublishResultSchema, PluginRemoveOptions, PluginRemoveOptionsSchema, PluginRemoveResult, PluginRemoveResultSchema, PluginRuntime, PluginRuntimeUi, PluginUiConfig, PluginUiConfigSchema, ProcessRole, ProcessRoleSchema, PsResult, PsResultSchema, PublishAuth, PublishAuthSchema, PublishConfig, PublishConfigSchema, PublishOptions, PublishOptionsSchema, PublishResult, PublishResultSchema, RailwayCi, RailwayCiSchema, RegistryUseOptionsSchema, RegistryUseResultSchema, ResolvedComposableReference, RollbackHistoryEntrySchema, RollbackOptionsSchema, RollbackResultSchema, RollbackSlotCheckSchema, type RouterContract, RuntimeConfig, RuntimeConfigSchema, RuntimeDependencyNode, RuntimeDependencyNodeSchema, RuntimeLineage, RuntimeLineageSchema, RuntimeOverrideTarget, RuntimeOverrideTargetBaseSchema, RuntimeOverrideTargetSchema, RuntimePluginConfig, RuntimePluginConfigSchema, Scope, SharedConfig, SharedConfigSchema, SharedDepConfig, SharedDepConfigSchema, SharedDepMapSchema, SlotPin, SlotPinSchema, SourceMode, SourceModeSchema, StartConfigSource, StartOptions, StartOptionsSchema, StartResult, StartResultSchema, StarterLevel, StarterLevelConfig, StarterLevelConfigSchema, StarterLevelSchema, StatusResult, StatusResultSchema, SyncOptions, SyncOptionsSchema, SyncResult, SyncResultSchema, TypecheckOptions, TypecheckOptionsSchema, TypecheckResult, TypecheckResultSchema, TypecheckWorkspaceResult, TypecheckWorkspaceResultSchema, TypesGenOptions, TypesGenOptionsSchema, TypesGenResult, TypesGenResultSchema, UiConfig, UiConfigSchema, UpgradeOptions, UpgradeOptionsSchema, UpgradeResult, UpgradeResultSchema, WorkspaceDeployResult, WorkspaceDeployResultSchema, bosContract, buildRegistryConfigUrl, buildRegistryConfigUrlForNetwork, buildRuntimeConfig, buildRuntimeConfigEffect, buildRuntimePluginsForConfig, cliCommandMeta, commandOptionSchemas, createPlugin, createPluginRuntime, defaultConfigEnv, fetchBosConfigFromFastKv, fetchConfigHistory, fetchDeployManifests, fetchRemotePluginManifest, findConfigPath, getConfigBaseDir, getFastKvBaseUrlForNetwork, getHostDevelopmentPort, getRegistryNamespaceForAccount, getRegistryNamespaceForNetwork, getResolvedConfigPath, isAppDescriptorPath, isLocalDevelopmentTarget, isRegistryStart, isRuntimeOverrideAllowed, loadAppDescriptorConfig, loadGeneratedResolvedConfig, localConfigEntryPath, mergeBosConfigWithExtends, oc, parseAppDescriptorModule, parseBosUrl, parseDevOverlayModule, parseExtendsTarget, parsePort, parseRuntimeOverrideTargets, readAuthoredConfigInput, readBosConfigForBuild, readLocalAuthoredConfigInput, rebuildOrderedConfig, resetConfigPathCache, resolveBosConfigPath, resolveComposableReference, resolveConfigComposableEntries, resolveDevelopmentHostUrl, resolveExtendsRef, resolveLocalDevelopmentPath, resolvePluginRuntimeName, resolveStartConfigSource, resolveUiRuntimeName, runWithConfigWarningSink, writeResolvedConfig, z };
|
|
9
|
+
export { type AnySchema, ApiPluginConfig, ApiPluginConfigSchema, BOS_CONFIG_ORDER, BosConfig, BosConfigInput, BosConfigInputAppEntry, BosConfigInputSchema, BosConfigResult, BosConfigSchema, type BosEnv, BosPluginRef, BosPluginRefSchema, BosStaging, BosStagingSchema, BuildOptions, BuildOptionsSchema, BuildResultSchema, BuildRuntimeConfigOptions, CdnConfig, CdnConfigSchema, CiConfig, CiConfigSchema, CircularExtendsError, CliCommandMeta, ClientRuntimeConfig, ClientRuntimeConfigSchema, ClientRuntimeInfo, ClientRuntimeInfoSchema, ComposableAppEntry, ComposableAppEntrySchema, ConfigExtendsError, ConfigHistoryEntry, ConfigLoadError, ConfigNotfoundError, ConfigOptionsSchema, ConfigResultSchema, ConfigVersionManifestError, Context, DEV_OVERLAY_FILENAME, DbDoctorOptions, DbDoctorOptionsSchema, DbDoctorResult, DbDoctorResultSchema, DbRepairOptions, DbRepairOptionsSchema, DbRepairResult, DbRepairResultSchema, DbStudioOptions, DbStudioOptionsSchema, DbStudioResult, DbStudioResultSchema, DependencyNodeKind, DependencyNodeKindSchema, DeployManifestEntry, DeployManifestListEntrySchema, DeployOptions, DeployOptionsSchema, DeployResult, DeployResultSchema, DeployedVersionStatusSchema, DevOptions, DevOptionsSchema, DevOverlayError, DevResult, DevResultSchema, Effect, Extends, ExtendsConfig, ExtendsSchema, FederationEntry, FederationEntrySchema, HostConfig, HostConfigSchema, InfraExportOptions, InfraExportOptionsSchema, InfraExportResult, InfraExportResultSchema, InfraExportService, InfraExportServiceSchema, InitOptions, InitOptionsSchema, InitResult, InitResultSchema, JsonObject, JsonObjectSchema, JsonPrimitive, JsonValue, JsonValueSchema, KeyPublishOptions, KeyPublishOptionsSchema, KeyPublishResult, KeyPublishResultSchema, KillOptions, KillOptionsSchema, KillResult, KillResultSchema, Layer, type LoadedPluginWithBinding, LoginOptions, LoginOptionsSchema, LoginResult, LoginResultSchema, LogoutOptions, LogoutOptionsSchema, LogoutResult, LogoutResultSchema, LogsOptions, LogsOptionsSchema, LogsResult, LogsResultSchema, MISSING_CONFIG_MESSAGE, MfCheckOptions, MfCheckOptionsSchema, MfCheckRemoteResultSchema, MfCheckResult, MfCheckResultSchema, NetworkId, OverrideSection, OverrideSectionSchema, ParentStarterConfig, ParentStarterConfigSchema, PhaseTiming, PhaseTimingSchema, PidEntry, PidEntrySchema, type Plugin, PluginAddOptions, PluginAddOptionsSchema, PluginAddResult, PluginAddResultSchema, PluginEntries, PluginEntryValue, PluginListResult, PluginListResultSchema, PluginManifest, PluginPublishOptions, PluginPublishOptionsSchema, PluginPublishResult, PluginPublishResultSchema, PluginRemoveOptions, PluginRemoveOptionsSchema, PluginRemoveResult, PluginRemoveResultSchema, PluginRuntime, PluginRuntimeUi, PluginUiConfig, PluginUiConfigSchema, ProcessRole, ProcessRoleSchema, PsResult, PsResultSchema, PublishAuth, PublishAuthSchema, PublishConfig, PublishConfigSchema, PublishOptions, PublishOptionsSchema, PublishResult, PublishResultSchema, RailwayCi, RailwayCiSchema, RegistryUseOptionsSchema, RegistryUseResultSchema, ResolvedComposableReference, RollbackHistoryEntrySchema, RollbackOptionsSchema, RollbackResultSchema, RollbackSlotCheckSchema, type RouterContract, RuntimeConfig, RuntimeConfigSchema, RuntimeDependencyNode, RuntimeDependencyNodeSchema, RuntimeLineage, RuntimeLineageSchema, RuntimeOverrideTarget, RuntimeOverrideTargetBaseSchema, RuntimeOverrideTargetSchema, RuntimePluginConfig, RuntimePluginConfigSchema, Scope, SharedConfig, SharedConfigSchema, SharedDepConfig, SharedDepConfigSchema, SharedDepMapSchema, SlotPin, SlotPinSchema, SmokeOptionsSchema, SmokeResultSchema, SourceMode, SourceModeSchema, StartConfigSource, StartOptions, StartOptionsSchema, StartResult, StartResultSchema, StarterLevel, StarterLevelConfig, StarterLevelConfigSchema, StarterLevelSchema, StatusResult, StatusResultSchema, SyncOptions, SyncOptionsSchema, SyncResult, SyncResultSchema, TypecheckOptions, TypecheckOptionsSchema, TypecheckResult, TypecheckResultSchema, TypecheckWorkspaceResult, TypecheckWorkspaceResultSchema, TypesGenOptions, TypesGenOptionsSchema, TypesGenResult, TypesGenResultSchema, UiConfig, UiConfigSchema, UpgradeOptions, UpgradeOptionsSchema, UpgradeResult, UpgradeResultSchema, WorkspaceDeployResult, WorkspaceDeployResultSchema, bosContract, buildRegistryConfigUrl, buildRegistryConfigUrlForNetwork, buildRuntimeConfig, buildRuntimeConfigEffect, buildRuntimePluginsForConfig, cliCommandMeta, commandOptionSchemas, createPlugin, createPluginRuntime, defaultConfigEnv, fetchBosConfigFromFastKv, fetchConfigHistory, fetchDeployManifests, fetchPublishedConfigFromFastKv, fetchRemotePluginManifest, findConfigPath, getConfigBaseDir, getFastKvBaseUrlForNetwork, getHostDevelopmentPort, getRegistryNamespaceForAccount, getRegistryNamespaceForNetwork, getResolvedConfigPath, isAppDescriptorPath, isLocalDevelopmentTarget, isRegistryStart, isRuntimeOverrideAllowed, loadAppDescriptorConfig, loadGeneratedResolvedConfig, localConfigEntryPath, mergeBosConfigWithExtends, oc, parseAppDescriptorModule, parseBosUrl, parseDevOverlayModule, parseExtendsTarget, parseFastKvConfigValue, parsePort, parseRuntimeOverrideTargets, readAuthoredConfigInput, readBosConfigForBuild, readLocalAuthoredConfigInput, rebuildOrderedConfig, resetConfigPathCache, resolveBosConfigPath, resolveComposableReference, resolveConfigComposableEntries, resolveDevelopmentHostUrl, resolveExtendsRef, resolveLocalDevelopmentPath, resolvePluginRuntimeName, resolveStartConfigSource, resolveUiRuntimeName, runWithConfigWarningSink, writeResolvedConfig, z };
|
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { BOS_CONFIG_ORDER, mergeBosConfigWithExtends, rebuildOrderedConfig, resolveExtendsRef } from "./merge.mjs";
|
|
2
2
|
import { ApiPluginConfigSchema, BosConfigInputSchema, BosConfigSchema, BosPluginRefSchema, BosStagingSchema, CdnConfigSchema, CiConfigSchema, ClientRuntimeConfigSchema, ClientRuntimeInfoSchema, ComposableAppEntrySchema, DependencyNodeKindSchema, ExtendsSchema, FederationEntrySchema, HostConfigSchema, JsonObjectSchema, JsonValueSchema, ParentStarterConfigSchema, PluginUiConfigSchema, PublishAuthSchema, PublishConfigSchema, RailwayCiSchema, RuntimeConfigSchema, RuntimeDependencyNodeSchema, RuntimeLineageSchema, RuntimePluginConfigSchema, SharedConfigSchema, SharedDepConfigSchema, SharedDepMapSchema, SlotPinSchema, SourceModeSchema, StarterLevelConfigSchema, StarterLevelSchema, UiConfigSchema } from "./types.mjs";
|
|
3
|
-
import { buildRegistryConfigUrl, buildRegistryConfigUrlForNetwork, fetchBosConfigFromFastKv, fetchConfigHistory, fetchDeployManifests, fetchRemotePluginManifest, getFastKvBaseUrlForNetwork, getRegistryNamespaceForAccount, getRegistryNamespaceForNetwork, parseBosUrl } from "./fastkv.mjs";
|
|
3
|
+
import { buildRegistryConfigUrl, buildRegistryConfigUrlForNetwork, fetchBosConfigFromFastKv, fetchConfigHistory, fetchDeployManifests, fetchPublishedConfigFromFastKv, fetchRemotePluginManifest, getFastKvBaseUrlForNetwork, getRegistryNamespaceForAccount, getRegistryNamespaceForNetwork, parseBosUrl, parseFastKvConfigValue } from "./fastkv.mjs";
|
|
4
4
|
import { CircularExtendsError, ConfigExtendsError, ConfigLoadError, ConfigNotfoundError, ConfigVersionManifestError, DEV_OVERLAY_FILENAME, DevOverlayError, MISSING_CONFIG_MESSAGE, buildRuntimeConfig, buildRuntimeConfigEffect, buildRuntimePluginsForConfig, defaultConfigEnv, findConfigPath, getConfigBaseDir, getHostDevelopmentPort, getResolvedConfigPath, isAppDescriptorPath, isLocalDevelopmentTarget, isRuntimeOverrideAllowed, loadAppDescriptorConfig, loadGeneratedResolvedConfig, localConfigEntryPath, parseAppDescriptorModule, parseDevOverlayModule, parseExtendsTarget, parsePort, parseRuntimeOverrideTargets, readAuthoredConfigInput, readBosConfigForBuild, readLocalAuthoredConfigInput, resetConfigPathCache, resolveBosConfigPath, resolveComposableReference, resolveConfigComposableEntries, resolveDevelopmentHostUrl, resolveLocalDevelopmentPath, resolvePluginRuntimeName, resolveUiRuntimeName, runWithConfigWarningSink, writeResolvedConfig } from "./config.mjs";
|
|
5
5
|
import { Context, Effect, Layer, PluginRuntime, Scope, createPlugin, createPluginRuntime, oc, z } from "./sdk.mjs";
|
|
6
|
-
import { BuildOptionsSchema, BuildResultSchema, ConfigOptionsSchema, ConfigResultSchema, DbDoctorOptionsSchema, DbDoctorResultSchema, DbRepairOptionsSchema, DbRepairResultSchema, DbStudioOptionsSchema, DbStudioResultSchema, DeployManifestListEntrySchema, DeployOptionsSchema, DeployResultSchema, DeployedVersionStatusSchema, DevOptionsSchema, DevResultSchema, InfraExportOptionsSchema, InfraExportResultSchema, InfraExportServiceSchema, InitOptionsSchema, InitResultSchema, KeyPublishOptionsSchema, KeyPublishResultSchema, KillOptionsSchema, KillResultSchema, LoginOptionsSchema, LoginResultSchema, LogoutOptionsSchema, LogoutResultSchema, LogsOptionsSchema, LogsResultSchema, MfCheckOptionsSchema, MfCheckRemoteResultSchema, MfCheckResultSchema, OverrideSectionSchema, PhaseTimingSchema, PidEntrySchema, PluginAddOptionsSchema, PluginAddResultSchema, PluginListResultSchema, PluginPublishOptionsSchema, PluginPublishResultSchema, PluginRemoveOptionsSchema, PluginRemoveResultSchema, ProcessRoleSchema, PsResultSchema, PublishOptionsSchema, PublishResultSchema, RegistryUseOptionsSchema, RegistryUseResultSchema, RollbackHistoryEntrySchema, RollbackOptionsSchema, RollbackResultSchema, RollbackSlotCheckSchema, RuntimeOverrideTargetBaseSchema, RuntimeOverrideTargetSchema, StartOptionsSchema, StartResultSchema, StatusResultSchema, SyncOptionsSchema, SyncResultSchema, TypecheckOptionsSchema, TypecheckResultSchema, TypecheckWorkspaceResultSchema, TypesGenOptionsSchema, TypesGenResultSchema, UpgradeOptionsSchema, UpgradeResultSchema, WorkspaceDeployResultSchema, bosContract, commandOptionSchemas } from "./contract.mjs";
|
|
6
|
+
import { BuildOptionsSchema, BuildResultSchema, ConfigOptionsSchema, ConfigResultSchema, DbDoctorOptionsSchema, DbDoctorResultSchema, DbRepairOptionsSchema, DbRepairResultSchema, DbStudioOptionsSchema, DbStudioResultSchema, DeployManifestListEntrySchema, DeployOptionsSchema, DeployResultSchema, DeployedVersionStatusSchema, DevOptionsSchema, DevResultSchema, InfraExportOptionsSchema, InfraExportResultSchema, InfraExportServiceSchema, InitOptionsSchema, InitResultSchema, KeyPublishOptionsSchema, KeyPublishResultSchema, KillOptionsSchema, KillResultSchema, LoginOptionsSchema, LoginResultSchema, LogoutOptionsSchema, LogoutResultSchema, LogsOptionsSchema, LogsResultSchema, MfCheckOptionsSchema, MfCheckRemoteResultSchema, MfCheckResultSchema, OverrideSectionSchema, PhaseTimingSchema, PidEntrySchema, PluginAddOptionsSchema, PluginAddResultSchema, PluginListResultSchema, PluginPublishOptionsSchema, PluginPublishResultSchema, PluginRemoveOptionsSchema, PluginRemoveResultSchema, ProcessRoleSchema, PsResultSchema, PublishOptionsSchema, PublishResultSchema, RegistryUseOptionsSchema, RegistryUseResultSchema, RollbackHistoryEntrySchema, RollbackOptionsSchema, RollbackResultSchema, RollbackSlotCheckSchema, RuntimeOverrideTargetBaseSchema, RuntimeOverrideTargetSchema, SmokeOptionsSchema, SmokeResultSchema, StartOptionsSchema, StartResultSchema, StatusResultSchema, SyncOptionsSchema, SyncResultSchema, TypecheckOptionsSchema, TypecheckResultSchema, TypecheckWorkspaceResultSchema, TypesGenOptionsSchema, TypesGenResultSchema, UpgradeOptionsSchema, UpgradeResultSchema, WorkspaceDeployResultSchema, bosContract, commandOptionSchemas } from "./contract.mjs";
|
|
7
7
|
import { cliCommandMeta } from "./contract.meta.mjs";
|
|
8
8
|
import { isRegistryStart, resolveStartConfigSource } from "./start-config-source.mjs";
|
|
9
9
|
|
|
10
|
-
export { ApiPluginConfigSchema, BOS_CONFIG_ORDER, BosConfigInputSchema, BosConfigSchema, BosPluginRefSchema, BosStagingSchema, BuildOptionsSchema, BuildResultSchema, CdnConfigSchema, CiConfigSchema, CircularExtendsError, ClientRuntimeConfigSchema, ClientRuntimeInfoSchema, ComposableAppEntrySchema, ConfigExtendsError, ConfigLoadError, ConfigNotfoundError, ConfigOptionsSchema, ConfigResultSchema, ConfigVersionManifestError, Context, DEV_OVERLAY_FILENAME, DbDoctorOptionsSchema, DbDoctorResultSchema, DbRepairOptionsSchema, DbRepairResultSchema, DbStudioOptionsSchema, DbStudioResultSchema, DependencyNodeKindSchema, DeployManifestListEntrySchema, DeployOptionsSchema, DeployResultSchema, DeployedVersionStatusSchema, DevOptionsSchema, DevOverlayError, DevResultSchema, Effect, ExtendsSchema, FederationEntrySchema, HostConfigSchema, InfraExportOptionsSchema, InfraExportResultSchema, InfraExportServiceSchema, InitOptionsSchema, InitResultSchema, JsonObjectSchema, JsonValueSchema, KeyPublishOptionsSchema, KeyPublishResultSchema, KillOptionsSchema, KillResultSchema, Layer, LoginOptionsSchema, LoginResultSchema, LogoutOptionsSchema, LogoutResultSchema, LogsOptionsSchema, LogsResultSchema, MISSING_CONFIG_MESSAGE, MfCheckOptionsSchema, MfCheckRemoteResultSchema, MfCheckResultSchema, OverrideSectionSchema, ParentStarterConfigSchema, PhaseTimingSchema, PidEntrySchema, PluginAddOptionsSchema, PluginAddResultSchema, PluginListResultSchema, PluginPublishOptionsSchema, PluginPublishResultSchema, PluginRemoveOptionsSchema, PluginRemoveResultSchema, PluginRuntime, PluginUiConfigSchema, ProcessRoleSchema, PsResultSchema, PublishAuthSchema, PublishConfigSchema, PublishOptionsSchema, PublishResultSchema, RailwayCiSchema, RegistryUseOptionsSchema, RegistryUseResultSchema, RollbackHistoryEntrySchema, RollbackOptionsSchema, RollbackResultSchema, RollbackSlotCheckSchema, RuntimeConfigSchema, RuntimeDependencyNodeSchema, RuntimeLineageSchema, RuntimeOverrideTargetBaseSchema, RuntimeOverrideTargetSchema, RuntimePluginConfigSchema, Scope, SharedConfigSchema, SharedDepConfigSchema, SharedDepMapSchema, SlotPinSchema, SourceModeSchema, StartOptionsSchema, StartResultSchema, StarterLevelConfigSchema, StarterLevelSchema, StatusResultSchema, SyncOptionsSchema, SyncResultSchema, TypecheckOptionsSchema, TypecheckResultSchema, TypecheckWorkspaceResultSchema, TypesGenOptionsSchema, TypesGenResultSchema, UiConfigSchema, UpgradeOptionsSchema, UpgradeResultSchema, WorkspaceDeployResultSchema, bosContract, buildRegistryConfigUrl, buildRegistryConfigUrlForNetwork, buildRuntimeConfig, buildRuntimeConfigEffect, buildRuntimePluginsForConfig, cliCommandMeta, commandOptionSchemas, createPlugin, createPluginRuntime, defaultConfigEnv, fetchBosConfigFromFastKv, fetchConfigHistory, fetchDeployManifests, fetchRemotePluginManifest, findConfigPath, getConfigBaseDir, getFastKvBaseUrlForNetwork, getHostDevelopmentPort, getRegistryNamespaceForAccount, getRegistryNamespaceForNetwork, getResolvedConfigPath, isAppDescriptorPath, isLocalDevelopmentTarget, isRegistryStart, isRuntimeOverrideAllowed, loadAppDescriptorConfig, loadGeneratedResolvedConfig, localConfigEntryPath, mergeBosConfigWithExtends, oc, parseAppDescriptorModule, parseBosUrl, parseDevOverlayModule, parseExtendsTarget, parsePort, parseRuntimeOverrideTargets, readAuthoredConfigInput, readBosConfigForBuild, readLocalAuthoredConfigInput, rebuildOrderedConfig, resetConfigPathCache, resolveBosConfigPath, resolveComposableReference, resolveConfigComposableEntries, resolveDevelopmentHostUrl, resolveExtendsRef, resolveLocalDevelopmentPath, resolvePluginRuntimeName, resolveStartConfigSource, resolveUiRuntimeName, runWithConfigWarningSink, writeResolvedConfig, z };
|
|
10
|
+
export { ApiPluginConfigSchema, BOS_CONFIG_ORDER, BosConfigInputSchema, BosConfigSchema, BosPluginRefSchema, BosStagingSchema, BuildOptionsSchema, BuildResultSchema, CdnConfigSchema, CiConfigSchema, CircularExtendsError, ClientRuntimeConfigSchema, ClientRuntimeInfoSchema, ComposableAppEntrySchema, ConfigExtendsError, ConfigLoadError, ConfigNotfoundError, ConfigOptionsSchema, ConfigResultSchema, ConfigVersionManifestError, Context, DEV_OVERLAY_FILENAME, DbDoctorOptionsSchema, DbDoctorResultSchema, DbRepairOptionsSchema, DbRepairResultSchema, DbStudioOptionsSchema, DbStudioResultSchema, DependencyNodeKindSchema, DeployManifestListEntrySchema, DeployOptionsSchema, DeployResultSchema, DeployedVersionStatusSchema, DevOptionsSchema, DevOverlayError, DevResultSchema, Effect, ExtendsSchema, FederationEntrySchema, HostConfigSchema, InfraExportOptionsSchema, InfraExportResultSchema, InfraExportServiceSchema, InitOptionsSchema, InitResultSchema, JsonObjectSchema, JsonValueSchema, KeyPublishOptionsSchema, KeyPublishResultSchema, KillOptionsSchema, KillResultSchema, Layer, LoginOptionsSchema, LoginResultSchema, LogoutOptionsSchema, LogoutResultSchema, LogsOptionsSchema, LogsResultSchema, MISSING_CONFIG_MESSAGE, MfCheckOptionsSchema, MfCheckRemoteResultSchema, MfCheckResultSchema, OverrideSectionSchema, ParentStarterConfigSchema, PhaseTimingSchema, PidEntrySchema, PluginAddOptionsSchema, PluginAddResultSchema, PluginListResultSchema, PluginPublishOptionsSchema, PluginPublishResultSchema, PluginRemoveOptionsSchema, PluginRemoveResultSchema, PluginRuntime, PluginUiConfigSchema, ProcessRoleSchema, PsResultSchema, PublishAuthSchema, PublishConfigSchema, PublishOptionsSchema, PublishResultSchema, RailwayCiSchema, RegistryUseOptionsSchema, RegistryUseResultSchema, RollbackHistoryEntrySchema, RollbackOptionsSchema, RollbackResultSchema, RollbackSlotCheckSchema, RuntimeConfigSchema, RuntimeDependencyNodeSchema, RuntimeLineageSchema, RuntimeOverrideTargetBaseSchema, RuntimeOverrideTargetSchema, RuntimePluginConfigSchema, Scope, SharedConfigSchema, SharedDepConfigSchema, SharedDepMapSchema, SlotPinSchema, SmokeOptionsSchema, SmokeResultSchema, SourceModeSchema, StartOptionsSchema, StartResultSchema, StarterLevelConfigSchema, StarterLevelSchema, StatusResultSchema, SyncOptionsSchema, SyncResultSchema, TypecheckOptionsSchema, TypecheckResultSchema, TypecheckWorkspaceResultSchema, TypesGenOptionsSchema, TypesGenResultSchema, UiConfigSchema, UpgradeOptionsSchema, UpgradeResultSchema, WorkspaceDeployResultSchema, bosContract, buildRegistryConfigUrl, buildRegistryConfigUrlForNetwork, buildRuntimeConfig, buildRuntimeConfigEffect, buildRuntimePluginsForConfig, cliCommandMeta, commandOptionSchemas, createPlugin, createPluginRuntime, defaultConfigEnv, fetchBosConfigFromFastKv, fetchConfigHistory, fetchDeployManifests, fetchPublishedConfigFromFastKv, fetchRemotePluginManifest, findConfigPath, getConfigBaseDir, getFastKvBaseUrlForNetwork, getHostDevelopmentPort, getRegistryNamespaceForAccount, getRegistryNamespaceForNetwork, getResolvedConfigPath, isAppDescriptorPath, isLocalDevelopmentTarget, isRegistryStart, isRuntimeOverrideAllowed, loadAppDescriptorConfig, loadGeneratedResolvedConfig, localConfigEntryPath, mergeBosConfigWithExtends, oc, parseAppDescriptorModule, parseBosUrl, parseDevOverlayModule, parseExtendsTarget, parseFastKvConfigValue, parsePort, parseRuntimeOverrideTargets, readAuthoredConfigInput, readBosConfigForBuild, readLocalAuthoredConfigInput, rebuildOrderedConfig, resetConfigPathCache, resolveBosConfigPath, resolveComposableReference, resolveConfigComposableEntries, resolveDevelopmentHostUrl, resolveExtendsRef, resolveLocalDevelopmentPath, resolvePluginRuntimeName, resolveStartConfigSource, resolveUiRuntimeName, runWithConfigWarningSink, writeResolvedConfig, z };
|
package/dist/infra/planner.cjs
CHANGED
|
@@ -273,13 +273,17 @@ function planInfra(input) {
|
|
|
273
273
|
return effect.Effect.gen(function* () {
|
|
274
274
|
const cliPorts = normalizeCliPorts(input.cli);
|
|
275
275
|
const wKey = workspaceKey(input.configDir);
|
|
276
|
-
const
|
|
276
|
+
const plugins = input.bosConfig.plugins ?? {};
|
|
277
|
+
const { ports: svcPorts, claims, devPortsState } = yield* allocateServices(cliPorts, plugins, input.configDir, input.bosConfig.auth, {
|
|
277
278
|
host: input.bosConfig.host?.source,
|
|
278
279
|
api: input.bosConfig.api?.source,
|
|
279
280
|
auth: input.bosConfig.auth?.source,
|
|
280
281
|
ui: input.bosConfig.ui?.source
|
|
281
282
|
});
|
|
282
|
-
const { dbs, redisPlans } = yield* allocateDatabases(input.bosConfig)
|
|
283
|
+
const { dbs, redisPlans } = input.bosConfig.host?.source === "local" || input.bosConfig.api?.source === "local" || input.bosConfig.auth?.source === "local" || input.bosConfig.ui?.source === "local" || Object.values(plugins).some((p) => p?.source === "local" || p?.ui?.source === "local") ? yield* allocateDatabases(input.bosConfig) : {
|
|
284
|
+
dbs: [],
|
|
285
|
+
redisPlans: []
|
|
286
|
+
};
|
|
283
287
|
const resolvedPorts = { ...svcPorts };
|
|
284
288
|
const previousDevPorts = require_infra.loadPortState(input.configDir).devPorts ?? {};
|
|
285
289
|
const devPorts = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"planner.cjs","names":["createHash","resolve","Effect","loadPortState","PortAllocator","isAuthMirrorPluginEntry","ownerOfPort","Clock","InfraError","getSecretGroups","buildConventionalDatabases","buildConventionalRedis","shouldPersistPortState","buildDescription"],"sources":["../../src/infra/planner.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { resolve } from \"node:path\";\nimport { Clock, Effect } from \"effect\";\nimport { PortAllocator, type PortBlockEntry } from \"../app\";\nimport {\n buildConventionalDatabases,\n buildConventionalRedis,\n getSecretGroups,\n loadPortState,\n savePortState,\n} from \"../cli/infra\";\nimport {\n type AuthSlotShape,\n buildDescription,\n isAuthMirrorPluginEntry,\n} from \"../service-descriptor\";\nimport type { RuntimeConfig } from \"../types\";\nimport { shouldPersistPortState } from \"./materializer\";\nimport { ownerOfPort } from \"./port-ownership\";\nimport type {\n ClaimRecord,\n CliPorts,\n DatabasePlan,\n InfraInput,\n InfraPlan,\n RedisPlan,\n ResolvedPorts,\n RuntimeLaunchSpec,\n ServiceDescriptorPlan,\n} from \"./types\";\nimport { InfraError } from \"./types\";\n\nconst DEFAULT_HOST_PORT = 3000;\n\nconst POSTGRES_USER = \"everythingdev\";\nconst POSTGRES_PASSWORD = \"everythingdev\";\n\nexport function workspaceKey(configDir: string): string {\n const hash = createHash(\"sha256\").update(resolve(configDir)).digest(\"hex\");\n return hash.slice(0, 12);\n}\n\nfunction normalizeCliPorts(input: InfraInput[\"cli\"]): CliPorts {\n return {\n host: input.port,\n api: input.apiPort,\n auth: input.authPort,\n ui: input.uiPort,\n pluginsStart: input.pluginPortStart,\n plugins: input.plugins,\n };\n}\n\ninterface AllocateServicesResult {\n ports: ResolvedPorts;\n claims: ClaimRecord[];\n devPortsState: {\n host?: number;\n api?: number;\n auth?: number;\n ui?: number;\n pluginPortStart?: number;\n };\n}\n\nexport interface ServiceSources {\n host?: \"local\" | \"remote\";\n api?: \"local\" | \"remote\";\n auth?: \"local\" | \"remote\";\n ui?: \"local\" | \"remote\";\n}\n\nconst PLUGIN_START_OFFSET = 10;\nconst BLOCK_STEP = 100;\n\nfunction allocateServices(\n cliPorts: CliPorts,\n plugins: Record<\n string,\n { source: string; localPath?: string; ui?: { source: string; localPath?: string } }\n >,\n configDir: string,\n auth?: AuthSlotShape,\n sources?: ServiceSources,\n): Effect.Effect<AllocateServicesResult, InfraError, PortAllocator> {\n return Effect.gen(function* () {\n const wKey = workspaceKey(configDir);\n const persisted = loadPortState(configDir).devPorts;\n const allocator = yield* PortAllocator;\n\n const base = cliPorts.host ?? persisted?.host ?? DEFAULT_HOST_PORT;\n const pluginStartPreferred =\n cliPorts.pluginsStart ?? persisted?.pluginPortStart ?? base + PLUGIN_START_OFFSET;\n const pluginStartPinned =\n cliPorts.pluginsStart !== undefined || persisted?.pluginPortStart !== undefined;\n\n const entries: PortBlockEntry[] = [];\n const addEntry = (\n key: string,\n flag: number | undefined,\n persistedValue: number | undefined,\n derived: number,\n ) => {\n if (flag !== undefined) {\n entries.push({ key, preferred: flag, pinned: true });\n } else if (persistedValue !== undefined) {\n entries.push({ key, preferred: persistedValue, pinned: true });\n } else {\n entries.push({ key, preferred: derived, pinned: false });\n }\n };\n\n // Remote-source services spawn nothing locally (ADR 0009 start stack:\n // remotes load over MF from their published origins) — no port is\n // allocated for them. The host is the exception: even when loaded as a\n // remote module, runServer binds its own port.\n addEntry(\"host\", cliPorts.host, undefined, base);\n if (sources?.api !== \"remote\") {\n addEntry(\"api\", cliPorts.api, persisted?.api, base + 1);\n }\n if (sources?.auth !== \"remote\") {\n addEntry(\"auth\", cliPorts.auth, persisted?.auth, base + 2);\n }\n if (sources?.ui !== \"remote\") {\n addEntry(\"ui\", cliPorts.ui, persisted?.ui, base + 3);\n }\n\n const pluginKeys = Object.keys(plugins).sort();\n const isAuthMirrorFor = (\n pluginId: string,\n pluginCfg: { source: string; localPath?: string } | undefined,\n ) => pluginCfg !== undefined && isAuthMirrorPluginEntry(auth, pluginId, pluginCfg);\n\n let pluginSlot = 0;\n for (const pluginId of pluginKeys) {\n const pluginCfg = plugins[pluginId];\n const pluginIsLocal = pluginCfg?.source === \"local\";\n const slotBase = pluginStartPinned ? pluginStartPreferred : base + PLUGIN_START_OFFSET;\n // The auth mirror's backend is owned by the `auth` app slot — no api\n // port. Its ui surface is still real: without a port the runtime config\n // advertises an empty ui.url and the browser can never load the remote\n // (the /login page never renders).\n if (!isAuthMirrorFor(pluginId, pluginCfg) && pluginIsLocal) {\n addEntry(\n `plugin:${pluginId}`,\n cliPorts.plugins?.[pluginId]?.api,\n undefined,\n slotBase + pluginSlot,\n );\n pluginSlot += 1;\n }\n if (\n pluginCfg?.source === \"local\" &&\n pluginCfg?.localPath &&\n pluginCfg?.ui?.source === \"local\"\n ) {\n addEntry(\n `plugin-ui:${pluginId}`,\n cliPorts.plugins?.[pluginId]?.ui,\n undefined,\n slotBase + pluginSlot,\n );\n pluginSlot += 1;\n }\n }\n\n const allocation = yield* allocator.acquireBlock({ base, step: BLOCK_STEP, entries });\n\n if (allocation.base !== base) {\n yield* Effect.logError(\n `[Dev] Preferred port block starting at ${base} is occupied — using ${allocation.base} (this run only; restarts will retry ${base})`,\n );\n for (const conflict of allocation.conflicts.slice(0, 6)) {\n if (conflict.claimed) {\n yield* Effect.logError(\n `[Dev] port ${conflict.port} (${conflict.key}) — live bos session (registry claim)`,\n );\n } else {\n const owner = yield* ownerOfPort(conflict.port);\n yield* Effect.logError(\n `[Dev] port ${conflict.port} (${conflict.key}) — ${\n owner ? `pid ${owner.pid} (${owner.command})` : \"foreign holder (lsof unavailable)\"\n }`,\n );\n }\n }\n }\n\n const pluginApiPorts: Record<string, number> = {};\n const pluginUiPorts: Record<string, number> = {};\n for (const pluginId of pluginKeys) {\n const api = allocation.ports[`plugin:${pluginId}`];\n if (api !== undefined) pluginApiPorts[pluginId] = api;\n const ui = allocation.ports[`plugin-ui:${pluginId}`];\n if (ui !== undefined) pluginUiPorts[pluginId] = ui;\n }\n\n const resolved: ResolvedPorts = {\n host: allocation.ports.host,\n api: allocation.ports.api,\n auth: allocation.ports.auth,\n ui: allocation.ports.ui,\n plugins: Object.fromEntries(\n pluginKeys.map((k) => [k, { api: pluginApiPorts[k], ui: pluginUiPorts[k] }]),\n ),\n };\n\n const devPortsState = {\n host: cliPorts.host,\n api: cliPorts.api,\n auth: cliPorts.auth,\n ui: cliPorts.ui,\n pluginPortStart: cliPorts.pluginsStart,\n };\n\n const claimPorts: Record<string, number> = {};\n for (const [key, port] of Object.entries(allocation.ports)) {\n claimPorts[key] = port;\n }\n\n const claim: ClaimRecord = {\n resourceKey: `workspace:${wKey}`,\n pid: process.pid,\n configDir,\n ports: claimPorts,\n startedAt: yield* Clock.currentTimeMillis,\n };\n\n return { ports: resolved, claims: [claim], devPortsState };\n }).pipe(\n Effect.mapError(\n (portErr) =>\n new InfraError({\n phase: \"allocate-services\",\n message: `Port allocation failed: ${String(portErr)}`,\n cause: portErr,\n }),\n ),\n );\n}\n\nfunction allocateDatabases(runtimeConfig: RuntimeConfig): Effect.Effect<\n {\n dbs: DatabasePlan[];\n redisPlans: RedisPlan[];\n },\n InfraError,\n PortAllocator\n> {\n return Effect.gen(function* () {\n const groups = getSecretGroups(runtimeConfig);\n const allSecrets = groups.flatMap((group) => group.secrets);\n const allocator = yield* PortAllocator;\n\n const conventionalDatabases = buildConventionalDatabases(allSecrets);\n const conventionalRedis = buildConventionalRedis(allSecrets);\n\n const dbs: DatabasePlan[] = [];\n const allocatedByDesired = new Map<number, number>();\n for (const db of conventionalDatabases) {\n let port: number;\n if (allocatedByDesired.has(db.port)) {\n port = allocatedByDesired.get(db.port)!;\n } else {\n port = yield* allocator.pickAvailable(db.port);\n allocatedByDesired.set(db.port, port);\n }\n dbs.push({\n secret: db.secret,\n slug: db.slug,\n port,\n dbName: db.databaseName,\n url: `postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:${port}/${db.databaseName}`,\n });\n }\n\n const redisPlans: RedisPlan[] = [];\n for (const r of conventionalRedis) {\n const port = yield* allocator.pickAvailable(r.port);\n redisPlans.push({\n secret: r.secret,\n slug: r.slug,\n port,\n url: `redis://localhost:${port}`,\n });\n }\n\n return { dbs, redisPlans };\n }).pipe(\n Effect.mapError(\n (portErr) =>\n new InfraError({\n phase: \"allocate-databases\",\n message: `Database port allocation failed: ${String(portErr)}`,\n cause: portErr,\n }),\n ),\n );\n}\n\nexport function buildServiceDescriptors(\n runtimeConfig: RuntimeConfig,\n resolvedPorts: ResolvedPorts,\n): ServiceDescriptorPlan[] {\n const descriptors: ServiceDescriptorPlan[] = [];\n\n if (runtimeConfig.host) {\n const isLocal = runtimeConfig.host.source === \"local\";\n descriptors.push({\n key: \"host\",\n source: runtimeConfig.host.source,\n url: isLocal ? `http://localhost:${resolvedPorts.host}` : runtimeConfig.host.url,\n port: isLocal ? resolvedPorts.host : undefined,\n localPath: isLocal ? runtimeConfig.host.localPath : undefined,\n });\n }\n\n if (runtimeConfig.api) {\n const isLocal = runtimeConfig.api.source === \"local\";\n descriptors.push({\n key: \"api\",\n source: runtimeConfig.api.source,\n url: isLocal ? `http://localhost:${resolvedPorts.api}` : runtimeConfig.api.url,\n port: isLocal ? resolvedPorts.api : undefined,\n localPath: isLocal ? runtimeConfig.api.localPath : undefined,\n });\n }\n\n if (runtimeConfig.auth) {\n const isLocal = runtimeConfig.auth.source === \"local\";\n descriptors.push({\n key: \"auth\",\n source: runtimeConfig.auth.source,\n url: isLocal ? `http://localhost:${resolvedPorts.auth}` : runtimeConfig.auth.url,\n port: isLocal ? resolvedPorts.auth : undefined,\n localPath: isLocal ? runtimeConfig.auth.localPath : undefined,\n });\n }\n\n if (runtimeConfig.ui) {\n const isLocal = runtimeConfig.ui.source === \"local\";\n descriptors.push({\n key: \"ui\",\n source: runtimeConfig.ui.source,\n url: isLocal ? `http://localhost:${resolvedPorts.ui}` : runtimeConfig.ui.url,\n port: isLocal ? resolvedPorts.ui : undefined,\n localPath: isLocal ? runtimeConfig.ui.localPath : undefined,\n });\n }\n\n if (runtimeConfig.plugins) {\n for (const [pluginId, pluginCfg] of Object.entries(runtimeConfig.plugins)) {\n const pluginIsLocal = pluginCfg.source === \"local\";\n const p = resolvedPorts.plugins[pluginId];\n const isAuthMirror = isAuthMirrorPluginEntry(runtimeConfig.auth, pluginId, pluginCfg);\n if (pluginIsLocal && p?.api && !isAuthMirror) {\n descriptors.push({\n key: `plugin:${pluginId}`,\n source: \"local\",\n url: `http://localhost:${p.api}`,\n port: p.api,\n localPath: pluginCfg.localPath,\n });\n }\n if (!pluginIsLocal && pluginCfg.url && !isAuthMirror) {\n descriptors.push({\n key: `plugin:${pluginId}`,\n source: \"remote\",\n url: pluginCfg.url,\n port: undefined,\n localPath: undefined,\n });\n }\n if (pluginIsLocal && p?.ui && pluginCfg.ui?.source === \"local\") {\n descriptors.push({\n key: `plugin-ui:${pluginId}`,\n source: \"local\",\n url: `http://localhost:${p.ui}`,\n port: p.ui,\n localPath: pluginCfg.ui?.localPath,\n });\n }\n }\n }\n\n return descriptors;\n}\n\nexport function buildLaunchSpec(\n runtimeConfig: RuntimeConfig,\n resolvedPorts: ResolvedPorts,\n): RuntimeLaunchSpec {\n const hostPort =\n runtimeConfig.host?.source === \"local\" ? resolvedPorts.host : runtimeConfig.host?.port;\n const corsOrigin = hostPort ? `http://localhost:${hostPort}` : `http://localhost:3000`;\n\n return {\n port: resolvedPorts.host,\n hostUrl: runtimeConfig.host?.url,\n corsOrigin,\n env: {\n ...(resolvedPorts.host ? { PORT: String(resolvedPorts.host) } : {}),\n ...(resolvedPorts.api ? { API_PORT: String(resolvedPorts.api) } : {}),\n ...(resolvedPorts.ui ? { UI_PORT: String(resolvedPorts.ui) } : {}),\n ...(resolvedPorts.auth ? { AUTH_PORT: String(resolvedPorts.auth) } : {}),\n },\n runtimeConfig,\n };\n}\n\nexport function buildEnvGenerated(\n resolvedPorts: ResolvedPorts,\n dbs: DatabasePlan[],\n redisPlans: RedisPlan[],\n): Record<string, string> {\n const env: Record<string, string> = {};\n\n if (resolvedPorts.host) {\n env.CORS_ORIGIN = `http://localhost:${resolvedPorts.host}`;\n // The host origin for plugins that derive absolute URLs from it (e.g. the\n // auth plugin's Better Auth baseURL — email links, passkey RP id).\n env.BASE_URL = `http://localhost:${resolvedPorts.host}`;\n }\n\n for (const db of dbs) {\n env[db.secret] = db.url;\n }\n for (const r of redisPlans) {\n env[r.secret] = r.url;\n }\n\n return env;\n}\n\nexport function planInfra(input: InfraInput): Effect.Effect<InfraPlan, InfraError, PortAllocator> {\n return Effect.gen(function* () {\n const cliPorts = normalizeCliPorts(input.cli);\n const wKey = workspaceKey(input.configDir);\n\n const plugins = (input.bosConfig.plugins ?? {}) as Record<\n string,\n { source: string; localPath?: string; ui?: { source: string; localPath?: string } }\n >;\n\n const {\n ports: svcPorts,\n claims,\n devPortsState,\n } = yield* allocateServices(cliPorts, plugins, input.configDir, input.bosConfig.auth, {\n host: input.bosConfig.host?.source,\n api: input.bosConfig.api?.source,\n auth: input.bosConfig.auth?.source,\n ui: input.bosConfig.ui?.source,\n });\n\n const { dbs, redisPlans } = yield* allocateDatabases(input.bosConfig);\n\n const resolvedPorts: ResolvedPorts = { ...svcPorts };\n\n // Write merged state once after all allocations succeed\n // Skip persistence for regression tests / ephemeral runs\n // devPorts pins are explicit choices only (ADR 0012 §4): this run's flags,\n // falling back to previously-persisted explicit choices — never drift.\n const previousDevPorts = loadPortState(input.configDir).devPorts ?? {};\n const devPorts = {\n host: devPortsState.host ?? previousDevPorts.host,\n api: devPortsState.api ?? previousDevPorts.api,\n auth: devPortsState.auth ?? previousDevPorts.auth,\n ui: devPortsState.ui ?? previousDevPorts.ui,\n pluginPortStart: devPortsState.pluginPortStart ?? previousDevPorts.pluginPortStart,\n };\n if (shouldPersistPortState()) {\n savePortState(input.configDir, { devPorts });\n }\n\n const hostIsLocal = input.bosConfig.host?.source === \"local\";\n const apiIsLocal = input.bosConfig.api?.source === \"local\";\n const uiIsLocal = input.bosConfig.ui?.source === \"local\";\n const authIsLocal = input.bosConfig.auth?.source === \"local\";\n const assignedRuntimeConfig: RuntimeConfig = {\n ...input.bosConfig,\n host: resolvedPorts.host\n ? {\n ...input.bosConfig.host,\n port: resolvedPorts.host,\n url: `http://localhost:${resolvedPorts.host}`,\n remoteUrl: !hostIsLocal\n ? (input.bosConfig.host.remoteUrl ?? input.bosConfig.host.url)\n : undefined,\n }\n : input.bosConfig.host,\n api:\n apiIsLocal && resolvedPorts.api\n ? {\n ...input.bosConfig.api,\n port: resolvedPorts.api,\n url: `http://localhost:${resolvedPorts.api}`,\n }\n : input.bosConfig.api,\n ui:\n uiIsLocal && resolvedPorts.ui\n ? {\n ...input.bosConfig.ui,\n port: resolvedPorts.ui,\n url: `http://localhost:${resolvedPorts.ui}`,\n ssrUrl: undefined,\n }\n : input.bosConfig.ui,\n auth:\n authIsLocal && resolvedPorts.auth && input.bosConfig.auth\n ? {\n ...input.bosConfig.auth,\n port: resolvedPorts.auth,\n url: `http://localhost:${resolvedPorts.auth}`,\n }\n : input.bosConfig.auth,\n plugins: input.bosConfig.plugins\n ? Object.fromEntries(\n Object.entries(input.bosConfig.plugins).map(([id, p]) => {\n const isAuthMirror = isAuthMirrorPluginEntry(input.bosConfig.auth, id, p);\n const pluginPort = resolvedPorts.plugins[id];\n const patchedUi = (() => {\n if (p.ui?.source !== \"local\" || !p.ui?.localPath || !pluginPort?.ui) return p.ui;\n return {\n ...p.ui,\n port: pluginPort.ui,\n url: `http://localhost:${pluginPort.ui}`,\n ssrUrl: undefined,\n };\n })();\n if (isAuthMirror) {\n return [id, { ...p, ui: patchedUi }];\n }\n if (p.source === \"local\" && pluginPort?.api) {\n return [\n id,\n {\n ...p,\n port: pluginPort.api,\n url: `http://localhost:${pluginPort.api}`,\n ui: patchedUi,\n },\n ];\n }\n return [id, p];\n }),\n )\n : undefined,\n };\n\n const serviceDescriptors = buildServiceDescriptors(assignedRuntimeConfig, resolvedPorts);\n\n const launch = buildLaunchSpec(input.bosConfig, resolvedPorts);\n const envGenerated = buildEnvGenerated(resolvedPorts, dbs, redisPlans);\n\n const packages = serviceDescriptors.map((d) => d.key);\n const descriptionMap = new Map(serviceDescriptors.map((d) => [d.key, d]));\n const description = buildDescription(descriptionMap);\n\n const orchestrator = {\n packages,\n env: {},\n description,\n port: resolvedPorts.host,\n interactive: input.cli.interactive,\n };\n\n return {\n workspaceKey: wKey,\n cliPorts,\n resolvedPorts,\n runtimeConfig: assignedRuntimeConfig,\n launch,\n description,\n serviceDescriptors: new Map(serviceDescriptors.map((d) => [d.key, d])),\n envGenerated,\n claims,\n orchestrator,\n };\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"planner.cjs","names":["createHash","resolve","Effect","loadPortState","PortAllocator","isAuthMirrorPluginEntry","ownerOfPort","Clock","InfraError","getSecretGroups","buildConventionalDatabases","buildConventionalRedis","shouldPersistPortState","buildDescription"],"sources":["../../src/infra/planner.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { resolve } from \"node:path\";\nimport { Clock, Effect } from \"effect\";\nimport { PortAllocator, type PortBlockEntry } from \"../app\";\nimport {\n buildConventionalDatabases,\n buildConventionalRedis,\n getSecretGroups,\n loadPortState,\n savePortState,\n} from \"../cli/infra\";\nimport {\n type AuthSlotShape,\n buildDescription,\n isAuthMirrorPluginEntry,\n} from \"../service-descriptor\";\nimport type { RuntimeConfig } from \"../types\";\nimport { shouldPersistPortState } from \"./materializer\";\nimport { ownerOfPort } from \"./port-ownership\";\nimport type {\n ClaimRecord,\n CliPorts,\n DatabasePlan,\n InfraInput,\n InfraPlan,\n RedisPlan,\n ResolvedPorts,\n RuntimeLaunchSpec,\n ServiceDescriptorPlan,\n} from \"./types\";\nimport { InfraError } from \"./types\";\n\nconst DEFAULT_HOST_PORT = 3000;\n\nconst POSTGRES_USER = \"everythingdev\";\nconst POSTGRES_PASSWORD = \"everythingdev\";\n\nexport function workspaceKey(configDir: string): string {\n const hash = createHash(\"sha256\").update(resolve(configDir)).digest(\"hex\");\n return hash.slice(0, 12);\n}\n\nfunction normalizeCliPorts(input: InfraInput[\"cli\"]): CliPorts {\n return {\n host: input.port,\n api: input.apiPort,\n auth: input.authPort,\n ui: input.uiPort,\n pluginsStart: input.pluginPortStart,\n plugins: input.plugins,\n };\n}\n\ninterface AllocateServicesResult {\n ports: ResolvedPorts;\n claims: ClaimRecord[];\n devPortsState: {\n host?: number;\n api?: number;\n auth?: number;\n ui?: number;\n pluginPortStart?: number;\n };\n}\n\nexport interface ServiceSources {\n host?: \"local\" | \"remote\";\n api?: \"local\" | \"remote\";\n auth?: \"local\" | \"remote\";\n ui?: \"local\" | \"remote\";\n}\n\nconst PLUGIN_START_OFFSET = 10;\nconst BLOCK_STEP = 100;\n\nfunction allocateServices(\n cliPorts: CliPorts,\n plugins: Record<\n string,\n { source: string; localPath?: string; ui?: { source: string; localPath?: string } }\n >,\n configDir: string,\n auth?: AuthSlotShape,\n sources?: ServiceSources,\n): Effect.Effect<AllocateServicesResult, InfraError, PortAllocator> {\n return Effect.gen(function* () {\n const wKey = workspaceKey(configDir);\n const persisted = loadPortState(configDir).devPorts;\n const allocator = yield* PortAllocator;\n\n const base = cliPorts.host ?? persisted?.host ?? DEFAULT_HOST_PORT;\n const pluginStartPreferred =\n cliPorts.pluginsStart ?? persisted?.pluginPortStart ?? base + PLUGIN_START_OFFSET;\n const pluginStartPinned =\n cliPorts.pluginsStart !== undefined || persisted?.pluginPortStart !== undefined;\n\n const entries: PortBlockEntry[] = [];\n const addEntry = (\n key: string,\n flag: number | undefined,\n persistedValue: number | undefined,\n derived: number,\n ) => {\n if (flag !== undefined) {\n entries.push({ key, preferred: flag, pinned: true });\n } else if (persistedValue !== undefined) {\n entries.push({ key, preferred: persistedValue, pinned: true });\n } else {\n entries.push({ key, preferred: derived, pinned: false });\n }\n };\n\n // Remote-source services spawn nothing locally (ADR 0009 start stack:\n // remotes load over MF from their published origins) — no port is\n // allocated for them. The host is the exception: even when loaded as a\n // remote module, runServer binds its own port.\n addEntry(\"host\", cliPorts.host, undefined, base);\n if (sources?.api !== \"remote\") {\n addEntry(\"api\", cliPorts.api, persisted?.api, base + 1);\n }\n if (sources?.auth !== \"remote\") {\n addEntry(\"auth\", cliPorts.auth, persisted?.auth, base + 2);\n }\n if (sources?.ui !== \"remote\") {\n addEntry(\"ui\", cliPorts.ui, persisted?.ui, base + 3);\n }\n\n const pluginKeys = Object.keys(plugins).sort();\n const isAuthMirrorFor = (\n pluginId: string,\n pluginCfg: { source: string; localPath?: string } | undefined,\n ) => pluginCfg !== undefined && isAuthMirrorPluginEntry(auth, pluginId, pluginCfg);\n\n let pluginSlot = 0;\n for (const pluginId of pluginKeys) {\n const pluginCfg = plugins[pluginId];\n const pluginIsLocal = pluginCfg?.source === \"local\";\n const slotBase = pluginStartPinned ? pluginStartPreferred : base + PLUGIN_START_OFFSET;\n // The auth mirror's backend is owned by the `auth` app slot — no api\n // port. Its ui surface is still real: without a port the runtime config\n // advertises an empty ui.url and the browser can never load the remote\n // (the /login page never renders).\n if (!isAuthMirrorFor(pluginId, pluginCfg) && pluginIsLocal) {\n addEntry(\n `plugin:${pluginId}`,\n cliPorts.plugins?.[pluginId]?.api,\n undefined,\n slotBase + pluginSlot,\n );\n pluginSlot += 1;\n }\n if (\n pluginCfg?.source === \"local\" &&\n pluginCfg?.localPath &&\n pluginCfg?.ui?.source === \"local\"\n ) {\n addEntry(\n `plugin-ui:${pluginId}`,\n cliPorts.plugins?.[pluginId]?.ui,\n undefined,\n slotBase + pluginSlot,\n );\n pluginSlot += 1;\n }\n }\n\n const allocation = yield* allocator.acquireBlock({ base, step: BLOCK_STEP, entries });\n\n if (allocation.base !== base) {\n yield* Effect.logError(\n `[Dev] Preferred port block starting at ${base} is occupied — using ${allocation.base} (this run only; restarts will retry ${base})`,\n );\n for (const conflict of allocation.conflicts.slice(0, 6)) {\n if (conflict.claimed) {\n yield* Effect.logError(\n `[Dev] port ${conflict.port} (${conflict.key}) — live bos session (registry claim)`,\n );\n } else {\n const owner = yield* ownerOfPort(conflict.port);\n yield* Effect.logError(\n `[Dev] port ${conflict.port} (${conflict.key}) — ${\n owner ? `pid ${owner.pid} (${owner.command})` : \"foreign holder (lsof unavailable)\"\n }`,\n );\n }\n }\n }\n\n const pluginApiPorts: Record<string, number> = {};\n const pluginUiPorts: Record<string, number> = {};\n for (const pluginId of pluginKeys) {\n const api = allocation.ports[`plugin:${pluginId}`];\n if (api !== undefined) pluginApiPorts[pluginId] = api;\n const ui = allocation.ports[`plugin-ui:${pluginId}`];\n if (ui !== undefined) pluginUiPorts[pluginId] = ui;\n }\n\n const resolved: ResolvedPorts = {\n host: allocation.ports.host,\n api: allocation.ports.api,\n auth: allocation.ports.auth,\n ui: allocation.ports.ui,\n plugins: Object.fromEntries(\n pluginKeys.map((k) => [k, { api: pluginApiPorts[k], ui: pluginUiPorts[k] }]),\n ),\n };\n\n const devPortsState = {\n host: cliPorts.host,\n api: cliPorts.api,\n auth: cliPorts.auth,\n ui: cliPorts.ui,\n pluginPortStart: cliPorts.pluginsStart,\n };\n\n const claimPorts: Record<string, number> = {};\n for (const [key, port] of Object.entries(allocation.ports)) {\n claimPorts[key] = port;\n }\n\n const claim: ClaimRecord = {\n resourceKey: `workspace:${wKey}`,\n pid: process.pid,\n configDir,\n ports: claimPorts,\n startedAt: yield* Clock.currentTimeMillis,\n };\n\n return { ports: resolved, claims: [claim], devPortsState };\n }).pipe(\n Effect.mapError(\n (portErr) =>\n new InfraError({\n phase: \"allocate-services\",\n message: `Port allocation failed: ${String(portErr)}`,\n cause: portErr,\n }),\n ),\n );\n}\n\nfunction allocateDatabases(runtimeConfig: RuntimeConfig): Effect.Effect<\n {\n dbs: DatabasePlan[];\n redisPlans: RedisPlan[];\n },\n InfraError,\n PortAllocator\n> {\n return Effect.gen(function* () {\n const groups = getSecretGroups(runtimeConfig);\n const allSecrets = groups.flatMap((group) => group.secrets);\n const allocator = yield* PortAllocator;\n\n const conventionalDatabases = buildConventionalDatabases(allSecrets);\n const conventionalRedis = buildConventionalRedis(allSecrets);\n\n const dbs: DatabasePlan[] = [];\n const allocatedByDesired = new Map<number, number>();\n for (const db of conventionalDatabases) {\n let port: number;\n if (allocatedByDesired.has(db.port)) {\n port = allocatedByDesired.get(db.port)!;\n } else {\n port = yield* allocator.pickAvailable(db.port);\n allocatedByDesired.set(db.port, port);\n }\n dbs.push({\n secret: db.secret,\n slug: db.slug,\n port,\n dbName: db.databaseName,\n url: `postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:${port}/${db.databaseName}`,\n });\n }\n\n const redisPlans: RedisPlan[] = [];\n for (const r of conventionalRedis) {\n const port = yield* allocator.pickAvailable(r.port);\n redisPlans.push({\n secret: r.secret,\n slug: r.slug,\n port,\n url: `redis://localhost:${port}`,\n });\n }\n\n return { dbs, redisPlans };\n }).pipe(\n Effect.mapError(\n (portErr) =>\n new InfraError({\n phase: \"allocate-databases\",\n message: `Database port allocation failed: ${String(portErr)}`,\n cause: portErr,\n }),\n ),\n );\n}\n\nexport function buildServiceDescriptors(\n runtimeConfig: RuntimeConfig,\n resolvedPorts: ResolvedPorts,\n): ServiceDescriptorPlan[] {\n const descriptors: ServiceDescriptorPlan[] = [];\n\n if (runtimeConfig.host) {\n const isLocal = runtimeConfig.host.source === \"local\";\n descriptors.push({\n key: \"host\",\n source: runtimeConfig.host.source,\n url: isLocal ? `http://localhost:${resolvedPorts.host}` : runtimeConfig.host.url,\n port: isLocal ? resolvedPorts.host : undefined,\n localPath: isLocal ? runtimeConfig.host.localPath : undefined,\n });\n }\n\n if (runtimeConfig.api) {\n const isLocal = runtimeConfig.api.source === \"local\";\n descriptors.push({\n key: \"api\",\n source: runtimeConfig.api.source,\n url: isLocal ? `http://localhost:${resolvedPorts.api}` : runtimeConfig.api.url,\n port: isLocal ? resolvedPorts.api : undefined,\n localPath: isLocal ? runtimeConfig.api.localPath : undefined,\n });\n }\n\n if (runtimeConfig.auth) {\n const isLocal = runtimeConfig.auth.source === \"local\";\n descriptors.push({\n key: \"auth\",\n source: runtimeConfig.auth.source,\n url: isLocal ? `http://localhost:${resolvedPorts.auth}` : runtimeConfig.auth.url,\n port: isLocal ? resolvedPorts.auth : undefined,\n localPath: isLocal ? runtimeConfig.auth.localPath : undefined,\n });\n }\n\n if (runtimeConfig.ui) {\n const isLocal = runtimeConfig.ui.source === \"local\";\n descriptors.push({\n key: \"ui\",\n source: runtimeConfig.ui.source,\n url: isLocal ? `http://localhost:${resolvedPorts.ui}` : runtimeConfig.ui.url,\n port: isLocal ? resolvedPorts.ui : undefined,\n localPath: isLocal ? runtimeConfig.ui.localPath : undefined,\n });\n }\n\n if (runtimeConfig.plugins) {\n for (const [pluginId, pluginCfg] of Object.entries(runtimeConfig.plugins)) {\n const pluginIsLocal = pluginCfg.source === \"local\";\n const p = resolvedPorts.plugins[pluginId];\n const isAuthMirror = isAuthMirrorPluginEntry(runtimeConfig.auth, pluginId, pluginCfg);\n if (pluginIsLocal && p?.api && !isAuthMirror) {\n descriptors.push({\n key: `plugin:${pluginId}`,\n source: \"local\",\n url: `http://localhost:${p.api}`,\n port: p.api,\n localPath: pluginCfg.localPath,\n });\n }\n if (!pluginIsLocal && pluginCfg.url && !isAuthMirror) {\n descriptors.push({\n key: `plugin:${pluginId}`,\n source: \"remote\",\n url: pluginCfg.url,\n port: undefined,\n localPath: undefined,\n });\n }\n if (pluginIsLocal && p?.ui && pluginCfg.ui?.source === \"local\") {\n descriptors.push({\n key: `plugin-ui:${pluginId}`,\n source: \"local\",\n url: `http://localhost:${p.ui}`,\n port: p.ui,\n localPath: pluginCfg.ui?.localPath,\n });\n }\n }\n }\n\n return descriptors;\n}\n\nexport function buildLaunchSpec(\n runtimeConfig: RuntimeConfig,\n resolvedPorts: ResolvedPorts,\n): RuntimeLaunchSpec {\n const hostPort =\n runtimeConfig.host?.source === \"local\" ? resolvedPorts.host : runtimeConfig.host?.port;\n const corsOrigin = hostPort ? `http://localhost:${hostPort}` : `http://localhost:3000`;\n\n return {\n port: resolvedPorts.host,\n hostUrl: runtimeConfig.host?.url,\n corsOrigin,\n env: {\n ...(resolvedPorts.host ? { PORT: String(resolvedPorts.host) } : {}),\n ...(resolvedPorts.api ? { API_PORT: String(resolvedPorts.api) } : {}),\n ...(resolvedPorts.ui ? { UI_PORT: String(resolvedPorts.ui) } : {}),\n ...(resolvedPorts.auth ? { AUTH_PORT: String(resolvedPorts.auth) } : {}),\n },\n runtimeConfig,\n };\n}\n\nexport function buildEnvGenerated(\n resolvedPorts: ResolvedPorts,\n dbs: DatabasePlan[],\n redisPlans: RedisPlan[],\n): Record<string, string> {\n const env: Record<string, string> = {};\n\n if (resolvedPorts.host) {\n env.CORS_ORIGIN = `http://localhost:${resolvedPorts.host}`;\n // The host origin for plugins that derive absolute URLs from it (e.g. the\n // auth plugin's Better Auth baseURL — email links, passkey RP id).\n env.BASE_URL = `http://localhost:${resolvedPorts.host}`;\n }\n\n for (const db of dbs) {\n env[db.secret] = db.url;\n }\n for (const r of redisPlans) {\n env[r.secret] = r.url;\n }\n\n return env;\n}\n\nexport function planInfra(input: InfraInput): Effect.Effect<InfraPlan, InfraError, PortAllocator> {\n return Effect.gen(function* () {\n const cliPorts = normalizeCliPorts(input.cli);\n const wKey = workspaceKey(input.configDir);\n\n const plugins = (input.bosConfig.plugins ?? {}) as Record<\n string,\n { source: string; localPath?: string; ui?: { source: string; localPath?: string } }\n >;\n\n const {\n ports: svcPorts,\n claims,\n devPortsState,\n } = yield* allocateServices(cliPorts, plugins, input.configDir, input.bosConfig.auth, {\n host: input.bosConfig.host?.source,\n api: input.bosConfig.api?.source,\n auth: input.bosConfig.auth?.source,\n ui: input.bosConfig.ui?.source,\n });\n\n // DB/Redis port probes only matter for services that will actually spawn\n // locally — their generated URLs are consumed exclusively by local spawn\n // env (composeSpawnEnv). When every source is remote (start mode, ADR\n // 0009), nothing binds those ports and the probes are wasted work in the\n // container boot path — and a probe against an occupied port (the staged\n // dist servers) can drift the whole plan (the #363 failure class).\n const hasLocalServices =\n input.bosConfig.host?.source === \"local\" ||\n input.bosConfig.api?.source === \"local\" ||\n input.bosConfig.auth?.source === \"local\" ||\n input.bosConfig.ui?.source === \"local\" ||\n Object.values(plugins).some((p) => p?.source === \"local\" || p?.ui?.source === \"local\");\n\n const { dbs, redisPlans } = hasLocalServices\n ? yield* allocateDatabases(input.bosConfig)\n : { dbs: [], redisPlans: [] };\n\n const resolvedPorts: ResolvedPorts = { ...svcPorts };\n\n // Write merged state once after all allocations succeed\n // Skip persistence for regression tests / ephemeral runs\n // devPorts pins are explicit choices only (ADR 0012 §4): this run's flags,\n // falling back to previously-persisted explicit choices — never drift.\n const previousDevPorts = loadPortState(input.configDir).devPorts ?? {};\n const devPorts = {\n host: devPortsState.host ?? previousDevPorts.host,\n api: devPortsState.api ?? previousDevPorts.api,\n auth: devPortsState.auth ?? previousDevPorts.auth,\n ui: devPortsState.ui ?? previousDevPorts.ui,\n pluginPortStart: devPortsState.pluginPortStart ?? previousDevPorts.pluginPortStart,\n };\n if (shouldPersistPortState()) {\n savePortState(input.configDir, { devPorts });\n }\n\n const hostIsLocal = input.bosConfig.host?.source === \"local\";\n const apiIsLocal = input.bosConfig.api?.source === \"local\";\n const uiIsLocal = input.bosConfig.ui?.source === \"local\";\n const authIsLocal = input.bosConfig.auth?.source === \"local\";\n const assignedRuntimeConfig: RuntimeConfig = {\n ...input.bosConfig,\n host: resolvedPorts.host\n ? {\n ...input.bosConfig.host,\n port: resolvedPorts.host,\n url: `http://localhost:${resolvedPorts.host}`,\n remoteUrl: !hostIsLocal\n ? (input.bosConfig.host.remoteUrl ?? input.bosConfig.host.url)\n : undefined,\n }\n : input.bosConfig.host,\n api:\n apiIsLocal && resolvedPorts.api\n ? {\n ...input.bosConfig.api,\n port: resolvedPorts.api,\n url: `http://localhost:${resolvedPorts.api}`,\n }\n : input.bosConfig.api,\n ui:\n uiIsLocal && resolvedPorts.ui\n ? {\n ...input.bosConfig.ui,\n port: resolvedPorts.ui,\n url: `http://localhost:${resolvedPorts.ui}`,\n ssrUrl: undefined,\n }\n : input.bosConfig.ui,\n auth:\n authIsLocal && resolvedPorts.auth && input.bosConfig.auth\n ? {\n ...input.bosConfig.auth,\n port: resolvedPorts.auth,\n url: `http://localhost:${resolvedPorts.auth}`,\n }\n : input.bosConfig.auth,\n plugins: input.bosConfig.plugins\n ? Object.fromEntries(\n Object.entries(input.bosConfig.plugins).map(([id, p]) => {\n const isAuthMirror = isAuthMirrorPluginEntry(input.bosConfig.auth, id, p);\n const pluginPort = resolvedPorts.plugins[id];\n const patchedUi = (() => {\n if (p.ui?.source !== \"local\" || !p.ui?.localPath || !pluginPort?.ui) return p.ui;\n return {\n ...p.ui,\n port: pluginPort.ui,\n url: `http://localhost:${pluginPort.ui}`,\n ssrUrl: undefined,\n };\n })();\n if (isAuthMirror) {\n return [id, { ...p, ui: patchedUi }];\n }\n if (p.source === \"local\" && pluginPort?.api) {\n return [\n id,\n {\n ...p,\n port: pluginPort.api,\n url: `http://localhost:${pluginPort.api}`,\n ui: patchedUi,\n },\n ];\n }\n return [id, p];\n }),\n )\n : undefined,\n };\n\n const serviceDescriptors = buildServiceDescriptors(assignedRuntimeConfig, resolvedPorts);\n\n const launch = buildLaunchSpec(input.bosConfig, resolvedPorts);\n const envGenerated = buildEnvGenerated(resolvedPorts, dbs, redisPlans);\n\n const packages = serviceDescriptors.map((d) => d.key);\n const descriptionMap = new Map(serviceDescriptors.map((d) => [d.key, d]));\n const description = buildDescription(descriptionMap);\n\n const orchestrator = {\n packages,\n env: {},\n description,\n port: resolvedPorts.host,\n interactive: input.cli.interactive,\n };\n\n return {\n workspaceKey: wKey,\n cliPorts,\n resolvedPorts,\n runtimeConfig: assignedRuntimeConfig,\n launch,\n description,\n serviceDescriptors: new Map(serviceDescriptors.map((d) => [d.key, d])),\n envGenerated,\n claims,\n orchestrator,\n };\n });\n}\n"],"mappings":"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"}
|
package/dist/infra/planner.mjs
CHANGED
|
@@ -273,13 +273,17 @@ function planInfra(input) {
|
|
|
273
273
|
return Effect.gen(function* () {
|
|
274
274
|
const cliPorts = normalizeCliPorts(input.cli);
|
|
275
275
|
const wKey = workspaceKey(input.configDir);
|
|
276
|
-
const
|
|
276
|
+
const plugins = input.bosConfig.plugins ?? {};
|
|
277
|
+
const { ports: svcPorts, claims, devPortsState } = yield* allocateServices(cliPorts, plugins, input.configDir, input.bosConfig.auth, {
|
|
277
278
|
host: input.bosConfig.host?.source,
|
|
278
279
|
api: input.bosConfig.api?.source,
|
|
279
280
|
auth: input.bosConfig.auth?.source,
|
|
280
281
|
ui: input.bosConfig.ui?.source
|
|
281
282
|
});
|
|
282
|
-
const { dbs, redisPlans } = yield* allocateDatabases(input.bosConfig)
|
|
283
|
+
const { dbs, redisPlans } = input.bosConfig.host?.source === "local" || input.bosConfig.api?.source === "local" || input.bosConfig.auth?.source === "local" || input.bosConfig.ui?.source === "local" || Object.values(plugins).some((p) => p?.source === "local" || p?.ui?.source === "local") ? yield* allocateDatabases(input.bosConfig) : {
|
|
284
|
+
dbs: [],
|
|
285
|
+
redisPlans: []
|
|
286
|
+
};
|
|
283
287
|
const resolvedPorts = { ...svcPorts };
|
|
284
288
|
const previousDevPorts = loadPortState(input.configDir).devPorts ?? {};
|
|
285
289
|
const devPorts = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"planner.mjs","names":[],"sources":["../../src/infra/planner.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { resolve } from \"node:path\";\nimport { Clock, Effect } from \"effect\";\nimport { PortAllocator, type PortBlockEntry } from \"../app\";\nimport {\n buildConventionalDatabases,\n buildConventionalRedis,\n getSecretGroups,\n loadPortState,\n savePortState,\n} from \"../cli/infra\";\nimport {\n type AuthSlotShape,\n buildDescription,\n isAuthMirrorPluginEntry,\n} from \"../service-descriptor\";\nimport type { RuntimeConfig } from \"../types\";\nimport { shouldPersistPortState } from \"./materializer\";\nimport { ownerOfPort } from \"./port-ownership\";\nimport type {\n ClaimRecord,\n CliPorts,\n DatabasePlan,\n InfraInput,\n InfraPlan,\n RedisPlan,\n ResolvedPorts,\n RuntimeLaunchSpec,\n ServiceDescriptorPlan,\n} from \"./types\";\nimport { InfraError } from \"./types\";\n\nconst DEFAULT_HOST_PORT = 3000;\n\nconst POSTGRES_USER = \"everythingdev\";\nconst POSTGRES_PASSWORD = \"everythingdev\";\n\nexport function workspaceKey(configDir: string): string {\n const hash = createHash(\"sha256\").update(resolve(configDir)).digest(\"hex\");\n return hash.slice(0, 12);\n}\n\nfunction normalizeCliPorts(input: InfraInput[\"cli\"]): CliPorts {\n return {\n host: input.port,\n api: input.apiPort,\n auth: input.authPort,\n ui: input.uiPort,\n pluginsStart: input.pluginPortStart,\n plugins: input.plugins,\n };\n}\n\ninterface AllocateServicesResult {\n ports: ResolvedPorts;\n claims: ClaimRecord[];\n devPortsState: {\n host?: number;\n api?: number;\n auth?: number;\n ui?: number;\n pluginPortStart?: number;\n };\n}\n\nexport interface ServiceSources {\n host?: \"local\" | \"remote\";\n api?: \"local\" | \"remote\";\n auth?: \"local\" | \"remote\";\n ui?: \"local\" | \"remote\";\n}\n\nconst PLUGIN_START_OFFSET = 10;\nconst BLOCK_STEP = 100;\n\nfunction allocateServices(\n cliPorts: CliPorts,\n plugins: Record<\n string,\n { source: string; localPath?: string; ui?: { source: string; localPath?: string } }\n >,\n configDir: string,\n auth?: AuthSlotShape,\n sources?: ServiceSources,\n): Effect.Effect<AllocateServicesResult, InfraError, PortAllocator> {\n return Effect.gen(function* () {\n const wKey = workspaceKey(configDir);\n const persisted = loadPortState(configDir).devPorts;\n const allocator = yield* PortAllocator;\n\n const base = cliPorts.host ?? persisted?.host ?? DEFAULT_HOST_PORT;\n const pluginStartPreferred =\n cliPorts.pluginsStart ?? persisted?.pluginPortStart ?? base + PLUGIN_START_OFFSET;\n const pluginStartPinned =\n cliPorts.pluginsStart !== undefined || persisted?.pluginPortStart !== undefined;\n\n const entries: PortBlockEntry[] = [];\n const addEntry = (\n key: string,\n flag: number | undefined,\n persistedValue: number | undefined,\n derived: number,\n ) => {\n if (flag !== undefined) {\n entries.push({ key, preferred: flag, pinned: true });\n } else if (persistedValue !== undefined) {\n entries.push({ key, preferred: persistedValue, pinned: true });\n } else {\n entries.push({ key, preferred: derived, pinned: false });\n }\n };\n\n // Remote-source services spawn nothing locally (ADR 0009 start stack:\n // remotes load over MF from their published origins) — no port is\n // allocated for them. The host is the exception: even when loaded as a\n // remote module, runServer binds its own port.\n addEntry(\"host\", cliPorts.host, undefined, base);\n if (sources?.api !== \"remote\") {\n addEntry(\"api\", cliPorts.api, persisted?.api, base + 1);\n }\n if (sources?.auth !== \"remote\") {\n addEntry(\"auth\", cliPorts.auth, persisted?.auth, base + 2);\n }\n if (sources?.ui !== \"remote\") {\n addEntry(\"ui\", cliPorts.ui, persisted?.ui, base + 3);\n }\n\n const pluginKeys = Object.keys(plugins).sort();\n const isAuthMirrorFor = (\n pluginId: string,\n pluginCfg: { source: string; localPath?: string } | undefined,\n ) => pluginCfg !== undefined && isAuthMirrorPluginEntry(auth, pluginId, pluginCfg);\n\n let pluginSlot = 0;\n for (const pluginId of pluginKeys) {\n const pluginCfg = plugins[pluginId];\n const pluginIsLocal = pluginCfg?.source === \"local\";\n const slotBase = pluginStartPinned ? pluginStartPreferred : base + PLUGIN_START_OFFSET;\n // The auth mirror's backend is owned by the `auth` app slot — no api\n // port. Its ui surface is still real: without a port the runtime config\n // advertises an empty ui.url and the browser can never load the remote\n // (the /login page never renders).\n if (!isAuthMirrorFor(pluginId, pluginCfg) && pluginIsLocal) {\n addEntry(\n `plugin:${pluginId}`,\n cliPorts.plugins?.[pluginId]?.api,\n undefined,\n slotBase + pluginSlot,\n );\n pluginSlot += 1;\n }\n if (\n pluginCfg?.source === \"local\" &&\n pluginCfg?.localPath &&\n pluginCfg?.ui?.source === \"local\"\n ) {\n addEntry(\n `plugin-ui:${pluginId}`,\n cliPorts.plugins?.[pluginId]?.ui,\n undefined,\n slotBase + pluginSlot,\n );\n pluginSlot += 1;\n }\n }\n\n const allocation = yield* allocator.acquireBlock({ base, step: BLOCK_STEP, entries });\n\n if (allocation.base !== base) {\n yield* Effect.logError(\n `[Dev] Preferred port block starting at ${base} is occupied — using ${allocation.base} (this run only; restarts will retry ${base})`,\n );\n for (const conflict of allocation.conflicts.slice(0, 6)) {\n if (conflict.claimed) {\n yield* Effect.logError(\n `[Dev] port ${conflict.port} (${conflict.key}) — live bos session (registry claim)`,\n );\n } else {\n const owner = yield* ownerOfPort(conflict.port);\n yield* Effect.logError(\n `[Dev] port ${conflict.port} (${conflict.key}) — ${\n owner ? `pid ${owner.pid} (${owner.command})` : \"foreign holder (lsof unavailable)\"\n }`,\n );\n }\n }\n }\n\n const pluginApiPorts: Record<string, number> = {};\n const pluginUiPorts: Record<string, number> = {};\n for (const pluginId of pluginKeys) {\n const api = allocation.ports[`plugin:${pluginId}`];\n if (api !== undefined) pluginApiPorts[pluginId] = api;\n const ui = allocation.ports[`plugin-ui:${pluginId}`];\n if (ui !== undefined) pluginUiPorts[pluginId] = ui;\n }\n\n const resolved: ResolvedPorts = {\n host: allocation.ports.host,\n api: allocation.ports.api,\n auth: allocation.ports.auth,\n ui: allocation.ports.ui,\n plugins: Object.fromEntries(\n pluginKeys.map((k) => [k, { api: pluginApiPorts[k], ui: pluginUiPorts[k] }]),\n ),\n };\n\n const devPortsState = {\n host: cliPorts.host,\n api: cliPorts.api,\n auth: cliPorts.auth,\n ui: cliPorts.ui,\n pluginPortStart: cliPorts.pluginsStart,\n };\n\n const claimPorts: Record<string, number> = {};\n for (const [key, port] of Object.entries(allocation.ports)) {\n claimPorts[key] = port;\n }\n\n const claim: ClaimRecord = {\n resourceKey: `workspace:${wKey}`,\n pid: process.pid,\n configDir,\n ports: claimPorts,\n startedAt: yield* Clock.currentTimeMillis,\n };\n\n return { ports: resolved, claims: [claim], devPortsState };\n }).pipe(\n Effect.mapError(\n (portErr) =>\n new InfraError({\n phase: \"allocate-services\",\n message: `Port allocation failed: ${String(portErr)}`,\n cause: portErr,\n }),\n ),\n );\n}\n\nfunction allocateDatabases(runtimeConfig: RuntimeConfig): Effect.Effect<\n {\n dbs: DatabasePlan[];\n redisPlans: RedisPlan[];\n },\n InfraError,\n PortAllocator\n> {\n return Effect.gen(function* () {\n const groups = getSecretGroups(runtimeConfig);\n const allSecrets = groups.flatMap((group) => group.secrets);\n const allocator = yield* PortAllocator;\n\n const conventionalDatabases = buildConventionalDatabases(allSecrets);\n const conventionalRedis = buildConventionalRedis(allSecrets);\n\n const dbs: DatabasePlan[] = [];\n const allocatedByDesired = new Map<number, number>();\n for (const db of conventionalDatabases) {\n let port: number;\n if (allocatedByDesired.has(db.port)) {\n port = allocatedByDesired.get(db.port)!;\n } else {\n port = yield* allocator.pickAvailable(db.port);\n allocatedByDesired.set(db.port, port);\n }\n dbs.push({\n secret: db.secret,\n slug: db.slug,\n port,\n dbName: db.databaseName,\n url: `postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:${port}/${db.databaseName}`,\n });\n }\n\n const redisPlans: RedisPlan[] = [];\n for (const r of conventionalRedis) {\n const port = yield* allocator.pickAvailable(r.port);\n redisPlans.push({\n secret: r.secret,\n slug: r.slug,\n port,\n url: `redis://localhost:${port}`,\n });\n }\n\n return { dbs, redisPlans };\n }).pipe(\n Effect.mapError(\n (portErr) =>\n new InfraError({\n phase: \"allocate-databases\",\n message: `Database port allocation failed: ${String(portErr)}`,\n cause: portErr,\n }),\n ),\n );\n}\n\nexport function buildServiceDescriptors(\n runtimeConfig: RuntimeConfig,\n resolvedPorts: ResolvedPorts,\n): ServiceDescriptorPlan[] {\n const descriptors: ServiceDescriptorPlan[] = [];\n\n if (runtimeConfig.host) {\n const isLocal = runtimeConfig.host.source === \"local\";\n descriptors.push({\n key: \"host\",\n source: runtimeConfig.host.source,\n url: isLocal ? `http://localhost:${resolvedPorts.host}` : runtimeConfig.host.url,\n port: isLocal ? resolvedPorts.host : undefined,\n localPath: isLocal ? runtimeConfig.host.localPath : undefined,\n });\n }\n\n if (runtimeConfig.api) {\n const isLocal = runtimeConfig.api.source === \"local\";\n descriptors.push({\n key: \"api\",\n source: runtimeConfig.api.source,\n url: isLocal ? `http://localhost:${resolvedPorts.api}` : runtimeConfig.api.url,\n port: isLocal ? resolvedPorts.api : undefined,\n localPath: isLocal ? runtimeConfig.api.localPath : undefined,\n });\n }\n\n if (runtimeConfig.auth) {\n const isLocal = runtimeConfig.auth.source === \"local\";\n descriptors.push({\n key: \"auth\",\n source: runtimeConfig.auth.source,\n url: isLocal ? `http://localhost:${resolvedPorts.auth}` : runtimeConfig.auth.url,\n port: isLocal ? resolvedPorts.auth : undefined,\n localPath: isLocal ? runtimeConfig.auth.localPath : undefined,\n });\n }\n\n if (runtimeConfig.ui) {\n const isLocal = runtimeConfig.ui.source === \"local\";\n descriptors.push({\n key: \"ui\",\n source: runtimeConfig.ui.source,\n url: isLocal ? `http://localhost:${resolvedPorts.ui}` : runtimeConfig.ui.url,\n port: isLocal ? resolvedPorts.ui : undefined,\n localPath: isLocal ? runtimeConfig.ui.localPath : undefined,\n });\n }\n\n if (runtimeConfig.plugins) {\n for (const [pluginId, pluginCfg] of Object.entries(runtimeConfig.plugins)) {\n const pluginIsLocal = pluginCfg.source === \"local\";\n const p = resolvedPorts.plugins[pluginId];\n const isAuthMirror = isAuthMirrorPluginEntry(runtimeConfig.auth, pluginId, pluginCfg);\n if (pluginIsLocal && p?.api && !isAuthMirror) {\n descriptors.push({\n key: `plugin:${pluginId}`,\n source: \"local\",\n url: `http://localhost:${p.api}`,\n port: p.api,\n localPath: pluginCfg.localPath,\n });\n }\n if (!pluginIsLocal && pluginCfg.url && !isAuthMirror) {\n descriptors.push({\n key: `plugin:${pluginId}`,\n source: \"remote\",\n url: pluginCfg.url,\n port: undefined,\n localPath: undefined,\n });\n }\n if (pluginIsLocal && p?.ui && pluginCfg.ui?.source === \"local\") {\n descriptors.push({\n key: `plugin-ui:${pluginId}`,\n source: \"local\",\n url: `http://localhost:${p.ui}`,\n port: p.ui,\n localPath: pluginCfg.ui?.localPath,\n });\n }\n }\n }\n\n return descriptors;\n}\n\nexport function buildLaunchSpec(\n runtimeConfig: RuntimeConfig,\n resolvedPorts: ResolvedPorts,\n): RuntimeLaunchSpec {\n const hostPort =\n runtimeConfig.host?.source === \"local\" ? resolvedPorts.host : runtimeConfig.host?.port;\n const corsOrigin = hostPort ? `http://localhost:${hostPort}` : `http://localhost:3000`;\n\n return {\n port: resolvedPorts.host,\n hostUrl: runtimeConfig.host?.url,\n corsOrigin,\n env: {\n ...(resolvedPorts.host ? { PORT: String(resolvedPorts.host) } : {}),\n ...(resolvedPorts.api ? { API_PORT: String(resolvedPorts.api) } : {}),\n ...(resolvedPorts.ui ? { UI_PORT: String(resolvedPorts.ui) } : {}),\n ...(resolvedPorts.auth ? { AUTH_PORT: String(resolvedPorts.auth) } : {}),\n },\n runtimeConfig,\n };\n}\n\nexport function buildEnvGenerated(\n resolvedPorts: ResolvedPorts,\n dbs: DatabasePlan[],\n redisPlans: RedisPlan[],\n): Record<string, string> {\n const env: Record<string, string> = {};\n\n if (resolvedPorts.host) {\n env.CORS_ORIGIN = `http://localhost:${resolvedPorts.host}`;\n // The host origin for plugins that derive absolute URLs from it (e.g. the\n // auth plugin's Better Auth baseURL — email links, passkey RP id).\n env.BASE_URL = `http://localhost:${resolvedPorts.host}`;\n }\n\n for (const db of dbs) {\n env[db.secret] = db.url;\n }\n for (const r of redisPlans) {\n env[r.secret] = r.url;\n }\n\n return env;\n}\n\nexport function planInfra(input: InfraInput): Effect.Effect<InfraPlan, InfraError, PortAllocator> {\n return Effect.gen(function* () {\n const cliPorts = normalizeCliPorts(input.cli);\n const wKey = workspaceKey(input.configDir);\n\n const plugins = (input.bosConfig.plugins ?? {}) as Record<\n string,\n { source: string; localPath?: string; ui?: { source: string; localPath?: string } }\n >;\n\n const {\n ports: svcPorts,\n claims,\n devPortsState,\n } = yield* allocateServices(cliPorts, plugins, input.configDir, input.bosConfig.auth, {\n host: input.bosConfig.host?.source,\n api: input.bosConfig.api?.source,\n auth: input.bosConfig.auth?.source,\n ui: input.bosConfig.ui?.source,\n });\n\n const { dbs, redisPlans } = yield* allocateDatabases(input.bosConfig);\n\n const resolvedPorts: ResolvedPorts = { ...svcPorts };\n\n // Write merged state once after all allocations succeed\n // Skip persistence for regression tests / ephemeral runs\n // devPorts pins are explicit choices only (ADR 0012 §4): this run's flags,\n // falling back to previously-persisted explicit choices — never drift.\n const previousDevPorts = loadPortState(input.configDir).devPorts ?? {};\n const devPorts = {\n host: devPortsState.host ?? previousDevPorts.host,\n api: devPortsState.api ?? previousDevPorts.api,\n auth: devPortsState.auth ?? previousDevPorts.auth,\n ui: devPortsState.ui ?? previousDevPorts.ui,\n pluginPortStart: devPortsState.pluginPortStart ?? previousDevPorts.pluginPortStart,\n };\n if (shouldPersistPortState()) {\n savePortState(input.configDir, { devPorts });\n }\n\n const hostIsLocal = input.bosConfig.host?.source === \"local\";\n const apiIsLocal = input.bosConfig.api?.source === \"local\";\n const uiIsLocal = input.bosConfig.ui?.source === \"local\";\n const authIsLocal = input.bosConfig.auth?.source === \"local\";\n const assignedRuntimeConfig: RuntimeConfig = {\n ...input.bosConfig,\n host: resolvedPorts.host\n ? {\n ...input.bosConfig.host,\n port: resolvedPorts.host,\n url: `http://localhost:${resolvedPorts.host}`,\n remoteUrl: !hostIsLocal\n ? (input.bosConfig.host.remoteUrl ?? input.bosConfig.host.url)\n : undefined,\n }\n : input.bosConfig.host,\n api:\n apiIsLocal && resolvedPorts.api\n ? {\n ...input.bosConfig.api,\n port: resolvedPorts.api,\n url: `http://localhost:${resolvedPorts.api}`,\n }\n : input.bosConfig.api,\n ui:\n uiIsLocal && resolvedPorts.ui\n ? {\n ...input.bosConfig.ui,\n port: resolvedPorts.ui,\n url: `http://localhost:${resolvedPorts.ui}`,\n ssrUrl: undefined,\n }\n : input.bosConfig.ui,\n auth:\n authIsLocal && resolvedPorts.auth && input.bosConfig.auth\n ? {\n ...input.bosConfig.auth,\n port: resolvedPorts.auth,\n url: `http://localhost:${resolvedPorts.auth}`,\n }\n : input.bosConfig.auth,\n plugins: input.bosConfig.plugins\n ? Object.fromEntries(\n Object.entries(input.bosConfig.plugins).map(([id, p]) => {\n const isAuthMirror = isAuthMirrorPluginEntry(input.bosConfig.auth, id, p);\n const pluginPort = resolvedPorts.plugins[id];\n const patchedUi = (() => {\n if (p.ui?.source !== \"local\" || !p.ui?.localPath || !pluginPort?.ui) return p.ui;\n return {\n ...p.ui,\n port: pluginPort.ui,\n url: `http://localhost:${pluginPort.ui}`,\n ssrUrl: undefined,\n };\n })();\n if (isAuthMirror) {\n return [id, { ...p, ui: patchedUi }];\n }\n if (p.source === \"local\" && pluginPort?.api) {\n return [\n id,\n {\n ...p,\n port: pluginPort.api,\n url: `http://localhost:${pluginPort.api}`,\n ui: patchedUi,\n },\n ];\n }\n return [id, p];\n }),\n )\n : undefined,\n };\n\n const serviceDescriptors = buildServiceDescriptors(assignedRuntimeConfig, resolvedPorts);\n\n const launch = buildLaunchSpec(input.bosConfig, resolvedPorts);\n const envGenerated = buildEnvGenerated(resolvedPorts, dbs, redisPlans);\n\n const packages = serviceDescriptors.map((d) => d.key);\n const descriptionMap = new Map(serviceDescriptors.map((d) => [d.key, d]));\n const description = buildDescription(descriptionMap);\n\n const orchestrator = {\n packages,\n env: {},\n description,\n port: resolvedPorts.host,\n interactive: input.cli.interactive,\n };\n\n return {\n workspaceKey: wKey,\n cliPorts,\n resolvedPorts,\n runtimeConfig: assignedRuntimeConfig,\n launch,\n description,\n serviceDescriptors: new Map(serviceDescriptors.map((d) => [d.key, d])),\n envGenerated,\n claims,\n orchestrator,\n };\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"planner.mjs","names":[],"sources":["../../src/infra/planner.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { resolve } from \"node:path\";\nimport { Clock, Effect } from \"effect\";\nimport { PortAllocator, type PortBlockEntry } from \"../app\";\nimport {\n buildConventionalDatabases,\n buildConventionalRedis,\n getSecretGroups,\n loadPortState,\n savePortState,\n} from \"../cli/infra\";\nimport {\n type AuthSlotShape,\n buildDescription,\n isAuthMirrorPluginEntry,\n} from \"../service-descriptor\";\nimport type { RuntimeConfig } from \"../types\";\nimport { shouldPersistPortState } from \"./materializer\";\nimport { ownerOfPort } from \"./port-ownership\";\nimport type {\n ClaimRecord,\n CliPorts,\n DatabasePlan,\n InfraInput,\n InfraPlan,\n RedisPlan,\n ResolvedPorts,\n RuntimeLaunchSpec,\n ServiceDescriptorPlan,\n} from \"./types\";\nimport { InfraError } from \"./types\";\n\nconst DEFAULT_HOST_PORT = 3000;\n\nconst POSTGRES_USER = \"everythingdev\";\nconst POSTGRES_PASSWORD = \"everythingdev\";\n\nexport function workspaceKey(configDir: string): string {\n const hash = createHash(\"sha256\").update(resolve(configDir)).digest(\"hex\");\n return hash.slice(0, 12);\n}\n\nfunction normalizeCliPorts(input: InfraInput[\"cli\"]): CliPorts {\n return {\n host: input.port,\n api: input.apiPort,\n auth: input.authPort,\n ui: input.uiPort,\n pluginsStart: input.pluginPortStart,\n plugins: input.plugins,\n };\n}\n\ninterface AllocateServicesResult {\n ports: ResolvedPorts;\n claims: ClaimRecord[];\n devPortsState: {\n host?: number;\n api?: number;\n auth?: number;\n ui?: number;\n pluginPortStart?: number;\n };\n}\n\nexport interface ServiceSources {\n host?: \"local\" | \"remote\";\n api?: \"local\" | \"remote\";\n auth?: \"local\" | \"remote\";\n ui?: \"local\" | \"remote\";\n}\n\nconst PLUGIN_START_OFFSET = 10;\nconst BLOCK_STEP = 100;\n\nfunction allocateServices(\n cliPorts: CliPorts,\n plugins: Record<\n string,\n { source: string; localPath?: string; ui?: { source: string; localPath?: string } }\n >,\n configDir: string,\n auth?: AuthSlotShape,\n sources?: ServiceSources,\n): Effect.Effect<AllocateServicesResult, InfraError, PortAllocator> {\n return Effect.gen(function* () {\n const wKey = workspaceKey(configDir);\n const persisted = loadPortState(configDir).devPorts;\n const allocator = yield* PortAllocator;\n\n const base = cliPorts.host ?? persisted?.host ?? DEFAULT_HOST_PORT;\n const pluginStartPreferred =\n cliPorts.pluginsStart ?? persisted?.pluginPortStart ?? base + PLUGIN_START_OFFSET;\n const pluginStartPinned =\n cliPorts.pluginsStart !== undefined || persisted?.pluginPortStart !== undefined;\n\n const entries: PortBlockEntry[] = [];\n const addEntry = (\n key: string,\n flag: number | undefined,\n persistedValue: number | undefined,\n derived: number,\n ) => {\n if (flag !== undefined) {\n entries.push({ key, preferred: flag, pinned: true });\n } else if (persistedValue !== undefined) {\n entries.push({ key, preferred: persistedValue, pinned: true });\n } else {\n entries.push({ key, preferred: derived, pinned: false });\n }\n };\n\n // Remote-source services spawn nothing locally (ADR 0009 start stack:\n // remotes load over MF from their published origins) — no port is\n // allocated for them. The host is the exception: even when loaded as a\n // remote module, runServer binds its own port.\n addEntry(\"host\", cliPorts.host, undefined, base);\n if (sources?.api !== \"remote\") {\n addEntry(\"api\", cliPorts.api, persisted?.api, base + 1);\n }\n if (sources?.auth !== \"remote\") {\n addEntry(\"auth\", cliPorts.auth, persisted?.auth, base + 2);\n }\n if (sources?.ui !== \"remote\") {\n addEntry(\"ui\", cliPorts.ui, persisted?.ui, base + 3);\n }\n\n const pluginKeys = Object.keys(plugins).sort();\n const isAuthMirrorFor = (\n pluginId: string,\n pluginCfg: { source: string; localPath?: string } | undefined,\n ) => pluginCfg !== undefined && isAuthMirrorPluginEntry(auth, pluginId, pluginCfg);\n\n let pluginSlot = 0;\n for (const pluginId of pluginKeys) {\n const pluginCfg = plugins[pluginId];\n const pluginIsLocal = pluginCfg?.source === \"local\";\n const slotBase = pluginStartPinned ? pluginStartPreferred : base + PLUGIN_START_OFFSET;\n // The auth mirror's backend is owned by the `auth` app slot — no api\n // port. Its ui surface is still real: without a port the runtime config\n // advertises an empty ui.url and the browser can never load the remote\n // (the /login page never renders).\n if (!isAuthMirrorFor(pluginId, pluginCfg) && pluginIsLocal) {\n addEntry(\n `plugin:${pluginId}`,\n cliPorts.plugins?.[pluginId]?.api,\n undefined,\n slotBase + pluginSlot,\n );\n pluginSlot += 1;\n }\n if (\n pluginCfg?.source === \"local\" &&\n pluginCfg?.localPath &&\n pluginCfg?.ui?.source === \"local\"\n ) {\n addEntry(\n `plugin-ui:${pluginId}`,\n cliPorts.plugins?.[pluginId]?.ui,\n undefined,\n slotBase + pluginSlot,\n );\n pluginSlot += 1;\n }\n }\n\n const allocation = yield* allocator.acquireBlock({ base, step: BLOCK_STEP, entries });\n\n if (allocation.base !== base) {\n yield* Effect.logError(\n `[Dev] Preferred port block starting at ${base} is occupied — using ${allocation.base} (this run only; restarts will retry ${base})`,\n );\n for (const conflict of allocation.conflicts.slice(0, 6)) {\n if (conflict.claimed) {\n yield* Effect.logError(\n `[Dev] port ${conflict.port} (${conflict.key}) — live bos session (registry claim)`,\n );\n } else {\n const owner = yield* ownerOfPort(conflict.port);\n yield* Effect.logError(\n `[Dev] port ${conflict.port} (${conflict.key}) — ${\n owner ? `pid ${owner.pid} (${owner.command})` : \"foreign holder (lsof unavailable)\"\n }`,\n );\n }\n }\n }\n\n const pluginApiPorts: Record<string, number> = {};\n const pluginUiPorts: Record<string, number> = {};\n for (const pluginId of pluginKeys) {\n const api = allocation.ports[`plugin:${pluginId}`];\n if (api !== undefined) pluginApiPorts[pluginId] = api;\n const ui = allocation.ports[`plugin-ui:${pluginId}`];\n if (ui !== undefined) pluginUiPorts[pluginId] = ui;\n }\n\n const resolved: ResolvedPorts = {\n host: allocation.ports.host,\n api: allocation.ports.api,\n auth: allocation.ports.auth,\n ui: allocation.ports.ui,\n plugins: Object.fromEntries(\n pluginKeys.map((k) => [k, { api: pluginApiPorts[k], ui: pluginUiPorts[k] }]),\n ),\n };\n\n const devPortsState = {\n host: cliPorts.host,\n api: cliPorts.api,\n auth: cliPorts.auth,\n ui: cliPorts.ui,\n pluginPortStart: cliPorts.pluginsStart,\n };\n\n const claimPorts: Record<string, number> = {};\n for (const [key, port] of Object.entries(allocation.ports)) {\n claimPorts[key] = port;\n }\n\n const claim: ClaimRecord = {\n resourceKey: `workspace:${wKey}`,\n pid: process.pid,\n configDir,\n ports: claimPorts,\n startedAt: yield* Clock.currentTimeMillis,\n };\n\n return { ports: resolved, claims: [claim], devPortsState };\n }).pipe(\n Effect.mapError(\n (portErr) =>\n new InfraError({\n phase: \"allocate-services\",\n message: `Port allocation failed: ${String(portErr)}`,\n cause: portErr,\n }),\n ),\n );\n}\n\nfunction allocateDatabases(runtimeConfig: RuntimeConfig): Effect.Effect<\n {\n dbs: DatabasePlan[];\n redisPlans: RedisPlan[];\n },\n InfraError,\n PortAllocator\n> {\n return Effect.gen(function* () {\n const groups = getSecretGroups(runtimeConfig);\n const allSecrets = groups.flatMap((group) => group.secrets);\n const allocator = yield* PortAllocator;\n\n const conventionalDatabases = buildConventionalDatabases(allSecrets);\n const conventionalRedis = buildConventionalRedis(allSecrets);\n\n const dbs: DatabasePlan[] = [];\n const allocatedByDesired = new Map<number, number>();\n for (const db of conventionalDatabases) {\n let port: number;\n if (allocatedByDesired.has(db.port)) {\n port = allocatedByDesired.get(db.port)!;\n } else {\n port = yield* allocator.pickAvailable(db.port);\n allocatedByDesired.set(db.port, port);\n }\n dbs.push({\n secret: db.secret,\n slug: db.slug,\n port,\n dbName: db.databaseName,\n url: `postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:${port}/${db.databaseName}`,\n });\n }\n\n const redisPlans: RedisPlan[] = [];\n for (const r of conventionalRedis) {\n const port = yield* allocator.pickAvailable(r.port);\n redisPlans.push({\n secret: r.secret,\n slug: r.slug,\n port,\n url: `redis://localhost:${port}`,\n });\n }\n\n return { dbs, redisPlans };\n }).pipe(\n Effect.mapError(\n (portErr) =>\n new InfraError({\n phase: \"allocate-databases\",\n message: `Database port allocation failed: ${String(portErr)}`,\n cause: portErr,\n }),\n ),\n );\n}\n\nexport function buildServiceDescriptors(\n runtimeConfig: RuntimeConfig,\n resolvedPorts: ResolvedPorts,\n): ServiceDescriptorPlan[] {\n const descriptors: ServiceDescriptorPlan[] = [];\n\n if (runtimeConfig.host) {\n const isLocal = runtimeConfig.host.source === \"local\";\n descriptors.push({\n key: \"host\",\n source: runtimeConfig.host.source,\n url: isLocal ? `http://localhost:${resolvedPorts.host}` : runtimeConfig.host.url,\n port: isLocal ? resolvedPorts.host : undefined,\n localPath: isLocal ? runtimeConfig.host.localPath : undefined,\n });\n }\n\n if (runtimeConfig.api) {\n const isLocal = runtimeConfig.api.source === \"local\";\n descriptors.push({\n key: \"api\",\n source: runtimeConfig.api.source,\n url: isLocal ? `http://localhost:${resolvedPorts.api}` : runtimeConfig.api.url,\n port: isLocal ? resolvedPorts.api : undefined,\n localPath: isLocal ? runtimeConfig.api.localPath : undefined,\n });\n }\n\n if (runtimeConfig.auth) {\n const isLocal = runtimeConfig.auth.source === \"local\";\n descriptors.push({\n key: \"auth\",\n source: runtimeConfig.auth.source,\n url: isLocal ? `http://localhost:${resolvedPorts.auth}` : runtimeConfig.auth.url,\n port: isLocal ? resolvedPorts.auth : undefined,\n localPath: isLocal ? runtimeConfig.auth.localPath : undefined,\n });\n }\n\n if (runtimeConfig.ui) {\n const isLocal = runtimeConfig.ui.source === \"local\";\n descriptors.push({\n key: \"ui\",\n source: runtimeConfig.ui.source,\n url: isLocal ? `http://localhost:${resolvedPorts.ui}` : runtimeConfig.ui.url,\n port: isLocal ? resolvedPorts.ui : undefined,\n localPath: isLocal ? runtimeConfig.ui.localPath : undefined,\n });\n }\n\n if (runtimeConfig.plugins) {\n for (const [pluginId, pluginCfg] of Object.entries(runtimeConfig.plugins)) {\n const pluginIsLocal = pluginCfg.source === \"local\";\n const p = resolvedPorts.plugins[pluginId];\n const isAuthMirror = isAuthMirrorPluginEntry(runtimeConfig.auth, pluginId, pluginCfg);\n if (pluginIsLocal && p?.api && !isAuthMirror) {\n descriptors.push({\n key: `plugin:${pluginId}`,\n source: \"local\",\n url: `http://localhost:${p.api}`,\n port: p.api,\n localPath: pluginCfg.localPath,\n });\n }\n if (!pluginIsLocal && pluginCfg.url && !isAuthMirror) {\n descriptors.push({\n key: `plugin:${pluginId}`,\n source: \"remote\",\n url: pluginCfg.url,\n port: undefined,\n localPath: undefined,\n });\n }\n if (pluginIsLocal && p?.ui && pluginCfg.ui?.source === \"local\") {\n descriptors.push({\n key: `plugin-ui:${pluginId}`,\n source: \"local\",\n url: `http://localhost:${p.ui}`,\n port: p.ui,\n localPath: pluginCfg.ui?.localPath,\n });\n }\n }\n }\n\n return descriptors;\n}\n\nexport function buildLaunchSpec(\n runtimeConfig: RuntimeConfig,\n resolvedPorts: ResolvedPorts,\n): RuntimeLaunchSpec {\n const hostPort =\n runtimeConfig.host?.source === \"local\" ? resolvedPorts.host : runtimeConfig.host?.port;\n const corsOrigin = hostPort ? `http://localhost:${hostPort}` : `http://localhost:3000`;\n\n return {\n port: resolvedPorts.host,\n hostUrl: runtimeConfig.host?.url,\n corsOrigin,\n env: {\n ...(resolvedPorts.host ? { PORT: String(resolvedPorts.host) } : {}),\n ...(resolvedPorts.api ? { API_PORT: String(resolvedPorts.api) } : {}),\n ...(resolvedPorts.ui ? { UI_PORT: String(resolvedPorts.ui) } : {}),\n ...(resolvedPorts.auth ? { AUTH_PORT: String(resolvedPorts.auth) } : {}),\n },\n runtimeConfig,\n };\n}\n\nexport function buildEnvGenerated(\n resolvedPorts: ResolvedPorts,\n dbs: DatabasePlan[],\n redisPlans: RedisPlan[],\n): Record<string, string> {\n const env: Record<string, string> = {};\n\n if (resolvedPorts.host) {\n env.CORS_ORIGIN = `http://localhost:${resolvedPorts.host}`;\n // The host origin for plugins that derive absolute URLs from it (e.g. the\n // auth plugin's Better Auth baseURL — email links, passkey RP id).\n env.BASE_URL = `http://localhost:${resolvedPorts.host}`;\n }\n\n for (const db of dbs) {\n env[db.secret] = db.url;\n }\n for (const r of redisPlans) {\n env[r.secret] = r.url;\n }\n\n return env;\n}\n\nexport function planInfra(input: InfraInput): Effect.Effect<InfraPlan, InfraError, PortAllocator> {\n return Effect.gen(function* () {\n const cliPorts = normalizeCliPorts(input.cli);\n const wKey = workspaceKey(input.configDir);\n\n const plugins = (input.bosConfig.plugins ?? {}) as Record<\n string,\n { source: string; localPath?: string; ui?: { source: string; localPath?: string } }\n >;\n\n const {\n ports: svcPorts,\n claims,\n devPortsState,\n } = yield* allocateServices(cliPorts, plugins, input.configDir, input.bosConfig.auth, {\n host: input.bosConfig.host?.source,\n api: input.bosConfig.api?.source,\n auth: input.bosConfig.auth?.source,\n ui: input.bosConfig.ui?.source,\n });\n\n // DB/Redis port probes only matter for services that will actually spawn\n // locally — their generated URLs are consumed exclusively by local spawn\n // env (composeSpawnEnv). When every source is remote (start mode, ADR\n // 0009), nothing binds those ports and the probes are wasted work in the\n // container boot path — and a probe against an occupied port (the staged\n // dist servers) can drift the whole plan (the #363 failure class).\n const hasLocalServices =\n input.bosConfig.host?.source === \"local\" ||\n input.bosConfig.api?.source === \"local\" ||\n input.bosConfig.auth?.source === \"local\" ||\n input.bosConfig.ui?.source === \"local\" ||\n Object.values(plugins).some((p) => p?.source === \"local\" || p?.ui?.source === \"local\");\n\n const { dbs, redisPlans } = hasLocalServices\n ? yield* allocateDatabases(input.bosConfig)\n : { dbs: [], redisPlans: [] };\n\n const resolvedPorts: ResolvedPorts = { ...svcPorts };\n\n // Write merged state once after all allocations succeed\n // Skip persistence for regression tests / ephemeral runs\n // devPorts pins are explicit choices only (ADR 0012 §4): this run's flags,\n // falling back to previously-persisted explicit choices — never drift.\n const previousDevPorts = loadPortState(input.configDir).devPorts ?? {};\n const devPorts = {\n host: devPortsState.host ?? previousDevPorts.host,\n api: devPortsState.api ?? previousDevPorts.api,\n auth: devPortsState.auth ?? previousDevPorts.auth,\n ui: devPortsState.ui ?? previousDevPorts.ui,\n pluginPortStart: devPortsState.pluginPortStart ?? previousDevPorts.pluginPortStart,\n };\n if (shouldPersistPortState()) {\n savePortState(input.configDir, { devPorts });\n }\n\n const hostIsLocal = input.bosConfig.host?.source === \"local\";\n const apiIsLocal = input.bosConfig.api?.source === \"local\";\n const uiIsLocal = input.bosConfig.ui?.source === \"local\";\n const authIsLocal = input.bosConfig.auth?.source === \"local\";\n const assignedRuntimeConfig: RuntimeConfig = {\n ...input.bosConfig,\n host: resolvedPorts.host\n ? {\n ...input.bosConfig.host,\n port: resolvedPorts.host,\n url: `http://localhost:${resolvedPorts.host}`,\n remoteUrl: !hostIsLocal\n ? (input.bosConfig.host.remoteUrl ?? input.bosConfig.host.url)\n : undefined,\n }\n : input.bosConfig.host,\n api:\n apiIsLocal && resolvedPorts.api\n ? {\n ...input.bosConfig.api,\n port: resolvedPorts.api,\n url: `http://localhost:${resolvedPorts.api}`,\n }\n : input.bosConfig.api,\n ui:\n uiIsLocal && resolvedPorts.ui\n ? {\n ...input.bosConfig.ui,\n port: resolvedPorts.ui,\n url: `http://localhost:${resolvedPorts.ui}`,\n ssrUrl: undefined,\n }\n : input.bosConfig.ui,\n auth:\n authIsLocal && resolvedPorts.auth && input.bosConfig.auth\n ? {\n ...input.bosConfig.auth,\n port: resolvedPorts.auth,\n url: `http://localhost:${resolvedPorts.auth}`,\n }\n : input.bosConfig.auth,\n plugins: input.bosConfig.plugins\n ? Object.fromEntries(\n Object.entries(input.bosConfig.plugins).map(([id, p]) => {\n const isAuthMirror = isAuthMirrorPluginEntry(input.bosConfig.auth, id, p);\n const pluginPort = resolvedPorts.plugins[id];\n const patchedUi = (() => {\n if (p.ui?.source !== \"local\" || !p.ui?.localPath || !pluginPort?.ui) return p.ui;\n return {\n ...p.ui,\n port: pluginPort.ui,\n url: `http://localhost:${pluginPort.ui}`,\n ssrUrl: undefined,\n };\n })();\n if (isAuthMirror) {\n return [id, { ...p, ui: patchedUi }];\n }\n if (p.source === \"local\" && pluginPort?.api) {\n return [\n id,\n {\n ...p,\n port: pluginPort.api,\n url: `http://localhost:${pluginPort.api}`,\n ui: patchedUi,\n },\n ];\n }\n return [id, p];\n }),\n )\n : undefined,\n };\n\n const serviceDescriptors = buildServiceDescriptors(assignedRuntimeConfig, resolvedPorts);\n\n const launch = buildLaunchSpec(input.bosConfig, resolvedPorts);\n const envGenerated = buildEnvGenerated(resolvedPorts, dbs, redisPlans);\n\n const packages = serviceDescriptors.map((d) => d.key);\n const descriptionMap = new Map(serviceDescriptors.map((d) => [d.key, d]));\n const description = buildDescription(descriptionMap);\n\n const orchestrator = {\n packages,\n env: {},\n description,\n port: resolvedPorts.host,\n interactive: input.cli.interactive,\n };\n\n return {\n workspaceKey: wKey,\n cliPorts,\n resolvedPorts,\n runtimeConfig: assignedRuntimeConfig,\n launch,\n description,\n serviceDescriptors: new Map(serviceDescriptors.map((d) => [d.key, d])),\n envGenerated,\n claims,\n orchestrator,\n };\n });\n}\n"],"mappings":"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"}
|
package/dist/orchestrator.cjs
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
+
const require_http_client = require('./http-client.cjs');
|
|
1
2
|
const require_service_descriptor = require('./service-descriptor.cjs');
|
|
2
3
|
const require_dev_log_pipeline = require('./dev-log-pipeline.cjs');
|
|
3
|
-
const
|
|
4
|
+
const require_federation = require('./federation.cjs');
|
|
4
5
|
const require_project_env = require('./env/project-env.cjs');
|
|
5
6
|
let effect = require("effect");
|
|
6
7
|
let node_child_process = require("node:child_process");
|
|
7
8
|
let node_stream = require("node:stream");
|
|
8
9
|
|
|
9
10
|
//#region src/orchestrator.ts
|
|
10
|
-
const runFetch = (url, init) => fetch(url, init);
|
|
11
11
|
process.on("unhandledRejection", (reason) => {
|
|
12
12
|
console.error("[Orchestrator] Unhandled rejection:", reason);
|
|
13
13
|
});
|
|
@@ -32,7 +32,7 @@ const encodeRuntimeConfig = (runtimeConfig) => effect.Schema.encodeUnknownEffect
|
|
|
32
32
|
const probeHttpOk = (url, timeoutMs = 400) => effect.Effect.tryPromise({
|
|
33
33
|
try: async () => {
|
|
34
34
|
try {
|
|
35
|
-
return (await
|
|
35
|
+
return (await fetch(url, { signal: AbortSignal.timeout(timeoutMs) })).ok;
|
|
36
36
|
} catch {
|
|
37
37
|
return false;
|
|
38
38
|
}
|
|
@@ -40,6 +40,14 @@ const probeHttpOk = (url, timeoutMs = 400) => effect.Effect.tryPromise({
|
|
|
40
40
|
catch: () => false
|
|
41
41
|
});
|
|
42
42
|
const LOCAL_PROBE_DEADLINE_MS = 9e4;
|
|
43
|
+
/** Remote-host boot budgets: every stage of the CDN-only boot is deadline-
|
|
44
|
+
* bounded so a hung connection or a wedged module load fails loud with the
|
|
45
|
+
* URL and stage — long before the smoke's 240s probe deadline turns the
|
|
46
|
+
* silence into a mystery. */
|
|
47
|
+
const MANIFEST_FETCH_DEADLINE = "10 seconds";
|
|
48
|
+
const LOAD_REMOTE_DEADLINE = "60 seconds";
|
|
49
|
+
const SERVER_READY_DEADLINE = "120 seconds";
|
|
50
|
+
const REMOTE_HOST_BOOT_DEADLINE = "180 seconds";
|
|
43
51
|
const LOCAL_PROBE_INTERVAL_MS = 200;
|
|
44
52
|
const cleanExitSignals = {
|
|
45
53
|
SIGTERM: true,
|
|
@@ -130,37 +138,12 @@ const spawnRemoteHost = (descriptor, callbacks) => effect.Effect.gen(function* (
|
|
|
130
138
|
callbacks.onLog(descriptor.key, `Remote: ${remoteUrl}`);
|
|
131
139
|
const restoreConsole = patchConsole(descriptor.key, callbacks);
|
|
132
140
|
callbacks.onLog(descriptor.key, "Loading Module Federation runtime...");
|
|
133
|
-
const mfRuntime = yield* effect.Effect.tryPromise({
|
|
134
|
-
try: () => import("@module-federation/enhanced/runtime"),
|
|
135
|
-
catch: (cause) => new OrchestratorError({
|
|
136
|
-
operation: "load module federation runtime",
|
|
137
|
-
detail: cause instanceof Error ? cause.message : String(cause),
|
|
138
|
-
cause
|
|
139
|
-
})
|
|
140
|
-
});
|
|
141
|
-
const mfCore = yield* effect.Effect.tryPromise({
|
|
142
|
-
try: () => import("@module-federation/runtime-core"),
|
|
143
|
-
catch: (cause) => new OrchestratorError({
|
|
144
|
-
operation: "load module federation core",
|
|
145
|
-
detail: cause instanceof Error ? cause.message : String(cause),
|
|
146
|
-
cause
|
|
147
|
-
})
|
|
148
|
-
});
|
|
149
|
-
let mf = mfRuntime.getInstance();
|
|
150
|
-
if (!mf) {
|
|
151
|
-
mf = mfRuntime.createInstance({
|
|
152
|
-
name: "cli-host",
|
|
153
|
-
remotes: []
|
|
154
|
-
});
|
|
155
|
-
mfCore.setGlobalFederationInstance(mf);
|
|
156
|
-
}
|
|
157
|
-
require_mf.patchManifestFetchForSsrPublicPath(mf);
|
|
158
141
|
const manifestUrl = `${remoteUrl.replace(/\/remoteEntry\.js$/, "").replace(/\/mf-manifest\.json$/, "").replace(/\/$/, "")}/mf-manifest.json`;
|
|
159
142
|
const entryUrl = yield* effect.Effect.tryPromise({
|
|
160
143
|
try: async () => {
|
|
161
144
|
let res;
|
|
162
145
|
try {
|
|
163
|
-
res = await
|
|
146
|
+
res = await require_http_client.fetchRaw(manifestUrl, void 0, MANIFEST_FETCH_DEADLINE);
|
|
164
147
|
} catch (e) {
|
|
165
148
|
throw new OrchestratorError({
|
|
166
149
|
operation: "fetch host manifest",
|
|
@@ -184,19 +167,25 @@ const spawnRemoteHost = (descriptor, callbacks) => effect.Effect.gen(function* (
|
|
|
184
167
|
detail: `${manifestUrl} — ${String(cause)}`
|
|
185
168
|
})
|
|
186
169
|
});
|
|
187
|
-
|
|
170
|
+
yield* effect.Effect.promise(() => require_federation.registerRemote({
|
|
188
171
|
name: "host",
|
|
189
172
|
entry: entryUrl
|
|
190
|
-
}
|
|
173
|
+
}));
|
|
191
174
|
callbacks.onLog(descriptor.key, `Loading host from ${entryUrl}...`);
|
|
192
175
|
const hostModule = yield* effect.Effect.tryPromise({
|
|
193
|
-
try: () =>
|
|
176
|
+
try: () => require_federation.loadRemoteModule("host/Server"),
|
|
194
177
|
catch: (cause) => new OrchestratorError({
|
|
195
178
|
operation: "load host module",
|
|
196
179
|
detail: cause instanceof Error ? cause.message : String(cause),
|
|
197
180
|
cause
|
|
198
181
|
})
|
|
199
|
-
})
|
|
182
|
+
}).pipe(effect.Effect.timeoutOrElse({
|
|
183
|
+
duration: LOAD_REMOTE_DEADLINE,
|
|
184
|
+
orElse: () => effect.Effect.fail(new OrchestratorError({
|
|
185
|
+
operation: "load host module",
|
|
186
|
+
detail: `timed out after ${LOAD_REMOTE_DEADLINE} — the module (or its shared dependencies) did not finish loading from ${entryUrl}`
|
|
187
|
+
}))
|
|
188
|
+
}));
|
|
200
189
|
if (!hostModule?.runServer) return yield* new HostModuleInvalid();
|
|
201
190
|
callbacks.onLog(descriptor.key, "Starting server...");
|
|
202
191
|
const hostPort = runtimeConfig.host?.port;
|
|
@@ -213,7 +202,16 @@ const spawnRemoteHost = (descriptor, callbacks) => effect.Effect.gen(function* (
|
|
|
213
202
|
detail: cause instanceof Error ? cause.message : String(cause),
|
|
214
203
|
cause
|
|
215
204
|
})
|
|
216
|
-
})
|
|
205
|
+
}).pipe(effect.Effect.timeoutOrElse({
|
|
206
|
+
duration: SERVER_READY_DEADLINE,
|
|
207
|
+
orElse: () => effect.Effect.gen(function* () {
|
|
208
|
+
yield* effect.Effect.exit(effect.Effect.promise(() => serverHandle.shutdown()));
|
|
209
|
+
return yield* new OrchestratorError({
|
|
210
|
+
operation: "start server",
|
|
211
|
+
detail: `server did not become ready within ${SERVER_READY_DEADLINE}`
|
|
212
|
+
});
|
|
213
|
+
})
|
|
214
|
+
}));
|
|
217
215
|
callbacks.onStatus(descriptor.key, "ready");
|
|
218
216
|
return {
|
|
219
217
|
name: descriptor.key,
|
|
@@ -494,7 +492,13 @@ const makeDevProcess = (pkg, callbacks, portOverride) => effect.Effect.gen(funct
|
|
|
494
492
|
waitForExit: effect.Effect.never
|
|
495
493
|
};
|
|
496
494
|
}
|
|
497
|
-
if (pkg === "host" && descriptor.source === "remote") return yield* spawnRemoteHost(descriptor, callbacks)
|
|
495
|
+
if (pkg === "host" && descriptor.source === "remote") return yield* spawnRemoteHost(descriptor, callbacks).pipe(effect.Effect.timeoutOrElse({
|
|
496
|
+
duration: REMOTE_HOST_BOOT_DEADLINE,
|
|
497
|
+
orElse: () => effect.Effect.fail(new OrchestratorError({
|
|
498
|
+
operation: "boot remote host",
|
|
499
|
+
detail: `remote host boot exceeded the ${REMOTE_HOST_BOOT_DEADLINE} overall deadline`
|
|
500
|
+
}))
|
|
501
|
+
}));
|
|
498
502
|
if (descriptor.source === "remote" || !descriptor.localPath) return yield* spawnRemoteProbe(pkg, descriptor, callbacks);
|
|
499
503
|
const resolvedDescriptor = portOverride ? {
|
|
500
504
|
...descriptor,
|