"use strict"; const fs = require("fs"); const path = require("path"); function isDirectory(p) { try { return fs.statSync(p).isDirectory(); } catch (e) { return false; } } function safeReadJson(filePath, logFn) { try { const txt = fs.readFileSync(filePath, "utf8"); if (!txt || txt.trim().length === 0) return null; return JSON.parse(txt); } catch (e) { if (logFn) logFn("provider json read failed", filePath, e && e.message ? e.message : e); return null; } } function loadFromJson(filePath, ctx) { const obj = safeReadJson(filePath, ctx && ctx.log); if (!obj) return []; if (Array.isArray(obj)) return obj; if (obj && Array.isArray(obj.entries)) return obj.entries; if (obj && Array.isArray(obj.buttons)) return obj.buttons; return []; } function loadFromJs(filePath, ctx) { try { // eslint-disable-next-line global-require, import/no-dynamic-require const mod = require(filePath); if (!mod) return []; if (typeof mod === "function") return mod(ctx) || []; if (typeof mod.getEntries === "function") return mod.getEntries(ctx) || []; if (Array.isArray(mod.entries)) return mod.entries; return []; } catch (e) { if (ctx && ctx.log) ctx.log("provider js load failed", filePath, e && e.message ? e.message : e); return []; } } function loadProviderEntries(providersDir, ctx) { const out = []; if (!providersDir || !fs.existsSync(providersDir) || !isDirectory(providersDir)) { return out; } let files; try { files = fs.readdirSync(providersDir); } catch (e) { return out; } files.sort(); files.forEach(function (name) { if (!name || name.charAt(0) === ".") return; const full = path.join(providersDir, name); if (isDirectory(full)) return; if (name.indexOf(".json", name.length - 5) !== -1) { const entries = loadFromJson(full, ctx); entries.forEach(function (e) { out.push(e); }); return; } if (name.indexOf(".js", name.length - 3) !== -1) { const entries = loadFromJs(full, ctx); entries.forEach(function (e) { out.push(e); }); } }); return out; } // Merge provider entries into scanned entries by id. // Provider entries win on conflicts. function mergeById(scannedEntries, providerEntries) { const byId = {}; (scannedEntries || []).forEach(function (e) { if (!e || !e.id) return; byId[e.id] = e; }); (providerEntries || []).forEach(function (p) { if (!p || !p.id) return; byId[p.id] = p; }); const merged = Object.keys(byId).map(function (k) { return byId[k]; }); merged.sort(function (a, b) { const ao = typeof a.order === "number" ? a.order : 100; const bo = typeof b.order === "number" ? b.order : 100; if (ao !== bo) return ao - bo; return String(a.title || a.label || a.id).localeCompare(String(b.title || b.label || b.id)); }); return merged; } module.exports = { loadProviderEntries: loadProviderEntries, mergeById: mergeById };