everything-dev
Version:
A consolidated product package for building Module Federation apps with oRPC APIs.
115 lines (113 loc) • 4.18 kB
JavaScript
const require_merge = require('./merge.cjs');
const require_types = require('../../types.cjs');
const require_load = require('./load.cjs');
const require_services_resolution_session = require('./session.cjs');
//#region src/services/resolution/boot-check.ts
function extendsRefOf(payload) {
return payload !== null && typeof payload === "object" && payload.extends ? require_merge.resolveExtendsRef(payload.extends, require_load.PUBLISHED_CONFIG_ENV) : void 0;
}
/**
* The boot walk itself, exposed so consumers beside `verifyBootPayload` can
* gate on the merged shape (the deploy train's composition gate) instead of
* re-walking under their own walker. Throws on chain failure; the caller
* decides how to report it.
*/
async function resolveBootShape(payload, slot, opts = {}) {
if (payload === null || typeof payload !== "object") throw new Error("payload is not a config object");
const input = payload;
if (!extendsRefOf(input)) return {
chain: [],
config: structuredClone(input)
};
const walked = await require_services_resolution_session.walkExtendsChain(`bos://${slot.account}/${slot.gateway}`, {
env: require_load.PUBLISHED_CONFIG_ENV,
...opts.registry ? { registry: opts.registry } : {},
...opts.io ? { io: opts.io } : {},
seedConfig: structuredClone(input),
visit: async () => {}
});
return {
chain: walked.chain.slice(1),
config: structuredClone(walked.config)
};
}
/** Verify a payload against a shape the caller already walked with
* `resolveBootShape` for this exact payload — the pure half of
* `verifyBootPayload`, so a shared walk cannot drift from its verification. */
function verifyResolvedBootShape(payload, shape) {
if (!extendsRefOf(payload)) return {
chain: [],
...parseShape(payload, payload, false)
};
return {
chain: shape.chain,
...parseShape(payload, shape.config, true)
};
}
async function verifyBootPayload(payload, slot, opts = {}) {
if (payload === null || typeof payload !== "object") return {
ok: false,
issues: [{
code: "schema",
path: "",
origin: "payload",
message: "payload is not a config object"
}],
chain: []
};
try {
return verifyResolvedBootShape(payload, await resolveBootShape(payload, slot, opts));
} catch (error) {
if (!(error instanceof Error)) throw error;
return {
ok: false,
chain: [],
issues: [{
code: "chain",
path: extendsRefOf(payload) ?? "",
origin: "parent",
message: chainFailureMessage(error)
}]
};
}
}
/** Parse a shape with BosConfigSchema and map the outcome onto a report —
* the merged shape in the child path, the payload itself in the root path.
* Origin attribution (child path only): a failing dotted path that exists
* in the leaf payload is the leaf's; anything else came from the chain. */
function parseShape(payload, shape, attributed) {
const parsed = require_types.BosConfigSchema.safeParse(shape);
if (parsed.success) return {
ok: true,
issues: []
};
return {
ok: false,
issues: parsed.error.issues.map((issue) => ({
code: "schema",
path: issue.path.join("."),
origin: !attributed || pathExistsIn(payload, issue.path) ? "payload" : "parent",
message: issue.message
}))
};
}
function pathExistsIn(payload, path) {
let cursor = payload;
for (const key of path) {
if (cursor === null || typeof cursor !== "object" || !(key in cursor)) return false;
cursor = cursor[key];
}
return true;
}
function chainFailureMessage(error) {
if (error instanceof require_load.CircularExtendsError) return `circular extends: ${error.message}`;
if (error instanceof require_load.ConfigNotfoundError) return `a parent config could not be found: ${error.message}`;
if (error instanceof require_load.ConfigLoadError) return `a parent config could not be loaded: ${error.message}`;
if (error instanceof require_load.ConfigExtendsError) return `the extends chain could not be resolved: ${error.message}`;
return `the extends chain could not be resolved: ${error.message}`;
}
//#endregion
exports.resolveBootShape = resolveBootShape;
exports.verifyBootPayload = verifyBootPayload;
exports.verifyResolvedBootShape = verifyResolvedBootShape;
//# sourceMappingURL=boot-check.cjs.map