UNPKG

everything-dev

Version:

A consolidated product package for building Module Federation apps with oRPC APIs.

1 lines • 43.6 kB
{"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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"}