diff options
Diffstat (limited to 'src/utils')
| -rw-r--r-- | src/utils/webmentions.ts | 115 |
1 files changed, 0 insertions, 115 deletions
diff --git a/src/utils/webmentions.ts b/src/utils/webmentions.ts deleted file mode 100644 index 8edfd90..0000000 --- a/src/utils/webmentions.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { WEBMENTION_API_KEY } from "astro:env/server"; -import * as fs from "node:fs"; -import type { WebmentionsCache, WebmentionsChildren, WebmentionsFeed } from "@/types"; - -const DOMAIN = import.meta.env.SITE; -const CACHE_DIR = ".data"; -const filePath = `${CACHE_DIR}/webmentions.json`; -const validWebmentionTypes = ["like-of", "mention-of", "in-reply-to"]; - -const hostName = new URL(DOMAIN).hostname; - -// Calls webmention.io api. -async function fetchWebmentions(timeFrom: string | null, perPage = 1000) { - if (!DOMAIN) { - console.warn("No domain specified. Please set in astro.config.ts"); - return null; - } - - if (!WEBMENTION_API_KEY) { - console.warn("No webmention api token specified in .env"); - return null; - } - - let url = `https://webmention.io/api/mentions.jf2?domain=${hostName}&token=${WEBMENTION_API_KEY}&sort-dir=up&per-page=${perPage}`; - - if (timeFrom) url += `&since${timeFrom}`; - - const res = await fetch(url); - - if (res.ok) { - const data = (await res.json()) as WebmentionsFeed; - return data; - } - - return null; -} - -// Merge cached entries [a] with fresh webmentions [b], merge by wm-id -function mergeWebmentions(a: WebmentionsCache, b: WebmentionsFeed): WebmentionsChildren[] { - return Array.from( - [...a.children, ...b.children] - .reduce((map, obj) => map.set(obj["wm-id"], obj), new Map()) - .values(), - ); -} - -// filter out WebmentionChildren -export function filterWebmentions(webmentions: WebmentionsChildren[]) { - return webmentions.filter((webmention) => { - // make sure the mention has a property so we can sort them later - if (!validWebmentionTypes.includes(webmention["wm-property"])) return false; - - // make sure 'mention-of' or 'in-reply-to' has text content. - if (webmention["wm-property"] === "mention-of" || webmention["wm-property"] === "in-reply-to") { - return webmention.content && webmention.content.text !== ""; - } - - return true; - }); -} - -// save combined webmentions in cache file -function writeToCache(data: WebmentionsCache) { - const fileContent = JSON.stringify(data, null, 2); - - // create cache folder if it doesn't exist already - if (!fs.existsSync(CACHE_DIR)) { - fs.mkdirSync(CACHE_DIR); - } - - // write data to cache json file - fs.writeFile(filePath, fileContent, (err) => { - if (err) throw err; - console.log(`Webmentions saved to ${filePath}`); - }); -} - -function getFromCache(): WebmentionsCache { - if (fs.existsSync(filePath)) { - const data = fs.readFileSync(filePath, "utf-8"); - return JSON.parse(data); - } - // no cache found - return { - lastFetched: null, - children: [], - }; -} - -async function getAndCacheWebmentions() { - const cache = getFromCache(); - const mentions = await fetchWebmentions(cache.lastFetched); - - if (mentions) { - mentions.children = filterWebmentions(mentions.children); - const webmentions: WebmentionsCache = { - lastFetched: new Date().toISOString(), - // Make sure the first arg is the cache - children: mergeWebmentions(cache, mentions), - }; - - writeToCache(webmentions); - return webmentions; - } - - return cache; -} - -let webMentions: WebmentionsCache; - -export async function getWebmentionsForUrl(url: string) { - if (!webMentions) webMentions = await getAndCacheWebmentions(); - - return webMentions.children.filter((entry) => entry["wm-target"] === url); -} |
