{"version":3,"file":"runtime.mjs","names":[],"sources":["../../../src/services/resolution/runtime.ts"],"sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { Effect } from \"effect\";\nimport { MANIFEST_FILENAME, sanitizeContainerName } from \"every-plugin/ui/manifest/contract\";\nimport { getProcessEnv } from \"../../env/process-env\";\nimport type {\n  BosConfig,\n  BosPluginRef,\n  JsonObject,\n  JsonValue,\n  PluginEntryValue,\n  RuntimeConfig,\n  RuntimePluginConfig,\n} from \"../../types\";\nimport { fetchJsonOrNull } from \"../../utils/http-client\";\nimport { getNetworkIdForAccount } from \"../../utils/network\";\nimport { fetchApiPluginManifest } from \"../codegen/api-contract\";\nimport { type ResolvedSlotVersion, resolveSlotVersion } from \"../deploy/version-manifest\";\nimport { manifestPluginsToNodes } from \"../registry/dag\";\nimport {\n  ConfigExtendsError,\n  ConfigVersionManifestError,\n  emitConfigWarning,\n  getEntryAssociatedUi,\n  LOCAL_PREFIX,\n  type ResolvedComposableReference,\n  resolveComposableReference,\n} from \"./load\";\nimport { type BosEnv, isPlainObject, resolveExtendsRef } from \"./merge\";\n\nconst warnOutsideEffect = (...args: unknown[]): void => {\n  console.warn(...args);\n};\n\nconst DEFAULT_HOST_PORT = 3000;\n\ninterface RuntimeTarget {\n  source: \"local\" | \"remote\";\n  url: string;\n  localPath?: string;\n  port?: number;\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 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 * Pinned remote slots derive in every environment, development included —\n * hash-canonical bundles never serve the fixed-name dev entry, so a dev\n * consumer pointing at remote production slots needs the same `entryUrl`\n * stamps or its readiness probe 404s forever. Unpinned remote slots skip\n * silently in development (a local-links resolution has nothing to pin);\n * outside development they fail loud — the deploy train pins every\n * workspace it uploads, so a manifest-less slot there is a\n * pre-atomic-deploy config.\n */\nasync function deriveVersionManifestFields(\n  result: RuntimeConfig,\n  config: BosConfig,\n  env: BosEnv,\n): Promise<void> {\n  const isDev = env === \"development\";\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 (a dev resolution materialized\n    // under NODE_ENV=production) has no deployment artifacts to pin — the\n    // slot URL is the local listening fallback. Pin enforcement is for\n    // 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      if (isDev) return;\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    let resolved: ResolvedSlotVersion;\n    try {\n      resolved = await resolveSlotVersion({ base: slot.remoteUrl ?? slot.url, pin });\n    } catch (cause) {\n      if (isDev) {\n        warnOutsideEffect(\n          `[Config] Version-manifest pin for \"${label}\" (${pin.manifest}) failed to resolve, ` +\n            `continuing unpinned (development): ${cause instanceof Error ? cause.message : String(cause)}`,\n        );\n        return;\n      }\n      throw cause;\n    }\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    ui.manifestIntegrity = r.files?.[MANIFEST_FILENAME] ?? ui.manifestIntegrity;\n    ui.sharedVersions = r.sharedVersions;\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\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"],"mappings":"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"}