2026-07-20 11:40:29 -03:00
|
|
|
import { basename } from "node:path";
|
2026-07-20 11:59:06 -03:00
|
|
|
import { type CodeDiff, type Differs, DiffType } from "../../types";
|
2026-07-20 11:40:29 -03:00
|
|
|
import { cuteVersion, maxDiffChanges, version } from "../shared";
|
2026-07-20 11:59:06 -03:00
|
|
|
import { formatBytes, sortEntries } from "../utils";
|
2026-07-20 11:40:29 -03:00
|
|
|
|
|
|
|
|
function fileBase(path: string, other?: string) {
|
|
|
|
|
if (!other) return `... ${basename(path)}`;
|
|
|
|
|
const paths = path.split("/"),
|
|
|
|
|
others = other.split("/");
|
|
|
|
|
|
|
|
|
|
let offset = 0;
|
|
|
|
|
while (offset < Math.min(paths.length, others.length) - 1 && paths[offset] === others[offset]) {
|
|
|
|
|
offset++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return `... ${paths.slice(offset).join("/")}`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function makeFooter(size: number, item: string) {
|
|
|
|
|
return `**${size.toLocaleString("en-US")}** ${item} change${size !== 1 ? "s" : ""} total`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getThreshold(lines: string[]) {
|
|
|
|
|
return lines.some((x) => x.includes("\n")) ? Math.floor(maxDiffChanges / 2) : maxDiffChanges;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function cap(lines: string[], item: string) {
|
|
|
|
|
const threshold = getThreshold(lines);
|
|
|
|
|
if (lines.length > threshold)
|
|
|
|
|
return [...lines.slice(0, threshold), `(+${(lines.length - threshold).toLocaleString("en-US")} ${item})`];
|
|
|
|
|
return lines;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface FormattedDiff {
|
|
|
|
|
embed: string[];
|
|
|
|
|
file: string;
|
|
|
|
|
capped: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-20 11:59:06 -03:00
|
|
|
function formatDiff(diffs: Map<string, CodeDiff>): FormattedDiff {
|
2026-07-20 11:40:29 -03:00
|
|
|
const entries = [...diffs.entries()];
|
|
|
|
|
|
|
|
|
|
const sections = {
|
|
|
|
|
Added: sortEntries(entries)
|
|
|
|
|
.map(
|
|
|
|
|
([name, diff]) =>
|
2026-07-20 11:59:06 -03:00
|
|
|
diff.type === DiffType.Added && `+ ${fileBase(name)} (${formatBytes(diff.size)})`,
|
2026-07-20 11:40:29 -03:00
|
|
|
)
|
|
|
|
|
.filter((x) => typeof x === "string"),
|
|
|
|
|
Renamed: sortEntries(entries)
|
|
|
|
|
.map(
|
|
|
|
|
([name, diff]) =>
|
|
|
|
|
diff.type === DiffType.Renamed &&
|
2026-07-20 11:59:06 -03:00
|
|
|
`- ${fileBase(diff.oldName, name)}\n+ ${fileBase(name, diff.oldName)}`,
|
2026-07-20 11:40:29 -03:00
|
|
|
)
|
|
|
|
|
.filter((x) => typeof x === "string"),
|
|
|
|
|
Removed: sortEntries(entries)
|
|
|
|
|
.map(
|
|
|
|
|
([name, diff]) =>
|
2026-07-20 11:59:06 -03:00
|
|
|
diff.type === DiffType.Removed && `- ${fileBase(name)} (${formatBytes(diff.size)})`,
|
2026-07-20 11:40:29 -03:00
|
|
|
)
|
|
|
|
|
.filter((x) => typeof x === "string"),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const text = Object.entries(sections).filter(([, lines]) => lines.length);
|
|
|
|
|
return {
|
|
|
|
|
embed: text.map(
|
|
|
|
|
([title, lines]) => `### ${title}\n\`\`\`diff\n${cap(lines, title.toLowerCase()).join("\n")}\`\`\``,
|
|
|
|
|
),
|
|
|
|
|
file: text.map(([title, lines]) => `# ${title}\n\n${lines.join("\n")}`).join("\n\n"),
|
|
|
|
|
capped: text.some(([, lines]) => lines.length > getThreshold(lines)),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function webhook(diffs: Differs) {
|
2026-07-20 11:59:06 -03:00
|
|
|
if (diffs.code?.size) {
|
|
|
|
|
const body = JSON.stringify({
|
|
|
|
|
content: `Code changes for **${version} (${cuteVersion})**`,
|
|
|
|
|
embeds: [
|
2026-07-20 11:40:29 -03:00
|
|
|
{
|
|
|
|
|
title: "Code",
|
2026-07-20 11:59:06 -03:00
|
|
|
description: formatDiff(diffs.code).embed.join("\n"),
|
|
|
|
|
footer: { text: makeFooter(diffs.code.size, "code") },
|
2026-07-20 11:40:29 -03:00
|
|
|
},
|
|
|
|
|
],
|
2026-07-20 11:59:06 -03:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const webhookUrl = process.env.code_webhook;
|
|
|
|
|
if (webhookUrl) {
|
|
|
|
|
await fetch(webhookUrl, {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: { "Content-Type": "application/json" },
|
|
|
|
|
body,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-07-20 11:40:29 -03:00
|
|
|
}
|