import { access, readFile, writeFile } from "node:fs/promises"; import path from "node:path"; const endpointCandidates = [ "node_modules/@rmdes/indiekit-endpoint-podroll", "node_modules/@indiekit/indiekit/node_modules/@rmdes/indiekit-endpoint-podroll", ]; const dashboardFormOld = '
'; const dashboardFormNew = ''; const dashboardOpmlFieldOld = [ '
', ' ', ' {{ __("podroll.opmlUrlHelp") }}', ' ', '
', ].join("\n"); const dashboardOpmlFieldNew = [ '
', ' ', ' {{ __("podroll.opmlUrlHelp") }}', ' ', '
', '
', ' ', ' {{ __("podroll.opmlFileHelp") }}', ' ', ' {% if config.hasOpmlUpload %}', '

{{ __("podroll.opmlFileActive") }}

', ' {% endif %}', '
', '
', ' ', '
', ].join("\n"); const controllerGetEffectiveOld = [ '/**', ' * Get effective URLs: DB-stored settings override env var defaults', ' * @param {object} db - MongoDB database instance', ' * @param {object} podrollConfig - Plugin config from env vars', ' * @returns {Promise} Effective episodesUrl and opmlUrl', ' */', 'async function getEffectiveUrls(db, podrollConfig) {', ' let episodesUrl = podrollConfig?.episodesUrl || "";', ' let opmlUrl = podrollConfig?.opmlUrl || "";', '', ' if (db) {', ' const settings = await db', ' .collection("podrollMeta")', ' .findOne({ key: "settings" });', ' if (settings) {', ' if (settings.episodesUrl) episodesUrl = settings.episodesUrl;', ' if (settings.opmlUrl) opmlUrl = settings.opmlUrl;', ' }', ' }', '', ' return { episodesUrl, opmlUrl };', '}', ].join("\n"); const controllerGetEffectiveNew = [ '/**', ' * Get effective podroll configuration: DB-stored settings override env var defaults', ' * @param {object} db - MongoDB database instance', ' * @param {object} podrollConfig - Plugin config from env vars', ' * @returns {Promise} Effective episodesUrl, opmlUrl and opmlUpload', ' */', 'async function getEffectiveUrls(db, podrollConfig) {', ' let episodesUrl = podrollConfig?.episodesUrl || "";', ' let opmlUrl = podrollConfig?.opmlUrl || "";', ' let opmlUpload = podrollConfig?.opmlUpload || "";', '', ' if (db) {', ' const settings = await db', ' .collection("podrollMeta")', ' .findOne({ key: "settings" });', ' if (settings) {', ' if (settings.episodesUrl) episodesUrl = settings.episodesUrl;', ' if (settings.opmlUrl) opmlUrl = settings.opmlUrl;', ' if (settings.opmlUpload) opmlUpload = settings.opmlUpload;', ' }', ' }', '', ' return { episodesUrl, opmlUrl, opmlUpload };', '}', ].join("\n"); const controllerConfigOld = [ ' config: {', ' episodesUrl: urls.episodesUrl,', ' opmlUrl: urls.opmlUrl,', ' syncInterval: application.podrollConfig?.syncInterval || 900000,', ' },', ].join("\n"); const controllerConfigNew = [ ' config: {', ' episodesUrl: urls.episodesUrl,', ' opmlUrl: urls.opmlUrl,', ' hasOpmlUpload: Boolean(urls.opmlUpload),', ' syncInterval: application.podrollConfig?.syncInterval || 900000,', ' },', ].join("\n"); const controllerSaveOld = [ ' const { episodesUrl, opmlUrl } = request.body;', '', ' await db.collection("podrollMeta").updateOne(', ' { key: "settings" },', ' {', ' $set: {', ' key: "settings",', ' episodesUrl: episodesUrl || "",', ' opmlUrl: opmlUrl || "",', ' updatedAt: new Date().toISOString(),', ' },', ' },', ' { upsert: true },', ' );', ].join("\n"); const controllerSaveNew = [ ' const { episodesUrl, opmlUrl, clearOpmlFile } = request.body;', '', ' const existingSettings = await db', ' .collection("podrollMeta")', ' .findOne({ key: "settings" });', '', ' let opmlUpload = existingSettings?.opmlUpload || "";', '', ' if (clearOpmlFile === "1") {', ' opmlUpload = "";', ' }', '', ' const uploadedFileRaw = request.files?.opmlFile;', ' const uploadedFile = Array.isArray(uploadedFileRaw)', ' ? uploadedFileRaw[0]', ' : uploadedFileRaw;', '', ' if (uploadedFile) {', ' const uploadedName = String(uploadedFile.name || "");', ' const uploadedType = String(uploadedFile.mimetype || "").toLowerCase();', ' const isXmlName = /\\.(opml|xml)$/i.test(uploadedName);', ' const isXmlType = uploadedType.includes("xml");', '', ' if (!isXmlName && !isXmlType) {', ' throw new Error(request.__("podroll.opmlFileInvalidType"));', ' }', '', ' if (uploadedFile.size > 1_048_576) {', ' throw new Error(request.__("podroll.opmlFileTooLarge"));', ' }', '', ' const opmlText = Buffer.from(uploadedFile.data).toString("utf8").trim();', '', ' if (!opmlText || !opmlText.toLowerCase().includes("