UNPKG

everything-dev

Version:

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

220 lines (218 loc) 7.87 kB
const require_runtime = require('./_virtual/_rolldown/runtime.cjs'); const require_fastkv = require('./fastkv.cjs'); const require_network = require('./network.cjs'); const require_config = require('./config.cjs'); const require_string = require('./utils/string.cjs'); const require_theme = require('./utils/theme.cjs'); const require_build = require('./build.cjs'); const require_code_artifacts = require('./code-artifacts.cjs'); const require_near_cli = require('./near-cli.cjs'); let node_fs = require("node:fs"); let node_path = require("node:path"); let effect = require("effect"); let node_process = require("node:process"); node_process = require_runtime.__toESM(node_process, 1); //#region src/publish.ts function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } function extractPublishedUrl(output) { const deployMatch = output.match(/🚀.*Deployed:\s*(https?:\S+)/); if (deployMatch) return deployMatch[1]; const match = output.match(/https?:\/\/[^\s"'<>]+/g); if (!match || match.length === 0) return null; return match[match.length - 1] ?? null; } async function waitForPublishedConfig(opts) { const envTimeoutMs = Number(node_process.default.env.BOS_PUBLISH_CONFIRMATION_TIMEOUT_MS); const envIntervalMs = Number(node_process.default.env.BOS_PUBLISH_CONFIRMATION_INTERVAL_MS); const timeoutMs = opts.timeoutMs ?? (Number.isFinite(envTimeoutMs) ? envTimeoutMs : void 0) ?? 12e4; const intervalMs = opts.intervalMs ?? (Number.isFinite(envIntervalMs) ? envIntervalMs : void 0) ?? 3e3; const startedAt = Date.now(); let lastError; while (Date.now() - startedAt < timeoutMs) { try { const verifiedConfig = await require_fastkv.fetchBosConfigFromFastKv(`bos://${opts.account}/${opts.gateway}`); if (JSON.stringify(verifiedConfig) === JSON.stringify(opts.publishConfig)) return; } catch (error) { lastError = error; } await sleep(intervalMs); } const reason = lastError instanceof Error ? ` Last error: ${lastError.message}` : ""; throw new Error(`Timed out waiting for publish confirmation at bos://${opts.account}/${opts.gateway}.${reason}`); } async function publishToFastKv(input) { const { env, dryRun, configDir } = input; let bosConfig = input.bosConfig; const runtimeConfig = input.runtimeConfig; const isStaging = env === "staging"; const account = bosConfig.account; const gateway = isStaging ? bosConfig.staging?.domain ?? bosConfig.domain : bosConfig.domain; if (!gateway) return { status: "error", registryUrl: "", error: "bos.config.json must define domain to publish" }; const network = input.network ?? require_network.getNetworkIdForAccount(account); const registryUrl = require_fastkv.buildRegistryConfigUrlForNetwork(network, account, gateway); const targets = require_build.selectWorkspaceTargets(input.packages, bosConfig); let built; let skipped; let deployResults; if (dryRun) return { status: "dry-run", registryUrl, built, skipped }; const privateKey = input.privateKey || node_process.default.env.NEAR_PRIVATE_KEY || node_process.default.env.BOS_NEAR_PRIVATE_KEY; let signingMode; try { signingMode = require_near_cli.resolveNearSigningMode(privateKey); } catch (error) { return { status: "error", registryUrl, error: error instanceof Error ? error.message : "Unknown error" }; } if (input.build) { console.log(" Ensuring NEAR CLI..."); await effect.Effect.runPromise(require_near_cli.ensureNearCli); console.log(" NEAR CLI ready"); await require_code_artifacts.generateCodeArtifacts(configDir, bosConfig, { env: "production", runtimeConfig: runtimeConfig ?? void 0 }); const result = await require_build.buildWorkspaceTargets({ configDir, bosConfig, runtimeConfig, targets, deploy: true, verbose: input.verbose }); built = result.built; skipped = result.skipped; deployResults = result.deployResults; if (deployResults) { const failures = deployResults.filter((r) => !r.success); if (failures.length > 0) { const total = deployResults.length; console.log(); console.log(require_theme.colors.error(` ${require_theme.icons.err} Deploy failed — ${failures.length} of ${total} workspace${total > 1 ? "s" : ""} failed`)); console.log(); for (const f of failures) { const errorLine = (f.error ?? "Failed").split("\n")[0]; console.log(` ${require_theme.colors.error(require_theme.icons.err)} ${require_string.padRight(f.key, 28)} ${errorLine}`); } console.log(); if (!input.verbose) { console.log(require_theme.colors.dim(" Run with --verbose for full build output.")); console.log(); } return { status: "error", registryUrl, built, skipped, deployResults, error: `${failures.length} of ${total} workspaces failed to deploy` }; } } const refreshed = await require_config.loadResolvedConfig({ cwd: configDir }); if (!refreshed?.config) return { status: "error", registryUrl, built, skipped, deployResults, error: "Failed to reload bos.config.json after build" }; bosConfig = refreshed.config; } const rawConfigPath = (0, node_path.join)(configDir, "bos.config.json"); const rawConfig = JSON.parse((0, node_fs.readFileSync)(rawConfigPath, "utf-8")); const publishPayload = isStaging ? { ...rawConfig, domain: gateway } : rawConfig; const registryEntries = { [`apps/${account}/${gateway}/bos.config.json`]: JSON.stringify(publishPayload) }; const payload = JSON.stringify(registryEntries); const argsBase64 = Buffer.from(payload).toString("base64"); console.log(); console.log(" Publishing to:"); console.log(` ${require_theme.colors.cyan(registryUrl)}`); try { let txHash; console.log(` Submitting transaction on ${network}...`); try { const tx = await effect.Effect.runPromise(require_near_cli.executeTransaction({ account, contract: require_fastkv.getRegistryNamespaceForNetwork(network), method: "__fastdata_kv", argsBase64, network, privateKey: signingMode._tag === "privateKey" ? signingMode.privateKey : void 0, gas: "300Tgas", deposit: "0NEAR", verbose: input.verbose }, signingMode)); txHash = tx.txHash; if (txHash && !tx.output?.includes("CodeDoesNotExist")) console.log(` Transaction submitted: ${require_theme.colors.dim(txHash)}`); } catch (error) { console.log(require_theme.colors.dim(" Transaction reported an error — verifying publish...")); try { await waitForPublishedConfig({ account, gateway, publishConfig: publishPayload, timeoutMs: 3e4, intervalMs: 2e3 }); txHash = extractTransactionHash(error); } catch { throw error; } } console.log(" Waiting for publish confirmation..."); await waitForPublishedConfig({ account, gateway, publishConfig: publishPayload }); return { status: "published", registryUrl, txHash, built, skipped, deployResults, publishConfig: publishPayload }; } catch (error) { return { status: "error", registryUrl, error: formatNearError(error), built, skipped, deployResults }; } } function formatNearError(error) { const message = error instanceof Error ? error.message : String(error); if (message.includes("exceeded gas") || message.includes("GasLimitExceeded")) return `Transaction exceeded gas limit.\n Original: ${message}`; if (message.includes("timeout") || message.includes("Timeout")) return `Transaction timed out. Check NEAR network status.\n Original: ${message}`; return message; } function extractTransactionHash(error) { return (error instanceof Error ? error.message : String(error)).match(/Transaction ID:\s*([A-Za-z0-9]+)/i)?.[1]; } //#endregion exports.extractPublishedUrl = extractPublishedUrl; exports.publishToFastKv = publishToFastKv; //# sourceMappingURL=publish.cjs.map