everything-dev
Version:
A consolidated product package for building Module Federation apps with oRPC APIs.
96 lines (94 loc) • 4.01 kB
JavaScript
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
//#region src/ui/router.ts
function getMetaKey(meta) {
if (!meta) return "null";
if ("title" in meta) return "title";
if ("charSet" in meta) return "charSet";
if ("name" in meta) return `name:${meta.name}`;
if ("property" in meta) return `property:${meta.property}`;
if ("httpEquiv" in meta) return `httpEquiv:${meta.httpEquiv}`;
return JSON.stringify(meta);
}
function getLinkKey(link) {
return `${link.rel ?? ""}:${link.href ?? ""}`;
}
function getScriptKey(script) {
if (!script) return "null";
if ("src" in script && script.src) return `src:${script.src}`;
if ("children" in script && script.children) return `children:${typeof script.children === "string" ? script.children : JSON.stringify(script.children)}`;
return JSON.stringify(script);
}
async function collectHeadData(router) {
await router.load();
const metaMap = /* @__PURE__ */ new Map();
const linkMap = /* @__PURE__ */ new Map();
const scriptMap = /* @__PURE__ */ new Map();
for (const match of router.state.matches) {
const headFn = (router.routesById?.[match.routeId] ?? match.route)?.options?.head;
if (!headFn) continue;
try {
const headResult = await headFn({
loaderData: match.loaderData,
matches: router.state.matches,
match,
params: match.params
});
if (headResult?.meta) for (const meta of headResult.meta) metaMap.set(getMetaKey(meta), meta);
if (headResult?.links) for (const link of headResult.links) linkMap.set(getLinkKey(link), link);
if (headResult?.scripts) for (const script of headResult.scripts) scriptMap.set(getScriptKey(script), script);
} catch (error) {
console.warn(`[collectHeadData] head() failed for ${match.routeId}:`, error);
}
}
return {
meta: [...metaMap.values()],
links: [...linkMap.values()],
scripts: [...scriptMap.values()]
};
}
function escapeHtml(s) {
return s.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
}
function serializeMeta(meta) {
if (!meta) return "";
if ("charSet" in meta) return `<meta charset="${escapeHtml(String(meta.charSet))}">`;
if ("title" in meta) return `<title>${escapeHtml(String(meta.title))}</title>`;
return `<meta ${Object.entries(meta).filter(([, v]) => v != null).map(([k, v]) => `${k}="${escapeHtml(String(v))}"`).join(" ")}>`;
}
function serializeLink(link) {
if (!link) return "";
return `<link ${Object.entries(link).filter(([, v]) => v != null).map(([k, v]) => `${k}="${escapeHtml(String(v))}"`).join(" ")}>`;
}
function serializeScript(script, cspNonce) {
if (!script) return "";
if ("src" in script && script.src) {
const attrs = [`src="${escapeHtml(script.src)}"`];
if (script.integrity) attrs.push(`integrity="${escapeHtml(script.integrity)}"`);
if (script.crossOrigin) attrs.push(`crossorigin="${escapeHtml(script.crossOrigin)}"`);
if (script.type) attrs.push(`type="${escapeHtml(script.type)}"`);
if (cspNonce) attrs.push(`nonce="${cspNonce}"`);
return `<script ${attrs.join(" ")}><\/script>`;
}
if ("children" in script) {
const attrs = [];
if (script.type) attrs.push(`type="${escapeHtml(script.type)}"`);
if (cspNonce) attrs.push(`nonce="${cspNonce}"`);
const content = typeof script.children === "string" ? script.children : JSON.stringify(script.children);
return `<script${attrs.length ? ` ${attrs.join(" ")}` : ""}>${content}<\/script>`;
}
return "";
}
function serializeHeadData(headData, cspNonce) {
return {
metaHtml: headData.meta.filter(Boolean).map((m) => serializeMeta(m)).join("\n"),
linkHtml: headData.links.filter(Boolean).map((l) => serializeLink(l)).join("\n"),
scriptHtml: headData.scripts.filter(Boolean).map((s) => serializeScript(s, cspNonce)).join("\n")
};
}
//#endregion
exports.collectHeadData = collectHeadData;
exports.getLinkKey = getLinkKey;
exports.getMetaKey = getMetaKey;
exports.getScriptKey = getScriptKey;
exports.serializeHeadData = serializeHeadData;
//# sourceMappingURL=router.cjs.map