UNPKG

everything-dev

Version:

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

131 lines (129 loc) 5.25 kB
import { buildRuntimeConfig as buildRuntimeConfig$1, getProjectRoot, resolveLocalDevelopmentPath } from "./config.mjs"; import { existsSync } from "node:fs"; import { join } from "node:path"; import { createConnection } from "node:net"; //#region src/app.ts const DEFAULT_HOST_PORT = 3e3; const DEFAULT_API_PORT = 3001; const DEFAULT_AUTH_PORT = 3002; const DEFAULT_UI_PORT = 3003; const DEFAULT_PLUGIN_PORT_START = 3010; function detectLocalPackages(bosConfig, runtimeConfig) { const packages = []; const configDir = getProjectRoot(); const uiLocalPath = runtimeConfig?.ui.localPath ?? resolveLocalDevelopmentPath(bosConfig?.app.ui.development, configDir); if (uiLocalPath && existsSync(join(uiLocalPath, "package.json"))) packages.push("ui"); const apiLocalPath = runtimeConfig?.api.localPath ?? resolveLocalDevelopmentPath(bosConfig?.app.api.development, configDir); if (apiLocalPath && existsSync(join(apiLocalPath, "package.json"))) packages.push("api"); const hostLocalPath = runtimeConfig?.host?.localPath ?? resolveLocalDevelopmentPath(bosConfig?.app.host.development, configDir); if (hostLocalPath && existsSync(join(hostLocalPath, "package.json"))) packages.push("host"); else if (existsSync(join(configDir, "host", "package.json"))) packages.push("host"); for (const [pluginId, pluginConfig] of Object.entries(runtimeConfig?.plugins ?? {})) { if (pluginConfig.localPath && existsSync(join(pluginConfig.localPath, "package.json"))) packages.push(`plugin:${pluginId}`); if (pluginConfig.ui?.localPath && existsSync(join(pluginConfig.ui.localPath, "package.json"))) packages.push(`plugin-ui:${pluginId}`); } const authLocalPath = runtimeConfig?.auth?.localPath ?? resolveLocalDevelopmentPath(bosConfig?.app.auth?.development, configDir); if (authLocalPath && existsSync(join(authLocalPath, "package.json"))) packages.push("auth"); return packages; } function buildRuntimeConfig(bosConfig, options) { return buildRuntimeConfig$1(bosConfig, getProjectRoot(), options.env ?? "development", { hostSource: options.hostSource, uiSource: options.uiSource, apiSource: options.apiSource, authSource: options.authSource, proxy: options.proxy, plugins: options.plugins }); } function probeTcpOpen(port, timeoutMs = 250) { return new Promise((resolve) => { const socket = createConnection({ host: "127.0.0.1", port }); const timer = setTimeout(() => { socket.destroy(); resolve(false); }, timeoutMs); socket.once("connect", () => { clearTimeout(timer); socket.destroy(); resolve(true); }); socket.once("error", () => { clearTimeout(timer); resolve(false); }); }); } async function pickAvailablePort(preferred, usedPorts) { let port = preferred; while (usedPorts.has(port) || await probeTcpOpen(port)) port += 1; usedPorts.add(port); return port; } function withLocalRuntimeUrl(entry, port) { const url = `http://localhost:${port}`; return { ...entry, url, entry: `${url}/mf-manifest.json`, port }; } async function prepareDevelopmentRuntimeConfig(runtimeConfig, options) { const usedPorts = /* @__PURE__ */ new Set(); const hostPort = await pickAvailablePort(options?.hostPort ?? DEFAULT_HOST_PORT, usedPorts); const next = { ...runtimeConfig, host: { ...runtimeConfig.host, url: `http://localhost:${hostPort}`, port: hostPort }, ui: { ...runtimeConfig.ui }, api: { ...runtimeConfig.api }, auth: runtimeConfig.auth ? { ...runtimeConfig.auth } : void 0, plugins: runtimeConfig.plugins ? { ...runtimeConfig.plugins } : void 0 }; if (next.api.source === "local" && next.api.localPath) { const apiPort = await pickAvailablePort(next.api.port ?? DEFAULT_API_PORT, usedPorts); next.api = withLocalRuntimeUrl(next.api, apiPort); } if (next.auth?.source === "local" && next.auth.localPath) { const authPort = await pickAvailablePort(next.auth.port ?? DEFAULT_AUTH_PORT, usedPorts); next.auth = withLocalRuntimeUrl(next.auth, authPort); } if (next.ui.source === "local" && next.ui.localPath) { const uiPort = await pickAvailablePort(next.ui.port ?? DEFAULT_UI_PORT, usedPorts); next.ui = withLocalRuntimeUrl(next.ui, uiPort); if (options?.ssr) { const ssrPort = await pickAvailablePort(uiPort + 1, usedPorts); next.ui.ssrUrl = `http://localhost:${ssrPort}`; } else next.ui.ssrUrl = void 0; } if (next.plugins) { const entries = Object.entries(next.plugins).sort(([a], [b]) => a.localeCompare(b)); let pluginBasePort = DEFAULT_PLUGIN_PORT_START; for (const [pluginId, plugin] of entries) { if (plugin.source === "local" && plugin.localPath) { const pluginPort = await pickAvailablePort(plugin.port ?? pluginBasePort, usedPorts); next.plugins[pluginId] = withLocalRuntimeUrl(plugin, pluginPort); pluginBasePort = pluginPort + 1; } if (plugin.ui?.source === "local" && plugin.ui.localPath) { const uiPort = await pickAvailablePort(plugin.ui.port ?? pluginBasePort, usedPorts); next.plugins[pluginId] = { ...next.plugins[pluginId], ui: withLocalRuntimeUrl(plugin.ui, uiPort) }; pluginBasePort = uiPort + 1; } } } return next; } //#endregion export { buildRuntimeConfig, detectLocalPackages, prepareDevelopmentRuntimeConfig }; //# sourceMappingURL=app.mjs.map