everything-dev
Version:
A consolidated product package for building Module Federation apps with oRPC APIs.
155 lines (153 loc) • 5.69 kB
JavaScript
const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
const require_merge = require('./merge.cjs');
const require_types = require('./types.cjs');
let node_fs = require("node:fs");
let node_path = require("node:path");
let node_crypto = require("node:crypto");
//#region src/shared.ts
function sha256(input) {
return (0, node_crypto.createHash)("sha256").update(input).digest("hex");
}
function extractSemverExact(input) {
if (typeof input !== "string") return null;
const match = input.match(/\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?/);
return match ? match[0] : null;
}
function caretRange(version) {
return `^${version}`;
}
function stableDepsObject(deps) {
const keys = Object.keys(deps).sort((a, b) => a.localeCompare(b));
const out = {};
for (const k of keys) out[k] = deps[k];
return out;
}
function writeFileIfChanged(filePath, nextContent) {
try {
if ((0, node_fs.readFileSync)(filePath, "utf-8") === nextContent) return false;
} catch {}
(0, node_fs.writeFileSync)(filePath, nextContent);
return true;
}
function fingerprintResolved(deps) {
const stable = stableDepsObject(deps);
return sha256(JSON.stringify(stable));
}
function getSharedUiDeps(bosConfig) {
return (bosConfig.shared ?? {}).ui ?? {};
}
async function syncAndGenerateSharedUi(opts) {
const bosConfigPath = (0, node_path.join)(opts.configDir, "bos.config.json");
const resolvedConfigPath = (0, node_path.join)(opts.configDir, ".bos", "bos.resolved-config.json");
const packageJsonPath = (0, node_path.join)(opts.configDir, "package.json");
const generatedPath = (0, node_path.join)(opts.configDir, ".bos", "generated", "shared-ui.json");
let bosConfig;
if (opts.bosConfig) bosConfig = opts.bosConfig;
else {
const raw = JSON.parse((0, node_fs.readFileSync)(bosConfigPath, "utf-8"));
bosConfig = require_types.BosConfigSchema.parse(raw);
}
let pkgJson = {};
try {
pkgJson = JSON.parse((0, node_fs.readFileSync)(packageJsonPath, "utf-8"));
} catch {}
const originalBos = JSON.stringify(bosConfig);
const originalPkg = JSON.stringify(pkgJson);
const catalog = pkgJson?.workspaces?.catalog ?? {};
const sharedUi = getSharedUiDeps(bosConfig);
const mode = opts.hostMode === "local" ? "catalog->bos" : "bos->catalog";
if (mode === "catalog->bos") for (const [name, cfg] of Object.entries(sharedUi)) {
const dep = cfg;
const version = catalog[name] ?? extractSemverExact(dep.version) ?? extractSemverExact(dep.requiredVersion);
if (!version) continue;
dep.version = version;
dep.requiredVersion = caretRange(version);
dep.shareScope = dep.shareScope ?? "default";
}
else {
for (const [name, cfg] of Object.entries(sharedUi)) {
const dep = cfg;
const version = extractSemverExact(dep.version) ?? extractSemverExact(dep.requiredVersion);
if (!version) continue;
dep.version = version;
dep.requiredVersion = caretRange(version);
dep.shareScope = dep.shareScope ?? "default";
if (catalog[name] !== version) catalog[name] = version;
}
if (!pkgJson.workspaces) pkgJson.workspaces = {
packages: [],
catalog: {}
};
pkgJson.workspaces.catalog = catalog;
}
const nextBos = JSON.stringify(bosConfig);
const nextPkg = JSON.stringify(pkgJson);
const bosConfigChanged = nextBos !== originalBos;
const catalogChanged = nextPkg !== originalPkg;
if (bosConfigChanged) if (mode === "catalog->bos") {
const resolvedDir = (0, node_path.dirname)(resolvedConfigPath);
if (!(0, node_fs.existsSync)(resolvedDir)) (0, node_fs.mkdirSync)(resolvedDir, { recursive: true });
const ordered = require_merge.rebuildOrderedConfig(bosConfig);
const resolvedOutput = {
_resolved: {
env: opts.env ?? "development",
resolvedAt: (/* @__PURE__ */ new Date()).toISOString(),
extendsChain: opts.extendsChain ?? [],
source: "shared-sync"
},
...ordered
};
writeFileIfChanged(resolvedConfigPath, `${JSON.stringify(resolvedOutput, null, 2)}\n`);
} else writeFileIfChanged(bosConfigPath, `${JSON.stringify(bosConfig, null, 2)}\n`);
if (catalogChanged) writeFileIfChanged(packageJsonPath, `${JSON.stringify(pkgJson, null, 2)}\n`);
const resolvedDeps = {};
for (const [name, cfg] of Object.entries(getSharedUiDeps(bosConfig))) {
const version = catalog[name] ?? extractSemverExact(cfg.version) ?? extractSemverExact(cfg.requiredVersion);
if (!version) continue;
resolvedDeps[name] = {
name,
version,
requiredVersion: caretRange(version),
shareScope: cfg.shareScope ?? "default",
singleton: cfg.singleton ?? false,
eager: cfg.eager ?? false,
strictVersion: cfg.strictVersion ?? false
};
}
const stableResolvedDeps = stableDepsObject(resolvedDeps);
const resolved = {
deps: stableResolvedDeps,
fingerprintSha256: fingerprintResolved(stableResolvedDeps)
};
const nextGenerated = {
schemaVersion: 1,
kind: "everything-dev/shared-ui",
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
ui: {
deps: stableResolvedDeps,
fingerprintSha256: resolved.fingerprintSha256
},
inputs: {
mode,
hostMode: opts.hostMode
}
};
let prevFingerprint = null;
try {
prevFingerprint = JSON.parse((0, node_fs.readFileSync)(generatedPath, "utf-8"))?.ui?.fingerprintSha256 ?? null;
} catch {}
(0, node_fs.mkdirSync)((0, node_path.dirname)(generatedPath), { recursive: true });
writeFileIfChanged(generatedPath, `${JSON.stringify(nextGenerated, null, 2)}\n`);
const generatedChanged = prevFingerprint !== nextGenerated.ui.fingerprintSha256;
return {
mode,
hostMode: opts.hostMode,
bosConfigChanged,
catalogChanged,
generatedChanged,
resolved
};
}
//#endregion
exports.syncAndGenerateSharedUi = syncAndGenerateSharedUi;
//# sourceMappingURL=shared.cjs.map