feat: patch q=category to return distinct tags from MongoDB posts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Sven
2026-04-09 21:25:01 +02:00
parent cb259d7b86
commit 3ab935cbae
@@ -0,0 +1,81 @@
/**
* Patch: make q=category return distinct tags from MongoDB posts collection.
*
* In queryController, line 28 rewrites q === "category" → "categories" before
* the switch, so the new case label must be "categories" (not "category").
* The default branch returns config.categories (always []) because
* publication.categories is not configured. This patch inserts a
* case "categories": before default: that queries the posts collection instead.
*
* postsCollection may be undefined (no MongoDB). The ternary provides a []
* fallback consistent with the guard pattern used throughout query.js.
*/
import { access, readFile, writeFile } from "node:fs/promises";
const MARKER = "// [patch] micropub-category-from-posts";
const candidates = [
"node_modules/@indiekit/endpoint-micropub/lib/controllers/query.js",
"node_modules/@indiekit/indiekit/node_modules/@indiekit/endpoint-micropub/lib/controllers/query.js",
];
const OLD_SNIPPET = ` break;
}
default: {
// Query configuration value (can be filtered, limited and offset)
if (config[q]) {`;
const NEW_SNIPPET = ` break;
}
case "categories": { ${MARKER}
const cats = postsCollection
? (await postsCollection.distinct("properties.category")).filter(Boolean).sort()
: [];
response.json({
categories: queryConfig(cats, { filter: filter?.toLowerCase(), limit, offset }),
});
break;
}
default: {
// Query configuration value (can be filtered, limited and offset)
if (config[q]) {`;
async function exists(p) {
try { await access(p); return true; } catch { return false; }
}
let totalPatched = 0;
let totalChecked = 0;
for (const filePath of candidates) {
if (!(await exists(filePath))) continue;
totalChecked++;
const source = await readFile(filePath, "utf8");
if (source.includes(MARKER)) {
console.log(`[postinstall] patch-micropub-category-from-posts: already applied to ${filePath}`);
continue;
}
if (!source.includes(OLD_SNIPPET)) {
console.warn(`[postinstall] patch-micropub-category-from-posts: snippet not found in ${filePath} (upstream changed?)`);
continue;
}
const updated = source.replace(OLD_SNIPPET, NEW_SNIPPET);
await writeFile(filePath, updated, "utf8");
console.log(`[postinstall] Applied patch-micropub-category-from-posts to ${filePath}`);
totalPatched++;
}
if (totalChecked === 0) {
console.log("[postinstall] patch-micropub-category-from-posts: no target files found");
} else if (totalPatched === 0) {
console.log("[postinstall] patch-micropub-category-from-posts: already up to date");
} else {
console.log(`[postinstall] patch-micropub-category-from-posts: patched ${totalPatched} file(s)`);
}