Files
blog-eleventy-indiekit/_data/urlAliases.js
Ricardo 3c21393989 fix: improve redirect map file discovery
- Fix fallback logic (empty object is truthy)
- Try multiple paths for Docker and local dev
- Add debug logging for file discovery

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 15:13:11 +01:00

158 lines
4.5 KiB
JavaScript

/**
* URL Aliases for Webmention Recovery
*
* Maps new URLs to their old URLs so webmentions from previous
* URL structures can be displayed on current pages.
*
* Sources:
* - redirects.map.rmendes (micro.blog: /YYYY/MM/DD/slug.html → /notes/...)
* - old-blog-redirects.map.rmendes (Known/WP: /YYYY/slug → /content/...)
*/
import { readFileSync, existsSync } from "fs";
import { resolve, dirname } from "path";
import { fileURLToPath } from "url";
const __dirname = dirname(fileURLToPath(import.meta.url));
const siteUrl = process.env.SITE_URL || "https://example.com";
/**
* Parse a redirect map file into URL mappings
* Format: old_path new_path;
*/
function parseRedirectMap(filePath) {
const aliases = {};
if (!existsSync(filePath)) {
console.log(`[urlAliases] File not found: ${filePath}`);
return aliases;
}
try {
const content = readFileSync(filePath, "utf-8");
const lines = content.split("\n").filter((line) => {
const trimmed = line.trim();
return trimmed && !trimmed.startsWith("#");
});
for (const line of lines) {
// Format: /old/path /new/path;
const match = line.match(/^(\S+)\s+(\S+);?$/);
if (match) {
const [, oldPath, newPath] = match;
// Normalize paths (remove trailing slashes, ensure leading slash)
const normalizedNew = newPath.replace(/;$/, "").replace(/\/$/, "");
const normalizedOld = oldPath.replace(/\/$/, "");
// Map new URL → array of old URLs
if (!aliases[normalizedNew]) {
aliases[normalizedNew] = [];
}
aliases[normalizedNew].push(normalizedOld);
}
}
} catch (error) {
console.error(`[urlAliases] Error parsing ${filePath}:`, error.message);
}
return aliases;
}
/**
* Merge multiple alias maps
*/
function mergeAliases(...maps) {
const merged = {};
for (const map of maps) {
for (const [newUrl, oldUrls] of Object.entries(map)) {
if (!merged[newUrl]) {
merged[newUrl] = [];
}
merged[newUrl].push(...oldUrls);
}
}
return merged;
}
// Parse redirect maps from /app/pkg (Docker) or parent directory (local dev)
// In Docker: eleventy-site is at /app/pkg/eleventy-site, maps are at /app/pkg/
// In local dev: maps might be at ../
const pkgRoot = resolve(__dirname, "../..");
// Helper to find first existing file
function findFile(candidates) {
for (const path of candidates) {
if (existsSync(path)) {
console.log(`[urlAliases] Found: ${path}`);
return path;
}
}
console.log(`[urlAliases] No file found in: ${candidates.join(", ")}`);
return null;
}
// Try multiple possible locations for each map type
const microblogMapPath = findFile([
resolve(pkgRoot, "redirects.map"),
resolve(pkgRoot, "redirects.map.rmendes"),
resolve(__dirname, "../../redirects.map"),
]);
const knownMapPath = findFile([
resolve(pkgRoot, "old-blog-redirects.map"),
resolve(pkgRoot, "old-blog-redirects.map.rmendes"),
resolve(__dirname, "../../old-blog-redirects.map"),
]);
const microblogAliases = microblogMapPath ? parseRedirectMap(microblogMapPath) : {};
const knownAliases = knownMapPath ? parseRedirectMap(knownMapPath) : {};
const allAliases = mergeAliases(microblogAliases, knownAliases);
// Log summary
const totalMappings = Object.keys(allAliases).length;
const totalOldUrls = Object.values(allAliases).reduce((sum, urls) => sum + urls.length, 0);
console.log(`[urlAliases] Loaded ${totalMappings} URL mappings with ${totalOldUrls} old URLs`);
export default {
// The merged alias map: new URL → [old URLs]
aliases: allAliases,
// Site URL for building absolute URLs
siteUrl,
/**
* Get all URLs (old and new) that should be checked for webmentions
* @param {string} url - Current page URL (relative)
* @returns {string[]} - Array of absolute URLs to check
*/
getAllUrls(url) {
const normalizedUrl = url.replace(/\/$/, "");
const urls = [
`${siteUrl}${url}`,
`${siteUrl}${normalizedUrl}`,
];
// Add old URL variations
const oldUrls = allAliases[normalizedUrl] || [];
for (const oldUrl of oldUrls) {
urls.push(`${siteUrl}${oldUrl}`);
// Also try with trailing slash
urls.push(`${siteUrl}${oldUrl}/`);
}
// Deduplicate
return [...new Set(urls)];
},
/**
* Get just the old URLs for a given new URL
* @param {string} url - Current page URL (relative)
* @returns {string[]} - Array of old relative URLs
*/
getOldUrls(url) {
const normalizedUrl = url.replace(/\/$/, "");
return allAliases[normalizedUrl] || [];
},
};