site-library/src/model/filters.ts
2025-03-25 20:50:32 +01:00

69 lines
2.2 KiB
TypeScript

export * from './howto-model.js'
import { filter as language } from "@/base/kbot.js";
import { HOWTO_FILTER_LLM, HOWTO_ROOT } from "config/config.js";
export const item_path = (item: any) => `${HOWTO_ROOT()}/${item.data.slug}`
const blacklist_ = [];
export const blacklist = ['precious-plastic', 'fair-enough', 'mad-plastic-labs',, 'easymoulds', 'plasticpreneur', 'sustainable-design-studio', 'johannplasto'];
export const urlBlacklist = ["thenounproject.com", "preciousplastic.com"];
export const bannedWords = ["wizard", "magic2"];
export const wordReplaceMap: Record<string, string> = {
Router: "CNC Router",
"laptop stand": "laptoppie",
Car: "tufftuff"
}
export const shortenUrl = (url: string): string => {
try {
const { hostname, pathname } = new URL(url);
const cleanHost = hostname.replace(/^www\./, '');
const cleanPath = pathname.replace(/\/$/, ''); // remove trailing slash
return `${cleanHost}${decodeURIComponent(cleanPath)}`;
} catch {
// If invalid URL, return as-is
return url;
}
};
// Turns URLs into clickable links, unless blacklisted
export const renderLinks = (text: string): string =>
text.replace(/https?:\/\/[^\s<"]+/gi, (url) => {
const isBlacklisted = urlBlacklist.some((domain) =>
url.toLowerCase().includes(domain.toLowerCase()),
);
return isBlacklisted
? "[Link Removed]"
: `<a class="text-orange-600 underline" href="${url}" target="_blank" rel="noopener noreferrer">${shortenUrl(url)}</a>`;
});
export const filterBannedPhrases = (text: string): string =>
bannedWords.reduce(
(acc, word) => acc.replace(new RegExp(`\\b${word}\\b`, "gi"), "[filtered]"),
text,
);
export const replaceWords = (text: string): string =>
Object.entries(wordReplaceMap).reduce(
(acc, [word, replacement]) =>
acc.replace(new RegExp(`\\b${word}\\b`, "gi"), replacement),
text,
);
export const filters = [
renderLinks,
filterBannedPhrases,
replaceWords,
HOWTO_FILTER_LLM ? language : (text: string) => text,
];
export async function applyFilters(text: string): Promise<string> {
let filtered = text;
for (const filterFn of filters) {
filtered = await filterFn(filtered);
}
return filtered;
}