UNPKG

omnichron

Version:

Unified interface for web archive providers

71 lines (69 loc) 2.66 kB
import { createErrorResponse, createSuccessResponse, mergeOptions, normalizeDomain } from "./_utils.mjs"; import { cleanDoubleSlashes } from "ufo"; import { $fetch } from "ofetch"; //#region src/providers/archive-today.ts /** * Create an Archive.today archive provider. * * @param initOptions - Initial options for Archive.today (e.g., maxRedirects, cache settings). * @returns ArchiveProvider instance for fetching snapshots from Archive.today. */ function archiveToday(initOptions = {}) { return { name: "Archive.today", slug: "archive-today", async getSnapshots(domain, reqOptions = {}) { const _options = mergeOptions(initOptions, reqOptions); const baseURL = "https://archive.is"; const _snapshotUrl = "https://archive.is"; const cleanDomain = normalizeDomain(domain, false); try { const fullUrl = cleanDomain.includes("://") ? cleanDomain : `http://${cleanDomain}`; const timemapUrl = `/timemap/${fullUrl}`; const timemapResponse = await $fetch(timemapUrl, { baseURL, retry: 5, timeout: 6e4, responseType: "text" }); const pages = []; const mementoRegex = /<(https?:\/\/archive\.(?:is|today|md|ph)\/([0-9]{8,14})\/(?:https?:\/\/)?([^>]+))>;\s*rel="(?:first\s+)?memento";\s*datetime="([^"]+)"/g; let mementoMatch; let index = 0; while ((mementoMatch = mementoRegex.exec(timemapResponse)) !== null) { const [, snapshotUrl, timestamp, origUrl, datetime] = mementoMatch; if (origUrl.includes(cleanDomain)) try { const parsedDate = new Date(datetime); const isoTimestamp = Number.isNaN(parsedDate.getTime()) ? new Date().toISOString() : parsedDate.toISOString(); let cleanedUrl = cleanDoubleSlashes(origUrl.includes("://") ? origUrl : `https://${origUrl}`); cleanedUrl = cleanedUrl.endsWith("/") ? cleanedUrl.slice(0, -1) : cleanedUrl; let cleanedSnapshotUrl = snapshotUrl; cleanedSnapshotUrl = cleanedSnapshotUrl.endsWith("/") ? cleanedSnapshotUrl.slice(0, -1) : cleanedSnapshotUrl; pages.push({ url: cleanedUrl, timestamp: isoTimestamp, snapshot: cleanedSnapshotUrl, _meta: { hash: timestamp, raw_date: datetime, position: index } }); index++; } catch (error) { console.error("Error parsing archive.today snapshot:", error); } } return createSuccessResponse(pages, "archive-today", { domain: cleanDomain, page: 1, empty: pages.length === 0 }); } catch (error) { return createErrorResponse(error, "archive-today", { domain: cleanDomain }); } } }; } //#endregion export { archiveToday as default };