mcp-scraper 0.34.0 → 0.35.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.md +6 -5
  2. package/dist/bin/api-server.cjs +3788 -2742
  3. package/dist/bin/api-server.cjs.map +1 -1
  4. package/dist/bin/api-server.js +2 -2
  5. package/dist/bin/mcp-scraper-cli.cjs +1 -1
  6. package/dist/bin/mcp-scraper-cli.cjs.map +1 -1
  7. package/dist/bin/mcp-scraper-cli.js +1 -1
  8. package/dist/bin/mcp-scraper-install.cjs +2 -2
  9. package/dist/bin/mcp-scraper-install.cjs.map +1 -1
  10. package/dist/bin/mcp-scraper-install.js +2 -2
  11. package/dist/bin/mcp-stdio-server.cjs +2129 -1932
  12. package/dist/bin/mcp-stdio-server.cjs.map +1 -1
  13. package/dist/bin/mcp-stdio-server.js +5 -5
  14. package/dist/bin/paa-harvest.js +2 -2
  15. package/dist/{chunk-V36LS5YV.js → chunk-4ZB3X6BQ.js} +4 -3
  16. package/dist/chunk-4ZB3X6BQ.js.map +1 -0
  17. package/dist/{chunk-JBSGBSGT.js → chunk-BWXLTWF7.js} +21 -16
  18. package/dist/chunk-BWXLTWF7.js.map +1 -0
  19. package/dist/{chunk-J32XSMJI.js → chunk-NPMW5HUS.js} +2350 -2151
  20. package/dist/chunk-NPMW5HUS.js.map +1 -0
  21. package/dist/{chunk-SUOHUXQS.js → chunk-U44TPRST.js} +3 -3
  22. package/dist/chunk-U44TPRST.js.map +1 -0
  23. package/dist/{chunk-4KQVIYIH.js → chunk-XVVNKASZ.js} +2 -2
  24. package/dist/chunk-YR4LJ6AQ.js +7 -0
  25. package/dist/chunk-YR4LJ6AQ.js.map +1 -0
  26. package/dist/{chunk-2EDFOQD7.js → chunk-YRGSEY5L.js} +2 -2
  27. package/dist/{chunk-2EDFOQD7.js.map → chunk-YRGSEY5L.js.map} +1 -1
  28. package/dist/chunk-YV2FUEBX.js +851 -0
  29. package/dist/chunk-YV2FUEBX.js.map +1 -0
  30. package/dist/{extract-bundle-GPZRLBVY.js → extract-bundle-ONWZVV55.js} +59 -8
  31. package/dist/extract-bundle-ONWZVV55.js.map +1 -0
  32. package/dist/index.js +2 -2
  33. package/dist/{server-LKVPEQFE.js → server-GKUTC73B.js} +278 -52
  34. package/dist/server-GKUTC73B.js.map +1 -0
  35. package/dist/{site-extract-repository-JHMVHENZ.js → site-extract-repository-L6BHWVDU.js} +3 -3
  36. package/dist/{worker-ZZHSYI3Y.js → worker-645BZPEK.js} +4 -4
  37. package/docs/mcp-tool-craft-lint.generated.md +171 -49
  38. package/docs/mcp-tool-manifest.generated.json +508 -10
  39. package/docs/specs/query-fanout-transport-contract-fix.md +45 -0
  40. package/package.json +1 -1
  41. package/dist/chunk-J32XSMJI.js.map +0 -1
  42. package/dist/chunk-JBSGBSGT.js.map +0 -1
  43. package/dist/chunk-JWIE5NCR.js +0 -284
  44. package/dist/chunk-JWIE5NCR.js.map +0 -1
  45. package/dist/chunk-NFMIHEYE.js +0 -7
  46. package/dist/chunk-NFMIHEYE.js.map +0 -1
  47. package/dist/chunk-SUOHUXQS.js.map +0 -1
  48. package/dist/chunk-V36LS5YV.js.map +0 -1
  49. package/dist/extract-bundle-GPZRLBVY.js.map +0 -1
  50. package/dist/server-LKVPEQFE.js.map +0 -1
  51. /package/dist/{chunk-4KQVIYIH.js.map → chunk-XVVNKASZ.js.map} +0 -0
  52. /package/dist/{site-extract-repository-JHMVHENZ.js.map → site-extract-repository-L6BHWVDU.js.map} +0 -0
  53. /package/dist/{worker-ZZHSYI3Y.js.map → worker-645BZPEK.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/media-extractor.ts","../src/api/wayback.ts"],"sourcesContent":["import { createWriteStream, mkdirSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join, extname, basename } from 'node:path'\nimport { pipeline } from 'node:stream/promises'\nimport { Readable } from 'node:stream'\n\nconst AD_PATTERNS: string[] = [\n 'doubleclick.net', 'googlesyndication.com', 'googletagmanager.com',\n 'google-analytics.com', 'googletagservices.com', 'adservice.google',\n 'googletag.', 'pagead2.googlesyndication',\n 'facebook.net/tr', 'connect.facebook.net', 'fbcdn.net/rsrc',\n 'analytics.twitter.com', 'static.ads-twitter.com', 'ads.twitter.com',\n 't.co/i/adsct', 'pixel.advertising.com',\n 'hotjar.com', 'clarity.ms', 'quantserve.com', 'scorecardresearch.com',\n 'newrelic.com', 'nr-data.net', 'segment.io', 'segment.com',\n 'amplitude.com', 'mixpanel.com', 'heap.io', 'fullstory.com',\n 'moatads.com', 'criteo.com', 'adsrvr.org', 'rubiconproject.com',\n 'pubmatic.com', 'openx.net', 'appnexus.com', 'amazon-adsystem.com',\n 'media.net', 'yieldmo.com', 'triplelift.com', 'sharethrough.com',\n 'prebid.', 'smaato.net', 'indexworm.com', 'casalemedia.com',\n 'outbrain.com', 'taboola.com', 'revcontent.com', 'mgid.com',\n 'tawk.to', 'intercom.io', 'drift.com', 'hs-scripts.com',\n 'zopim.com', 'livechatinc.com', 'userlike.com',\n 'onetrust.com', 'cookielaw.org', 'cookieinformation.com', 'trustarc.com',\n '/ads/', '/ad/', '/banner/', '/banners/', '/pixel/', '/beacon/',\n '/tracking/', '/tracker/', '/remarketing/', '/conversion/',\n '1x1.gif', 'spacer.gif', 'blank.gif', 'transparent.gif',\n]\n\nconst IMAGE_EXTS = new Set(['.jpg', '.jpeg', '.png', '.webp', '.gif', '.avif', '.svg', '.tiff'])\nconst VIDEO_EXTS = new Set(['.mp4', '.webm', '.mov', '.avi', '.m4v', '.ogv', '.mkv'])\nconst AUDIO_EXTS = new Set(['.mp3', '.wav', '.ogg', '.aac', '.m4a', '.flac', '.opus'])\n\nexport type MediaType = 'image' | 'video' | 'audio'\n\nexport interface MediaAsset {\n url: string\n type: MediaType\n mimeType: string | null\n filename: string\n savedPath: string | null\n sizeBytes: number | null\n}\n\nexport interface MediaManifest {\n pageUrl: string\n outputDir: string | null\n assets: MediaAsset[]\n filteredCount: number\n totalFound: number\n}\n\nexport interface MediaExtractOptions {\n types?: MediaType[]\n outputDir?: string | null\n}\n\nfunction isAdUrl(url: string): boolean {\n const lower = url.toLowerCase()\n return AD_PATTERNS.some(p => lower.includes(p))\n}\n\nfunction isDataUri(url: string): boolean {\n return url.startsWith('data:')\n}\n\nfunction typeFromUrl(url: string): MediaType | null {\n try {\n const ext = extname(new URL(url).pathname).toLowerCase()\n if (IMAGE_EXTS.has(ext)) return 'image'\n if (VIDEO_EXTS.has(ext)) return 'video'\n if (AUDIO_EXTS.has(ext)) return 'audio'\n } catch { /* non-parseable URL */ }\n return null\n}\n\nfunction typeFromMime(mime: string): MediaType | null {\n const lower = mime.toLowerCase()\n if (lower.startsWith('image/')) return 'image'\n if (lower.startsWith('video/')) return 'video'\n if (lower.startsWith('audio/')) return 'audio'\n return null\n}\n\nfunction resolveUrl(raw: string, base: string): string | null {\n if (!raw || isDataUri(raw)) return null\n try { return new URL(raw, base).href } catch { return null }\n}\n\nfunction safeFilename(url: string, index: number): string {\n try {\n const u = new URL(url)\n const base = basename(u.pathname).replace(/[^a-zA-Z0-9._-]/g, '_').slice(0, 80)\n return base || `asset-${index}`\n } catch {\n return `asset-${index}`\n }\n}\n\nexport function extractMediaUrls(html: string, baseUrl: string): string[] {\n const seen = new Set<string>()\n const urls: string[] = []\n\n const add = (raw: string) => {\n const resolved = resolveUrl(raw.trim(), baseUrl)\n if (!resolved || seen.has(resolved) || isAdUrl(resolved)) return\n seen.add(resolved)\n urls.push(resolved)\n }\n\n for (const m of html.matchAll(/<img\\s[^>]*>/gi)) {\n const tag = m[0]\n for (const attr of ['src', 'data-src', 'data-lazy-src', 'data-original']) {\n const v = (tag.match(new RegExp(`\\\\b${attr}\\\\s*=\\\\s*[\"']([^\"']+)[\"']`, 'i')) ?? [])[1]\n if (v) add(v)\n }\n const srcset = (tag.match(/\\bsrcset\\s*=\\s*[\"']([^\"']+)[\"']/i) ?? [])[1]\n if (srcset) {\n for (const part of srcset.split(',')) {\n const u = part.trim().split(/\\s+/)[0]\n if (u) add(u)\n }\n }\n }\n\n for (const m of html.matchAll(/<source\\s[^>]*>/gi)) {\n const tag = m[0]\n const src = (tag.match(/\\bsrc\\s*=\\s*[\"']([^\"']+)[\"']/i) ?? [])[1]\n if (src) add(src)\n const srcset = (tag.match(/\\bsrcset\\s*=\\s*[\"']([^\"']+)[\"']/i) ?? [])[1]\n if (srcset) {\n for (const part of srcset.split(',')) {\n const u = part.trim().split(/\\s+/)[0]\n if (u) add(u)\n }\n }\n }\n\n for (const m of html.matchAll(/<video\\s[^>]*>/gi)) {\n const tag = m[0]\n for (const attr of ['src', 'poster']) {\n const v = (tag.match(new RegExp(`\\\\b${attr}\\\\s*=\\\\s*[\"']([^\"']+)[\"']`, 'i')) ?? [])[1]\n if (v) add(v)\n }\n }\n\n for (const m of html.matchAll(/<audio\\s[^>]*>/gi)) {\n const tag = m[0]\n const v = (tag.match(/\\bsrc\\s*=\\s*[\"']([^\"']+)[\"']/i) ?? [])[1]\n if (v) add(v)\n }\n\n for (const m of html.matchAll(/<meta\\s[^>]*>/gi)) {\n const tag = m[0]\n const prop = (tag.match(/\\b(?:property|name)\\s*=\\s*[\"']([^\"']+)[\"']/i) ?? [])[1]?.toLowerCase()\n if (prop === 'og:image' || prop === 'twitter:image') {\n const content = (tag.match(/\\bcontent\\s*=\\s*[\"']([^\"']+)[\"']/i) ?? [])[1]\n if (content) add(content)\n }\n }\n\n for (const m of html.matchAll(/background(?:-image)?\\s*:\\s*url\\(\\s*[\"']?([^\"')]+)[\"']?\\s*\\)/gi)) {\n add(m[1])\n }\n\n return urls\n}\n\nexport async function downloadAsset(\n url: string,\n destDir: string,\n filename: string,\n): Promise<{ savedPath: string; sizeBytes: number; mimeType: string | null }> {\n const res = await fetch(url, {\n headers: { 'User-Agent': 'Mozilla/5.0 (compatible; ThorbitBot/1.0)' },\n signal: AbortSignal.timeout(15_000),\n })\n if (!res.ok) throw new Error(`HTTP ${res.status}`)\n if (!res.body) throw new Error('Empty response body')\n\n const mimeType = res.headers.get('content-type')?.split(';')[0].trim() ?? null\n\n let dest = join(destDir, filename)\n if (mimeType && !extname(filename)) {\n const mimeExt: Record<string, string> = {\n 'image/jpeg': '.jpg', 'image/png': '.png', 'image/webp': '.webp',\n 'image/gif': '.gif', 'image/svg+xml': '.svg', 'image/avif': '.avif',\n 'video/mp4': '.mp4', 'video/webm': '.webm',\n 'audio/mpeg': '.mp3', 'audio/ogg': '.ogg', 'audio/wav': '.wav',\n }\n const ext = mimeExt[mimeType]\n if (ext) dest = dest + ext\n }\n\n const writer = createWriteStream(dest)\n await pipeline(Readable.fromWeb(res.body as import('stream/web').ReadableStream), writer)\n\n const { statSync } = await import('node:fs')\n const sizeBytes = statSync(dest).size\n\n return { savedPath: dest, sizeBytes, mimeType }\n}\n\nexport async function harvestPageMedia(\n html: string,\n pageUrl: string,\n options: MediaExtractOptions = {},\n): Promise<MediaManifest> {\n const types = options.types ?? ['image', 'video', 'audio']\n const typesSet = new Set(types)\n const rawUrls = extractMediaUrls(html, pageUrl)\n const totalFound = rawUrls.length\n\n const filteredUrls: string[] = []\n const kept: Array<{ url: string; type: MediaType }> = []\n\n for (const url of rawUrls) {\n const type = typeFromUrl(url)\n if (!type || !typesSet.has(type)) { filteredUrls.push(url); continue }\n kept.push({ url, type })\n }\n\n if (options.outputDir === null) {\n return {\n pageUrl,\n outputDir: null,\n assets: kept.map(({ url, type }, i) => ({\n url, type, mimeType: null, filename: safeFilename(url, i), savedPath: null, sizeBytes: null,\n })),\n filteredCount: filteredUrls.length,\n totalFound,\n }\n }\n\n const domain = (() => { try { return new URL(pageUrl).hostname.replace(/^www\\./, '') } catch { return 'unknown' } })()\n const stamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19)\n const outDir = options.outputDir ?? join(homedir(), 'Downloads', 'mcp-scraper', 'media', `${stamp}-${domain}`)\n mkdirSync(outDir, { recursive: true })\n\n const assets: MediaAsset[] = []\n\n await Promise.allSettled(\n kept.map(async ({ url, type }, i) => {\n const filename = safeFilename(url, i)\n try {\n const { savedPath, sizeBytes, mimeType } = await downloadAsset(url, outDir, filename)\n const resolvedType = mimeType ? (typeFromMime(mimeType) ?? type) : type\n assets.push({ url, type: resolvedType, mimeType, filename: basename(savedPath), savedPath, sizeBytes })\n } catch {\n assets.push({ url, type, mimeType: null, filename, savedPath: null, sizeBytes: null })\n }\n })\n )\n\n assets.sort((a, b) => {\n if (a.savedPath && !b.savedPath) return -1\n if (!a.savedPath && b.savedPath) return 1\n return a.url.localeCompare(b.url)\n })\n\n return { pageUrl, outputDir: outDir, assets, filteredCount: filteredUrls.length, totalFound }\n}\n","import pLimit from 'p-limit'\nimport type { WaybackTimelineInput } from './wayback-schemas.js'\n\nconst WAYBACK_HOSTS = new Set(['web.archive.org'])\nconst MAX_CDX_RESPONSE_BYTES = 5 * 1024 * 1024\nconst MAX_CDX_ROWS = 5_000\nconst MAX_ARCHIVE_URL_CHARS = 4_096\nconst MAX_SELECTED_TIMELINE_CELLS = 1_000\nconst TIMELINE_CDX_CONCURRENCY = 4\n\nexport interface WaybackReplay {\n timestamp: string\n modifier: string | null\n originalUrl: string\n replayUrl: string\n rawReplayUrl: string\n}\n\nexport interface WaybackCapture {\n timestamp: string\n originalUrl: string\n digest: string | null\n rawReplayUrl: string\n replayUrl?: string\n statusCode?: number | null\n mimeType?: string | null\n length?: number | null\n requestedMonth?: string\n}\n\nexport interface WaybackTimelinePlan {\n months: string[]\n captures: WaybackCapture[]\n requestedUrls: string[] | null\n missing: Array<{ requestedMonth: string; originalUrl: string }>\n}\n\nexport type WaybackInventoryScope = 'exact' | 'prefix' | 'host' | 'domain'\n\nexport interface WaybackInventoryResult {\n url: string\n scope: WaybackInventoryScope\n selectedUrls: string[] | null\n from: string | null\n to: string | null\n successfulHtmlOnly: boolean\n totalCaptures: number\n countType: 'exact' | 'lower_bound'\n complete: boolean\n truncated: boolean\n maxCaptures: number\n queryPages: number\n uniqueUrls: number\n uniqueDigests: number\n firstCapture: WaybackCapture | null\n lastCapture: WaybackCapture | null\n monthlyCounts: Array<{ month: string; captures: number }>\n yearlyCounts: Array<{ year: string; captures: number }>\n missingMonths: string[]\n perUrl: Array<{\n url: string\n captures: number\n uniqueDigests: number\n firstTimestamp: string\n lastTimestamp: string\n }>\n perUrlTruncatedCount: number\n captures: WaybackCapture[]\n captureRowsTruncatedCount: number\n durationMs: number\n}\n\nexport interface FeaturedImage {\n url: string\n archivedUrl: string | null\n source: 'og:image' | 'twitter:image' | 'json-ld' | 'content-image'\n}\n\nfunction validTimestamp(value: string): boolean {\n return /^\\d{1,14}$/.test(value)\n}\n\nfunction safeHttpUrl(value: string, base?: string): string | null {\n try {\n const parsed = base ? new URL(value, base) : new URL(value)\n if (!['http:', 'https:'].includes(parsed.protocol) || parsed.username || parsed.password) return null\n parsed.hash = ''\n return parsed.href\n } catch {\n return null\n }\n}\n\nexport function parseWaybackReplayUrl(value: string): WaybackReplay | null {\n let parsed: URL\n try {\n parsed = new URL(value)\n } catch {\n return null\n }\n if (!WAYBACK_HOSTS.has(parsed.hostname.toLowerCase())) return null\n\n const match = parsed.pathname.match(/^\\/web\\/(\\d{1,14})([a-z_]+)?\\/(https?:\\/\\/.+)$/i)\n if (!match || !validTimestamp(match[1])) return null\n const originalUrl = safeHttpUrl(`${match[3]}${parsed.search}`)\n if (!originalUrl || originalUrl.length > MAX_ARCHIVE_URL_CHARS) return null\n\n const timestamp = match[1]\n return {\n timestamp,\n modifier: match[2] ?? null,\n originalUrl,\n replayUrl: `https://web.archive.org/web/${timestamp}/${originalUrl}`,\n rawReplayUrl: `https://web.archive.org/web/${timestamp}id_/${originalUrl}`,\n }\n}\n\nexport function buildWaybackReplayUrl(timestamp: string, originalUrl: string, modifier = 'id_'): string {\n if (!validTimestamp(timestamp)) throw new Error('Wayback timestamp must contain 1-14 digits.')\n const safeOriginal = safeHttpUrl(originalUrl)\n if (!safeOriginal || safeOriginal.length > MAX_ARCHIVE_URL_CHARS) throw new Error('Wayback original URL is invalid.')\n return `https://web.archive.org/web/${timestamp}${modifier}/${safeOriginal}`\n}\n\nfunction timestampMillis(value: string): number {\n const padded = value.padEnd(14, '0')\n const year = Number(padded.slice(0, 4))\n const month = Number(padded.slice(4, 6) || '1')\n const day = Number(padded.slice(6, 8) || '1')\n const hour = Number(padded.slice(8, 10) || '0')\n const minute = Number(padded.slice(10, 12) || '0')\n const second = Number(padded.slice(12, 14) || '0')\n return Date.UTC(year, Math.max(0, month - 1), Math.max(1, day), hour, minute, second)\n}\n\nfunction monthAnchor(month: string): string {\n return `${month.replace('-', '')}15120000`\n}\n\nexport function expandWaybackMonths(input: WaybackTimelineInput): string[] {\n if (input.months?.length) return [...new Set(input.months)].sort()\n if (!input.from || !input.to) return []\n const [fromYear, fromMonth] = input.from.split('-').map(Number)\n const [toYear, toMonth] = input.to.split('-').map(Number)\n const interval = input.intervalMonths ?? 1\n const cursor = new Date(Date.UTC(fromYear, fromMonth - 1, 1))\n const end = new Date(Date.UTC(toYear, toMonth - 1, 1))\n const months: string[] = []\n while (cursor <= end && months.length < 60) {\n months.push(`${cursor.getUTCFullYear()}-${String(cursor.getUTCMonth() + 1).padStart(2, '0')}`)\n cursor.setUTCMonth(cursor.getUTCMonth() + interval)\n }\n return months\n}\n\nasync function readBoundedText(response: Response, maxBytes: number): Promise<string> {\n const reader = response.body?.getReader()\n if (!reader) return ''\n const chunks: Uint8Array[] = []\n let bytes = 0\n for (;;) {\n const { done, value } = await reader.read()\n if (done) break\n bytes += value.byteLength\n if (bytes > maxBytes) {\n await reader.cancel()\n throw new Error('Wayback CDX response exceeded the safe response limit.')\n }\n chunks.push(value)\n }\n return Buffer.concat(chunks).toString('utf8')\n}\n\nasync function fetchCdxRaw(params: URLSearchParams): Promise<string> {\n const endpoint = new URL('https://web.archive.org/cdx/search/cdx')\n endpoint.search = params.toString()\n let raw = ''\n let lastError: unknown\n for (let attempt = 0; attempt < 2; attempt++) {\n try {\n const response = await fetch(endpoint, {\n headers: { 'User-Agent': 'MCP-Scraper/Wayback (+https://mcpscraper.dev)' },\n signal: AbortSignal.timeout(45_000),\n })\n if (!response.ok) {\n const error = new Error(`Wayback CDX returned HTTP ${response.status}.`)\n if (attempt === 0 && (response.status === 429 || response.status >= 500)) {\n lastError = error\n continue\n }\n throw error\n }\n raw = await readBoundedText(response, MAX_CDX_RESPONSE_BYTES)\n lastError = null\n break\n } catch (error) {\n lastError = error\n if (attempt === 0 && (error instanceof DOMException || error instanceof TypeError)) continue\n throw error\n }\n }\n if (lastError) throw lastError\n return raw\n}\n\nfunction parseCdxPage(raw: string): { captures: WaybackCapture[]; resumeKey: string | null } {\n let rows: unknown\n try {\n rows = JSON.parse(raw)\n } catch {\n throw new Error('Wayback CDX returned invalid JSON.')\n }\n if (!Array.isArray(rows) || rows.length < 1) return { captures: [], resumeKey: null }\n\n const header = Array.isArray(rows[0]) ? rows[0].map(String) : []\n const timestampIndex = header.indexOf('timestamp')\n const originalIndex = header.indexOf('original')\n const digestIndex = header.indexOf('digest')\n const statusIndex = header.indexOf('statuscode')\n const mimeIndex = header.indexOf('mimetype')\n const lengthIndex = header.indexOf('length')\n if (timestampIndex < 0 || originalIndex < 0) throw new Error('Wayback CDX response is missing required fields.')\n\n const captures: WaybackCapture[] = []\n let resumeKey: string | null = null\n let sawResumeSeparator = false\n for (const row of rows.slice(1)) {\n if (!Array.isArray(row)) continue\n if (row.length === 0) {\n sawResumeSeparator = true\n continue\n }\n if (sawResumeSeparator && row.length === 1 && typeof row[0] === 'string') {\n resumeKey = row[0]\n continue\n }\n const timestamp = String(row[timestampIndex] ?? '')\n const originalUrl = safeHttpUrl(String(row[originalIndex] ?? ''))\n if (!validTimestamp(timestamp) || !originalUrl || originalUrl.length > MAX_ARCHIVE_URL_CHARS) continue\n const statusValue = statusIndex >= 0 ? Number(row[statusIndex]) : NaN\n const lengthValue = lengthIndex >= 0 ? Number(row[lengthIndex]) : NaN\n captures.push({\n timestamp,\n originalUrl,\n digest: digestIndex >= 0 && row[digestIndex] != null ? String(row[digestIndex]) : null,\n rawReplayUrl: buildWaybackReplayUrl(timestamp, originalUrl),\n replayUrl: buildWaybackReplayUrl(timestamp, originalUrl, ''),\n statusCode: Number.isInteger(statusValue) ? statusValue : null,\n mimeType: mimeIndex >= 0 && row[mimeIndex] != null ? String(row[mimeIndex]) : null,\n length: Number.isFinite(lengthValue) && lengthValue >= 0 ? lengthValue : null,\n })\n }\n return { captures, resumeKey }\n}\n\nasync function queryCdxPage(\n baseParams: URLSearchParams,\n limit: number,\n resumeKey?: string,\n): Promise<{ captures: WaybackCapture[]; resumeKey: string | null }> {\n const params = new URLSearchParams(baseParams)\n params.set('limit', String(Math.max(1, Math.min(MAX_CDX_ROWS, Math.floor(limit)))))\n params.set('showResumeKey', 'true')\n if (resumeKey) params.set('resumeKey', resumeKey)\n else params.delete('resumeKey')\n return parseCdxPage(await fetchCdxRaw(params))\n}\n\nasync function queryCdx(params: URLSearchParams): Promise<WaybackCapture[]> {\n return (await queryCdxPage(params, Number(params.get('limit') ?? MAX_CDX_ROWS))).captures\n}\n\nfunction siteHost(value: string): string {\n return new URL(value).hostname.replace(/^www\\./, '').toLowerCase()\n}\n\nfunction pageIdentity(value: string): string | null {\n const safe = safeHttpUrl(value)\n if (!safe) return null\n const parsed = new URL(safe)\n parsed.hash = ''\n parsed.hostname = parsed.hostname.replace(/^www\\./, '').toLowerCase()\n for (const key of [...parsed.searchParams.keys()]) {\n if (/^(utm_|fbclid$|gclid$|mc_)/i.test(key)) parsed.searchParams.delete(key)\n }\n return parsed.href\n}\n\nfunction isLikelyContentPage(value: string): boolean {\n const parsed = new URL(value)\n const path = parsed.pathname.toLowerCase()\n if (\n /(?:^|\\/)(?:wp-admin|wp-login\\.php|wp-json|xmlrpc\\.php)(?:\\/|$)/.test(path)\n || /(?:^|\\/)(?:author|tag|category|feed|comments|search)(?:\\/|$)/.test(path)\n || /\\.(?:css|js|json|xml|txt|ico|svg|png|jpe?g|gif|webp|avif|mp4|mp3|pdf|zip|woff2?|ttf|eot)$/i.test(path)\n ) return false\n if ([...parsed.searchParams.keys()].some(key => /^(?:redirect_to|reauth|action|rest_route|s|replytocom)$/i.test(key))) return false\n return true\n}\n\nfunction selectClosestCaptures(captures: WaybackCapture[], replay: WaybackReplay, maxPages: number): WaybackCapture[] {\n const expectedHost = siteHost(replay.originalUrl)\n const targetTime = timestampMillis(replay.timestamp)\n const byPage = new Map<string, WaybackCapture>()\n\n for (const capture of captures) {\n if (siteHost(capture.originalUrl) !== expectedHost) continue\n if (!isLikelyContentPage(capture.originalUrl)) continue\n const identity = pageIdentity(capture.originalUrl)\n if (!identity) continue\n const previous = byPage.get(identity)\n if (!previous) {\n byPage.set(identity, capture)\n continue\n }\n const candidateDistance = Math.abs(timestampMillis(capture.timestamp) - targetTime)\n const previousDistance = Math.abs(timestampMillis(previous.timestamp) - targetTime)\n if (candidateDistance < previousDistance) byPage.set(identity, capture)\n }\n\n const root = new URL(replay.originalUrl).origin + '/'\n return [...byPage.values()]\n .sort((a, b) => {\n if (a.originalUrl === root) return -1\n if (b.originalUrl === root) return 1\n const timeDelta = Math.abs(timestampMillis(a.timestamp) - targetTime) - Math.abs(timestampMillis(b.timestamp) - targetTime)\n return timeDelta || a.originalUrl.localeCompare(b.originalUrl)\n })\n .slice(0, maxPages)\n}\n\nfunction cdxParams(replay: WaybackReplay, maxRows: number, from?: string, to?: string): URLSearchParams {\n const original = new URL(replay.originalUrl)\n const params = new URLSearchParams({\n url: `${original.hostname}/*`,\n output: 'json',\n fl: 'timestamp,original,statuscode,mimetype,digest',\n filter: 'statuscode:200',\n limit: String(Math.min(MAX_CDX_ROWS, Math.max(maxRows, 100))),\n })\n params.append('filter', 'mimetype:text/html')\n if (from) params.set('from', from)\n if (to) params.set('to', to)\n return params\n}\n\nfunction exactCdxParams(originalUrl: string, month: string): URLSearchParams {\n const params = new URLSearchParams({\n url: originalUrl,\n output: 'json',\n fl: 'timestamp,original,statuscode,mimetype,digest',\n filter: 'statuscode:200',\n from: month.replace('-', ''),\n to: month.replace('-', ''),\n limit: '100',\n })\n params.append('filter', 'mimetype:text/html')\n return params\n}\n\nfunction closestCapture(captures: WaybackCapture[], timestamp: string): WaybackCapture | null {\n const target = timestampMillis(timestamp)\n return captures.reduce<WaybackCapture | null>((best, capture) => {\n if (!best) return capture\n return Math.abs(timestampMillis(capture.timestamp) - target) < Math.abs(timestampMillis(best.timestamp) - target)\n ? capture\n : best\n }, null)\n}\n\nexport async function resolveWaybackSiteCaptures(replay: WaybackReplay, maxPages: number): Promise<WaybackCapture[]> {\n const safeMaxPages = Math.max(1, Math.min(500, Math.floor(maxPages)))\n const maxRows = Math.min(MAX_CDX_ROWS, safeMaxPages * 25)\n const month = replay.timestamp.slice(0, 6)\n const year = replay.timestamp.slice(0, 4)\n\n let captures = await queryCdx(cdxParams(replay, maxRows, month, month))\n let selected = selectClosestCaptures(captures, replay, safeMaxPages)\n if (selected.length < Math.min(5, safeMaxPages)) {\n captures = captures.concat(await queryCdx(cdxParams(replay, maxRows, year, year)))\n selected = selectClosestCaptures(captures, replay, safeMaxPages)\n }\n if (selected.length === 0) {\n captures = await queryCdx(cdxParams(replay, maxRows, undefined, replay.timestamp))\n selected = selectClosestCaptures(captures, replay, safeMaxPages)\n }\n\n const exactPage = {\n timestamp: replay.timestamp,\n originalUrl: replay.originalUrl,\n digest: null,\n rawReplayUrl: replay.rawReplayUrl,\n }\n const exactIdentity = pageIdentity(exactPage.originalUrl)\n const withoutDuplicate = selected.filter(capture => pageIdentity(capture.originalUrl) !== exactIdentity)\n return [exactPage, ...withoutDuplicate].slice(0, safeMaxPages)\n}\n\nexport async function resolveWaybackTimelineCaptures(input: {\n rootUrl: string\n timeline: WaybackTimelineInput\n maxPagesPerSnapshot: number\n maxCaptures?: number\n}): Promise<WaybackTimelinePlan> {\n const rootUrl = safeHttpUrl(input.rootUrl)\n if (!rootUrl) throw new Error('Wayback timeline root URL is invalid.')\n const rootHost = siteHost(rootUrl)\n const months = expandWaybackMonths(input.timeline)\n if (months.length === 0) throw new Error('At least one Wayback month is required.')\n const maxPagesPerSnapshot = Math.max(1, Math.min(500, Math.floor(input.maxPagesPerSnapshot)))\n const maxCaptures = Math.max(1, Math.min(10_000, Math.floor(input.maxCaptures ?? 10_000)))\n const requestedUrls = input.timeline.urls\n ? [...new Set(input.timeline.urls.map(url => safeHttpUrl(url)).filter((url): url is string => Boolean(url)))]\n .slice(0, maxPagesPerSnapshot)\n : null\n if (requestedUrls?.some(url => siteHost(url) !== rootHost)) {\n throw new Error('Every selected Wayback URL must belong to the same site as the root URL.')\n }\n if (requestedUrls && requestedUrls.length * months.length > MAX_SELECTED_TIMELINE_CELLS) {\n throw new Error(`Selected-page Wayback timelines are limited to ${MAX_SELECTED_TIMELINE_CELLS} page-month cells per job.`)\n }\n\n const captures: WaybackCapture[] = []\n const missing: WaybackTimelinePlan['missing'] = []\n if (requestedUrls) {\n const limit = pLimit(TIMELINE_CDX_CONCURRENCY)\n const cells = months.flatMap(requestedMonth =>\n requestedUrls.map(originalUrl => ({ requestedMonth, originalUrl })))\n .slice(0, maxCaptures)\n const resolved = await Promise.all(cells.map(cell => limit(async () => {\n const rows = await queryCdx(exactCdxParams(cell.originalUrl, cell.requestedMonth))\n const capture = closestCapture(\n rows.filter(row => pageIdentity(row.originalUrl) === pageIdentity(cell.originalUrl)),\n monthAnchor(cell.requestedMonth),\n )\n return { ...cell, capture }\n })))\n for (const cell of resolved) {\n if (!cell.capture) {\n missing.push({ requestedMonth: cell.requestedMonth, originalUrl: cell.originalUrl })\n continue\n }\n captures.push({ ...cell.capture, requestedMonth: cell.requestedMonth })\n }\n } else {\n for (const requestedMonth of months) {\n const replay = {\n timestamp: monthAnchor(requestedMonth),\n modifier: null,\n originalUrl: rootUrl,\n replayUrl: buildWaybackReplayUrl(monthAnchor(requestedMonth), rootUrl, ''),\n rawReplayUrl: buildWaybackReplayUrl(monthAnchor(requestedMonth), rootUrl),\n } satisfies WaybackReplay\n const month = requestedMonth.replace('-', '')\n const rows = await queryCdx(cdxParams(replay, Math.min(MAX_CDX_ROWS, maxPagesPerSnapshot * 25), month, month))\n const selected = selectClosestCaptures(rows, replay, maxPagesPerSnapshot)\n if (selected.length === 0) {\n missing.push({ requestedMonth, originalUrl: rootUrl })\n continue\n }\n captures.push(...selected.map(capture => ({ ...capture, requestedMonth })))\n if (captures.length >= maxCaptures) break\n }\n }\n\n return {\n months,\n captures: captures.slice(0, maxCaptures),\n requestedUrls,\n missing,\n }\n}\n\nfunction normalizeCdxRangeValue(value: string | undefined): string | null {\n if (!value) return null\n const normalized = value.replace(/-/g, '')\n if (!/^(?:\\d{4}|\\d{6}|\\d{8}|\\d{14})$/.test(normalized)) {\n throw new Error('Wayback date ranges must use YYYY, YYYY-MM, YYYY-MM-DD, or a 14-digit timestamp.')\n }\n return normalized\n}\n\nfunction monthRange(from: string | null, to: string | null): string[] {\n if (!from || !to || from.length < 6 || to.length < 6) return []\n const start = new Date(Date.UTC(Number(from.slice(0, 4)), Number(from.slice(4, 6)) - 1, 1))\n const end = new Date(Date.UTC(Number(to.slice(0, 4)), Number(to.slice(4, 6)) - 1, 1))\n const months: string[] = []\n while (start <= end && months.length < 600) {\n months.push(`${start.getUTCFullYear()}-${String(start.getUTCMonth() + 1).padStart(2, '0')}`)\n start.setUTCMonth(start.getUTCMonth() + 1)\n }\n return months\n}\n\nfunction inventoryCdxParams(input: {\n url: string\n scope: WaybackInventoryScope\n from: string | null\n to: string | null\n successfulHtmlOnly: boolean\n}): URLSearchParams {\n const parsed = new URL(input.url)\n const target = input.scope === 'host' || input.scope === 'domain'\n ? parsed.hostname\n : parsed.href\n const params = new URLSearchParams({\n url: target,\n output: 'json',\n fl: 'timestamp,original,statuscode,mimetype,digest,length',\n })\n if (input.scope !== 'exact') params.set('matchType', input.scope)\n if (input.from) params.set('from', input.from)\n if (input.to) params.set('to', input.to)\n if (input.successfulHtmlOnly) {\n params.append('filter', 'statuscode:200')\n params.append('filter', 'mimetype:text/html')\n }\n return params\n}\n\nexport async function inventoryWaybackSnapshots(input: {\n url: string\n scope?: WaybackInventoryScope\n urls?: string[]\n from?: string\n to?: string\n successfulHtmlOnly?: boolean\n maxCaptures?: number\n includeCaptures?: boolean\n maxCaptureRows?: number\n}): Promise<WaybackInventoryResult> {\n const startedAt = Date.now()\n const replay = parseWaybackReplayUrl(input.url)\n const rootUrl = safeHttpUrl(replay?.originalUrl ?? input.url)\n if (!rootUrl) throw new Error('Wayback inventory URL is invalid.')\n const scope = input.scope ?? 'exact'\n const from = normalizeCdxRangeValue(input.from)\n const to = normalizeCdxRangeValue(input.to)\n if (from && to && from > to) throw new Error('Wayback inventory from must not be after to.')\n const successfulHtmlOnly = input.successfulHtmlOnly !== false\n const maxCaptures = Math.max(1, Math.min(100_000, Math.floor(input.maxCaptures ?? 10_000)))\n const maxCaptureRows = Math.max(0, Math.min(1_000, Math.floor(input.maxCaptureRows ?? 500)))\n const selectedUrls = input.urls?.length\n ? [...new Set(input.urls.map(url => safeHttpUrl(url)).filter((url): url is string => Boolean(url)))]\n : null\n const rootHost = siteHost(rootUrl)\n if (selectedUrls?.some(url => siteHost(url) !== rootHost)) {\n throw new Error('Every selected Wayback inventory URL must belong to the same site as url.')\n }\n const targets = selectedUrls ?? [rootUrl]\n const effectiveScope: WaybackInventoryScope = selectedUrls ? 'exact' : scope\n const monthly = new Map<string, number>()\n const yearly = new Map<string, number>()\n const digests = new Set<string>()\n const perUrlState = new Map<string, {\n captures: number\n digests: Set<string>\n firstTimestamp: string\n lastTimestamp: string\n }>()\n const captureRows: WaybackCapture[] = []\n let totalCaptures = 0\n let queryPages = 0\n let firstCapture: WaybackCapture | null = null\n let lastCapture: WaybackCapture | null = null\n let truncated = false\n\n targetLoop:\n for (let targetIndex = 0; targetIndex < targets.length; targetIndex++) {\n const target = targets[targetIndex]\n const params = inventoryCdxParams({\n url: target,\n scope: effectiveScope,\n from,\n to,\n successfulHtmlOnly,\n })\n let resumeKey: string | undefined\n do {\n const remaining = maxCaptures - totalCaptures\n if (remaining <= 0) {\n truncated = true\n break targetLoop\n }\n const page = await queryCdxPage(params, Math.min(MAX_CDX_ROWS, remaining), resumeKey)\n queryPages++\n for (const capture of page.captures) {\n totalCaptures++\n const month = `${capture.timestamp.slice(0, 4)}-${capture.timestamp.slice(4, 6)}`\n const year = capture.timestamp.slice(0, 4)\n monthly.set(month, (monthly.get(month) ?? 0) + 1)\n yearly.set(year, (yearly.get(year) ?? 0) + 1)\n if (capture.digest) digests.add(capture.digest)\n const state = perUrlState.get(capture.originalUrl) ?? {\n captures: 0,\n digests: new Set<string>(),\n firstTimestamp: capture.timestamp,\n lastTimestamp: capture.timestamp,\n }\n state.captures++\n if (capture.digest) state.digests.add(capture.digest)\n if (capture.timestamp < state.firstTimestamp) state.firstTimestamp = capture.timestamp\n if (capture.timestamp > state.lastTimestamp) state.lastTimestamp = capture.timestamp\n perUrlState.set(capture.originalUrl, state)\n if (!firstCapture || capture.timestamp < firstCapture.timestamp) firstCapture = capture\n if (!lastCapture || capture.timestamp > lastCapture.timestamp) lastCapture = capture\n if (input.includeCaptures === true && captureRows.length < maxCaptureRows) captureRows.push(capture)\n }\n resumeKey = page.resumeKey ?? undefined\n if (resumeKey && totalCaptures >= maxCaptures) {\n truncated = true\n break targetLoop\n }\n } while (resumeKey)\n if (targetIndex < targets.length - 1 && totalCaptures >= maxCaptures) {\n truncated = true\n break\n }\n }\n\n const monthlyCounts = [...monthly.entries()]\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([month, captures]) => ({ month, captures }))\n const yearlyCounts = [...yearly.entries()]\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([year, captures]) => ({ year, captures }))\n const allPerUrl = [...perUrlState.entries()]\n .map(([url, state]) => ({\n url,\n captures: state.captures,\n uniqueDigests: state.digests.size,\n firstTimestamp: state.firstTimestamp,\n lastTimestamp: state.lastTimestamp,\n }))\n .sort((a, b) => b.captures - a.captures || a.url.localeCompare(b.url))\n const availableMonths = new Set(monthly.keys())\n\n return {\n url: rootUrl,\n scope: effectiveScope,\n selectedUrls,\n from,\n to,\n successfulHtmlOnly,\n totalCaptures,\n countType: truncated ? 'lower_bound' : 'exact',\n complete: !truncated,\n truncated,\n maxCaptures,\n queryPages,\n uniqueUrls: perUrlState.size,\n uniqueDigests: digests.size,\n firstCapture,\n lastCapture,\n monthlyCounts,\n yearlyCounts,\n missingMonths: monthRange(from, to).filter(month => !availableMonths.has(month)),\n perUrl: allPerUrl.slice(0, 500),\n perUrlTruncatedCount: Math.max(0, allPerUrl.length - 500),\n captures: captureRows,\n captureRowsTruncatedCount: input.includeCaptures === true\n ? Math.max(0, totalCaptures - captureRows.length)\n : totalCaptures,\n durationMs: Date.now() - startedAt,\n }\n}\n\nfunction firstJsonLdImage(value: unknown): string | null {\n if (typeof value === 'string') return value\n if (Array.isArray(value)) {\n for (const item of value) {\n const found = firstJsonLdImage(item)\n if (found) return found\n }\n return null\n }\n if (!value || typeof value !== 'object') return null\n const record = value as Record<string, unknown>\n for (const key of ['url', 'contentUrl']) {\n if (typeof record[key] === 'string') return record[key] as string\n }\n for (const key of ['image', 'thumbnailUrl', '@graph']) {\n const found = firstJsonLdImage(record[key])\n if (found) return found\n }\n return null\n}\n\nfunction firstContentImage(html: string): string | null {\n for (const match of html.matchAll(/<img\\b[^>]*>/gi)) {\n const tag = match[0]\n const attr = (name: string) =>\n tag.match(new RegExp(`\\\\b${name}\\\\s*=\\\\s*(?:\"([^\"]+)\"|'([^']+)'|([^\\\\s>]+))`, 'i'))?.slice(1).find(Boolean) ?? null\n const candidate = attr('data-src') ?? attr('src') ?? attr('data-lazy-src')\n if (!candidate || /^(?:data:|javascript:)/i.test(candidate)) continue\n const descriptor = `${candidate} ${attr('alt') ?? ''} ${attr('class') ?? ''}`.toLowerCase()\n if (/(?:logo|icon|avatar|sprite|pixel|tracking|spacer)/.test(descriptor)) continue\n const width = Number(attr('width') ?? 0)\n const height = Number(attr('height') ?? 0)\n if ((width > 0 && width < 200) || (height > 0 && height < 120)) continue\n return candidate\n }\n return null\n}\n\nexport function resolveFeaturedImage(input: {\n html: string\n meta: Record<string, string>\n schema: unknown[]\n pageUrl: string\n}): FeaturedImage | null {\n const replay = parseWaybackReplayUrl(input.pageUrl)\n const baseUrl = replay?.originalUrl ?? input.pageUrl\n const candidates: Array<{ value: string | null | undefined; source: FeaturedImage['source'] }> = [\n { value: input.meta['og:image'] ?? input.meta['og:image:url'] ?? input.meta['og:image:secure_url'], source: 'og:image' },\n { value: input.meta['twitter:image'] ?? input.meta['twitter:image:src'], source: 'twitter:image' },\n { value: firstJsonLdImage(input.schema), source: 'json-ld' },\n { value: firstContentImage(input.html), source: 'content-image' },\n ]\n\n for (const candidate of candidates) {\n if (!candidate.value) continue\n const url = safeHttpUrl(candidate.value, baseUrl)\n if (!url) continue\n return {\n url,\n archivedUrl: replay ? buildWaybackReplayUrl(replay.timestamp, url, 'im_') : null,\n source: candidate.source,\n }\n }\n return null\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,7 @@
1
1
  import {
2
- downloadAsset
3
- } from "./chunk-JWIE5NCR.js";
2
+ downloadAsset,
3
+ expandWaybackMonths
4
+ } from "./chunk-YV2FUEBX.js";
4
5
  import {
5
6
  computeIssues,
6
7
  getBlobStore,
@@ -64,6 +65,7 @@ async function* pageChunks(jobId) {
64
65
  async function assembleExtractArtifacts(job, extras = {}) {
65
66
  const dir = join(tmpdir(), `extract-bundle-${job.id}-${Date.now()}`);
66
67
  const downloadImages = job.options.downloadImages === true;
68
+ const waybackTimeline = job.options.waybackTimeline;
67
69
  mkdirSync(join(dir, "pages"), { recursive: true });
68
70
  if (downloadImages) mkdirSync(join(dir, "images"), { recursive: true });
69
71
  try {
@@ -107,12 +109,17 @@ async function assembleExtractArtifacts(job, extras = {}) {
107
109
  for (const p of chunk) {
108
110
  if (p.bodyMarkdown) {
109
111
  pagesWithBody++;
112
+ const provenance = p;
113
+ const pageDir = provenance.requestedMonth ? join(dir, "pages", provenance.requestedMonth) : join(dir, "pages");
114
+ mkdirSync(pageDir, { recursive: true });
110
115
  writeFileSync(
111
- join(dir, "pages", slug(p.url) + ".md"),
112
- `# ${p.title ?? p.url}
116
+ join(pageDir, slug(provenance.originalUrl ?? p.url) + ".md"),
117
+ `# ${p.title ?? provenance.originalUrl ?? p.url}
113
118
 
114
- URL: ${p.url}
115
- Status: ${p.status}
119
+ URL: ${provenance.originalUrl ?? p.url}
120
+ ${provenance.archivedUrl ? `Archived URL: ${provenance.archivedUrl}
121
+ ` : ""}${provenance.archiveTimestamp ? `Archive timestamp: ${provenance.archiveTimestamp}
122
+ ` : ""}Status: ${p.status}
116
123
 
117
124
  ---
118
125
 
@@ -282,6 +289,42 @@ ${renderImageSection(extras.imageAudit)}`;
282
289
  perSiteCap: MAX_IMAGES_PER_SITE
283
290
  }, null, 2));
284
291
  }
292
+ if (waybackTimeline) {
293
+ const months = expandWaybackMonths(waybackTimeline.timeline);
294
+ const selectedUrls = waybackTimeline.timeline.urls ?? null;
295
+ const captureRows = metas.map((page) => {
296
+ const provenance = page;
297
+ return {
298
+ requestedMonth: provenance.requestedMonth ?? provenance.archiveTimestamp?.slice(0, 6).replace(/^(\d{4})(\d{2})$/, "$1-$2") ?? null,
299
+ originalUrl: provenance.originalUrl ?? page.url,
300
+ archivedUrl: provenance.archivedUrl ?? page.url,
301
+ timestamp: provenance.archiveTimestamp ?? null,
302
+ status: page.status,
303
+ captured: page.status != null && page.status >= 200 && page.status < 300 && page.wordCount > 0
304
+ };
305
+ });
306
+ const matrixRows = selectedUrls ? months.flatMap((month) => selectedUrls.map((originalUrl) => {
307
+ const found = captureRows.find((row) => row.requestedMonth === month && row.originalUrl === originalUrl);
308
+ return found ?? {
309
+ requestedMonth: month,
310
+ originalUrl,
311
+ archivedUrl: null,
312
+ timestamp: null,
313
+ status: null,
314
+ captured: false,
315
+ failureCode: "wayback_capture_missing"
316
+ };
317
+ })) : captureRows;
318
+ writeFileSync(join(dir, "wayback-manifest.json"), JSON.stringify({
319
+ rootUrl: waybackTimeline.rootUrl,
320
+ requested: waybackTimeline.timeline,
321
+ months,
322
+ maxPagesPerSnapshot: waybackTimeline.maxPagesPerSnapshot,
323
+ capturedPages: captureRows.filter((row) => row.captured).length,
324
+ missingCells: matrixRows.filter((row) => !row.captured).length
325
+ }, null, 2));
326
+ writeFileSync(join(dir, "capture-matrix.jsonl"), matrixRows.map((row) => JSON.stringify(row)).join("\n"));
327
+ }
285
328
  const artifactFiles = [
286
329
  { name: "report.md", type: "text/markdown" },
287
330
  { name: "issues.json", type: "application/json" },
@@ -299,12 +342,20 @@ ${renderImageSection(extras.imageAudit)}`;
299
342
  if (extras.seoAudit) artifactFiles.push({ name: "seo-audit.json", type: "application/json" });
300
343
  if (extras.branding) artifactFiles.push({ name: "branding.json", type: "application/json" });
301
344
  if (downloadImages) artifactFiles.push({ name: "images-download-summary.json", type: "application/json" });
345
+ if (waybackTimeline) {
346
+ artifactFiles.push({ name: "wayback-manifest.json", type: "application/json" });
347
+ artifactFiles.push({ name: "capture-matrix.jsonl", type: "application/x-ndjson" });
348
+ }
302
349
  const zip = new ZipFile();
303
350
  const zipOut = createWriteStream(join(dir, "bundle.zip"));
304
351
  zip.outputStream.pipe(zipOut);
305
352
  for (const f of artifactFiles) zip.addFile(join(dir, f.name), f.name);
306
353
  if (pagesWithBody > 0) {
307
- for (const f of readdirSync(join(dir, "pages"))) zip.addFile(join(dir, "pages", f), `pages/${f}`);
354
+ const pagesDir = join(dir, "pages");
355
+ for (const rel of readdirSync(pagesDir, { recursive: true })) {
356
+ const full = join(pagesDir, rel);
357
+ if (statSync(full).isFile()) zip.addFile(full, `pages/${rel.split("\\").join("/")}`);
358
+ }
308
359
  }
309
360
  if (downloadImages && imagesQueued > imagesFailed) {
310
361
  const imagesDir = join(dir, "images");
@@ -328,4 +379,4 @@ ${renderImageSection(extras.imageAudit)}`;
328
379
  export {
329
380
  assembleExtractArtifacts
330
381
  };
331
- //# sourceMappingURL=extract-bundle-GPZRLBVY.js.map
382
+ //# sourceMappingURL=extract-bundle-ONWZVV55.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/api/extract-bundle.ts"],"sourcesContent":["import { createWriteStream, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from 'node:fs'\nimport { basename, join } from 'node:path'\nimport { tmpdir } from 'node:os'\nimport { createGzip } from 'node:zlib'\nimport { once } from 'node:events'\nimport { ZipFile } from 'yazl'\nimport pLimit from 'p-limit'\nimport { getDb } from './db.js'\nimport { getBlobStore, type StoredArtifact } from './blob-store.js'\nimport { computeIssues, renderIssueReport } from './seo-issues.js'\nimport { renderLinkReport, type ExtDomainRow, type LinkReport } from './seo-link-report.js'\nimport type { PageLinkMetrics } from './seo-link-graph.js'\nimport type { SeoAudit } from './seo-audit.js'\nimport type { ExtractJobRow } from './site-extract-repository.js'\nimport type { PageData } from './site-extractor.js'\nimport { renderImageSection, type ImageAudit } from './image-audit.js'\nimport { downloadAsset } from '../lib/media-extractor.js'\nimport { expandWaybackMonths } from './wayback.js'\nimport type { WaybackTimelineInput } from './wayback-schemas.js'\n\nconst CHUNK = 400\nconst MAX_IMAGES_PER_PAGE = 20\nconst MAX_IMAGES_PER_SITE = 500\nconst IMAGE_DOWNLOAD_CONCURRENCY = 8\n\nfunction normalize(u: string): string {\n return u.split('#')[0].replace(/\\/$/, '')\n}\n\nfunction registrableDomain(host: string): string {\n const h = host.replace(/^www\\./, '').toLowerCase()\n const parts = h.split('.')\n return parts.length <= 2 ? h : parts.slice(-2).join('.')\n}\n\nfunction safeImageFilename(url: string, index: number): string {\n try {\n const u = new URL(url)\n const base = basename(u.pathname).replace(/[^a-zA-Z0-9._-]/g, '_').slice(0, 80)\n return base || `image-${index}`\n } catch {\n return `image-${index}`\n }\n}\n\nfunction slugFactory() {\n const counts = new Map<string, number>()\n return (url: string): string => {\n const base = url.replace(/^https?:\\/\\//, '').replace(/[^a-zA-Z0-9]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 80) || 'page'\n const n = counts.get(base) ?? 0\n counts.set(base, n + 1)\n return n ? `${base}-${n}` : base\n }\n}\n\nasync function* pageChunks(jobId: string): AsyncGenerator<PageData[]> {\n const db = getDb()\n for (let offset = 0; ; offset += CHUNK) {\n const res = await db.execute({\n sql: `SELECT page FROM site_extract_pages WHERE job_id = ? ORDER BY rowid LIMIT ${CHUNK} OFFSET ?`,\n args: [jobId, offset],\n })\n if (!res.rows.length) return\n yield res.rows.map(r => JSON.parse(String((r as unknown as Record<string, unknown>).page)) as PageData)\n }\n}\n\nexport interface AssembleExtras {\n branding?: unknown\n imageAudit?: ImageAudit | null\n seoAudit?: SeoAudit | null\n}\n\nexport async function assembleExtractArtifacts(job: ExtractJobRow, extras: AssembleExtras = {}): Promise<StoredArtifact[]> {\n const dir = join(tmpdir(), `extract-bundle-${job.id}-${Date.now()}`)\n const downloadImages = job.options.downloadImages === true\n const waybackTimeline = job.options.waybackTimeline as {\n rootUrl: string\n timeline: WaybackTimelineInput\n maxPagesPerSnapshot: number\n } | undefined\n mkdirSync(join(dir, 'pages'), { recursive: true })\n if (downloadImages) mkdirSync(join(dir, 'images'), { recursive: true })\n try {\n const metas: PageData[] = []\n const statusByUrl = new Map<string, number | null>()\n for await (const chunk of pageChunks(job.id)) {\n for (const p of chunk) {\n statusByUrl.set(normalize(p.url), p.status)\n const { bodyMarkdown: _b, schema: _s, outlinks: _o, ...slim } = p\n metas.push(slim as unknown as PageData)\n }\n }\n\n const gz = createGzip()\n const linksOut = createWriteStream(join(dir, 'links.jsonl.gz'))\n gz.pipe(linksOut)\n const gzWrite = async (line: string) => { if (!gz.write(line)) await once(gz, 'drain') }\n\n const slug = slugFactory()\n const inboundFrom = new Map<string, Set<string>>()\n const anchorCounts = new Map<string, Map<string, number>>()\n const adjacency = new Map<string, Set<string>>()\n const outCounts = new Map<string, { int: number; ext: number }>()\n const domMap = new Map<string, { links: number; nofollow: number; pages: Set<string> }>()\n const brokenLinkPages = new Set<string>()\n let internalTotal = 0\n let externalTotal = 0\n let brokenInternal = 0\n let pagesWithBody = 0\n let siteReg = ''\n try { siteReg = registrableDomain(new URL(job.startUrl).hostname) } catch { siteReg = '' }\n\n const imageLimit = pLimit(IMAGE_DOWNLOAD_CONCURRENCY)\n const imageDownloads: Promise<void>[] = []\n let imagesQueued = 0\n let imagesFailed = 0\n\n for await (const chunk of pageChunks(job.id)) {\n for (const p of chunk) {\n if (p.bodyMarkdown) {\n pagesWithBody++\n const provenance = p as PageData & {\n archivedUrl?: string\n archiveTimestamp?: string\n originalUrl?: string\n requestedMonth?: string\n }\n const pageDir = provenance.requestedMonth\n ? join(dir, 'pages', provenance.requestedMonth)\n : join(dir, 'pages')\n mkdirSync(pageDir, { recursive: true })\n writeFileSync(join(pageDir, slug(provenance.originalUrl ?? p.url) + '.md'),\n `# ${p.title ?? provenance.originalUrl ?? p.url}\\n\\nURL: ${provenance.originalUrl ?? p.url}\\n${provenance.archivedUrl ? `Archived URL: ${provenance.archivedUrl}\\n` : ''}${provenance.archiveTimestamp ? `Archive timestamp: ${provenance.archiveTimestamp}\\n` : ''}Status: ${p.status}\\n\\n---\\n\\n${p.bodyMarkdown}\\n`)\n }\n if (downloadImages && p.imageLinks?.length && imagesQueued < MAX_IMAGES_PER_SITE) {\n const pageDir = join(dir, 'images', slug(p.url))\n mkdirSync(pageDir, { recursive: true })\n for (const [idx, imgUrl] of p.imageLinks.slice(0, MAX_IMAGES_PER_PAGE).entries()) {\n if (imagesQueued >= MAX_IMAGES_PER_SITE) break\n imagesQueued++\n const filename = safeImageFilename(imgUrl, idx)\n imageDownloads.push(\n imageLimit(() => downloadAsset(imgUrl, pageDir, filename)).then(() => undefined, () => { imagesFailed++ }),\n )\n }\n }\n const from = normalize(p.url)\n const oc = { int: 0, ext: 0 }\n for (const l of p.outlinks ?? []) {\n const nofollow = (l.rel ?? '').split(/\\s+/).includes('nofollow')\n const to = normalize(l.href)\n const targetStatus = statusByUrl.get(to) ?? null\n await gzWrite(JSON.stringify({ from: p.url, to: l.href, anchor: l.anchor, rel: l.rel, internal: l.internal, nofollow, targetStatus }) + '\\n')\n if (l.internal) {\n oc.int++\n internalTotal++\n if (!inboundFrom.has(to)) inboundFrom.set(to, new Set())\n inboundFrom.get(to)!.add(from)\n if (l.anchor) {\n if (!anchorCounts.has(to)) anchorCounts.set(to, new Map())\n const ac = anchorCounts.get(to)!\n ac.set(l.anchor, (ac.get(l.anchor) ?? 0) + 1)\n }\n if (!nofollow && (statusByUrl.get(to) === 200 || !statusByUrl.has(to))) {\n if (!adjacency.has(from)) adjacency.set(from, new Set())\n adjacency.get(from)!.add(to)\n }\n if (targetStatus != null && targetStatus >= 400) {\n brokenInternal++\n brokenLinkPages.add(p.url)\n }\n } else {\n oc.ext++\n let domain = ''\n try { domain = registrableDomain(new URL(l.href).hostname) } catch { continue }\n if (!domain || domain === siteReg) continue\n externalTotal++\n const d = domMap.get(domain) ?? { links: 0, nofollow: 0, pages: new Set<string>() }\n d.links++\n if (nofollow) d.nofollow++\n d.pages.add(p.url)\n domMap.set(domain, d)\n }\n }\n outCounts.set(p.url, oc)\n }\n }\n gz.end()\n await once(linksOut, 'finish')\n await Promise.all(imageDownloads)\n\n const depth = new Map<string, number>()\n const start = normalize(job.startUrl)\n depth.set(start, 0)\n const queue: string[] = [start]\n while (queue.length > 0) {\n const cur = queue.shift()!\n const d = depth.get(cur)!\n for (const next of adjacency.get(cur) ?? []) {\n if (!depth.has(next)) { depth.set(next, d + 1); queue.push(next) }\n }\n }\n\n const metrics = new Map<string, PageLinkMetrics>()\n for (const p of metas) {\n const key = normalize(p.url)\n const inbound = inboundFrom.get(key) ?? new Set()\n const ac = anchorCounts.get(key)\n const topAnchors = ac\n ? [...ac.entries()].sort((a, b) => b[1] - a[1]).slice(0, 3).map(e => e[0])\n : []\n const oc = outCounts.get(p.url) ?? { int: 0, ext: 0 }\n metrics.set(p.url, {\n url: p.url,\n inlinks: inbound.size,\n uniqueInlinks: inbound.size,\n outlinksInternal: oc.int,\n outlinksExternal: oc.ext,\n crawlDepth: depth.has(key) ? depth.get(key)! : null,\n orphan: inbound.size === 0 && key !== start,\n topAnchors,\n })\n }\n\n const issues = computeIssues(metas, metrics, brokenLinkPages)\n let reportMd = renderIssueReport(job.startUrl, metas, issues, metrics)\n if (extras.imageAudit) reportMd += `\\n\\n${renderImageSection(extras.imageAudit)}`\n\n const metricValues = [...metrics.values()]\n const round = (n: number) => Math.round(n * 10) / 10\n const distribution = { zero: 0, oneToTwo: 0, threeToTen: 0, elevenPlus: 0 }\n let sumInlinks = 0\n let sumOutlinks = 0\n for (const m of metricValues) {\n sumInlinks += m.inlinks\n sumOutlinks += m.outlinksInternal + m.outlinksExternal\n if (m.inlinks === 0) distribution.zero++\n else if (m.inlinks <= 2) distribution.oneToTwo++\n else if (m.inlinks <= 10) distribution.threeToTen++\n else distribution.elevenPlus++\n }\n const externalDomains: ExtDomainRow[] = [...domMap.entries()]\n .map(([domain, d]) => ({ domain, links: d.links, nofollow: d.nofollow, pages: d.pages.size }))\n .sort((a, b) => b.links - a.links)\n const linkReport: LinkReport = {\n summary: {\n internal: {\n totalLinks: internalTotal,\n pages: metas.length,\n orphans: metricValues.filter(m => m.orphan).length,\n brokenInternal,\n avgInlinks: metas.length ? round(sumInlinks / metas.length) : 0,\n avgOutlinks: metas.length ? round(sumOutlinks / metas.length) : 0,\n distribution,\n topByInlinks: [...metricValues].sort((a, b) => b.inlinks - a.inlinks).slice(0, 20)\n .map(m => ({ url: m.url, inlinks: m.inlinks, outlinksInternal: m.outlinksInternal, outlinksExternal: m.outlinksExternal })),\n },\n external: {\n totalLinks: externalTotal,\n uniqueDomains: externalDomains.length,\n topDomains: externalDomains.slice(0, 20),\n },\n },\n externalDomains,\n }\n\n const pagesOut = createWriteStream(join(dir, 'pages.jsonl'))\n for (const p of metas) {\n const m = metrics.get(p.url)\n const row = { ...(p as unknown as Record<string, unknown>), inlinks: m?.inlinks ?? 0, crawlDepth: m?.crawlDepth ?? null, orphan: m?.orphan ?? false }\n if (!pagesOut.write(JSON.stringify(row) + '\\n')) await once(pagesOut, 'drain')\n }\n pagesOut.end()\n await once(pagesOut, 'finish')\n\n writeFileSync(join(dir, 'report.md'), reportMd)\n writeFileSync(join(dir, 'issues.json'), JSON.stringify(issues, null, 2))\n writeFileSync(join(dir, 'link-metrics.jsonl'), metricValues.map(m => JSON.stringify(m)).join('\\n'))\n writeFileSync(join(dir, 'link-report.md'), renderLinkReport(linkReport))\n writeFileSync(join(dir, 'links-summary.json'), JSON.stringify(linkReport.summary, null, 2))\n writeFileSync(join(dir, 'external-domains.json'), JSON.stringify(linkReport.externalDomains, null, 2))\n if (extras.imageAudit) {\n writeFileSync(join(dir, 'images.jsonl'), extras.imageAudit.rows.map(r => JSON.stringify(r)).join('\\n'))\n writeFileSync(join(dir, 'images-summary.json'), JSON.stringify(extras.imageAudit.summary, null, 2))\n }\n if (extras.seoAudit) writeFileSync(join(dir, 'seo-audit.json'), JSON.stringify(extras.seoAudit, null, 2))\n if (extras.branding) writeFileSync(join(dir, 'branding.json'), JSON.stringify(extras.branding, null, 2))\n if (downloadImages) {\n writeFileSync(join(dir, 'images-download-summary.json'), JSON.stringify({\n queued: imagesQueued,\n downloaded: imagesQueued - imagesFailed,\n failed: imagesFailed,\n perPageCap: MAX_IMAGES_PER_PAGE,\n perSiteCap: MAX_IMAGES_PER_SITE,\n }, null, 2))\n }\n if (waybackTimeline) {\n const months = expandWaybackMonths(waybackTimeline.timeline)\n const selectedUrls = waybackTimeline.timeline.urls ?? null\n const captureRows = metas.map(page => {\n const provenance = page as PageData & {\n archivedUrl?: string\n archiveTimestamp?: string\n originalUrl?: string\n requestedMonth?: string\n }\n return {\n requestedMonth: provenance.requestedMonth ?? provenance.archiveTimestamp?.slice(0, 6).replace(/^(\\d{4})(\\d{2})$/, '$1-$2') ?? null,\n originalUrl: provenance.originalUrl ?? page.url,\n archivedUrl: provenance.archivedUrl ?? page.url,\n timestamp: provenance.archiveTimestamp ?? null,\n status: page.status,\n captured: page.status != null && page.status >= 200 && page.status < 300 && page.wordCount > 0,\n }\n })\n const matrixRows = selectedUrls\n ? months.flatMap(month => selectedUrls.map(originalUrl => {\n const found = captureRows.find(row => row.requestedMonth === month && row.originalUrl === originalUrl)\n return found ?? {\n requestedMonth: month,\n originalUrl,\n archivedUrl: null,\n timestamp: null,\n status: null,\n captured: false,\n failureCode: 'wayback_capture_missing',\n }\n }))\n : captureRows\n writeFileSync(join(dir, 'wayback-manifest.json'), JSON.stringify({\n rootUrl: waybackTimeline.rootUrl,\n requested: waybackTimeline.timeline,\n months,\n maxPagesPerSnapshot: waybackTimeline.maxPagesPerSnapshot,\n capturedPages: captureRows.filter(row => row.captured).length,\n missingCells: matrixRows.filter(row => !row.captured).length,\n }, null, 2))\n writeFileSync(join(dir, 'capture-matrix.jsonl'), matrixRows.map(row => JSON.stringify(row)).join('\\n'))\n }\n\n const artifactFiles: Array<{ name: string; type: string }> = [\n { name: 'report.md', type: 'text/markdown' },\n { name: 'issues.json', type: 'application/json' },\n { name: 'pages.jsonl', type: 'application/x-ndjson' },\n { name: 'links.jsonl.gz', type: 'application/gzip' },\n { name: 'link-metrics.jsonl', type: 'application/x-ndjson' },\n { name: 'link-report.md', type: 'text/markdown' },\n { name: 'links-summary.json', type: 'application/json' },\n { name: 'external-domains.json', type: 'application/json' },\n ]\n if (extras.imageAudit) {\n artifactFiles.push({ name: 'images.jsonl', type: 'application/x-ndjson' })\n artifactFiles.push({ name: 'images-summary.json', type: 'application/json' })\n }\n if (extras.seoAudit) artifactFiles.push({ name: 'seo-audit.json', type: 'application/json' })\n if (extras.branding) artifactFiles.push({ name: 'branding.json', type: 'application/json' })\n if (downloadImages) artifactFiles.push({ name: 'images-download-summary.json', type: 'application/json' })\n if (waybackTimeline) {\n artifactFiles.push({ name: 'wayback-manifest.json', type: 'application/json' })\n artifactFiles.push({ name: 'capture-matrix.jsonl', type: 'application/x-ndjson' })\n }\n\n const zip = new ZipFile()\n const zipOut = createWriteStream(join(dir, 'bundle.zip'))\n zip.outputStream.pipe(zipOut)\n for (const f of artifactFiles) zip.addFile(join(dir, f.name), f.name)\n if (pagesWithBody > 0) {\n const pagesDir = join(dir, 'pages')\n for (const rel of readdirSync(pagesDir, { recursive: true }) as string[]) {\n const full = join(pagesDir, rel)\n if (statSync(full).isFile()) zip.addFile(full, `pages/${rel.split('\\\\').join('/')}`)\n }\n }\n if (downloadImages && imagesQueued > imagesFailed) {\n const imagesDir = join(dir, 'images')\n for (const rel of readdirSync(imagesDir, { recursive: true }) as string[]) {\n const full = join(imagesDir, rel)\n if (statSync(full).isFile()) zip.addFile(full, `images/${rel.split('\\\\').join('/')}`)\n }\n }\n zip.end()\n await once(zipOut, 'finish')\n\n const store = getBlobStore()\n const stored: StoredArtifact[] = []\n for (const f of [...artifactFiles, { name: 'bundle.zip', type: 'application/zip' }]) {\n stored.push(await store.put(`extract/${job.id}/${f.name}`, readFileSync(join(dir, f.name)), f.type))\n }\n return stored\n } finally {\n rmSync(dir, { recursive: true, force: true })\n }\n}\n"],"mappings":"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","names":[]}
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  harvest
3
- } from "./chunk-4KQVIYIH.js";
3
+ } from "./chunk-XVVNKASZ.js";
4
4
  import {
5
5
  recordVendorUsage
6
- } from "./chunk-V36LS5YV.js";
6
+ } from "./chunk-4ZB3X6BQ.js";
7
7
  import "./chunk-K443GQY5.js";
8
8
  import "./chunk-CB5C3BPB.js";
9
9
  import "./chunk-M2S27J6Z.js";