everything-dev
Version:
A consolidated product package for building Module Federation apps with oRPC APIs.
146 lines (145 loc) • 6.59 kB
JavaScript
//#region src/services/deploy/cdn.ts
const LOCAL_HOSTNAMES = /* @__PURE__ */ new Set([
"localhost",
"127.0.0.1",
"::1",
"[::1]",
"0.0.0.0",
"local"
]);
/** Local/private destinations can never serve production bundles. */
function isLocalOrigin(url) {
try {
const { hostname, protocol } = new URL(url);
if (protocol !== "http:" && protocol !== "https:") return true;
const host = hostname.toLowerCase().replace(/^\[|\]$/g, "");
return LOCAL_HOSTNAMES.has(host) || host.endsWith(".localhost") || host.endsWith(".local") || /^127\.\d+\.\d+\.\d+$/.test(host) || /^10\.\d+\.\d+\.\d+$/.test(host) || /^192\.168\.\d+\.\d+$/.test(host) || /^172\.(1[6-9]|2\d|3[01])\.\d+\.\d+$/.test(host) || host.startsWith("169.254.") || host.includes(":") && (host.startsWith("fe80:") || host.startsWith("fc") || host.startsWith("fd"));
} catch {
return true;
}
}
/**
* Deploy origin resolution (ADR 0020, as amended): the CDN origin comes from
* the env or the authored `cdn.origin` (inherited via extends) — a hard
* requirement when uploads are planned, because the host never serves
* `/bundles` itself. The upload origin is the env, the `bos login` session's
* siteUrl, or the runtime's own gateway. A session pinned to a local site is
* a hard error (the origin can only ever be a squatter's port); an env-pinned
* local origin is deliberate local testing and only warns. Config-only
* publishes (`uploadsPlanned: false`) ship the committed config verbatim —
* no origins are resolved and nothing is required.
*/
function resolveCdnDeployInputs(input) {
const envCdnOrigin = input.env.BOS_BUNDLE_CDN_ORIGIN?.replace(/\/$/, "");
const configCdnOrigin = input.bosConfig?.cdn?.origin?.replace(/\/$/, "");
const storageEnvOrigin = input.env.BOS_STORAGE_ORIGIN?.replace(/\/$/, "");
const sessionSite = input.session?.siteUrl?.replace(/\/$/, "");
const apiKey = input.env.BOS_STORAGE_API_KEY ?? input.session?.apiKey;
const uploadsPlanned = input.uploadsPlanned;
const storageOriginDefault = storageEnvOrigin ?? sessionSite ?? `https://${input.gateway}`;
if (!uploadsPlanned) return {
cdnOrigin: void 0,
storageOrigin: storageOriginDefault,
apiKey
};
let cdnOrigin;
let warning;
if (envCdnOrigin) {
cdnOrigin = envCdnOrigin;
if (isLocalOrigin(envCdnOrigin)) warning = `BOS_BUNDLE_CDN_ORIGIN is a local URL (${envCdnOrigin}) — deploying to a local stack, published bundle URLs will not resolve publicly.`;
} else if (configCdnOrigin) {
if (isLocalOrigin(configCdnOrigin)) return {
cdnOrigin,
storageOrigin: storageOriginDefault,
apiKey,
error: `the authored config sets cdn.origin to the local URL ${configCdnOrigin} — deploy bundle origins must be publicly reachable. Set BOS_BUNDLE_CDN_ORIGIN for a local deploy, or fix cdn.origin (inherited via extends).`
};
cdnOrigin = configCdnOrigin;
} else return {
cdnOrigin,
storageOrigin: storageOriginDefault,
apiKey,
error: "CDN deploy requires a bundle origin — set `cdn.origin` in bos.config.json (children inherit it from the base runtime via extends) or BOS_BUNDLE_CDN_ORIGIN in the environment."
};
let storageOrigin;
if (storageEnvOrigin) {
storageOrigin = storageEnvOrigin;
if (isLocalOrigin(storageEnvOrigin) && !warning) warning = `BOS_STORAGE_ORIGIN is a local URL (${storageEnvOrigin}) — uploading to a local stack.`;
} else if (sessionSite) {
if (isLocalOrigin(sessionSite)) return {
cdnOrigin,
storageOrigin: sessionSite,
apiKey,
error: `The CLI session pins uploads to ${sessionSite} — a local site can never receive production bundles. Re-run \`bos login\` against the production site, or set BOS_STORAGE_ORIGIN explicitly.`
};
storageOrigin = sessionSite;
} else return {
cdnOrigin,
storageOrigin: storageOriginDefault,
apiKey,
warning,
error: `Bundle uploads require an upload-service origin — the gateway (${input.gateway}) no longer serves uploads (ADR 0027: the upload service is standalone at upload.everything.dev). Set BOS_STORAGE_ORIGIN in the environment (CI) or re-run \`bos login\` against the production site so the session pins it.`
};
if (!apiKey) return {
cdnOrigin,
storageOrigin,
apiKey,
warning,
error: "CDN deploy requires bundle-upload credentials — run `bos login --key` and add the printed key to GitHub secrets as BOS_STORAGE_API_KEY (the deploy key also serves interactive deploys)"
};
const uploadIdentities = new Set([input.session?.accountId, input.custodyAccount].filter((id) => !!id));
if (uploadIdentities.size > 0 && !uploadIdentities.has(input.account)) {
const sessionAccount = input.session?.accountId;
return {
cdnOrigin,
storageOrigin,
apiKey,
warning,
error: sessionAccount ? `The CLI session was created for ${sessionAccount}, but the configured account is ${input.account}. Re-run bos login under the matching account.` : `The configured account is ${input.account}, but the custody publish identity is ${input.custodyAccount}. Set the authored config's account to the custody wallet account.`
};
}
return {
cdnOrigin,
storageOrigin,
apiKey,
warning
};
}
/**
* Pre-upload probe: the storage origin must actually be the bundle-upload
* service.
* `/health` is the primary readiness check, with MCP kept as a compatibility
* fallback for older fixtures and legacy hosts.
*/
async function probeStorageOrigin(storageOrigin, fetchImpl = fetch) {
const base = storageOrigin.replace(/\/$/, "");
const healthUrl = `${base}/health`;
const mcpUrl = `${base}/.well-known/mcp.json`;
let response;
try {
response = await fetchImpl(healthUrl, { headers: { accept: "text/plain" } });
} catch (error) {
return `unreachable (${String(error instanceof Error ? error.message : error)})`;
}
if (response.ok) {
const body = await response.text().catch(() => "");
if (body.trim() === "OK" || body.trim().length === 0) return void 0;
}
let mcpResponse;
try {
mcpResponse = await fetchImpl(mcpUrl, { headers: { accept: "application/json" } });
} catch {
return `GET /health responded ${response.status}; fallback /.well-known/mcp.json unreachable`;
}
if (!mcpResponse.ok) return `GET /health responded ${response.status}; GET /.well-known/mcp.json responded ${mcpResponse.status}`;
try {
const body = await mcpResponse.json();
if (!body || typeof body !== "object") return "did not return the platform MCP descriptor";
return;
} catch {
return "did not return the platform MCP descriptor (non-JSON response)";
}
}
//#endregion
export { isLocalOrigin, probeStorageOrigin, resolveCdnDeployInputs };
//# sourceMappingURL=cdn.mjs.map