openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
74 lines (73 loc) • 2.75 kB
JavaScript
import { D as createConfigIncludeResolutionSession, E as INCLUDE_KEY, k as readConfigIncludeFileWithGuards } from "./redact-BtvPPfTi.js";
import { t as parseJsonWithJson5Fallback } from "./parse-json-compat-Cc8PAOTi.js";
import { v as resolveIncludeRoots } from "./paths-D2sRr1a_.js";
import fs from "node:fs";
import path from "node:path";
//#region src/config/includes-scan.ts
function listDirectIncludes(parsed) {
const out = [];
const visit = (value) => {
if (!value) return;
if (Array.isArray(value)) {
for (const item of value) visit(item);
return;
}
if (typeof value !== "object") return;
const rec = value;
const includeVal = rec[INCLUDE_KEY];
if (typeof includeVal === "string") out.push(includeVal);
else if (Array.isArray(includeVal)) {
for (const item of includeVal) if (typeof item === "string") out.push(item);
}
for (const v of Object.values(rec)) visit(v);
};
visit(parsed);
return out;
}
/** Collects recursively referenced config include files without requiring a valid full config. */
async function collectIncludePathsRecursive(params) {
const includedPaths = /* @__PURE__ */ new Set();
const walkedDepthByBase = /* @__PURE__ */ new Map();
const allowedRoots = params.allowedRoots ?? resolveIncludeRoots(params.env);
const resolveInclude = createConfigIncludeResolutionSession(params.configPath, allowedRoots);
const walk = (basePath, parsed, depth) => {
if (depth >= 10) return;
for (const includePath of listDirectIncludes(parsed)) {
let openedBasePath;
let nestedInclude;
const resolver = {
readFile: (candidate) => fs.readFileSync(candidate, "utf-8"),
readFileWithGuards: (readParams) => {
return readConfigIncludeFileWithGuards({
...readParams,
onResolvedPath: (resolvedIncludePath) => {
includedPaths.add(resolvedIncludePath);
const lexicalBasePath = path.normalize(readParams.resolvedPath);
const nextDepth = depth + 1;
const walkedDepth = walkedDepthByBase.get(lexicalBasePath);
if (walkedDepth !== void 0 && walkedDepth <= nextDepth) return;
walkedDepthByBase.set(lexicalBasePath, nextDepth);
openedBasePath = lexicalBasePath;
}
});
},
parseJson: (raw) => {
const nestedParsed = parseJsonWithJson5Fallback(raw);
if (openedBasePath) nestedInclude = {
basePath: openedBasePath,
parsed: nestedParsed
};
return {};
}
};
try {
resolveInclude({ [INCLUDE_KEY]: includePath }, basePath, resolver);
} catch {}
if (nestedInclude) walk(nestedInclude.basePath, nestedInclude.parsed, depth + 1);
}
};
walk(params.configPath, params.parsed, 0);
return [...includedPaths];
}
//#endregion
export { collectIncludePathsRecursive as t };