@openinc/parse-server-opendash
Version:
Parse Server Cloud Code for open.INC Stack.
111 lines (110 loc) • 5.02 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConfigApplier = void 0;
const config_1 = require("../config");
class ConfigApplier {
static async apply(root, configFiles, githubClient, branch, rootPath) {
if (!configFiles.length)
return;
for (const cfgFile of configFiles) {
let folderPath = "";
if (cfgFile.path.endsWith("/config.json"))
folderPath = cfgFile.path.slice(0, -"/config.json".length);
const folder = folderPath
? this.findFolderByPath(root, folderPath)
: root;
if (!folder)
continue;
try {
if (githubClient) {
const customRaw = await this.fetchConfigFromGitHub(cfgFile, githubClient, branch, rootPath);
const custom = (0, config_1.sanitizeFolderConfig)(customRaw);
this.diffAndWarnFolderConfig(customRaw, custom, cfgFile.path);
folder.config = { ...folder.config, ...custom };
if (folder.config.files)
this.applyFileConfigs(folder);
}
}
catch (e) {
console.warn(`Failed to apply config ${cfgFile.path}`, e);
}
}
}
/** Compare raw vs sanitized folder config and log warnings for dropped / invalid entries */
static diffAndWarnFolderConfig(raw, sanitized, sourcePath) {
if (!raw || typeof raw !== "object")
return;
const allowedSet = new Set(config_1.FOLDER_CONFIG_ALLOWED_KEYS);
for (const key of Object.keys(raw)) {
if (!allowedSet.has(key)) {
console.warn(`[ConfigApplier] Unknown folder config key '${key}' in ${sourcePath}. Allowed: ${config_1.FOLDER_CONFIG_ALLOWED_KEYS.join(", ")}`);
}
}
// File config diffs
if (raw.files && typeof raw.files === "object") {
for (const [fileBase, rawFile] of Object.entries(raw.files)) {
const sanitizedFile = sanitized.files?.[fileBase];
this.diffAndWarnFileConfig(rawFile, sanitizedFile || {}, sourcePath, fileBase);
}
}
}
static diffAndWarnFileConfig(raw, sanitized, sourcePath, fileBase) {
if (!raw || typeof raw !== "object")
return;
const allowedSet = new Set(config_1.FILE_CONFIG_ALLOWED_KEYS);
for (const key of Object.keys(raw)) {
if (!allowedSet.has(key)) {
console.warn(`[ConfigApplier] Unknown file config key '${key}' for '${fileBase}' in ${sourcePath}. Allowed: ${config_1.FILE_CONFIG_ALLOWED_KEYS.join(", ")}`);
}
}
// Basic type checks for known keys
if ("order" in raw && raw.order != null && typeof raw.order !== "number") {
console.warn(`[ConfigApplier] Invalid type for 'order' (expected number) in file '${fileBase}' (${sourcePath})`);
}
if ("icon" in raw && raw.icon != null && typeof raw.icon !== "string") {
console.warn(`[ConfigApplier] Invalid type for 'icon' (expected string) in file '${fileBase}' (${sourcePath})`);
}
if ("title" in raw && raw.title != null && typeof raw.title !== "string") {
console.warn(`[ConfigApplier] Invalid type for 'title' (expected string) in file '${fileBase}' (${sourcePath})`);
}
if ("locations" in raw &&
raw.locations != null &&
(!Array.isArray(raw.locations) ||
raw.locations.some((v) => typeof v !== "string"))) {
console.warn(`[ConfigApplier] Invalid type for 'locations' (expected string[]) in file '${fileBase}' (${sourcePath})`);
}
}
static async fetchConfigFromGitHub(cfgFile, githubClient, branch, rootPath) {
const normalizedRoot = rootPath?.replace(/^\/+/g, "").replace(/\/+$/g, "");
const fullPath = normalizedRoot
? `${normalizedRoot}/${cfgFile.path}`
: cfgFile.path;
const fileContent = await githubClient.getFileContent(fullPath);
const json = Buffer.from(fileContent.content, "base64").toString("utf-8");
return JSON.parse(json);
}
static applyFileConfigs(folder) {
if (!folder.config.files)
return;
for (const file of folder.files) {
const cfg = folder.config.files[file.name];
if (cfg) {
file.config = { ...config_1.DEFAULT_FILE_CONFIG, ...cfg };
}
}
}
static findFolderByPath(root, path) {
if (!path)
return root;
const parts = path.split("/").filter(Boolean);
let current = root;
for (const segment of parts) {
const next = current.subfolders.get(segment);
if (!next)
return null;
current = next;
}
return current;
}
}
exports.ConfigApplier = ConfigApplier;