diff --git a/scripts/patch-webmention-sender-livefetch.mjs b/scripts/patch-webmention-sender-livefetch.mjs index 0bb9b099..529cf1a9 100644 --- a/scripts/patch-webmention-sender-livefetch.mjs +++ b/scripts/patch-webmention-sender-livefetch.mjs @@ -22,7 +22,7 @@ import { access, readFile, writeFile } from "node:fs/promises"; const filePath = "node_modules/@rmdes/indiekit-endpoint-webmention-sender/lib/controllers/webmention-sender.js"; -const patchMarker = "// [patched:livefetch:v5]"; +const patchMarker = "// [patched:livefetch:v6]"; // Original upstream code const originalBlock = ` // If no content, try fetching the published page @@ -64,6 +64,8 @@ const retryPatchedBlock = ` // If no content, try fetching the published if (!contentToProcess) { if (fetchFailed) { + // Page not yet available — skip and retry on next poll rather than + // permanently marking this post as sent with zero webmentions. console.log(\`[webmention] Page not yet available for \${postUrl}, will retry next poll\`); continue; } @@ -72,7 +74,7 @@ const retryPatchedBlock = ` // If no content, try fetching the published continue; }`; -const newBlock = ` // [patched:livefetch:v5] Build synthetic h-entry HTML from stored post properties. +const newBlock = ` // [patched:livefetch:v6] Build synthetic h-entry HTML from stored post properties. // The stored properties already contain all microformat target URLs // (in-reply-to, like-of, bookmark-of, repost-of) and content.html has inline // links — no live page fetch needed, and no exposure to internal DNS issues. @@ -95,7 +97,8 @@ const newBlock = ` // [patched:livefetch:v5] Build synthetic h-entry HTML } } const _bodyHtml = post.properties.content?.html || post.properties.content?.value || ""; - const contentToProcess = \`
\${_anchors.join("")}\${_bodyHtml ? \`
\${_bodyHtml}
\` : ""}
\`;`; + const contentToProcess = \`
\${_anchors.join("")}\${_bodyHtml ? \`
\${_bodyHtml}
\` : ""}
\`; + console.log(\`[webmention] Built synthetic h-entry for \${postUrl}: \${_anchors.length} prop link(s) [\${Object.entries(_propLinks).filter(([p]) => post.properties[p]).map(([p]) => p).join(", ") || "none"}]\`);`; async function exists(p) { try { @@ -114,21 +117,26 @@ if (!(await exists(filePath))) { const source = await readFile(filePath, "utf8"); if (source.includes(patchMarker)) { - console.log("[patch-webmention-sender-livefetch] Already patched (v5)"); + console.log("[patch-webmention-sender-livefetch] Already patched (v6)"); process.exit(0); } -// For v1–v4: extract the old patched block by finding the marker and the -// closing "continue;\n }" that ends the if (!contentToProcess) block. -const priorMarkers = [ +// Extract the old patched block by finding the marker and the end of the block. +// v1–v4 end with "continue;\n }" (the if (!contentToProcess) block). +// v5+ end with the contentToProcess assignment line (no continue block). +const priorMarkersWithContinue = [ "// [patched:livefetch:v4]", "// [patched:livefetch:v3]", "// [patched:livefetch:v2]", "// [patched:livefetch]", ]; +const priorMarkersNoContinue = [ + "// [patched:livefetch:v5]", +]; let oldPatchBlock = null; -for (const marker of priorMarkers) { + +for (const marker of priorMarkersWithContinue) { if (!source.includes(marker)) continue; const startIdx = source.lastIndexOf(` ${marker}`); const endMarker = " continue;\n }"; @@ -139,6 +147,21 @@ for (const marker of priorMarkers) { } } +if (!oldPatchBlock) { + for (const marker of priorMarkersNoContinue) { + if (!source.includes(marker)) continue; + const startIdx = source.lastIndexOf(` ${marker}`); + // v5 block ends with the contentToProcess = `...`; line + // Find the semicolon that closes the last template literal on that line + const endMarker = '""}`;\n'; + const endSearch = source.indexOf(endMarker, startIdx); + if (startIdx !== -1 && endSearch !== -1) { + oldPatchBlock = source.slice(startIdx, endSearch + endMarker.length); + break; + } + } +} + const targetBlock = oldPatchBlock ? oldPatchBlock : source.includes(originalBlock) @@ -162,4 +185,4 @@ if (!patched.includes(patchMarker)) { } await writeFile(filePath, patched, "utf8"); -console.log("[patch-webmention-sender-livefetch] Patched successfully (v5)"); +console.log("[patch-webmention-sender-livefetch] Patched successfully (v6)"); diff --git a/scripts/patch-webmention-sender-reset-stale.mjs b/scripts/patch-webmention-sender-reset-stale.mjs index 6ca0e507..5a471162 100644 --- a/scripts/patch-webmention-sender-reset-stale.mjs +++ b/scripts/patch-webmention-sender-reset-stale.mjs @@ -9,7 +9,7 @@ import { MongoClient } from "mongodb"; import config from "../indiekit.config.mjs"; -const MIGRATION_ID = "webmention-sender-reset-stale-v10"; +const MIGRATION_ID = "webmention-sender-reset-stale-v11"; const mongodbUrl = config.application?.mongodbUrl; if (!mongodbUrl) {