mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-05-23 12:57:09 +00:00
84 lines
2.8 KiB
JavaScript
84 lines
2.8 KiB
JavaScript
/**
|
|
* Incremental re-sync of idea files: append new comments only,
|
|
* update frontmatter snapshot.
|
|
*/
|
|
import { parseFrontmatter, serializeFrontmatter, stripFrontmatter } from "./frontmatter.mjs";
|
|
import { isBot } from "./classify.mjs";
|
|
|
|
function countThumbs(reactionGroups) {
|
|
if (!Array.isArray(reactionGroups)) return 0;
|
|
const g = reactionGroups.find((rg) => rg.content === "THUMBS_UP");
|
|
return g?.users?.totalCount ?? 0;
|
|
}
|
|
|
|
function uniqueCommenters(comments, authorLogin) {
|
|
const seen = new Set();
|
|
for (const c of comments ?? []) {
|
|
const u = c.author;
|
|
if (!u || !u.login) continue;
|
|
if (u.login === authorLogin) continue;
|
|
if (isBot(u)) continue;
|
|
seen.add(u.login);
|
|
}
|
|
return seen.size;
|
|
}
|
|
|
|
function renderComments(comments) {
|
|
return comments
|
|
.map(
|
|
(c) =>
|
|
`- **@${c.author?.login ?? "unknown"}** (${c.createdAt}):\n > ${(c.body ?? "").split("\n").join("\n > ")}`
|
|
)
|
|
.join("\n");
|
|
}
|
|
|
|
function appendComments(body, newComments) {
|
|
const heading = "## 💬 Community Discussion";
|
|
let idx = body.indexOf(heading);
|
|
if (idx < 0) idx = body.indexOf("## Community Discussion");
|
|
if (idx < 0) {
|
|
return body + `\n\n${heading}\n\n` + renderComments(newComments);
|
|
}
|
|
const after = body.slice(idx);
|
|
const nextHeaderMatch = after.slice(heading.length).match(/^##\s+/m);
|
|
const insertAt = nextHeaderMatch ? idx + heading.length + nextHeaderMatch.index : body.length;
|
|
const insertBlock = "\n\n" + renderComments(newComments) + "\n";
|
|
return body.slice(0, insertAt) + insertBlock + body.slice(insertAt);
|
|
}
|
|
|
|
export function resyncIdeaFile(text, issue, now = new Date(), opts = {}) {
|
|
const meta = parseFrontmatter(text);
|
|
if (!meta) return { changed: false, text };
|
|
|
|
const lastSyncedId = Number(meta.last_synced_comment_id ?? 0);
|
|
const allComments = issue.comments ?? [];
|
|
const newComments = allComments.filter((c) => Number(c.databaseId) > lastSyncedId);
|
|
|
|
if (newComments.length === 0) {
|
|
return { changed: false, text };
|
|
}
|
|
|
|
const body = stripFrontmatter(text);
|
|
const newBody = appendComments(body, newComments);
|
|
|
|
const newMeta = {
|
|
...meta,
|
|
last_synced_at: now.toISOString(),
|
|
last_synced_comment_id: Math.max(...newComments.map((c) => Number(c.databaseId))),
|
|
snapshot: {
|
|
...(meta.snapshot ?? {}),
|
|
thumbs: countThumbs(issue.reactionGroups),
|
|
commenters: uniqueCommenters(allComments, issue.author?.login),
|
|
labels: (issue.labels ?? []).map((l) => l.name).filter(Boolean),
|
|
state: String(issue.state ?? "open").toLowerCase(),
|
|
},
|
|
};
|
|
|
|
const out = serializeFrontmatter(newMeta, newBody);
|
|
|
|
const needsReclassification = !!(
|
|
opts.inNeedDetails && newComments.some((c) => c.author?.login === issue.author?.login)
|
|
);
|
|
|
|
return { changed: true, text: out, needsReclassification };
|
|
}
|