everything-dev
Version:
A consolidated product package for building Module Federation apps with oRPC APIs.
1 lines • 75.1 kB
Source Map (JSON)
{"version":3,"file":"config.mjs","names":[],"sources":["../src/config.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, isAbsolute, join, resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { Effect, Schema } from \"effect\";\nimport { getProcessEnv } from \"./env/process-env\";\n\nconst warnOutsideEffect = (...args: unknown[]): void => {\n console.warn(...args);\n};\n\nimport { sanitizeContainerName } from \"every-plugin/ui/manifest/contract\";\nimport { fetchApiPluginManifest } from \"./api-contract\";\nimport { manifestPluginsToNodes } from \"./dag\";\nimport { resolveApp, toConfigInput } from \"./descriptor/resolve\";\nimport { type AppDescriptor, AppDescriptorSchema } from \"./descriptor/schema\";\nimport { fetchBosConfigFromFastKv } from \"./fastkv\";\nimport { fetchJsonOrNull } from \"./http-client\";\nimport {\n type BosEnv,\n bosConfigMerger,\n isPlainObject,\n type ResolvedConfigMeta,\n rebuildOrderedConfig,\n resolveExtendsRef,\n} from \"./merge\";\nimport { getNetworkIdForAccount } from \"./network\";\nimport type {\n BosConfig,\n BosConfigInput,\n BosPluginRef,\n JsonObject,\n JsonValue,\n PluginEntryValue,\n RuntimeConfig,\n RuntimePluginConfig,\n} from \"./types\";\nimport { BosConfigSchema } from \"./types\";\nimport { type ResolvedSlotVersion, resolveSlotVersion } from \"./version-manifest-resolve\";\n\nconst LOCAL_PREFIX = \"local:\";\nconst DEFAULT_HOST_PORT = 3000;\nconst RESOLVED_CONFIG_FILENAME = \"bos.resolved-config.json\";\n\nexport const MISSING_CONFIG_MESSAGE = \"No config found (bos.app.ts or bos.config.json)\";\n\nexport const DEV_OVERLAY_FILENAME = \"bos.dev.ts\";\n\ntype RuntimeOverrideTarget = \"ui\" | \"api\" | \"plugins\" | `plugins.${string}`;\n\ninterface RuntimeTarget {\n source: \"local\" | \"remote\";\n url: string;\n localPath?: string;\n port?: number;\n}\n\ninterface ConfigWarningCapture {\n sink: string[];\n previous: ConfigWarningCapture | undefined;\n}\n\nconst warningCapture = new AsyncLocalStorage<ConfigWarningCapture | undefined>();\n\n/**\n * @internal — runs `fn` with config warnings captured into `sink` instead of\n * the console. Plumbing for the resolution session; not part of the public\n * config surface.\n */\nexport function runWithConfigWarningSink<T>(sink: string[], fn: () => T): T {\n return warningCapture.run({ sink, previous: warningCapture.getStore() }, fn);\n}\n\nfunction emitConfigWarning(message: string): void {\n const capture = warningCapture.getStore();\n if (capture) {\n capture.sink.push(message);\n } else {\n console.warn(message);\n }\n}\n\nconst configPathCache = new Map<string, string | null>();\n\n/**\n * @internal — clears the findConfigPath memo. Plumbing for tests and the\n * resolution session; not part of the public config surface.\n */\nexport function resetConfigPathCache(): void {\n configPathCache.clear();\n}\n\n/**\n * Reads the local authored config without resolving the extends chain or\n * touching the network — the build-surface factories (generated rsbuild\n * configs) consume it for their APP_NAME/APP_ACCOUNT defines.\n */\nexport async function readAuthoredConfigInput(cwd?: string): Promise<BosConfigInput | null> {\n const configPath = findConfigPath(cwd);\n if (!configPath || configPath.startsWith(\"bos://\")) return null;\n return readConfigInput(configPath, dirname(configPath));\n}\n\n/**\n * The authored config entry inside exactly `dir` — no upward walk. Unlike\n * `findConfigPath` this never escapes the given directory, for write targets\n * and nested-local-path resolution where a parent's config must not be\n * picked up. Prefers the authored `bos.app.ts` descriptor (the canonical\n * form) over a legacy `bos.config.json`.\n */\nexport function localConfigEntryPath(dir: string): string | null {\n const appPath = join(dir, \"bos.app.ts\");\n if (existsSync(appPath)) return appPath;\n const jsonPath = join(dir, \"bos.config.json\");\n return existsSync(jsonPath) ? jsonPath : null;\n}\n\n/** `localConfigEntryPath` + the form-aware read (`BosConfigInput`). */\nexport async function readLocalAuthoredConfigInput(dir: string): Promise<BosConfigInput | null> {\n const entry = localConfigEntryPath(dir);\n if (!entry) return null;\n return readConfigInput(entry, dirname(entry));\n}\n\n/**\n * The authored `bos.app.ts` descriptor is the canonical form — when both\n * forms coexist (e.g. a generated `bos.config.json` write-back beside the\n * authored descriptor), the authored file wins. JSON-form-only children are\n * unaffected: with no `bos.app.ts`, the JSON file is the entry.\n */\nexport function findConfigPath(cwd?: string): string | null {\n const cacheKey = resolve(cwd ?? process.cwd());\n const cached = configPathCache.get(cacheKey);\n if (cached !== undefined) return cached;\n\n let dir = cacheKey;\n while (true) {\n const appPath = join(dir, \"bos.app.ts\");\n if (existsSync(appPath)) {\n configPathCache.set(cacheKey, appPath);\n return appPath;\n }\n const jsonPath = join(dir, \"bos.config.json\");\n if (existsSync(jsonPath)) {\n configPathCache.set(cacheKey, jsonPath);\n return jsonPath;\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n configPathCache.set(cacheKey, null);\n return null;\n}\n\nexport function isAppDescriptorPath(configPath: string): boolean {\n return configPath.endsWith(\".app.ts\") || configPath.endsWith(\".app.js\");\n}\n\n/**\n * Materialize an authored bos.app.ts descriptor into the authoring-shape\n * `BosConfigInput` the config pipeline consumes. Import-extends is honored\n * two ways: the parent descriptor value can be imported directly (an\n * inlined parent, resolved through `resolveApp`), or `extends` can name a\n * published config (`bos://…`) / a local file, which flows into the JSON\n * extends chain unchanged.\n */\nexport async function loadAppDescriptorConfig(resolvedPath: string): Promise<BosConfigInput> {\n // webpackIgnore: the path is inherently runtime-resolved — bundlers must\n // not try to statically analyze it (rsbuild otherwise warns \"Critical\n // dependency: the request of a dependency is an expression\").\n const mod = (await import(/* webpackIgnore: true */ pathToFileURL(resolvedPath).href)) as Record<\n string,\n unknown\n >;\n return parseAppDescriptorModule(mod, resolvedPath);\n}\n\n/**\n * @internal — parses an already-imported app descriptor module into the\n * authoring-shape `BosConfigInput`. Plumbing for the resolution session's\n * injectable module loader; not part of the public config surface.\n */\nexport function parseAppDescriptorModule(\n mod: Record<string, unknown>,\n sourcePath?: string,\n): BosConfigInput {\n if (!mod.default) {\n throw new Error(\n `${sourcePath ?? \"App descriptor module\"} must default-export an App() descriptor`,\n );\n }\n const descriptor = AppDescriptorSchema.parse(mod.default);\n\n // Registry candidates: named exports that parse as App descriptors.\n const registry: Record<string, unknown> = {};\n for (const value of Object.values(mod)) {\n const parsed = AppDescriptorSchema.safeParse(value);\n if (parsed.success) registry[parsed.data.name] = parsed.data;\n }\n\n const extendsRef = descriptor.extends;\n const inRegistry = typeof extendsRef === \"string\" && registry[extendsRef] !== undefined;\n const importedParent = extendsRef !== undefined && typeof extendsRef !== \"string\";\n\n if (inRegistry || importedParent) {\n return resolveApp(descriptor.name, registry as never);\n }\n\n const input = toConfigInput(descriptor);\n if (extendsRef !== undefined) {\n input.extends = extendsRef as BosConfigInput[\"extends\"];\n }\n return input;\n}\n\n/**\n * @internal — validates an already-imported `bos.dev.ts` module as a\n * `Partial<AppDescriptor>` dev overlay. Plumbing for the resolution session's\n * injectable module loader; not part of the public config surface.\n */\nexport function parseDevOverlayModule(\n mod: Record<string, unknown>,\n sourcePath?: string,\n): Partial<AppDescriptor> {\n const source = sourcePath ?? DEV_OVERLAY_FILENAME;\n if (!mod?.default) {\n throw new DevOverlayError({\n path: source,\n message: `${source} must default-export a dev overlay (Partial<AppDescriptor>)`,\n });\n }\n const parsed = AppDescriptorSchema.partial().safeParse(mod.default);\n if (!parsed.success) {\n throw new DevOverlayError({\n path: source,\n message: `${source} is not a valid dev overlay: ${parsed.error.message}`,\n cause: parsed.error,\n });\n }\n return parsed.data;\n}\n\nexport interface ResolvedComposableReference {\n entry: BosPluginRef;\n providerBaseDir: string;\n targetPath: string;\n associatedUi?: Record<string, unknown>;\n}\n\ninterface ParsedExtendsTarget {\n configPath: string;\n targetPath?: string;\n}\n\nexport class ConfigLoadError extends Schema.TaggedError<ConfigLoadError>()(\"ConfigLoadError\", {\n path: Schema.String,\n message: Schema.String,\n cause: Schema.optional(Schema.Unknown),\n}) {}\n\nexport class CircularExtendsError extends Schema.TaggedError<CircularExtendsError>()(\n \"CircularExtendsError\",\n { chain: Schema.Array(Schema.String), message: Schema.String },\n) {}\n\nexport class ConfigNotfoundError extends Schema.TaggedError<ConfigNotfoundError>()(\n \"ConfigNotfoundError\",\n { message: Schema.String },\n) {}\n\nexport class ConfigExtendsError extends Schema.TaggedError<ConfigExtendsError>()(\n \"ConfigExtendsError\",\n {\n message: Schema.String,\n cause: Schema.optional(Schema.Unknown),\n },\n) {}\n\nexport class ConfigVersionManifestError extends Schema.TaggedError<ConfigVersionManifestError>()(\n \"ConfigVersionManifestError\",\n {\n message: Schema.String,\n cause: Schema.optional(Schema.Unknown),\n },\n) {}\n\nexport class DevOverlayError extends Schema.TaggedError<DevOverlayError>()(\"DevOverlayError\", {\n path: Schema.String,\n message: Schema.String,\n cause: Schema.optional(Schema.Unknown),\n}) {}\n\nexport function defaultConfigEnv(): BosEnv {\n return process.env.NODE_ENV === \"production\" ? \"production\" : \"development\";\n}\n\nexport function parseRuntimeOverrideTargets(value?: string | null): RuntimeOverrideTarget[] {\n if (!value) {\n return [];\n }\n\n return [\n ...new Set(\n value\n .split(\",\")\n .map((entry) => entry.trim())\n .filter(Boolean),\n ),\n ].map((entry) => {\n if (entry === \"ui\" || entry === \"api\" || entry === \"plugins\") {\n return entry;\n }\n\n if (entry.startsWith(\"plugins.\") && entry.length > \"plugins.\".length) {\n return entry as RuntimeOverrideTarget;\n }\n\n throw new ConfigExtendsError({ message: `Invalid runtime override target: ${entry}` });\n });\n}\n\nexport function isRuntimeOverrideAllowed(\n allowedTargets: ReadonlyArray<RuntimeOverrideTarget>,\n target: \"ui\" | \"api\" | \"plugins\" | `plugins.${string}`,\n): boolean {\n if (allowedTargets.includes(target as RuntimeOverrideTarget)) {\n return true;\n }\n\n if (target.startsWith(\"plugins.\")) {\n return allowedTargets.includes(\"plugins.*\");\n }\n\n return false;\n}\n\nexport async function buildRuntimePluginsForConfig(\n config: BosConfig,\n baseDir: string,\n env: BosEnv,\n remotePlugins?: string[],\n): Promise<Record<string, RuntimePluginConfig> | undefined> {\n const plugins = await resolveRuntimePlugins(config.plugins ?? {}, baseDir, env, remotePlugins);\n return Object.keys(plugins).length > 0 ? plugins : undefined;\n}\n\nfunction getEntryAssociatedUi(entry: Partial<BosPluginRef>): Record<string, unknown> | undefined {\n const flat = isPlainObject(entry.ui) ? (entry.ui as Record<string, unknown>) : undefined;\n const nested = (() => {\n if (!isPlainObject(entry.app)) return undefined;\n const app = entry.app as Record<string, unknown>;\n return isPlainObject(app.ui) ? (app.ui as Record<string, unknown>) : undefined;\n })();\n const ui = flat ?? nested;\n if (!ui) return undefined;\n\n if (\"shared\" in ui) {\n throw new ConfigExtendsError({\n message:\n \"app.ui.shared is no longer supported. Move shared deps to app.api.shared, app.auth.shared, or plugins.*.shared.\",\n });\n }\n\n return ui;\n}\n\nfunction mergeAssociatedUi(\n parentUi: Record<string, unknown> | undefined,\n childUi: Record<string, unknown> | undefined,\n): Record<string, unknown> | undefined {\n if (!parentUi) {\n return childUi ? { ...childUi } : undefined;\n }\n\n if (!childUi) {\n return { ...parentUi };\n }\n\n return bosConfigMerger({ ...childUi }, parentUi) as Record<string, unknown>;\n}\n\nfunction withAssociatedUi(\n entry: BosPluginRef,\n associatedUi?: Record<string, unknown>,\n): BosPluginRef {\n if (!associatedUi) {\n return entry;\n }\n\n const app = isPlainObject(entry.app)\n ? ({ ...(entry.app as Record<string, unknown>) } as Record<string, unknown>)\n : {};\n app.ui = mergeAssociatedUi(getEntryAssociatedUi(entry), associatedUi);\n\n return {\n ...entry,\n app,\n };\n}\n\nexport async function resolveConfigComposableEntries(\n config: BosConfig,\n baseDir: string,\n env: BosEnv,\n): Promise<BosConfig> {\n const [resolvedApi, resolvedAuth] = await Promise.all([\n resolveComposableReference(config.app.api as BosPluginRef, baseDir, env, \"app.api\"),\n config.app.auth\n ? resolveComposableReference(config.app.auth as BosPluginRef, baseDir, env, \"app.auth\")\n : Promise.resolve(undefined),\n ]);\n\n const resolvedPlugins = config.plugins\n ? Object.fromEntries(\n await Promise.all(\n Object.entries(config.plugins).map(async ([pluginId, pluginValue]) => {\n const resolvedPlugin = await resolveComposableReference(\n asComposableEntry(pluginValue),\n baseDir,\n env,\n `plugins.${pluginId}`,\n );\n\n return [\n pluginId,\n withAssociatedUi(resolvedPlugin.entry, resolvedPlugin.associatedUi),\n ] as const;\n }),\n ),\n )\n : undefined;\n\n return {\n ...config,\n app: {\n ...config.app,\n api: resolvedApi.entry,\n auth: resolvedAuth?.entry,\n },\n plugins: resolvedPlugins,\n };\n}\n\nexport function getResolvedConfigPath(configDir: string): string {\n return join(configDir, \".bos\", RESOLVED_CONFIG_FILENAME);\n}\n\nexport function loadGeneratedResolvedConfig(configDir: string): BosConfig | null {\n const resolvedPath = getResolvedConfigPath(configDir);\n if (!existsSync(resolvedPath)) return null;\n try {\n const raw = JSON.parse(readFileSync(resolvedPath, \"utf-8\"));\n if (!isPlainObject(raw)) return null;\n const { _resolved, ...configData } = raw;\n return BosConfigSchema.parse(configData);\n } catch {\n return null;\n }\n}\n\nexport function writeResolvedConfig(\n configDir: string,\n config: BosConfig,\n env: BosEnv,\n extendsChain?: string[],\n source?: string,\n): void {\n const resolvedPath = getResolvedConfigPath(configDir);\n const resolvedDir = dirname(resolvedPath);\n if (!existsSync(resolvedDir)) {\n mkdirSync(resolvedDir, { recursive: true });\n }\n\n const ordered = rebuildOrderedConfig(config);\n const meta: ResolvedConfigMeta = {\n env,\n resolvedAt: new Date().toISOString(),\n extendsChain: extendsChain ?? [],\n ...(source ? { source } : {}),\n };\n const output = {\n _resolved: meta,\n ...ordered,\n };\n\n const content = `${JSON.stringify(output, null, 2)}\\n`;\n try {\n if (readFileSync(resolvedPath, \"utf-8\") === content) return;\n } catch {\n // file doesn't exist yet\n }\n writeFileSync(resolvedPath, content);\n}\n\nexport function resolveBosConfigPath(configDir: string): string {\n const resolvedPath = getResolvedConfigPath(configDir);\n if (existsSync(resolvedPath)) return resolvedPath;\n return join(configDir, \"bos.config.json\");\n}\n\nexport async function readBosConfigForBuild(configDir: string): Promise<Record<string, unknown>> {\n const resolvedPath = getResolvedConfigPath(configDir);\n if (existsSync(resolvedPath)) {\n try {\n const raw = JSON.parse(readFileSync(resolvedPath, \"utf-8\"));\n if (isPlainObject(raw)) {\n const { _resolved, ...configData } = raw;\n return configData as Record<string, unknown>;\n }\n } catch (e) {\n console.warn(\n `[Config] Failed to parse _resolved.json, falling back to the authored config: ${String(e)}`,\n );\n }\n }\n // Form-aware fallback: the authored `bos.app.ts` descriptor is canonical —\n // a TS-form child has no committed bos.config.json to parse.\n const authored = await readLocalAuthoredConfigInput(configDir);\n if (authored) return authored as unknown as Record<string, unknown>;\n const bosConfigPath = join(configDir, \"bos.config.json\");\n return JSON.parse(readFileSync(bosConfigPath, \"utf-8\")) as Record<string, unknown>;\n}\n\n/**\n * @internal — splits an extends ref into its config path and optional\n * `#target` suffix. Plumbing for the resolution session; not part of the\n * public config surface.\n */\nexport function parseExtendsTarget(ref: string): ParsedExtendsTarget {\n const hashIndex = ref.indexOf(\"#\");\n if (hashIndex === -1) {\n return { configPath: ref };\n }\n\n const configPath = ref.slice(0, hashIndex);\n const targetPath = ref.slice(hashIndex + 1);\n return {\n configPath,\n targetPath: targetPath.length > 0 ? targetPath : undefined,\n };\n}\n\n/**\n * @internal — resolves the base directory a config path extends from.\n * Plumbing for the resolution session; not part of the public config surface.\n */\nexport function getConfigBaseDir(configPath: string, baseDir: string): string {\n if (configPath.startsWith(\"bos://\")) return baseDir;\n return dirname(isAbsolute(configPath) ? configPath : resolve(baseDir, configPath));\n}\n\nfunction asComposableEntry(value: unknown): BosPluginRef {\n if (value === undefined) {\n return {};\n }\n if (typeof value === \"string\") {\n return { extends: value };\n }\n if (!isPlainObject(value)) {\n throw new ConfigExtendsError({\n message: `Expected config entry object, received ${typeof value}`,\n });\n }\n return value as BosPluginRef;\n}\n\nfunction getTargetedEntry(config: BosConfigInput, targetPath: string): BosPluginRef {\n if (targetPath.startsWith(\"app.\")) {\n const entryKey = targetPath.slice(\"app.\".length);\n return asComposableEntry(config.app?.[entryKey]);\n }\n\n if (targetPath.startsWith(\"plugins.\")) {\n const pluginId = targetPath.slice(\"plugins.\".length);\n if (pluginId.length === 0) {\n throw new ConfigExtendsError({ message: `Invalid plugin target path: ${targetPath}` });\n }\n return asComposableEntry(config.plugins?.[pluginId]);\n }\n\n throw new ConfigExtendsError({ message: `Unsupported extends target path: ${targetPath}` });\n}\n\nfunction getAssociatedUi(\n config: BosConfigInput,\n _targetPath: string,\n): Record<string, unknown> | undefined {\n if (!isPlainObject(config.app?.ui)) {\n return undefined;\n }\n\n const ui = config.app.ui as Record<string, unknown>;\n if (\"shared\" in ui) {\n throw new ConfigExtendsError({\n message:\n \"app.ui.shared is no longer supported. Move shared deps to app.api.shared, app.auth.shared, or plugins.*.shared.\",\n });\n }\n\n return ui;\n}\n\nfunction applyNullOverrides(\n target: Record<string, unknown>,\n source: Record<string, unknown>,\n): void {\n for (const [key, value] of Object.entries(source)) {\n if (value === null) {\n target[key] = null;\n } else if (isPlainObject(value) && isPlainObject(target[key])) {\n applyNullOverrides(target[key] as Record<string, unknown>, value as Record<string, unknown>);\n }\n }\n}\n\nfunction mergeComposableEntries(\n parent: Partial<BosPluginRef>,\n child: Partial<BosPluginRef>,\n): BosPluginRef {\n const merged = bosConfigMerger({ ...child }, parent) as Record<string, unknown>;\n applyNullOverrides(merged, child as Record<string, unknown>);\n return merged as BosPluginRef;\n}\n\nfunction stripUnsafeLocalDevelopment<T extends Record<string, unknown> | undefined>(\n entry: T,\n allowLocalPaths: boolean,\n): T {\n if (!entry || allowLocalPaths) {\n return entry;\n }\n\n if (typeof entry.development === \"string\" && entry.development.startsWith(LOCAL_PREFIX)) {\n const { development: _ignored, ...rest } = entry;\n return rest as T;\n }\n\n return entry;\n}\n\nexport async function resolveComposableReference(\n source: BosPluginRef,\n baseDir: string,\n env: BosEnv,\n defaultTargetPath: string,\n): Promise<ResolvedComposableReference> {\n let resolvedEntry: BosPluginRef = {};\n let providerBaseDir = baseDir;\n let targetPath = defaultTargetPath;\n let associatedUi = getEntryAssociatedUi(source);\n let allowLocalPaths = false;\n let extendsError: unknown;\n\n const extendsRef = source.extends ? resolveExtendsRef(source.extends, env) : undefined;\n if (extendsRef) {\n const { resolveMergedConfigInput } = await import(\"./resolution/session\");\n const parsed = parseExtendsTarget(extendsRef);\n targetPath = parsed.targetPath ?? defaultTargetPath;\n const extendsBaseDir = getConfigBaseDir(parsed.configPath, baseDir);\n try {\n const extendedConfig = await resolveMergedConfigInput(parsed.configPath, {\n baseDir: extendsBaseDir,\n env,\n });\n resolvedEntry = mergeComposableEntries(\n resolvedEntry,\n getTargetedEntry(extendedConfig, targetPath),\n );\n providerBaseDir = extendsBaseDir;\n associatedUi = mergeAssociatedUi(associatedUi, getAssociatedUi(extendedConfig, targetPath));\n } catch (error) {\n extendsError = error;\n }\n }\n\n const localDevelopment =\n typeof source.development === \"string\" && source.development.startsWith(LOCAL_PREFIX)\n ? source.development\n : undefined;\n const localDevelopmentPath = localDevelopment\n ? resolve(baseDir, localDevelopment.slice(LOCAL_PREFIX.length).trim())\n : undefined;\n const hasUsableLocalDevelopment = Boolean(\n localDevelopmentPath && existsSync(localDevelopmentPath),\n );\n\n if (localDevelopmentPath) {\n const { resolveMergedConfigInput } = await import(\"./resolution/session\");\n const localPath = localDevelopmentPath;\n const localConfigPath = localConfigEntryPath(localPath);\n if (localConfigPath) {\n const localConfig = await resolveMergedConfigInput(localConfigPath, {\n baseDir: localPath,\n env,\n });\n resolvedEntry = mergeComposableEntries(\n resolvedEntry,\n getTargetedEntry(localConfig, targetPath),\n );\n providerBaseDir = localPath;\n associatedUi = mergeAssociatedUi(associatedUi, getAssociatedUi(localConfig, targetPath));\n allowLocalPaths = true;\n }\n }\n\n const sourceOverrides = { ...source };\n if (allowLocalPaths && localDevelopment) {\n delete sourceOverrides.development;\n }\n\n resolvedEntry = mergeComposableEntries(resolvedEntry, sourceOverrides);\n associatedUi = mergeAssociatedUi(associatedUi, getEntryAssociatedUi(sourceOverrides));\n\n if (extendsError && !allowLocalPaths && !hasUsableLocalDevelopment) {\n throw extendsError;\n }\n\n return {\n entry: stripUnsafeLocalDevelopment(resolvedEntry, allowLocalPaths || Boolean(localDevelopment)),\n providerBaseDir,\n targetPath,\n // A plugin's own ui lives under its local development tree — the same\n // safety argument as the entry itself: keep its local target when the\n // plugin resolves locally, or the folder-form ui surface silently\n // disappears (no BOS_UI_PORT, an unassigned ui dev server, and a\n // port collision with another plugin's ui slot).\n associatedUi: stripUnsafeLocalDevelopment(\n associatedUi,\n allowLocalPaths || Boolean(localDevelopment),\n ),\n };\n}\n\nfunction resolveDevelopmentTarget(\n development: string | undefined,\n production: string | undefined,\n baseDir: string,\n forceSource?: \"local\" | \"remote\",\n target?: string,\n extendsRef?: string,\n): RuntimeTarget {\n if (forceSource === \"remote\") {\n return resolveRuntimeTarget(production, baseDir, \"remote\");\n }\n if (!development) {\n if (production && target) {\n if (extendsRef) {\n emitConfigWarning(`[Config] Resolving \"${target}\" from ${extendsRef}`);\n } else {\n emitConfigWarning(`[Config] No development target for \"${target}\", using production`);\n }\n }\n return resolveRuntimeTarget(production, baseDir, \"remote\");\n }\n const devTarget = resolveRuntimeTarget(development, baseDir);\n if (devTarget.source === \"local\" && (!devTarget.localPath || !existsSync(devTarget.localPath))) {\n if (production && target) {\n emitConfigWarning(`[Config] Could not load local target for \"${target}\", using production`);\n }\n return resolveRuntimeTarget(production, baseDir, \"remote\");\n }\n return devTarget;\n}\n\nexport interface BuildRuntimeConfigOptions {\n plugins?: Record<string, RuntimePluginConfig>;\n hostSource?: \"local\" | \"remote\";\n uiSource?: \"local\" | \"remote\";\n apiSource?: \"local\" | \"remote\";\n authSource?: \"local\" | \"remote\";\n proxy?: string;\n}\n\nexport const buildRuntimeConfigEffect = Effect.fn(\"buildRuntimeConfig\")(function* (\n config: BosConfig,\n baseDir: string,\n env: BosEnv,\n options?: BuildRuntimeConfigOptions,\n): Effect.fn.Return<RuntimeConfig, ConfigExtendsError | ConfigVersionManifestError> {\n const uiConfig = config.app.ui;\n const apiConfig = config.app.api;\n const authConfig = config.app.auth;\n const uiRuntime =\n env === \"development\"\n ? resolveDevelopmentTarget(\n uiConfig.development,\n uiConfig.production,\n baseDir,\n options?.uiSource,\n \"app.ui\",\n )\n : resolveRuntimeTarget(uiConfig.production, baseDir, \"remote\");\n const apiRuntime =\n env === \"development\"\n ? resolveDevelopmentTarget(\n apiConfig.development,\n apiConfig.production,\n baseDir,\n options?.apiSource,\n \"app.api\",\n )\n : resolveRuntimeTarget(apiConfig.production, baseDir, \"remote\");\n const authExtendsRef = authConfig?.extends\n ? resolveExtendsRef(authConfig.extends, env)\n : undefined;\n const authRuntime = authConfig\n ? env === \"development\"\n ? resolveDevelopmentTarget(\n authConfig.development,\n authConfig.production,\n baseDir,\n options?.authSource,\n \"app.auth\",\n authExtendsRef,\n )\n : resolveRuntimeTarget(authConfig.production, baseDir, \"remote\")\n : undefined;\n\n const hostConfig = config.app.host;\n const hostRuntime =\n env === \"development\"\n ? resolveDevelopmentTarget(\n hostConfig.development,\n hostConfig.production,\n baseDir,\n options?.hostSource,\n \"app.host\",\n )\n : resolveRuntimeTarget(hostConfig.production, baseDir, \"remote\");\n\n const hostListeningUrl =\n env === \"development\"\n ? resolveDevelopmentHostUrl(hostConfig.development)\n : `http://localhost:${getProcessEnv(\"PORT\") ?? DEFAULT_HOST_PORT}`;\n\n const hostIsRemote = hostRuntime.source === \"remote\";\n const uiIsRemote = uiRuntime.source === \"remote\";\n const apiIsRemote = apiRuntime.source === \"remote\";\n const resolvedApiName = resolvePluginRuntimeName(apiConfig.name, apiRuntime.localPath, \"api\");\n\n const authEntry = yield* Effect.tryPromise({\n try: async () => {\n if (!authConfig || !authRuntime) return undefined;\n if (!authRuntime.localPath && !authRuntime.url) return undefined;\n let authName = resolvePluginRuntimeName(authConfig.name, authRuntime.localPath, \"auth\");\n if (\n authRuntime.source === \"remote\" &&\n authRuntime.url &&\n !authRuntime.localPath &&\n typeof authConfig.name !== \"string\"\n ) {\n authName = await resolveRemotePluginRuntimeName(authRuntime.url, authName);\n }\n return {\n name: authName,\n extendsRef: authExtendsRef,\n url: authRuntime.url,\n entry: authRuntime.url ? `${authRuntime.url}/mf-manifest.json` : \"/mf-manifest.json\",\n localPath: authRuntime.localPath,\n port: authRuntime.port,\n source: authRuntime.source,\n proxy: authConfig.proxy,\n variables: authConfig.variables,\n secrets: authConfig.secrets,\n integrity: authRuntime.source === \"remote\" ? authConfig.integrity : undefined,\n shared: authConfig.shared,\n ui: buildRuntimeUiConfig(\n \"auth\",\n env,\n getEntryAssociatedUi(authConfig as Partial<BosPluginRef>),\n baseDir,\n authName,\n options?.authSource,\n ),\n };\n },\n catch: (cause) => new ConfigExtendsError({ message: String(cause), cause }),\n });\n\n const explicitPlugins =\n options?.plugins && Object.keys(options.plugins).length > 0 ? options.plugins : undefined;\n const runtimePlugins: Record<string, RuntimePluginConfig> = { ...explicitPlugins };\n if (authEntry && !runtimePlugins.auth) {\n runtimePlugins.auth = authEntry;\n }\n\n const result: RuntimeConfig = {\n env,\n account: config.account,\n domain: config.domain,\n title: config.title,\n description: config.description,\n networkId: getNetworkIdForAccount(config.account),\n repository: config.repository,\n host: {\n name: \"host\",\n url: hostListeningUrl,\n entry: `${hostListeningUrl}/mf-manifest.json`,\n localPath: hostRuntime.localPath,\n port:\n env === \"development\"\n ? parsePort(hostListeningUrl)\n : Number(getProcessEnv(\"PORT\")) || DEFAULT_HOST_PORT,\n secrets: hostConfig.secrets,\n integrity: hostIsRemote ? hostConfig.integrity : undefined,\n source: hostRuntime.source,\n remoteUrl: hostIsRemote ? hostRuntime.url : undefined,\n },\n ui: {\n name: resolvePluginRuntimeName(uiConfig.name, uiRuntime.localPath, \"ui\"),\n url: uiRuntime.url,\n entry: uiRuntime.url ? `${uiRuntime.url}/mf-manifest.json` : \"/mf-manifest.json\",\n publicUrl: typeof uiConfig.publicUrl === \"string\" ? uiConfig.publicUrl : undefined,\n localPath: uiRuntime.localPath,\n port: uiRuntime.port,\n ssrUrl: uiIsRemote ? uiConfig.ssr : undefined,\n ssrIntegrity: uiIsRemote ? uiConfig.ssrIntegrity : undefined,\n integrity: uiIsRemote ? uiConfig.integrity : undefined,\n source: uiRuntime.source,\n },\n api: {\n name: resolvedApiName,\n url: apiRuntime.url,\n entry: apiRuntime.url ? `${apiRuntime.url}/mf-manifest.json` : \"/mf-manifest.json\",\n localPath: apiRuntime.localPath,\n port: apiRuntime.port,\n source: apiRuntime.source,\n proxy: options?.proxy ?? apiConfig.proxy,\n variables: apiConfig.variables,\n secrets: apiConfig.secrets,\n integrity: apiIsRemote ? apiConfig.integrity : undefined,\n shared: apiConfig.shared,\n dependsOn: apiConfig.dependsOn ? normalizeStringArray(apiConfig.dependsOn) : undefined,\n },\n auth: authEntry,\n plugins: Object.keys(runtimePlugins).length > 0 ? runtimePlugins : undefined,\n };\n\n yield* Effect.tryPromise({\n try: async () => {\n // catch-all diagnostics: a failed discovery fetch degrades to a\n // warning, never fails the runtime config build\n try {\n if (result.api.source !== \"remote\" || !result.api.url) return;\n const manifest = await fetchApiPluginManifest(result.api.url);\n const manifestPluginEntries: Array<{ key: string; config: RuntimePluginConfig }> = [];\n if (manifest.plugins?.length) {\n for (const node of manifestPluginsToNodes(manifest.plugins)) {\n if (!result.plugins?.[node.key]) {\n manifestPluginEntries.push({\n key: node.key,\n config: {\n name: node.name,\n url: node.url,\n entry: node.entry,\n source: \"remote\",\n dependsOn: node.dependsOn,\n secrets: node.secrets,\n variables: node.variables,\n },\n });\n if (node.secrets) {\n for (const secretName of node.secrets) {\n if (!getProcessEnv(secretName)) {\n warnOutsideEffect(\n `[Config] Plugin \"${node.key}\" (discovered from manifest) expects secret \"${secretName}\" but it is not set in the environment.`,\n );\n }\n }\n }\n }\n }\n }\n if (manifest.dependsOn?.length) {\n const existing = new Set(result.api.dependsOn ?? []);\n for (const dep of manifest.dependsOn) {\n if (!existing.has(dep)) {\n result.api.dependsOn = [...(result.api.dependsOn ?? []), dep];\n }\n }\n }\n if (manifestPluginEntries.length > 0) {\n if (!result.plugins) result.plugins = {};\n for (const { key, config: pluginConfig } of manifestPluginEntries) {\n if (!result.plugins[key]) {\n result.plugins[key] = pluginConfig;\n }\n }\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n warnOutsideEffect(`[Config] Failed to fetch API plugin manifest for discovery: ${message}`);\n }\n },\n catch: (cause) => new ConfigExtendsError({ message: String(cause), cause }),\n });\n\n yield* Effect.tryPromise({\n try: () => deriveVersionManifestFields(result, config, env),\n catch: (cause) => new ConfigVersionManifestError({ message: String(cause), cause }),\n });\n\n return result;\n});\n\n/**\n * Version-manifest derivation (atomic-deploys 04): for every remote slot,\n * resolve its `pin` (fetch + SRI-verify the pinned manifest, process-cached\n * per pin) and stamp the derived entry-level fields — `entryUrl` (hashed\n * container entry), the browser-manifest `entry`, and entry-level\n * `integrity`/`ssrIntegrity`/`ssrEntryUrl` — so consumers load immutable\n * hashed bytes without knowing the pointer indirection.\n *\n * Hard break: outside development every remote slot MUST pin a version\n * manifest — an unpinned remote slot fails resolution loudly (the deploy\n * train pins every workspace it uploads; a manifest-less slot means a\n * pre-atomic-deploy config).\n */\nasync function deriveVersionManifestFields(\n result: RuntimeConfig,\n config: BosConfig,\n env: BosEnv,\n): Promise<void> {\n if (env === \"development\") return;\n\n const derive = async (\n label: string,\n slotConfig: { pin?: unknown } | undefined,\n slot: { url?: string; remoteUrl?: string; source?: string } | undefined,\n apply: (resolved: ResolvedSlotVersion) => void,\n ): Promise<void> => {\n if (!slot || slot.source !== \"remote\" || !slot.url) return;\n // A config without a production form (the image's baked boot fallback, or\n // a dev resolution materialized under NODE_ENV=production) has no\n // deployment artifacts to pin — the slot URL is the local listening\n // fallback. Pin enforcement is for published configs.\n const slotWithProduction = slotConfig as { production?: unknown } | undefined;\n if (!slotWithProduction || slotWithProduction.production === undefined) return;\n const rawPin = slotConfig?.pin as { manifest?: unknown; integrity?: unknown } | undefined;\n const pin =\n rawPin &&\n typeof rawPin.manifest === \"string\" &&\n rawPin.manifest &&\n typeof rawPin.integrity === \"string\" &&\n rawPin.integrity\n ? { manifest: rawPin.manifest, integrity: rawPin.integrity }\n : undefined;\n if (!pin) {\n throw new Error(\n `slot \"${label}\" (${slot.url}) pins no version manifest — remote slots must pin ` +\n `a version manifest outside development (pre-atomic-deploy config; redeploy required)`,\n );\n }\n // The pin resolves against the slot's REMOTE base — the host slot's `url`\n // is its own listening origin (the bytes it would serve don't exist\n // there); its `remoteUrl` carries the deployment bundle base.\n const resolved = await resolveSlotVersion({ base: slot.remoteUrl ?? slot.url, pin });\n apply(resolved);\n };\n\n const applyUi = (ui: RuntimePluginConfig[\"ui\"], r: ResolvedSlotVersion): void => {\n if (!ui) return;\n ui.entryUrl = r.entryUrl;\n ui.entry = r.browserManifestUrl ?? ui.entry;\n ui.browserManifestUrl = r.browserManifestUrl;\n ui.integrity = r.entryIntegrity;\n ui.ssrEntryUrl = r.ssrEntryUrl;\n ui.ssrIntegrity = r.ssrIntegrity ?? ui.ssrIntegrity;\n };\n\n await derive(\"app.host\", config.app.host, result.host, (r) => {\n result.host.entryUrl = r.entryUrl;\n result.host.integrity = r.entryIntegrity;\n });\n await derive(\"app.ui\", config.app.ui, result.ui, (r) => applyUi(result.ui, r));\n await derive(\"app.api\", config.app.api, result.api, (r) => {\n result.api.entryUrl = r.entryUrl;\n result.api.integrity = r.entryIntegrity;\n });\n if (result.auth) {\n await derive(\"app.auth\", config.app.auth, result.auth, (r) => {\n result.auth!.entryUrl = r.entryUrl;\n result.auth!.integrity = r.entryIntegrity;\n });\n await derive(\n \"app.auth.ui\",\n getEntryAssociatedUi(config.app.auth as Partial<BosPluginRef>),\n result.auth.ui,\n (r) => applyUi(result.auth!.ui, r),\n );\n }\n for (const [key, plugin] of Object.entries(result.plugins ?? {})) {\n let pluginConfig = config.plugins?.[key];\n // The auth mirror (config.ts adds plugins.auth when the authored config\n // has no plugins.auth entry) derives from the app.auth slot — it is the\n // only compose surface for the auth ui, and its pins live on app.auth.\n const isAuthMirror =\n key === \"auth\" && result.auth && (plugin === result.auth || plugin.url === result.auth.url);\n if ((!pluginConfig || typeof pluginConfig === \"string\") && isAuthMirror) {\n pluginConfig = config.app.auth;\n }\n if (!pluginConfig || typeof pluginConfig === \"string\") continue;\n await derive(`plugins.${key}`, pluginConfig, plugin, (r) => {\n plugin.entryUrl = r.entryUrl;\n plugin.integrity = r.entryIntegrity;\n });\n await derive(\n `plugins.${key}.ui`,\n getEntryAssociatedUi(pluginConfig as Partial<BosPluginRef>),\n plugin.ui,\n (r) => applyUi(plugin.ui, r),\n );\n }\n}\n\nexport async function buildRuntimeConfig(\n config: BosConfig,\n baseDir: string,\n env: BosEnv,\n options?: BuildRuntimeConfigOptions,\n): Promise<RuntimeConfig> {\n return Effect.runPromise(buildRuntimeConfigEffect(config, baseDir, env, options));\n}\n\nasync function readConfigInput(configPath: string, baseDir: string): Promise<BosConfigInput> {\n if (configPath.startsWith(\"bos://\")) {\n return fetchBosConfigFromFastKv<BosConfigInput>(configPath);\n }\n\n const resolvedPath = isAbsolute(configPath) ? configPath : resolve(baseDir, configPath);\n if (isAppDescriptorPath(resolvedPath)) {\n return loadAppDescriptorConfig(resolvedPath);\n }\n return JSON.parse(readFileSync(resolvedPath, \"utf-8\")) as BosConfigInput;\n}\n\ntype PluginOverrideValue = PluginEntryValue | null | false;\n\nfunction normalizePluginEntry(raw: PluginOverrideValue): BosPluginRef | null | false {\n if (raw === null || raw === false) return raw;\n if (typeof raw === \"string\") {\n return { extends: raw };\n }\n return raw;\n}\n\nconst resolveRuntimePluginsEffect = Effect.fn(\"resolveRuntimePlugins\")(function* (\n plugins: Record<string, PluginOverrideValue>,\n baseDir: string,\n env: BosEnv,\n remotePlugins?: string[],\n): Effect.fn.Return<Record<string, RuntimePluginConfig>, ConfigExtendsError> {\n const entries = Object.entries(plugins)\n .map(([pluginId, rawInput]) => ({\n pluginId,\n normalized: normalizePluginEntry(rawInput),\n }))\n .filter(\n (entry): entry is { pluginId: string; normalized: BosPluginRef } =>\n entry.normalized !== null && entry.normalized !== false,\n );\n\n const resolved = yield* Effect.forEach(\n entries,\n ({ pluginId, normalized }) =>\n Effect.gen(function* () {\n const resolvedReference = yield* Effect.tryPromise({\n try: () => resolveComposableReference(normalized, baseDir, env, `plugins.${pluginId}`),\n catch: (cause) => new ConfigExtendsError({ message: String(cause), cause }),\n });\n\n const forceSource =\n remotePlugins === undefined\n ? undefined\n : remotePlugins.length === 0 || remotePlugins.includes(pluginId)\n ? (\"remote\" as const)\n : undefined;\n const pluginRuntime = buildRuntimePluginConfig(\n pluginId,\n env,\n resolvedReference,\n forceSource,\n );\n\n if (!pluginRuntime.localPath && !pluginRuntime.url) {\n if (forceSource === \"remote\") {\n emitConfigWarning(\n `[Config] Plugin \"${pluginId}\" has no production URL in bos.config.json and cannot be resolved as remote. Add a \"production\" field or remove it from --remote-plugins.`,\n );\n }\n return null;\n }\n\n if (\n pluginRuntime.source === \"remote\" &&\n pluginRuntime.url &&\n !pluginRuntime.localPath &&\n typeof resolvedReference.entry.name !== \"string\"\n ) {\n pluginRuntime.name = yield* Effect.tryPromise({\n try: () => resolveRemotePluginRuntimeName(pluginRuntime.url, pluginRuntime.name),\n catch: (cause) => new ConfigExtendsError({ message: String(cause), cause }),\n });\n }\n\n return [pluginId, pluginRuntime] as const;\n }),\n { concurrency: \"unbounded\" },\n );\n\n const out: Record<string, RuntimePluginConfig> = {};\n for (const entry of resolved) {\n if (entry) {\n out[entry[0]] = entry[1];\n }\n }\n\n return out;\n});\n\nfunction resolveRuntimePlugins(\n plugins: Record<string, PluginOverrideValue>,\n baseDir: string,\n env: BosEnv,\n remotePlugins?: string[],\n): Promise<Record<string, RuntimePluginConfig>> {\n return Effect.runPromise(resolveRuntimePluginsEffect(plugins, baseDir, env, remotePlugins));\n}\n\nasync function resolveRemotePluginRuntimeName(baseUrl: string, fallback: string): Promise<string> {\n const manifest = await fetchJsonOrNull<{\n plugin?: { name?: unknown };\n }>(`${baseUrl.replace(/\\/$/, \"\")}/plugin.manifest.json`, { retries: 2 });\n\n return typeof manifest?.plugin?.name === \"string\" && manifest.plugin.name.length > 0\n ? manifest.plugin.name\n : fallback;\n}\n\nfunction buildRuntimePluginConfig(\n pluginId: string,\n env: BosEnv,\n resolved: ResolvedComposableReference,\n forceSource?: \"local\" | \"remote\",\n): RuntimePluginConfig {\n const source = resolved.entry;\n const development = typeof source.development === \"string\" ? source.development : undefined;\n const production = typeof source.production === \"string\" ? source.production : undefined;\n\n if (production?.startsWith(\"bos://\")) {\n throw new ConfigExtendsError({\n message: `Plugin \"${pluginId}\" has unsupported production target \"${production}\". Use extends: \"bos://account/domain\" for plugin configs or a CDN URL for production.`,\n });\n }\n\n const pluginExtendsRef = source.extends ? resolveExtendsRef(source.extends, env) : undefined;\n\n const runtimeTarget =\n env === \"development\"\n ? resolveDevelopmentTarget(\n development,\n production,\n resolved.providerBaseDir,\n forceSource,\n `plugins.${pluginId}`,\n pluginExtendsRef,\n )\n : resolveRuntimeTarget(production, resolved.providerBaseDir, \"remote\");\n const apiName = resolvePluginRuntimeName(source.name, runtimeTarget.localPath, pluginId);\n\n const ui = buildRuntimeUiConfig(\n pluginId,\n env,\n resolved.associatedUi,\n resolved.providerBaseDir,\n apiName,\n forceSource,\n );\n\n const routes = source.routes;\n\n return {\n name: apiName,\n url: runtimeTarget.url,\n entry: runtimeTarget.url\n ? `${runtimeTarget.url.replace(/\\/$/, \"\")}/mf-manifest.json`\n : \"/mf-manifest.json\",\n source: runtimeTarget.source,\n extendsRef: pluginExtendsRef,\n localPath: runtimeTarget.localPath,\n port: runtimeTarget.port,\n proxy: typeof source.proxy === \"string\" ? source.proxy : undefined,\n variables: normalizeJsonRecord(source.variables),\n secrets: normalizeStringArray(source.secrets),\n shared: source.shared,\n connectSrc: normalizeStringArray(source.connectSrc),\n integrity: runtimeTarget.source === \"remote\" ? source.integrity : undefined,\n ui,\n routes,\n dependsOn: source.dependsOn ? normalizeStringArray(source.dependsOn) : undefined,\n };\n}\n\n/**\n * Resolve a plugin entry's associated ui surface (`plugins.<id>.ui` / legacy\n * `plugins.<id>.app.ui`) into the runtime ui config. Extracted so app-slot\n * entries (app.auth) resolve their ui the same way.\n */\nfunction buildRuntimeUiConfig(\n pluginId: string,\n env: BosEnv,\n uiConfig: Record<string, unknown> | undefined,\n providerBaseDir: string,\n apiName: string,\n forceSource?: \"local\" | \"remote\",\n): RuntimePluginConfig[\"ui\"] {\n const uiDevelopment =\n typeof uiConfig?.development === \"string\" ? uiConfig.development : undefined;\n const uiProduction = typeof uiConfig?.production === \"string\" ? uiConfig.production : undefined;\n const uiRuntime =\n uiConfig && (uiDevelopment || uiProduction)\n ? env === \"development\"\n ? resolveDevelopmentTarget(\n uiDevelopment,\n uiProduction,\n providerBaseDir,\n forceSource,\n `plugins.${pluginId}.ui`,\n )\n : resolveRuntimeTarget(uiProduction, providerBaseDir, \"remote\")\n : undefined;\n if (!uiRuntime) return undefined;\n // A remote ui target with no URL is not a deployable surface (e.g. a\n // plugin ui entry with only a development key) — dropping it here keeps\n // the phantom source out of runtime resolution and client payloads.\n if (uiRuntime.source === \"remote\" && !uiRuntime.url) return undefined;\n\n return {\n name: resolveUiRuntimeName(uiConfig, uiRuntime.localPath, apiName),\n url: uiRuntime.url,\n entry: uiRuntime.url\n ? `${uiRuntime.url.replace(/\\/$/, \"\")}/mf-manifest.json`\n : \"/mf-manifest.json\",\n source: uiRuntime.source,\n publicUrl: typeof uiConfig?.publicUrl === \"string\" ? uiConfig.publicUrl : undefined,\n localPath: uiRuntime.localPath,\n port: uiRuntime.port,\n integrity:\n uiRuntime.source === \"remote\" && typeof uiConfig?.integrity === \"string\"\n ? uiConfig.integrity\n : undefined,\n ssrUrl:\n uiRuntime.source === \"remote\" && typeof uiConfig?.ssr === \"string\"\n ? uiConfig.ssr\n : uiRuntime.source === \"local\"\n ? uiRuntime.url\n : undefined,\n ssrIntegrity:\n uiRuntime.source === \"remote\" && typeof uiConfig?.ssrIntegrity === \"string\"\n ? uiConfig.ssrIntegrity\n : undefined,\n };\n}\n\n/**\n * MF container identity must match the build: folder-form plugin ui sources\n * build under the sanitized plugin workspace package name (the generated\n * rsbuild config imports the plugin's package.json), so derive the same\n * value here — an authored `ui.name` is only a fallback, and can never\n * override what the container actually registers under.\n */\nexport function resolveUiRuntimeName(\n uiConfig: Record<string, unknown> | undefined,\n localPath: string | undefined,\n apiName: string,\n): string {\n if (localPath) {\n const uiPkgPath = join(localPath, \"package.json\");\n const pkgPath = existsSync(uiPkgPath) ? uiPkgPath : join(dirname(localPath), \"package.json\");\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\")) as { name?: unknown };\n if (typeof pkg.name === \"string\" && pkg.name.length > 0) {\n return sanitizeContainerName(pkg.name);\n }\n } catch (e) {\n console.warn(`[Config] Could not read package.json at ${pkgPath}: ${String(e)}`);\n }\n }\n return typeof uiConfig?.name === \"string\" ? uiConfig.name : `${apiName}-ui`;\n}\n\nexport function resolvePluginRuntimeName(\n explicitName: string | undefined,\n localPath: string | undefined,\n fallback: string,\n): string {\n if (explicitName) {\n return explicitName;\n }\n\n if (!localPath) {\n return fallback;\n }\n\n try {\n const packageJsonPath = join(localPath, \"package.json\");\n const packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\")) as { name?: unknown };\n if (typeof packageJson.name === \"string\" && packageJson.name.length > 0) {\n return packageJson.name;\n }\n } catch (e) {\n console.warn(`[Config] Could not read package.json at ${localPath}: ${String(e)}`);\n }\n\n return fallback;\n}\n\nfunction normalizeJsonValue(value: unknown): JsonValue | undefined {\n if (\n value === null ||\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\"\n ) {\n return value;\n }\n\n if (Array.isArray(value)) {\n return value\n .map((item) => normalizeJsonValue(item))\n .filter((item): item is JsonValue => item !== undefined);\n }\n\n if (isPlainObject(value)) {\n const out: JsonObject = {};\n for (const [key, raw] of Object.entries(value)) {\n const normalized = normalizeJsonValue(raw);\n if (normalized !== undefined) {\n out[key] = normalized;\n }\n }\n return out;\n }\n\n return undefined;\n}\n\nfunction normalizeJsonRecord(value: unknown): JsonObject | undefined {\n if (!isPlainObject(value)) return undefined;\n const out: JsonObject = {};\n for (const [key, raw] of Object.entries(value)) {\n const normalized = normalizeJsonValue(raw);\n if (normalized !== undefined) {\n out[key] = normalized;\n }\n }\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\nfunction normalizeStringArray(value: unknown): string[] | undefined {\n if (!Array.isArray(value)) return undefined;\n const out = value.filter((item): item is string => typeof item === \"string\" && item.length > 0);\n return out.length > 0 ? out : undefined;\n}\n\nfunction resolveRuntimeTarget(\n value: string | undefined,\n baseDir: string,\n defaultSource: \"local\" | \"remote\" = \"remote\",\n): RuntimeTarget {\n if (!value) {\n return { source: defaultSource, url: \"\" };\n }\n\n if (value.startsWith(LOCAL_PREFIX)) {\n const localTarget = value?.slice(LOCAL_PREFIX.length).trim();\n if (!localTarget) {\n throw new ConfigExtendsError({ message: `Invalid local development target: ${value}` });\n }\n\n const localPath = resolve(baseDir, localTarget);\n if (!existsSync(localPath)) {\n return { source: \"local\", url: \"\" };\n }\n\n return {\n source: \"local\",\n url: \"\",\n localPath,\n };\n }\n\n return {\n source: defaultSource,\n url: value.replace(/\\/$/, \"\"),\n port: parsePort(value),\n };\n}\n\nexport function isLocalDevelopmentTarget(\n value: string | undefined,\n): value is `${typeof LOCAL_PREFIX}${string}` {\n return typeof value === \"string\" && value.startsWith(LOCAL_PREFIX);\n}\n\nexport function resolveLocalDevelopmentPath(\n value: string | undefined,\n baseDir: string,\n): string | null {\n if (!isLocalDevelopmentTarget(value)) {\n return null;\n }\n\n const localTarget = value.slice(LOCAL_PREFIX.length).trim();\n return localTarget ? resolve(baseDir, localTarget) : null;\n}\n\nexport function resolveDevelopmentHostUrl(value: string | undefined): string {\n if (!value || isLocalDevelopmentTarget(value)) {\n return `http://localhost:${DEFAULT_HOST_PORT}`;\n }\n\n return value.replace(/\\/$/, \"\");\n}\n\nexport function getHostDevelopmentPort(value: string | undefined): number {\n return parsePort(resolveDevelopmentHostUrl(value));\n}\n\nexport function parsePort(url: string): number {\n try {\n const parsed = new URL(url);\n return parsed.port ? parseInt(parsed.port, 10) : parsed.protocol === \"https:\" ? 443 : 80;\n } catch {\n return 3000;\n }\n}\n\nexport type { BosEnv } from \"./merge\";\nexport {\n BOS_CONFIG_ORDER,\n mergeBosConfigWithExtends,\n rebuildOrderedConfig,\n resolveExtendsRef,\n} from \"./merge\";\nexport type { BosConfig, RuntimeConfig } from \"./types\";\nexport { BosConfigSchema } from \"./types\";\n"],"mappings":"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"}