huge changes

This commit is contained in:
indifferentketchup
2026-04-07 01:43:06 -05:00
parent ca63ecbcfd
commit 69c247ed1b
37 changed files with 3468 additions and 169 deletions

View File

@@ -275,7 +275,106 @@ function replaceVariables(template, context = {}) {
return result;
}
/** Sanitize user input for safe embedding in Discord code blocks. */
function sanitizeEmbedText(str) {
if (str == null) return '';
return String(str).replace(/```/g, "'''").trim();
}
// --- EMBED TRUNCATION ---
/** Truncate a string for use as an embed field value (max 1024). */
function truncateEmbedField(str, max = 1024) {
if (str == null) return '';
const s = String(str);
return s.length > max ? s.slice(0, max - 3) + '...' : s;
}
/** Truncate a string for use as an embed description (max 4096). */
function truncateEmbedDescription(str, max = 4096) {
if (str == null) return '';
const s = String(str);
return s.length > max ? s.slice(0, max - 3) + '...' : s;
}
/**
* Enforce the 6 000 char total embed limit across an array of EmbedBuilder
* instances. Mutates in place: trims the largest description first, then
* largest field values, until the total is under 6 000 chars.
* Returns the same array for chaining.
*/
function enforceEmbedLimit(embeds) {
const charCount = (e) => {
const d = e.data || {};
let total = 0;
if (d.title) total += d.title.length;
if (d.description) total += d.description.length;
if (d.footer?.text) total += d.footer.text.length;
if (d.author?.name) total += d.author.name.length;
if (d.fields) {
for (const f of d.fields) {
if (f.name) total += f.name.length;
if (f.value) total += f.value.length;
}
}
return total;
};
const LIMIT = 6000;
const totalChars = () => embeds.reduce((sum, e) => sum + charCount(e), 0);
// Trim largest descriptions first
while (totalChars() > LIMIT) {
let largestIdx = -1;
let largestLen = 0;
for (let i = 0; i < embeds.length; i++) {
const desc = embeds[i].data?.description;
if (desc && desc.length > largestLen) {
largestLen = desc.length;
largestIdx = i;
}
}
if (largestIdx === -1 || largestLen <= 4) break;
const excess = totalChars() - LIMIT;
const newLen = Math.max(1, largestLen - excess - 3);
embeds[largestIdx].setDescription(
embeds[largestIdx].data.description.slice(0, newLen) + '...'
);
if (totalChars() <= LIMIT) break;
// If still over, loop will pick next largest
}
// Trim largest field values
while (totalChars() > LIMIT) {
let targetEmbed = null;
let targetFieldIdx = -1;
let targetLen = 0;
for (const e of embeds) {
const fields = e.data?.fields || [];
for (let fi = 0; fi < fields.length; fi++) {
if (fields[fi].value && fields[fi].value.length > targetLen) {
targetLen = fields[fi].value.length;
targetEmbed = e;
targetFieldIdx = fi;
}
}
}
if (!targetEmbed || targetLen <= 4) break;
const excess = totalChars() - LIMIT;
const newLen = Math.max(1, targetLen - excess - 3);
targetEmbed.data.fields[targetFieldIdx].value =
targetEmbed.data.fields[targetFieldIdx].value.slice(0, newLen) + '...';
}
return embeds;
}
module.exports = {
sanitizeEmbedText,
truncateEmbedField,
truncateEmbedDescription,
enforceEmbedLimit,
BLOCK_TAG_REGEX,
escapeRegex,
escapeHtml,