ultra-igdl 1.0.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../node_modules/tsup/assets/cjs_shims.js","../../src/utils/logger.ts","../../src/utils/caption-normalize.ts","../../src/utils/engagement.ts","../../src/utils/caption.ts","../../src/core/parser.ts","../../src/cli/index.ts","../../src/index.ts","../../src/core/downloader.ts","../../src/types/index.ts","../../src/version.ts","../../src/network/client.ts","../../src/network/request.ts","../../src/network/headers.ts","../../src/network/retry.ts","../../src/network/pool.ts","../../src/core/cache.ts","../../src/core/extractor.ts","../../src/extractors/reel.ts","../../src/extractors/post.ts","../../src/extractors/story.ts","../../src/utils/media-quality.ts","../../src/utils/media-dimensions.ts","../../src/network/instagram-api.ts","../../src/utils/engagement-tags.ts","../../src/extractors/highlight.ts","../../src/core/normalize.ts","../../src/utils/post-carousel.ts","../../src/network/post-media.ts","../../src/network/embed-caption.ts","../../src/utils/media-id.ts","../../src/utils/post-media-pk.ts","../../src/utils/shortcode.ts","../../src/utils/post-carousel-detect.ts","../../src/utils/urls.ts","../../src/utils/validators.ts","../../src/utils/downloader.ts"],"sourcesContent":["// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","export type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\" | \"silent\";\n\nlet globalLevel: LogLevel = \"info\";\nlet verboseEnabled = false;\n\nexport function setLogLevel(level: LogLevel): void {\n globalLevel = level;\n}\n\nexport function setVerbose(enabled: boolean): void {\n verboseEnabled = enabled;\n}\n\nconst LEVELS: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n silent: 4,\n};\n\nfunction shouldLog(level: LogLevel): boolean {\n if (verboseEnabled && level === \"debug\") return true;\n return LEVELS[level] >= LEVELS[globalLevel];\n}\n\nexport const logger = {\n debug(...args: unknown[]): void {\n if (shouldLog(\"debug\")) console.debug(\"[ultra-igdl]\", ...args);\n },\n info(...args: unknown[]): void {\n if (shouldLog(\"info\")) console.info(\"[ultra-igdl]\", ...args);\n },\n warn(...args: unknown[]): void {\n if (shouldLog(\"warn\")) console.warn(\"[ultra-igdl]\", ...args);\n },\n error(...args: unknown[]): void {\n if (shouldLog(\"error\")) console.error(\"[ultra-igdl]\", ...args);\n },\n};","import { decodeHtmlEntities } from \"../core/parser.js\";\n\n/** Turn literal \\\\n, \\\\r\\\\n, \\\\u000a, etc. into real line breaks (incl. double-escaped API/HTML). */\nexport function unescapeCaptionEscapes(text: string): string {\n let cur = text;\n for (let i = 0; i < 4; i++) {\n const next = cur\n .replace(/\\\\+u000d\\\\+u000a/gi, \"\\n\")\n .replace(/\\\\+u000a/gi, \"\\n\")\n .replace(/\\\\+u000d/gi, \"\\n\")\n .replace(/\\\\+r\\\\+n/gi, \"\\n\")\n .replace(/\\\\+n/g, \"\\n\")\n .replace(/\\\\+r/g, \"\\n\");\n if (next === cur) break;\n cur = next;\n }\n return cur.replace(/\\u2028/g, \"\\n\").replace(/\\u2029/g, \"\\n\");\n}\n\n/** Preserve internal newlines; decode entities and JSON-style escapes. */\nexport function normalizeCaptionText(raw: string): string {\n if (!raw) return \"\";\n let text = unescapeCaptionEscapes(decodeHtmlEntities(raw));\n text = text.replace(/^\\s+/, \"\").replace(/\\s+$/, \"\");\n text = text.replace(/^[\"'\\u201c\\u201d]+|[\"'\\u201d\\u201c]+$/g, \"\");\n return text;\n}\n\n/** Drop lone \".\" / \"…\" lines and extra breaks (common on Instagram post captions). */\nexport function cleanInstagramCaptionLayout(text: string): string {\n const lines = text.split(/\\r?\\n/);\n const kept = lines\n .map((line) => line.trim())\n .filter((line) => line && !/^\\.+$/.test(line) && !/^[\\u2026…]+$/.test(line));\n return kept.join(\" \").replace(/\\s+/g, \" \").trim();\n}\n\n/** Post captions: unescape + flatten to a single readable line (no \\\\n in JSON output). */\nexport function normalizePostCaptionText(raw: string): string {\n return cleanInstagramCaptionLayout(normalizeCaptionText(raw));\n}","import type { Engagement } from \"../types/index.js\";\nimport { normalizeCaptionText } from \"./caption-normalize.js\";\n\n/** Normalize Instagram curly/smart quotes for caption extraction. */\nexport function normalizeInstagramQuotes(raw: string): string {\n return raw\n .replace(/[\\u201c\\u201d\\u201e\\u2033\\u2036]/g, '\"')\n .replace(/[\\u2018\\u2019\\u2032]/g, \"'\")\n .trim();\n}\n\nfunction parseCount(token: string): number | undefined {\n const m = token.trim().match(/^([\\d.]+)\\s*([KMB])?$/i);\n if (!m) return undefined;\n let n = parseFloat(m[1]!);\n const suffix = (m[2] ?? \"\").toUpperCase();\n if (suffix === \"K\") n *= 1000;\n else if (suffix === \"M\") n *= 1_000_000;\n else if (suffix === \"B\") n *= 1_000_000_000;\n return Math.round(n);\n}\n\nexport function extractEngagementCounts(statsSegment: string): Engagement {\n const engagement: Engagement = {};\n const likes = statsSegment.match(/([\\d.]+[KMB]?)\\s+likes?/i);\n const comments = statsSegment.match(/([\\d.]+[KMB]?)\\s+comments?/i);\n const views = statsSegment.match(/([\\d.]+[KMB]?)\\s+views?/i);\n const shares = statsSegment.match(/([\\d.]+[KMB]?)\\s+shares?/i);\n\n if (likes) engagement.likes = parseCount(likes[1]!);\n if (comments) engagement.comments = parseCount(comments[1]!);\n if (views) engagement.views = parseCount(views[1]!);\n if (shares) engagement.shares = parseCount(shares[1]!);\n\n return engagement;\n}\n\nexport interface ParsedCaptionMeta {\n caption: string;\n username: string;\n engagement: Engagement;\n}\n\n/** Split og:description into engagement stats vs original caption. */\nexport function parseInstagramDescription(raw: string): ParsedCaptionMeta {\n const text = normalizeInstagramQuotes(raw);\n const engagement: Engagement = {};\n let caption = text;\n let username = \"\";\n\n const quoted = text.match(\n /^([\\d\\s,KMB.likescommentsviews]+?)\\s*-\\s*@?([\\w.]+)\\s+on\\s+[\\s\\S]+?:\\s*[\"']([\\s\\S]+)[\"']\\s*\\.?\\s*$/i\n );\n if (quoted) {\n Object.assign(engagement, extractEngagementCounts(quoted[1]!));\n username = quoted[2]!;\n caption = normalizeCaptionText(quoted[3]!.trim());\n return { caption, username, engagement };\n }\n\n const colonBody = text.match(\n /^([\\d\\s,KMB.likescommentsviews]+?)\\s*-\\s*@?([\\w.]+)\\s+on\\s+([^:]+):\\s*([\\s\\S]+)\\s*$/i\n );\n if (colonBody) {\n Object.assign(engagement, extractEngagementCounts(colonBody[1]!));\n username = colonBody[2]!;\n caption = normalizeCaptionText(\n colonBody[4]!\n .replace(/^[\"']|[\"']$/g, \"\")\n .replace(/\\s*\\.\\s*$/, \"\")\n .trim()\n );\n return { caption, username, engagement };\n }\n\n if (\n !/\\s+on\\s+[\\w\\s\\d,]+:\\s*/i.test(text) &&\n /^\\d[\\d.KMB,\\s]*(?:likes?|comments?|views?)/i.test(text)\n ) {\n Object.assign(engagement, extractEngagementCounts(text));\n caption = \"\";\n engagement.raw = text;\n }\n\n return { caption, username, engagement };\n}\n\nexport function parseInstagramTitle(raw: string): { username: string; caption: string } {\n const text = raw.trim();\n let username = \"\";\n let caption = \"\";\n\n const highlight = text.match(/^(.+?)\\s*=\\s*@([\\w.]+)/);\n if (highlight) {\n caption = highlight[1]!.trim();\n username = highlight[2]!;\n return { username, caption };\n }\n\n const paren = text.match(/\\(@([\\w.]+)\\)/);\n if (paren) username = paren[1]!;\n\n const reel = text.match(/^(.+?)\\s*\\(@([\\w.]+)\\)\\s*•/);\n if (reel) {\n caption = \"\";\n username = reel[2]!;\n return { username, caption };\n }\n\n const onIg = text.match(/^(.+?)\\s+on Instagram/i);\n if (onIg && !text.toLowerCase().includes(\"watch this story\")) {\n const part = onIg[1]!.trim();\n const at = part.match(/@([\\w.]+)/);\n if (at) username = at[1]!;\n else caption = part;\n }\n\n const atOnly = text.match(/@([\\w.]+)/);\n if (!username && atOnly) username = atOnly[1]!;\n\n return { username, caption };\n}","import { parseInstagramDescription } from \"./engagement.js\";\nimport { normalizeCaptionText } from \"./caption-normalize.js\";\n\nexport {\n normalizeCaptionText,\n normalizePostCaptionText,\n unescapeCaptionEscapes,\n cleanInstagramCaptionLayout,\n} from \"./caption-normalize.js\";\n\n/** Instagram og:description / JSON-LD text that still includes likes/comments prefix. */\nexport function isEngagementPrefixedCaption(text: string): boolean {\n return (\n /^\\d[\\d.KMB,\\s]*(?:likes?|comments?|views?)/i.test(text) &&\n /\\s+on\\s+[\\w\\s\\d,.]+:\\s*/i.test(text)\n );\n}\n\n/** Strip stats/username prefix when caption is still a full og:description line. */\nexport function captionWithoutEngagementPrefix(raw: string): string {\n const text = normalizeCaptionText(raw);\n if (!text) return \"\";\n if (!isEngagementPrefixedCaption(text)) return text;\n return normalizeCaptionText(parseInstagramDescription(text).caption);\n}\n\n/** Prefer the longer, non-engagement caption when multiple sources exist. */\nexport function pickBestCaption(...candidates: (string | undefined)[]): string {\n let best = \"\";\n for (const raw of candidates) {\n if (!raw) continue;\n const text = captionWithoutEngagementPrefix(raw);\n if (!text) continue;\n if (text.length > best.length) best = text;\n }\n return best;\n}\n\n/** Walk embedded JSON in page HTML for caption.text fields. */\nexport function scrapeCaptionFromHtml(html: string): string {\n if (!html) return \"\";\n const found: string[] = [];\n const patterns = [\n /\"caption\"\\s*:\\s*\\{[^}]*\"text\"\\s*:\\s*\"((?:\\\\.|[^\"\\\\])*)\"/g,\n /\"edge_media_to_caption\"\\s*:\\s*\\{[^}]*\"text\"\\s*:\\s*\"((?:\\\\.|[^\"\\\\])*)\"/g,\n ];\n\n for (const re of patterns) {\n let m: RegExpExecArray | null;\n while ((m = re.exec(html)) !== null) {\n try {\n const text = JSON.parse(`\"${m[1]!}\"`) as string;\n if (text && !isEngagementPrefixedCaption(text)) found.push(text);\n } catch {\n /* ignore malformed escapes */\n }\n }\n }\n\n return pickBestCaption(...found);\n}\n\n/** Reels/posts: prefer embed UI caption (no og newline artifacts). */\nexport function resolveCaptionForContent(\n type: string,\n sources: {\n embed?: string;\n scraped?: string;\n extracted?: string;\n og?: string;\n }\n): string {\n const embed = sources.embed ? normalizeCaptionText(sources.embed) : \"\";\n const scraped = sources.scraped ? captionWithoutEngagementPrefix(sources.scraped) : \"\";\n const extracted = sources.extracted ? captionWithoutEngagementPrefix(sources.extracted) : \"\";\n const og = sources.og ? captionWithoutEngagementPrefix(sources.og) : \"\";\n\n if (type === \"reel\" || type === \"tv\") {\n if (embed) return embed;\n return pickBestCaption(scraped, extracted, og);\n }\n return pickBestCaption(scraped, embed, extracted, og);\n}\n\nexport function extractCaptionFromApiItem(item: Record<string, unknown>): string {\n const cap = item.caption as Record<string, unknown> | undefined;\n if (cap && typeof cap.text === \"string\") return normalizeCaptionText(cap.text);\n if (typeof item.caption_text === \"string\") return normalizeCaptionText(item.caption_text);\n return \"\";\n}","import * as cheerio from \"cheerio\";\nimport type { ResultTag, Media, ExtractedPostData } from \"../types/index.js\";\nimport { pickBestCaption } from \"../utils/caption.js\";\nimport { normalizeCaptionText } from \"../utils/caption-normalize.js\";\nimport { logger } from \"../utils/logger.js\";\n\ntype LayerResult = ExtractedPostData | null;\n\nfunction area(w?: number, h?: number): number {\n return (w ?? 0) * (h ?? 0);\n}\n\nexport function pickBestImage(candidates: Media[]): Media | null {\n if (!candidates.length) return null;\n return candidates.reduce((best, cur) =>\n area(cur.width, cur.height) > area(best.width, best.height) ? cur : best\n );\n}\n\nexport function pickBestVideo(candidates: Media[]): Media | null {\n if (!candidates.length) return null;\n return candidates.reduce((best, cur) => {\n const bestScore = area(best.width, best.height) + (best.duration ?? 0);\n const curScore = area(cur.width, cur.height) + (cur.duration ?? 0);\n return curScore > bestScore ? cur : best;\n });\n}\n\nexport function decodeEscapedUrl(url: string): string {\n let decoded = url\n .replace(/\\\\u0026/g, \"&\")\n .replace(/\\\\u00253D/g, \"=\")\n .replace(/\\\\u003c/g, \"<\")\n .replace(/\\\\u003e/g, \">\")\n .replace(/&amp;/g, \"&\");\n\n while (decoded.includes(\"\\\\/\") || decoded.includes(\"\\\\\\\\\")) {\n decoded = decoded.replace(/\\\\+\\//g, \"/\").replace(/\\\\\\\\/g, \"\\\\\");\n }\n decoded = decoded.replace(/\\\\+$/, \"\").replace(/\\\\/g, \"\");\n\n if (decoded.startsWith(\"https:/\") && !decoded.startsWith(\"https://\")) {\n decoded = decoded.replace(\"https:/\", \"https://\");\n }\n return decoded;\n}\n\nexport function decodeHtmlEntities(text: string): string {\n return text\n .replace(/&amp;/g, \"&\")\n .replace(/&quot;/g, '\"')\n .replace(/&#39;/g, \"'\")\n .replace(/&lt;/g, \"<\")\n .replace(/&gt;/g, \">\")\n .replace(/&#x([0-9a-f]+);/gi, (_, hex) =>\n String.fromCodePoint(parseInt(hex, 16))\n )\n .replace(/&#(\\d+);/g, (_, dec) => String.fromCodePoint(parseInt(dec, 10)));\n}\n\nfunction isProfileOrStaticCdn(url: string): boolean {\n return (\n url.includes(\"static.cdninstagram.com\") ||\n /\\/t51\\.2885-19\\//.test(url) ||\n /stp=dst-jpg_s\\d+x\\d+/.test(url)\n );\n}\n\nfunction extractJsonLd(html: string): LayerResult {\n const $ = cheerio.load(html);\n const scripts = $('script[type=\"application/ld+json\"]');\n\n for (let i = 0; i < scripts.length; i++) {\n try {\n const raw = $(scripts[i]).html();\n if (!raw) continue;\n const data = JSON.parse(raw) as Record<string, unknown>;\n const items = Array.isArray(data) ? data : [data];\n const media: Media[] = [];\n let caption = \"\";\n let username = \"\";\n\n for (const item of items) {\n if (typeof item !== \"object\" || !item) continue;\n const obj = item as Record<string, unknown>;\n\n if (typeof obj.description === \"string\") {\n caption = pickBestCaption(caption, obj.description);\n }\n if (typeof obj.author === \"object\" && obj.author) {\n const author = obj.author as Record<string, unknown>;\n if (typeof author.name === \"string\") username = author.name;\n if (typeof author.identifier === \"string\") {\n username = author.identifier.replace(/^@/, \"\");\n }\n }\n\n const contentUrl = obj.contentUrl ?? obj.embedUrl;\n if (typeof contentUrl === \"string\") {\n const isVideo =\n obj[\"@type\"] === \"VideoObject\" ||\n String(contentUrl).includes(\".mp4\");\n media.push({\n type: isVideo ? \"video\" : \"image\",\n url: decodeEscapedUrl(contentUrl),\n thumbnail:\n typeof obj.thumbnailUrl === \"string\"\n ? decodeEscapedUrl(obj.thumbnailUrl)\n : undefined,\n width: typeof obj.width === \"number\" ? obj.width : undefined,\n height: typeof obj.height === \"number\" ? obj.height : undefined,\n duration:\n typeof obj.duration === \"string\"\n ? parseDuration(obj.duration)\n : undefined,\n });\n }\n\n if (Array.isArray(obj.image)) {\n for (const img of obj.image) {\n if (typeof img === \"string\") {\n media.push({ type: \"image\", url: decodeEscapedUrl(img) });\n } else if (img && typeof img === \"object\") {\n const im = img as Record<string, unknown>;\n if (typeof im.url === \"string\") {\n media.push({\n type: \"image\",\n url: decodeEscapedUrl(im.url),\n width: typeof im.width === \"number\" ? im.width : undefined,\n height: typeof im.height === \"number\" ? im.height : undefined,\n });\n }\n }\n }\n } else if (typeof obj.image === \"string\") {\n media.push({ type: \"image\", url: decodeEscapedUrl(obj.image) });\n }\n }\n\n if (media.length) {\n logger.debug(\"Layer 1 (JSON-LD) succeeded\");\n return { media: dedupeMedia(media), caption, username };\n }\n } catch {\n continue;\n }\n }\n return null;\n}\n\nfunction parseDuration(iso: string): number | undefined {\n const match = iso.match(/PT(?:(\\d+)H)?(?:(\\d+)M)?(?:(\\d+)S)?/);\n if (!match) return undefined;\n const h = parseInt(match[1] ?? \"0\", 10);\n const m = parseInt(match[2] ?? \"0\", 10);\n const s = parseInt(match[3] ?? \"0\", 10);\n return h * 3600 + m * 60 + s;\n}\n\nfunction extractWindowJson(html: string, marker: string): unknown | null {\n const idx = html.indexOf(marker);\n if (idx === -1) return null;\n\n const start = html.indexOf(\"{\", idx + marker.length);\n if (start === -1) return null;\n\n let depth = 0;\n let inString = false;\n let escape = false;\n\n for (let i = start; i < html.length; i++) {\n const ch = html[i];\n if (inString) {\n if (escape) escape = false;\n else if (ch === \"\\\\\") escape = true;\n else if (ch === '\"') inString = false;\n continue;\n }\n if (ch === '\"') {\n inString = true;\n continue;\n }\n if (ch === \"{\") depth++;\n else if (ch === \"}\") {\n depth--;\n if (depth === 0) {\n try {\n return JSON.parse(html.slice(start, i + 1));\n } catch {\n return null;\n }\n }\n }\n }\n return null;\n}\n\nfunction mediaFromNode(node: Record<string, unknown>): Media[] {\n const results: Media[] = [];\n const isVideo = node.is_video === true || node.media_type === 2 || node.__typename === \"GraphVideo\";\n\n if (isVideo && node.video_versions) {\n const versions = node.video_versions as Array<Record<string, unknown>>;\n const best = versions.reduce((a, b) =>\n ((b.width as number) ?? 0) > ((a.width as number) ?? 0) ? b : a\n );\n if (typeof best.url === \"string\") {\n results.push({\n type: \"video\",\n url: decodeEscapedUrl(best.url),\n width: best.width as number | undefined,\n height: best.height as number | undefined,\n duration: (node.video_duration ?? node.duration) as number | undefined,\n thumbnail: extractThumbnail(node),\n });\n }\n } else if (node.image_versions2) {\n const candidates = (node.image_versions2 as Record<string, unknown>).candidates as\n | Array<Record<string, unknown>>\n | undefined;\n if (candidates?.length) {\n const best = candidates.reduce((a, b) =>\n ((b.width as number) ?? 0) > ((a.width as number) ?? 0) ? b : a\n );\n if (typeof best.url === \"string\") {\n results.push({\n type: \"image\",\n url: decodeEscapedUrl(best.url),\n width: best.width as number | undefined,\n height: best.height as number | undefined,\n });\n }\n }\n } else if (node.display_url) {\n results.push({\n type: \"image\",\n url: decodeEscapedUrl(String(node.display_url)),\n width: node.original_width as number | undefined,\n height: node.original_height as number | undefined,\n });\n } else if (node.display_resources) {\n const resources = node.display_resources as Array<Record<string, unknown>>;\n const best = resources.reduce((a, b) =>\n ((b.config_width as number) ?? 0) > ((a.config_width as number) ?? 0) ? b : a\n );\n if (typeof best.src === \"string\") {\n results.push({\n type: \"image\",\n url: decodeEscapedUrl(best.src),\n width: best.config_width as number | undefined,\n height: best.config_height as number | undefined,\n });\n }\n }\n\n return results;\n}\n\nfunction extractThumbnail(node: Record<string, unknown>): string | undefined {\n if (typeof node.thumbnail_src === \"string\") return decodeEscapedUrl(node.thumbnail_src);\n const candidates = (node.image_versions2 as Record<string, unknown> | undefined)\n ?.candidates as Array<Record<string, unknown>> | undefined;\n if (candidates?.[0] && typeof candidates[0].url === \"string\") {\n return decodeEscapedUrl(candidates[0].url);\n }\n return undefined;\n}\n\nfunction walkForMedia(obj: unknown, media: Media[], meta: { caption: string; username: string }): void {\n if (!obj || typeof obj !== \"object\") return;\n\n if (Array.isArray(obj)) {\n for (const item of obj) walkForMedia(item, media, meta);\n return;\n }\n\n const record = obj as Record<string, unknown>;\n\n if (typeof record.caption === \"object\" && record.caption) {\n const cap = record.caption as Record<string, unknown>;\n if (typeof cap.text === \"string\") {\n meta.caption = pickBestCaption(meta.caption, normalizeCaptionText(cap.text));\n }\n } else if (typeof record.edge_media_to_caption === \"object\") {\n const edges = (record.edge_media_to_caption as Record<string, unknown>).edges as\n | Array<Record<string, unknown>>\n | undefined;\n const text = edges?.[0]?.node as Record<string, unknown> | undefined;\n if (typeof text?.text === \"string\") {\n meta.caption = pickBestCaption(meta.caption, normalizeCaptionText(text.text));\n }\n }\n\n if (typeof record.owner === \"object\" && record.owner) {\n const owner = record.owner as Record<string, unknown>;\n if (typeof owner.username === \"string\") meta.username = owner.username;\n }\n\n const carouselSlides: Record<string, unknown>[] = [];\n if (Array.isArray(record.carousel_media)) {\n for (const item of record.carousel_media) {\n if (item && typeof item === \"object\") {\n carouselSlides.push(item as Record<string, unknown>);\n }\n }\n }\n if (record.edge_sidecar_to_children) {\n const edges = (record.edge_sidecar_to_children as Record<string, unknown>).edges as\n | Array<Record<string, unknown>>\n | undefined;\n for (const edge of edges ?? []) {\n const node = edge.node as Record<string, unknown> | undefined;\n if (node) carouselSlides.push(node);\n }\n }\n\n if (carouselSlides.length > 0) {\n for (const slide of carouselSlides) {\n media.push(...mediaFromNode(slide));\n }\n } else if (\n record.shortcode ||\n record.display_url ||\n record.video_versions ||\n record.image_versions2 ||\n record.is_video !== undefined\n ) {\n media.push(...mediaFromNode(record));\n }\n\n for (const [key, value] of Object.entries(record)) {\n if (key === \"carousel_media\" || key === \"edge_sidecar_to_children\") continue;\n if (value && typeof value === \"object\") walkForMedia(value, media, meta);\n }\n}\n\nfunction extractAdditionalData(html: string): LayerResult {\n const data = extractWindowJson(html, \"window.__additionalDataLoaded(\");\n if (!data) return null;\n const media: Media[] = [];\n const meta = { caption: \"\", username: \"\" };\n walkForMedia(data, media, meta);\n if (media.length) {\n logger.debug(\"Layer 2 (__additionalDataLoaded) succeeded\");\n return { media: dedupeMedia(media), caption: meta.caption, username: meta.username };\n }\n return null;\n}\n\nfunction extractSharedData(html: string): LayerResult {\n const data = extractWindowJson(html, \"window._sharedData\");\n if (!data) return null;\n const media: Media[] = [];\n const meta = { caption: \"\", username: \"\" };\n walkForMedia(data, media, meta);\n if (media.length) {\n logger.debug(\"Layer 3 (_sharedData) succeeded\");\n return { media: dedupeMedia(media), caption: meta.caption, username: meta.username };\n }\n return null;\n}\n\nfunction extractNextData(html: string): LayerResult {\n const $ = cheerio.load(html);\n const script = $(\"#__NEXT_DATA__\").html();\n if (!script) return null;\n try {\n const data = JSON.parse(script);\n const media: Media[] = [];\n const meta = { caption: \"\", username: \"\" };\n walkForMedia(data, media, meta);\n if (media.length) {\n logger.debug(\"Layer 4 (Next.js) succeeded\");\n return { media: dedupeMedia(media), caption: meta.caption, username: meta.username };\n }\n } catch {\n return null;\n }\n return null;\n}\n\nfunction extractOpenGraph(html: string): LayerResult {\n const $ = cheerio.load(html);\n const media: Media[] = [];\n let caption = normalizeCaptionText(\n decodeHtmlEntities(\n $('meta[property=\"og:description\"]').attr(\"content\") ??\n $('meta[name=\"description\"]').attr(\"content\") ??\n \"\"\n )\n );\n\n const ogTitle = decodeHtmlEntities($('meta[property=\"og:title\"]').attr(\"content\") ?? \"\");\n let username =\n ogTitle.match(/\\(@([^)]+)\\)/)?.[1] ??\n ogTitle.split(\"(@\")[1]?.replace(\")\", \"\").trim() ??\n \"\";\n if (!username && ogTitle.includes(\" on Instagram\")) {\n username = ogTitle.split(\" on Instagram\")[0]?.replace(/^.*@/, \"\").trim() ?? \"\";\n }\n if (!username && ogTitle.includes(\"@\")) {\n const m = ogTitle.match(/@([\\w.]+)/);\n if (m) username = m[1]!;\n }\n\n const ogVideo = decodeHtmlEntities(\n $('meta[property=\"og:video:secure_url\"], meta[property=\"og:video\"]').attr(\"content\") ?? \"\"\n );\n const ogImage = decodeHtmlEntities(\n $('meta[property=\"og:image\"]').attr(\"content\") ??\n $('meta[property=\"og:image:url\"]').attr(\"content\") ??\n $('meta[name=\"twitter:image\"]').attr(\"content\") ??\n \"\"\n );\n\n if (ogVideo) {\n media.push({\n type: \"video\",\n url: decodeEscapedUrl(ogVideo),\n thumbnail: ogImage ? decodeEscapedUrl(ogImage) : undefined,\n });\n }\n if (ogImage) {\n const imageUrl = decodeEscapedUrl(ogImage);\n const type = imageUrl.includes(\".mp4\") ? \"video\" : \"image\";\n const isThumbForVideo = Boolean(ogVideo) && type === \"image\";\n if (\n !isThumbForVideo &&\n !media.some((m) => m.url === imageUrl) &&\n (!isProfileOrStaticCdn(imageUrl) || !ogVideo)\n ) {\n media.push({ type, url: imageUrl });\n } else if (ogVideo && imageUrl && !media[0]?.thumbnail) {\n media[0]!.thumbnail = imageUrl;\n }\n }\n\n if (media.length) {\n logger.debug(\"Layer 5 (Open Graph) succeeded\");\n return { media: dedupeMedia(media), caption, username };\n }\n return null;\n}\n\nfunction extractScriptJson(html: string): LayerResult {\n const $ = cheerio.load(html);\n const media: Media[] = [];\n const meta = { caption: \"\", username: \"\" };\n\n $('script[type=\"application/json\"]').each((_, el) => {\n const raw = $(el).html();\n if (!raw || raw.length < 500) return;\n try {\n const data = JSON.parse(raw);\n walkForMedia(data, media, meta);\n } catch {\n /* ignore invalid JSON chunks */\n }\n });\n\n if (media.length) {\n logger.debug(\"Layer 5b (application/json scripts) succeeded\");\n return { media: dedupeMedia(media), caption: meta.caption, username: meta.username };\n }\n return null;\n}\n\n/** Parse Instagram /embed/ pages for video_url fields. */\nexport function parseEmbedHtml(html: string): ExtractedPostData | null {\n const scriptResult = extractScriptJson(html);\n if (scriptResult?.media.some((m) => m.type === \"video\")) {\n return scriptResult;\n }\n\n const media: Media[] = [];\n const patterns = [\n /video_url\\\\\":\\\\\"([^\"]+)/g,\n /\"video_url\":\"(https?:[^\"]+)\"/g,\n /playback_url\\\\\":\\\\\"([^\"]+)/g,\n /\"playback_url\":\"(https?:[^\"]+)\"/g,\n ];\n\n for (const pattern of patterns) {\n let match: RegExpExecArray | null;\n while ((match = pattern.exec(html)) !== null) {\n let url = decodeEscapedUrl(match[1]!);\n if (!url.startsWith(\"http\")) url = `https://${url.replace(/^\\/+/, \"\")}`;\n if (url.includes(\".mp4\") || url.includes(\"fbcdn\") || url.includes(\"cdninstagram\")) {\n media.push({ type: \"video\", url });\n }\n }\n }\n\n if (!media.length) return null;\n return { media: dedupeMedia(media), caption: \"\", username: \"\" };\n}\n\nfunction extractDirectCdn(html: string): LayerResult {\n const media: Media[] = [];\n const found = new Set<string>();\n const patterns = [\n /https:\\/\\/scontent\\.cdninstagram\\.com\\/[^\"'\\s<>\\\\&]+/g,\n /https:\\\\\\/\\\\\\/scontent\\.cdninstagram\\.com\\/[^\"\\\\]+/g,\n ];\n\n for (const pattern of patterns) {\n let match: RegExpExecArray | null;\n while ((match = pattern.exec(html)) !== null) {\n const url = decodeEscapedUrl(match[0]!);\n if (isProfileOrStaticCdn(url) || found.has(url)) continue;\n found.add(url);\n const type = url.includes(\".mp4\") ? \"video\" : \"image\";\n media.push({ type, url });\n }\n }\n\n if (media.length) {\n logger.debug(\"Layer 6b (direct CDN) succeeded\");\n return { media: dedupeMedia(media), caption: \"\", username: \"\" };\n }\n return null;\n}\n\nfunction extractGraphQLFromPage(html: string): LayerResult {\n const docIdMatch = html.match(/\"doc_id\":\"(\\d+)\"/);\n const queryIdMatch = html.match(/\"query_id\":\"(\\d+)\"/);\n if (!docIdMatch && !queryIdMatch) return null;\n\n const media: Media[] = [];\n const cdnPatterns = [\n /\"video_url\":\"([^\"]+)\"/g,\n /\"display_url\":\"([^\"]+)\"/g,\n /\"url\":\"(https:\\\\\\/\\\\\\/[^\"]+?cdninstagram[^\"]+)\"/g,\n ];\n\n for (const pattern of cdnPatterns) {\n let match: RegExpExecArray | null;\n while ((match = pattern.exec(html)) !== null) {\n const url = decodeEscapedUrl(match[1]!);\n if (url.includes(\".mp4\") || url.includes(\"video\")) {\n media.push({ type: \"video\", url });\n } else if (url.includes(\"cdninstagram\") || url.includes(\"fbcdn\")) {\n media.push({ type: \"image\", url });\n }\n }\n }\n\n if (media.length) {\n logger.debug(\"Layer 6 (GraphQL discovery) succeeded\");\n return { media: dedupeMedia(media), caption: \"\", username: \"\" };\n }\n return null;\n}\n\nfunction extractFallback(html: string): LayerResult {\n const media: Media[] = [];\n const videoRegex =\n /\"video_versions\":\\s*\\[([^\\]]+)\\]/g;\n const urlRegex = /\"url\":\"(https?:\\\\\\/\\\\\\/[^\"]+)\"/g;\n\n let block: RegExpExecArray | null;\n while ((block = videoRegex.exec(html)) !== null) {\n const segment = block[1]!;\n const urls: Array<{ url: string; width: number }> = [];\n let m: RegExpExecArray | null;\n const inner = /\"url\":\"([^\"]+)\",\"width\":(\\d+)/g;\n while ((m = inner.exec(segment)) !== null) {\n urls.push({ url: decodeEscapedUrl(m[1]!), width: parseInt(m[2]!, 10) });\n }\n if (urls.length) {\n const best = urls.reduce((a, b) => (b.width > a.width ? b : a));\n media.push({ type: \"video\", url: best.url, width: best.width });\n }\n }\n\n const imageCandidates: Array<{ url: string; width: number }> = [];\n const imgRegex = /\"display_url\":\"([^\"]+)\"|\"src\":\"(https?:\\\\\\/\\\\\\/[^\"]+?)\"/g;\n let im: RegExpExecArray | null;\n while ((im = imgRegex.exec(html)) !== null) {\n const url = decodeEscapedUrl(im[1] ?? im[2]!);\n if (url.includes(\"cdninstagram\") || url.includes(\"fbcdn\")) {\n imageCandidates.push({ url, width: 0 });\n }\n }\n\n const configRegex =\n /\"src\":\"(https?:\\\\\\/\\\\\\/[^\"]+)\",\"config_width\":(\\d+)/g;\n while ((im = configRegex.exec(html)) !== null) {\n imageCandidates.push({\n url: decodeEscapedUrl(im[1]!),\n width: parseInt(im[2]!, 10),\n });\n }\n\n if (imageCandidates.length) {\n const best = imageCandidates.reduce((a, b) => (b.width > a.width ? b : a));\n if (!media.some((m) => m.url === best.url)) {\n media.push({ type: \"image\", url: best.url, width: best.width || undefined });\n }\n }\n\n if (!media.length) {\n let m: RegExpExecArray | null;\n while ((m = urlRegex.exec(html)) !== null) {\n const url = decodeEscapedUrl(m[1]!);\n if (url.includes(\".mp4\")) media.push({ type: \"video\", url });\n else if (url.includes(\"cdninstagram\")) media.push({ type: \"image\", url });\n }\n }\n\n if (media.length) {\n logger.debug(\"Layer 7 (fallback) succeeded\");\n return { media: dedupeMedia(media), caption: \"\", username: \"\" };\n }\n return null;\n}\n\nfunction dedupeMedia(media: Media[]): Media[] {\n const seen = new Set<string>();\n const result: Media[] = [];\n for (const item of media) {\n const normalized = item.url.split(\"?\")[0]!;\n if (seen.has(normalized)) continue;\n seen.add(normalized);\n if (!item.url.startsWith(\"http\")) continue;\n if (item.url.includes(\"static.cdninstagram.com\")) continue;\n result.push(item);\n }\n return result.map((m) => ({\n ...m,\n url: decodeEscapedUrl(m.url),\n }));\n}\n\nexport function mergeExtracted(\n primary: ExtractedPostData | null,\n secondary: ExtractedPostData | null\n): ExtractedPostData | null {\n if (!primary && !secondary) return null;\n if (!primary) return secondary;\n if (!secondary) return primary;\n\n const media = dedupeMedia([...primary.media, ...secondary.media]);\n const tags = [...new Set<ResultTag>([...(primary.tags ?? []), ...(secondary.tags ?? [])])];\n return {\n media,\n caption: pickBestCaption(primary.caption, secondary.caption),\n username: primary.username || secondary.username,\n engagement:\n primary.engagement || secondary.engagement\n ? { ...secondary.engagement, ...primary.engagement }\n : undefined,\n tags: tags.length ? tags : undefined,\n isPrivate: primary.isPrivate || secondary.isPrivate,\n };\n}\n\nexport function needsVideoEmbedFallback(\n parsed: { type: string },\n data: ExtractedPostData | null\n): boolean {\n if (!data?.media.length) return parsed.type === \"reel\" || parsed.type === \"tv\";\n if (parsed.type !== \"reel\" && parsed.type !== \"tv\") return false;\n return !data.media.some((m) => m.type === \"video\");\n}\n\nfunction extractionComplete(\n data: ExtractedPostData,\n contentType?: string\n): boolean {\n if (data.media.some((m) => m.type === \"video\")) return true;\n if (contentType === \"post\") {\n const img = data.media.find((m) => m.type === \"image\");\n if (!img) return false;\n if (img.width && img.height && img.width > 640) return true;\n const fromUrl = img.url.match(/stp=c[\\d.]+?\\.(\\d+)\\.(\\d+)a/i);\n if (fromUrl) {\n const w = parseInt(fromUrl[1]!, 10);\n return w > 640;\n }\n return false;\n }\n if (contentType === \"reel\" || contentType === \"tv\") {\n return data.media.some((m) => m.type === \"video\");\n }\n return data.media.length > 0;\n}\n\nexport function parseHtml(\n html: string,\n contentType?: string\n): ExtractedPostData | null {\n const fast =\n contentType === \"post\" ||\n contentType === \"reel\" ||\n contentType === \"tv\" ||\n contentType === \"highlight\" ||\n contentType === \"story\";\n\n const layers = fast\n ? [\n extractOpenGraph,\n extractScriptJson,\n extractAdditionalData,\n extractSharedData,\n extractFallback,\n ]\n : [\n extractScriptJson,\n extractJsonLd,\n extractAdditionalData,\n extractSharedData,\n extractNextData,\n extractOpenGraph,\n extractGraphQLFromPage,\n extractDirectCdn,\n extractFallback,\n ];\n\n let merged: ExtractedPostData | null = null;\n for (const layer of layers) {\n const result = layer(html);\n if (result?.media.length) {\n merged = mergeExtracted(merged, result);\n // Posts may be carousels — keep scanning after OG returns a single image.\n if (\n fast &&\n contentType !== \"post\" &&\n merged &&\n extractionComplete(merged, contentType)\n ) {\n break;\n }\n }\n }\n\n if (merged?.media.length) {\n return upgradeMediaQuality(merged);\n }\n\n if (html.includes(\"login\") && html.includes(\"Log in to Instagram\")) {\n return { media: [], caption: \"\", username: \"\", isPrivate: true };\n }\n\n return null;\n}\n\nfunction upgradeMediaQuality(data: ExtractedPostData): ExtractedPostData {\n const videos = data.media.filter((m) => m.type === \"video\");\n const images = data.media.filter((m) => m.type === \"image\");\n\n const upgraded: Media[] = [];\n const bestVideo = pickBestVideo(videos);\n if (bestVideo) upgraded.push(bestVideo);\n else if (videos[0]) upgraded.push(videos[0]);\n\n for (const img of images) {\n if (!upgraded.some((u) => u.url.split(\"?\")[0] === img.url.split(\"?\")[0])) {\n upgraded.push(img);\n }\n }\n\n if (!bestVideo && images.length > 1) {\n const sorted = [...images].sort(\n (a, b) => area(b.width, b.height) - area(a.width, a.height)\n );\n return { ...data, media: sorted };\n }\n\n return { ...data, media: upgraded.length ? upgraded : data.media };\n}\n\nexport function detectRateLimit(html: string): boolean {\n return (\n html.includes(\"Please wait a few minutes\") ||\n html.includes(\"429 Too Many Requests\") ||\n html.includes(\"rate limit\")\n );\n}\n\nexport function detectNotFound(html: string, statusCode: number): boolean {\n return (\n statusCode === 404 ||\n html.includes(\"Sorry, this page isn't available\") ||\n html.includes(\"Page Not Found\")\n );\n}","import { readFile } from \"node:fs/promises\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { resolve, join } from \"node:path\";\nimport { ultraigdl } from \"../index.js\";\nimport type { DownloadResponse } from \"../types/index.js\";\nimport { downloadAllMedia } from \"../utils/downloader.js\";\nimport { setVerbose, setLogLevel } from \"../utils/logger.js\";\nimport { isInstagramUrl } from \"../utils/urls.js\";\n\nconst c = {\n reset: \"\\x1b[0m\",\n bold: \"\\x1b[1m\",\n green: \"\\x1b[32m\",\n yellow: \"\\x1b[33m\",\n red: \"\\x1b[31m\",\n cyan: \"\\x1b[36m\",\n dim: \"\\x1b[2m\",\n};\n\nfunction formatBytes(n: number): string {\n if (n < 1024) return `${n} B`;\n if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;\n return `${(n / (1024 * 1024)).toFixed(2)} MB`;\n}\n\nfunction progressBar(pct: number, width = 24): string {\n const filled = Math.round((pct / 100) * width);\n return `[${\"█\".repeat(filled)}${\"░\".repeat(width - filled)}] ${pct.toFixed(0)}%`;\n}\n\ninterface CliArgs {\n urls: string[];\n json: boolean;\n download: boolean;\n output: string;\n verbose: boolean;\n batch: boolean;\n}\n\nfunction parseArgs(argv: string[]): CliArgs {\n const urls: string[] = [];\n let json = false;\n let download = false;\n let output = \"./downloads\";\n let verbose = false;\n\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i]!;\n if (arg === \"--json\" || arg === \"-j\") json = true;\n else if (arg === \"--download\" || arg === \"-d\") download = true;\n else if (arg === \"--verbose\" || arg === \"-v\") verbose = true;\n else if (arg === \"--output\" || arg === \"-o\") {\n output = argv[++i] ?? \"./downloads\";\n } else if (arg === \"--help\" || arg === \"-h\") {\n printHelp();\n process.exit(0);\n } else if (!arg.startsWith(\"-\")) {\n urls.push(arg);\n }\n }\n\n return { urls, json, download, output, verbose, batch: false };\n}\n\nfunction loadDotEnv(): void {\n const candidates = [\n resolve(process.cwd(), \".env\"),\n resolve(process.cwd(), \"..\", \"ultra-igdl-live-test\", \".env\"),\n ];\n for (const envPath of candidates) {\n if (!existsSync(envPath)) continue;\n for (const line of readFileSync(envPath, \"utf8\").split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n const eq = trimmed.indexOf(\"=\");\n if (eq <= 0) continue;\n const key = trimmed.slice(0, eq).trim();\n let value = trimmed.slice(eq + 1).trim();\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1);\n }\n if (process.env[key] === undefined) process.env[key] = value;\n }\n break;\n }\n}\n\nfunction sessionFromEnv(): { sessionId?: string; cookies?: string } {\n const cookies = process.env.INSTAGRAM_COOKIES?.trim();\n if (cookies) return { cookies };\n const raw = process.env.INSTAGRAM_SESSION_ID?.trim();\n if (!raw) return {};\n try {\n return { sessionId: decodeURIComponent(raw) };\n } catch {\n return { sessionId: raw };\n }\n}\n\nfunction printHelp(): void {\n console.log(`\n${c.bold}ultra-igdl${c.reset} — Advanced Instagram Downloader CLI\n\n${c.cyan}Usage:${c.reset}\n npx ultra-igdl \"<url>\"\n npx ultra-igdl \"<url>\" --json\n npx ultra-igdl \"<url>\" --download\n npx ultra-igdl \"<url>\" --output ./downloads\n npx ultra-igdl \"<url>\" --verbose\n npx ultra-igdl urls.txt\n\n${c.cyan}Environment (optional):${c.reset}\n INSTAGRAM_SESSION_ID sessionid cookie value (carousel, reel MP4, stories)\n INSTAGRAM_COOKIES full Cookie header\n\n${c.cyan}Options:${c.reset}\n --json, -j Output JSON response\n --download, -d Download media files to disk\n --output, -o Output directory (default: ./downloads)\n --verbose, -v Verbose logging\n --help, -h Show this help\n\n${c.dim}PowerShell: wrap URLs in double quotes when they contain & (query params).${c.reset}\n`);\n}\n\nasync function loadUrlsFromFile(path: string): Promise<string[]> {\n const content = await readFile(path, \"utf-8\");\n return content\n .split(/\\r?\\n/)\n .map((l) => l.trim())\n .filter((l) => l && !l.startsWith(\"#\"));\n}\n\nfunction printResult(result: DownloadResponse, json: boolean): void {\n if (json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n console.log(`${c.green}✓${c.reset} ${c.bold}@${result.username || \"unknown\"}${c.reset}`);\n if (result.caption) {\n console.log(`${c.dim}${result.caption.slice(0, 120)}${result.caption.length > 120 ? \"…\" : \"\"}${c.reset}`);\n }\n if (result.tags?.length) {\n console.log(`${c.dim}Tags: ${result.tags.join(\", \")}${c.reset}`);\n }\n console.log(`${c.cyan}Media (${result.media.length}):${c.reset}`);\n result.media.forEach((m, i) => {\n const dims = m.width && m.height ? ` ${m.width}x${m.height}` : \"\";\n const dur = m.duration ? ` ${m.duration}s` : \"\";\n console.log(` ${i + 1}. [${m.type}]${dims}${dur}`);\n console.log(` ${m.url.slice(0, 80)}…`);\n });\n}\n\nasync function run(): Promise<void> {\n loadDotEnv();\n const args = parseArgs(process.argv.slice(2));\n\n if (args.verbose) {\n setVerbose(true);\n setLogLevel(\"debug\");\n }\n\n if (!args.urls.length) {\n printHelp();\n process.exit(1);\n }\n\n let urlList = [...args.urls];\n const first = urlList[0]!;\n\n if (urlList.length === 1 && (first.endsWith(\".txt\") || existsSync(first))) {\n if (existsSync(first)) {\n urlList = await loadUrlsFromFile(first);\n console.log(`${c.cyan}Batch mode:${c.reset} ${urlList.length} URLs loaded`);\n }\n }\n\n const ig = new ultraigdl({ verbose: args.verbose, ...sessionFromEnv() });\n const outputDir = resolve(args.output);\n\n for (let i = 0; i < urlList.length; i++) {\n const url = urlList[i]!;\n if (!isInstagramUrl(url)) {\n console.error(`${c.red}✗${c.reset} Invalid URL: ${url}`);\n continue;\n }\n\n console.log(`${c.dim}[${i + 1}/${urlList.length}]${c.reset} ${url}`);\n const start = Date.now();\n const result = await ig.download(url);\n const elapsed = Date.now() - start;\n\n if (result.code !== 200) {\n console.error(\n `${c.red}✗${c.reset} Error ${result.code}: ${\"message\" in result ? result.message : \"Unknown\"}`\n );\n if (args.json) console.log(JSON.stringify(result, null, 2));\n continue;\n }\n\n printResult(result as DownloadResponse, args.json);\n console.log(`${c.dim}Fetched in ${elapsed}ms${c.reset}`);\n\n if (args.download && result.code === 200) {\n const media = (result as DownloadResponse).media;\n console.log(`${c.yellow}Downloading ${media.length} file(s)...${c.reset}`);\n const files = await downloadAllMedia(media, {\n outputDir: join(outputDir, (result as DownloadResponse).username || \"media\"),\n onProgress: (info) => {\n if (!args.verbose) return;\n console.log(\n ` ${progressBar(100)} ${info.filename} ${formatBytes(info.downloaded)} @ ${formatBytes(info.speed)}/s`\n );\n },\n });\n files.forEach((f) => {\n console.log(`${c.green}✓${c.reset} Saved ${f.path} (${formatBytes(f.size)})`);\n });\n }\n }\n}\n\nrun().catch((err) => {\n console.error(`${c.red}Fatal:${c.reset}`, err);\n process.exit(1);\n});","import { DownloaderCore } from \"./core/downloader.js\";\nimport type {\n UltraIgdlOptions,\n ApiResponse,\n Media,\n HealthStatus,\n BatchResult,\n} from \"./types/index.js\";\n\nexport { DownloaderCore };\nexport type {\n UltraIgdlOptions,\n ApiResponse,\n DownloadResponse,\n Media,\n Engagement,\n EngagementTag,\n PostContentTag,\n ResultTag,\n HealthStatus,\n BatchResult,\n RedisAdapter,\n ErrorResponse,\n} from \"./types/index.js\";\nexport type { ValidationResult } from \"./utils/validators.js\";\nexport { validateUrl } from \"./utils/validators.js\";\nexport { parseInstagramUrl, isInstagramUrl } from \"./utils/urls.js\";\nexport { PACKAGE_VERSION, EXTRACTOR_NAME } from \"./types/index.js\";\n\nexport class ultraigdl {\n private core: DownloaderCore;\n\n constructor(options?: UltraIgdlOptions) {\n this.core = new DownloaderCore(options);\n }\n\n download(url: string): Promise<ApiResponse> {\n return this.core.download(url);\n }\n\n info(url: string): Promise<ApiResponse> {\n return this.core.info(url);\n }\n\n validate(url: string): Promise<{ valid: boolean; type?: string; normalized?: string }> {\n return this.core.validate(url);\n }\n\n media(url: string): Promise<Media[] | import(\"./types/index.js\").ErrorResponse> {\n return this.core.media(url);\n }\n\n batch(urls: string[]): Promise<BatchResult[]> {\n return this.core.batch(urls);\n }\n\n health(): Promise<HealthStatus> {\n return this.core.health();\n }\n\n clearCache(): void {\n this.core.clearCache();\n }\n\n /** Start extraction now so the next `download()` can return within `responseBudgetMs`. */\n prefetch(url: string): Promise<ApiResponse> {\n return this.core.prefetch(url);\n }\n}\n\nexport default ultraigdl;","import type {\n ApiResponse,\n DownloadResponse,\n ErrorResponse,\n UltraIgdlOptions,\n BatchResult,\n HealthStatus,\n ExtractedPostData,\n Media,\n} from \"../types/index.js\";\nimport { PACKAGE_VERSION, EXTRACTOR_NAME } from \"../types/index.js\";\nimport { HttpClient } from \"../network/client.js\";\nimport { ResponseCache } from \"./cache.js\";\nimport {\n runExtractor,\n resolveFetchUrl,\n resolveEmbedUrl,\n resolveStoryEmbedUrl,\n} from \"./extractor.js\";\nimport {\n mergeExtracted,\n needsVideoEmbedFallback,\n parseEmbedHtml,\n} from \"./parser.js\";\nimport { normalizeExtraction, extractPageMeta } from \"./normalize.js\";\nimport {\n filterValidMedia,\n isCdnMediaUrl,\n isValidThumbnailUrl,\n} from \"../utils/media-quality.js\";\nimport { imageNeedsHigherResolution, postNeedsEmbedFetch } from \"../utils/media-dimensions.js\";\nimport {\n applyLargePostImage,\n fetchPostLargeImageUrl,\n} from \"../network/post-media.js\";\nimport {\n captionedEmbedUrl,\n contentTypesWithEmbedCaption,\n parseCaptionFromCaptionedEmbed,\n} from \"../network/embed-caption.js\";\nimport {\n buildSessionCookie,\n enrichSessionCookie,\n fetchStoryViaSession,\n fetchMediaInfoByPk,\n userIdFromCookie,\n sessionCookieReady,\n} from \"../network/instagram-api.js\";\nimport { extractMediaPkFromHtml } from \"../utils/media-id.js\";\nimport { postMediaPkCandidates } from \"../utils/post-media-pk.js\";\nimport { shortcodeToMediaPk } from \"../utils/shortcode.js\";\nimport {\n buildPostContentTags,\n htmlIndicatesCarouselPost,\n mergeResultTags,\n} from \"../utils/post-carousel-detect.js\";\nimport { parseInstagramUrl } from \"../utils/urls.js\";\nimport { validateUrl } from \"../utils/validators.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { getPoolStats } from \"../network/pool.js\";\nimport { sleep } from \"../network/retry.js\";\n\nconst pendingDownloads = new Map<string, Promise<ApiResponse>>();\n\nfunction hasStoryVideo(media: Media[]): boolean {\n return media.some((m) => m.type === \"video\" && isCdnMediaUrl(m.url));\n}\n\nfunction hasReelVideo(media: Media[]): boolean {\n return media.some((m) => m.type === \"video\" && isCdnMediaUrl(m.url));\n}\n\nexport class DownloaderCore {\n private client: HttpClient;\n private cache: ResponseCache;\n private options: UltraIgdlOptions;\n private startTime = Date.now();\n private semaphore: { max: number; current: number; queue: Array<() => void> };\n\n constructor(options: UltraIgdlOptions = {}) {\n const fastMode = options.fastMode === true;\n const responseBudgetMs = fastMode ? 500 : options.responseBudgetMs;\n\n this.options = {\n cache: true,\n cacheTtlMs: 300_000,\n staleCacheTtlMs: 86_400_000,\n cacheMaxSize: 500,\n maxConcurrency: 100,\n timeoutMs: 8_000,\n retries: 2,\n userAgentRotation: true,\n ...options,\n responseBudgetMs,\n fastMode,\n };\n\n if (responseBudgetMs) {\n this.options.retries = 0;\n this.options.cache = this.options.cache !== false;\n }\n\n this.client = new HttpClient({\n timeoutMs: this.options.timeoutMs,\n retries: this.options.retries,\n userAgentRotation: this.options.userAgentRotation,\n });\n\n this.cache = new ResponseCache({\n maxSize: this.options.cacheMaxSize,\n ttlMs: this.options.cacheTtlMs,\n staleTtlMs: this.options.staleCacheTtlMs,\n redis: this.options.redis,\n });\n\n this.semaphore = {\n max: this.options.maxConcurrency ?? 100,\n current: 0,\n queue: [],\n };\n }\n\n private async acquire(): Promise<void> {\n if (this.semaphore.current < this.semaphore.max) {\n this.semaphore.current++;\n return;\n }\n await new Promise<void>((resolve) => {\n this.semaphore.queue.push(() => {\n this.semaphore.current++;\n resolve();\n });\n });\n }\n\n private release(): void {\n this.semaphore.current--;\n const next = this.semaphore.queue.shift();\n if (next) next();\n }\n\n private meta() {\n return { extractor: EXTRACTOR_NAME, version: PACKAGE_VERSION };\n }\n\n private success(data: ExtractedPostData): DownloadResponse {\n return {\n code: 200,\n meta: this.meta(),\n media: data.media,\n caption: data.caption,\n username: data.username,\n engagement: data.engagement,\n tags: data.tags,\n };\n }\n\n private error(code: number, message: string, retryAfterMs?: number): ErrorResponse {\n return { code, message, meta: this.meta(), retryAfterMs };\n }\n\n private startDownloadTask(\n cacheKey: string,\n parsed: ReturnType<typeof parseInstagramUrl>\n ): Promise<ApiResponse> {\n return (async () => {\n await this.acquire();\n try {\n const result = await this.fetchAndExtract(parsed);\n if (this.options.cache !== false && result.code === 200) {\n this.cache.set(cacheKey, result);\n }\n return result;\n } catch (err: unknown) {\n logger.error(\"Background extraction failed\", err);\n return this.error(500, err instanceof Error ? err.message : \"Extraction failed\");\n } finally {\n this.release();\n }\n })();\n }\n\n /** API-only attempt for story/highlight (fits ~500ms budget). */\n private async fetchFastExtract(\n parsed: ReturnType<typeof parseInstagramUrl>\n ): Promise<ApiResponse | null> {\n const budget = this.options.responseBudgetMs;\n if (!budget) return null;\n\n const sessionCookie = buildSessionCookie(\n this.options.sessionId,\n this.options.cookies\n );\n if (!sessionCookie || !sessionCookieReady(sessionCookie)) return null;\n\n const apiMs = Math.max(250, budget - 80);\n try {\n if (parsed.type === \"story\" && parsed.storyId) {\n const fromApi = await fetchMediaInfoByPk(\n parsed.storyId,\n sessionCookie,\n parsed.normalized,\n userIdFromCookie(sessionCookie) ?? undefined,\n apiMs\n );\n const media = filterValidMedia(fromApi?.media ?? []);\n if (!hasStoryVideo(media)) return null;\n const extracted = normalizeExtraction(\n {\n ...fromApi!,\n media,\n caption: \"\",\n username: parsed.username ?? fromApi!.username,\n },\n parsed,\n {},\n \"\"\n );\n return extracted?.media.length ? this.success(extracted) : null;\n }\n\n if (parsed.type === \"highlight\" && parsed.storyMediaId) {\n const pk = parsed.storyMediaId.split(\"_\")[0]!;\n const ownerId = parsed.storyMediaId.split(\"_\")[1];\n const fromApi = await fetchMediaInfoByPk(\n pk,\n sessionCookie,\n parsed.normalized,\n ownerId,\n apiMs\n );\n const media = filterValidMedia(fromApi?.media ?? []);\n if (!media.some((m) => m.type === \"video\" && isCdnMediaUrl(m.url))) return null;\n const extracted = normalizeExtraction(\n {\n ...fromApi!,\n media,\n caption: fromApi!.caption ?? \"\",\n username: parsed.username ?? fromApi!.username,\n },\n parsed,\n {},\n \"\"\n );\n return extracted?.media.length ? this.success(extracted) : null;\n }\n } catch {\n return null;\n }\n return null;\n }\n\n /** Warm cache in background (full extraction, no response budget). */\n prefetch(url: string): Promise<ApiResponse> {\n const validation = validateUrl(url);\n if (!validation.valid) {\n return Promise.resolve(this.error(400, validation.error ?? \"Invalid URL\"));\n }\n const parsed = parseInstagramUrl(url);\n const cacheKey = parsed.normalized;\n let task = pendingDownloads.get(cacheKey);\n if (!task) {\n task = this.startDownloadTask(cacheKey, parsed);\n pendingDownloads.set(cacheKey, task);\n void task.finally(() => pendingDownloads.delete(cacheKey));\n }\n return task;\n }\n\n async download(url: string): Promise<ApiResponse> {\n const validation = validateUrl(url);\n if (!validation.valid) {\n return this.error(400, validation.error ?? \"Invalid URL\");\n }\n\n const parsed = parseInstagramUrl(url);\n const cacheKey = parsed.normalized;\n const budget = this.options.responseBudgetMs;\n\n if (this.options.cache !== false) {\n const fresh = this.cache.getFreshSync<ApiResponse>(cacheKey);\n if (fresh) {\n logger.debug(`Cache hit (sync) for ${cacheKey}`);\n return fresh;\n }\n\n const stale = this.cache.getStaleSync<ApiResponse>(cacheKey);\n if (stale) {\n logger.debug(`Stale cache hit for ${cacheKey}`);\n this.ensureBackgroundFetch(cacheKey, parsed);\n return stale;\n }\n\n if (!budget) {\n const cached = await this.cache.get<ApiResponse>(cacheKey);\n if (cached) {\n logger.debug(`Cache hit for ${cacheKey}`);\n return cached;\n }\n }\n }\n\n const inFlight = pendingDownloads.get(cacheKey);\n if (inFlight) {\n return inFlight;\n }\n\n const task = this.startDownloadTask(cacheKey, parsed);\n pendingDownloads.set(cacheKey, task);\n void task.finally(() => pendingDownloads.delete(cacheKey));\n\n if (!budget) {\n return task;\n }\n\n const fastAttempt = this.fetchFastExtract(parsed);\n const raced = await Promise.race([\n fastAttempt,\n task,\n sleep(budget).then(() => null),\n ]);\n if (raced) {\n if (raced.code === 200 && this.options.cache !== false) {\n this.cache.set(cacheKey, raced);\n }\n return raced;\n }\n\n const retryAfterMs = Math.max(200, Math.min(500, budget));\n return this.error(\n 503,\n \"Response budget exceeded — fetch still running; retry the same URL immediately\",\n retryAfterMs\n );\n }\n\n private ensureBackgroundFetch(\n cacheKey: string,\n parsed: ReturnType<typeof parseInstagramUrl>\n ): void {\n if (pendingDownloads.has(cacheKey)) return;\n const task = this.startDownloadTask(cacheKey, parsed);\n pendingDownloads.set(cacheKey, task);\n void task.finally(() => pendingDownloads.delete(cacheKey));\n }\n\n private async fetchAndExtract(\n parsed: ReturnType<typeof parseInstagramUrl>\n ): Promise<ApiResponse> {\n const resolvedUrl = resolveFetchUrl(parsed);\n\n try {\n let sessionCookie = buildSessionCookie(\n this.options.sessionId,\n this.options.cookies\n );\n const sessionTypes = parsed.type === \"story\" || parsed.type === \"highlight\";\n const embedUrl = resolveEmbedUrl(parsed);\n let prefetchApiData: ExtractedPostData | null = null;\n\n let body = \"\";\n let statusCode = 200;\n let embedBody = \"\";\n\n const ensureSession = async (cookie: string): Promise<string> => {\n if (sessionCookieReady(cookie)) return cookie;\n return enrichSessionCookie(cookie);\n };\n\n // API-first: one round-trip when media/info succeeds (skips heavy page HTML).\n if (sessionCookie && parsed.type === \"story\" && parsed.storyId) {\n sessionCookie = await ensureSession(sessionCookie);\n const fromApi = await fetchMediaInfoByPk(\n parsed.storyId,\n sessionCookie,\n parsed.normalized,\n userIdFromCookie(sessionCookie) ?? undefined\n );\n const apiMedia = filterValidMedia(fromApi?.media ?? []);\n if (hasStoryVideo(apiMedia)) {\n const extracted = normalizeExtraction(\n {\n ...fromApi!,\n media: apiMedia,\n caption: fromApi!.caption ?? \"\",\n username: parsed.username ?? fromApi!.username,\n },\n parsed,\n {},\n \"\"\n );\n if (extracted?.media.length) {\n return this.success(extracted);\n }\n }\n prefetchApiData = fromApi;\n } else if (sessionCookie && parsed.type === \"highlight\" && parsed.storyMediaId) {\n sessionCookie = await ensureSession(sessionCookie);\n const pk = parsed.storyMediaId.split(\"_\")[0]!;\n const ownerId = parsed.storyMediaId.split(\"_\")[1];\n const [fromApi, pageRes] = await Promise.all([\n fetchMediaInfoByPk(pk, sessionCookie, parsed.normalized, ownerId),\n this.client.fetchWithCookie(resolvedUrl, sessionCookie),\n ]);\n body = pageRes.body;\n statusCode = pageRes.statusCode;\n const apiMedia = filterValidMedia(fromApi?.media ?? []);\n if (apiMedia.some((m) => m.type === \"video\" && isCdnMediaUrl(m.url))) {\n const pageMeta = extractPageMeta(body);\n const extracted = normalizeExtraction(\n {\n ...fromApi!,\n media: apiMedia,\n caption: fromApi!.caption ?? \"\",\n username: parsed.username ?? fromApi!.username,\n },\n parsed,\n { ...pageMeta, html: body },\n body\n );\n if (extracted?.media.length) {\n return this.success(extracted);\n }\n }\n prefetchApiData = fromApi;\n } else if (sessionCookie && parsed.type === \"post\" && parsed.shortcode) {\n sessionCookie = await ensureSession(sessionCookie);\n const mediaPk = shortcodeToMediaPk(parsed.shortcode);\n const ownerId = userIdFromCookie(sessionCookie) ?? undefined;\n const pagePromise = this.client.fetchWithCookie(resolvedUrl, sessionCookie);\n if (mediaPk) {\n const [fromApi, pageRes] = await Promise.all([\n fetchMediaInfoByPk(mediaPk, sessionCookie, parsed.normalized, ownerId),\n pagePromise,\n ]);\n prefetchApiData = fromApi;\n body = pageRes.body;\n statusCode = pageRes.statusCode;\n } else {\n const pageRes = await pagePromise;\n body = pageRes.body;\n statusCode = pageRes.statusCode;\n }\n }\n\n if (!body) {\n if (sessionCookie && sessionTypes) {\n sessionCookie = await ensureSession(sessionCookie);\n const res = await this.client.fetchWithCookie(resolvedUrl, sessionCookie);\n body = res.body;\n statusCode = res.statusCode;\n } else {\n const res = await this.client.fetch(resolvedUrl);\n body = res.body;\n statusCode = res.statusCode;\n }\n }\n\n if (statusCode === 404) {\n return this.error(404, \"Media not found\");\n }\n\n if (statusCode === 429) {\n return this.error(429, \"Rate limited\");\n }\n\n const pageMeta = extractPageMeta(body);\n const ctx = { html: body, url: resolvedUrl, parsed, sessionCookie };\n\n const prefetchedMedia = prefetchApiData\n ? filterValidMedia(prefetchApiData.media)\n : [];\n\n let extracted: ExtractedPostData | null;\n if (\n parsed.type === \"story\" &&\n prefetchedMedia.length &&\n hasStoryVideo(prefetchedMedia)\n ) {\n extracted = {\n ...prefetchApiData!,\n media: prefetchedMedia,\n username: parsed.username ?? prefetchApiData!.username,\n };\n } else {\n extracted = await runExtractor(ctx);\n if (prefetchApiData) {\n extracted = mergeExtracted(extracted, prefetchApiData);\n }\n }\n\n if (parsed.type === \"post\" && prefetchApiData) {\n const apiMedia = filterValidMedia(prefetchApiData.media);\n const htmlCount = filterValidMedia(extracted?.media ?? []).length;\n if (apiMedia.length >= 2 || apiMedia.length > htmlCount) {\n extracted = {\n ...(extracted ?? { media: [], caption: \"\", username: \"\" }),\n ...prefetchApiData,\n media: apiMedia,\n caption: prefetchApiData.caption || extracted?.caption || \"\",\n username: prefetchApiData.username || extracted?.username || \"\",\n engagement: prefetchApiData.engagement ?? extracted?.engagement,\n };\n }\n }\n\n const validExtracted = filterValidMedia(extracted?.media ?? []);\n if (parsed.type === \"story\" && sessionCookie && !hasStoryVideo(validExtracted)) {\n logger.debug(\"Trying story API with session cookie\");\n const fromApi = await fetchStoryViaSession(parsed, sessionCookie, body);\n extracted = mergeExtracted(extracted, fromApi);\n }\n\n let embedCaption = \"\";\n let captionEmbedHtml = \"\";\n const captionEmbedUrl = contentTypesWithEmbedCaption(parsed.type)\n ? captionedEmbedUrl(parsed)\n : null;\n\n const enrichmentTasks: Array<Promise<void>> = [];\n\n if (captionEmbedUrl) {\n enrichmentTasks.push(\n (async () => {\n try {\n const capRes = await this.client.fetch(captionEmbedUrl, false);\n captionEmbedHtml = capRes.body;\n embedCaption = parseCaptionFromCaptionedEmbed(capRes.body, parsed.type);\n } catch {\n /* optional caption source */\n }\n })()\n );\n }\n\n if (\n parsed.type === \"post\" &&\n parsed.shortcode &&\n imageNeedsHigherResolution(extracted?.media ?? [])\n ) {\n enrichmentTasks.push(\n (async () => {\n const large = await fetchPostLargeImageUrl(parsed.shortcode!);\n if (large && extracted?.media.length) {\n extracted = {\n ...extracted,\n media: applyLargePostImage(extracted.media, large),\n };\n }\n })()\n );\n }\n\n if (enrichmentTasks.length) {\n await Promise.all(enrichmentTasks);\n }\n\n if (\n (parsed.type === \"reel\" || parsed.type === \"tv\") &&\n !hasReelVideo(extracted?.media ?? []) &&\n captionEmbedHtml\n ) {\n extracted = mergeExtracted(extracted, parseEmbedHtml(captionEmbedHtml));\n }\n\n const postHtml = body;\n const carouselHintEarly =\n parsed.type === \"post\" && htmlIndicatesCarouselPost(postHtml);\n const needPostEmbed =\n parsed.type === \"post\" &&\n embedUrl &&\n (postNeedsEmbedFetch(extracted?.media ?? []) || carouselHintEarly);\n const needReelEmbed =\n (parsed.type === \"reel\" || parsed.type === \"tv\") &&\n embedUrl &&\n needsVideoEmbedFallback(parsed, extracted);\n\n if (needPostEmbed || needReelEmbed) {\n logger.debug(`Fetching embed: ${embedUrl}`);\n const embedRes = await this.client.fetch(embedUrl!, false);\n embedBody = embedRes.body;\n if (needReelEmbed) {\n const embedData = parseEmbedHtml(embedBody);\n extracted = mergeExtracted(extracted, embedData);\n } else {\n const { parseHtml: parseHtmlLayers } = await import(\"./parser.js\");\n const embedParsed =\n parseEmbedHtml(embedBody) ?? parseHtmlLayers(embedBody, \"post\");\n extracted = mergeExtracted(extracted, embedParsed);\n }\n }\n\n const dimensionHtmlPre =\n embedBody || captionEmbedHtml ? `${body}\\n${embedBody}\\n${captionEmbedHtml}` : body;\n\n if (\n (parsed.type === \"reel\" || parsed.type === \"tv\") &&\n sessionCookie &&\n !hasReelVideo(extracted?.media ?? [])\n ) {\n const mediaPk = extractMediaPkFromHtml(dimensionHtmlPre);\n if (mediaPk) {\n logger.debug(`Reel API fallback for media pk=${mediaPk}`);\n const fromApi = await fetchMediaInfoByPk(\n mediaPk,\n sessionCookie,\n parsed.normalized\n );\n extracted = mergeExtracted(extracted, fromApi);\n }\n }\n\n if (parsed.type === \"post\" && sessionCookie && parsed.shortcode) {\n sessionCookie = await ensureSession(sessionCookie);\n const htmlSlideCount = extracted?.media.length ?? 0;\n const carouselHint = htmlIndicatesCarouselPost(dimensionHtmlPre);\n const pkCandidates = postMediaPkCandidates(\n parsed.shortcode,\n dimensionHtmlPre,\n extracted?.media ?? []\n );\n let bestApi: ExtractedPostData | null = null;\n for (const mediaPk of pkCandidates) {\n logger.debug(`Post API carousel pk=${mediaPk}`);\n const fromApi = await fetchMediaInfoByPk(\n mediaPk,\n sessionCookie,\n parsed.normalized,\n userIdFromCookie(sessionCookie) ?? undefined\n );\n const apiMedia = filterValidMedia(fromApi?.media ?? []);\n if (\n fromApi &&\n apiMedia.length > (bestApi?.media.length ?? 0)\n ) {\n bestApi = { ...fromApi, media: apiMedia };\n }\n }\n const apiMedia = filterValidMedia(bestApi?.media ?? []);\n const apiImprovesCarousel =\n apiMedia.length >= 2 ||\n apiMedia.length > htmlSlideCount ||\n (carouselHint && apiMedia.length > htmlSlideCount);\n if (bestApi && apiImprovesCarousel) {\n extracted = {\n ...extracted,\n ...bestApi,\n media: apiMedia,\n caption: bestApi.caption || extracted?.caption || \"\",\n username: bestApi.username || extracted?.username || \"\",\n engagement: bestApi.engagement ?? extracted?.engagement,\n };\n }\n }\n\n const storyEmbedUrl = resolveStoryEmbedUrl(parsed);\n if (storyEmbedUrl && parsed.type === \"story\" && !hasStoryVideo(extracted?.media ?? [])) {\n logger.debug(`Fetching story embed: ${storyEmbedUrl}`);\n const storyEmbedRes = await this.client.fetch(storyEmbedUrl, false);\n const storyEmbedData = parseEmbedHtml(storyEmbedRes.body);\n extracted = mergeExtracted(extracted, storyEmbedData);\n if (!extracted?.media.some((m) => m.type === \"video\")) {\n const { parseHtml } = await import(\"./parser.js\");\n extracted = mergeExtracted(extracted, parseHtml(storyEmbedRes.body));\n }\n }\n\n const dimensionHtml = dimensionHtmlPre;\n extracted = normalizeExtraction(\n extracted,\n parsed,\n { ...pageMeta, html: dimensionHtml, embedCaption },\n dimensionHtml\n );\n\n if (extracted && parsed.type === \"post\") {\n const contentTags = buildPostContentTags(\n parsed.type,\n extracted.media.length,\n dimensionHtml,\n Boolean(sessionCookie)\n );\n extracted = {\n ...extracted,\n tags: mergeResultTags(extracted.tags, contentTags),\n };\n }\n\n if (extracted?.media.length) {\n extracted = {\n ...extracted,\n media: extracted.media.map((m) => {\n if (m.type !== \"video\" || isValidThumbnailUrl(m.thumbnail)) return m;\n const { thumbnail: _t, ...rest } = m;\n return rest;\n }),\n };\n }\n\n if (extracted?.isPrivate) {\n return this.error(403, \"Private account\");\n }\n\n if (!extracted?.media.length) {\n const msg =\n parsed.type === \"story\"\n ? sessionCookie\n ? \"Story not found or expired (check sessionId and that the story is still active)\"\n : \"Story media requires sessionId — Instagram does not expose story CDN URLs to logged-out requests. Pass options.sessionId from a logged-in browser cookie.\"\n : parsed.type === \"reel\" || parsed.type === \"tv\"\n ? sessionCookie\n ? \"Reel video not found — reel may be unavailable or session expired\"\n : \"Reel video requires INSTAGRAM_SESSION_ID or INSTAGRAM_COOKIES — Instagram no longer exposes reel MP4 URLs in public HTML\"\n : \"Media not found\";\n return this.error(404, msg);\n }\n\n return this.success(extracted);\n } catch (err: unknown) {\n const code =\n (err as { code?: number })?.code ??\n (err as { statusCode?: number })?.statusCode;\n if (code === 429) return this.error(429, \"Rate limited\");\n if (err instanceof Error && err.name === \"AbortError\") {\n return this.error(504, \"Request timed out\");\n }\n logger.error(\"Extraction failed\", err);\n return this.error(500, err instanceof Error ? err.message : \"Extraction failed\");\n }\n }\n\n async info(url: string): Promise<ApiResponse> {\n return this.download(url);\n }\n\n async validate(url: string): Promise<{ valid: boolean; type?: string; normalized?: string }> {\n return validateUrl(url);\n }\n\n async media(url: string): Promise<Media[] | ErrorResponse> {\n const result = await this.download(url);\n if (result.code !== 200) return result as ErrorResponse;\n return (result as DownloadResponse).media;\n }\n\n async batch(urls: string[]): Promise<BatchResult[]> {\n const tasks = urls.map(async (url) => {\n const start = Date.now();\n const result = await this.download(url);\n return { url, result, durationMs: Date.now() - start };\n });\n return Promise.all(tasks);\n }\n\n async health(): Promise<HealthStatus> {\n const stats = this.cache.getStats();\n const pool = getPoolStats();\n return {\n status: \"ok\",\n version: PACKAGE_VERSION,\n uptime: Date.now() - this.startTime,\n cache: {\n size: stats.size,\n maxSize: stats.maxSize,\n hitRate: stats.hitRate,\n },\n pool: {\n connections: pool.connections,\n pending: this.client.getInFlightCount(),\n },\n };\n }\n\n clearCache(): void {\n this.cache.clear();\n }\n}","export type MediaType = \"video\" | \"image\";\n\nexport interface Media {\n type: MediaType;\n url: string;\n thumbnail?: string;\n width?: number;\n height?: number;\n duration?: number;\n}\n\nexport interface ResponseMeta {\n extractor: string;\n version: string;\n}\n\nexport interface Engagement {\n likes?: number;\n comments?: number;\n views?: number;\n shares?: number;\n /** Creator disabled public like/view counts (not the same as zero likes). */\n likesHidden?: boolean;\n /** Creator disabled comments or comment counts. */\n commentsHidden?: boolean;\n /** Raw stats line from Instagram (likes/comments prefix) when present */\n raw?: string;\n}\n\n/** Visibility / extraction hints for clients (e.g. owner hid like counts). */\nexport type EngagementTag =\n | \"likes_hidden\"\n | \"comments_hidden\"\n | \"engagement_hidden\";\n\n/** Post shape hints (carousel detection, session needs). */\nexport type PostContentTag = \"carousel\" | \"partial_carousel\" | \"session_recommended\";\n\nexport type ResultTag = EngagementTag | PostContentTag;\n\nexport interface DownloadResponse {\n code: number;\n meta: ResponseMeta;\n media: Media[];\n /** Original post caption only (no likes/comments/shares text) */\n caption: string;\n username: string;\n /** Likes, comments, views, shares — separate from caption */\n engagement?: Engagement;\n /** e.g. likes_hidden, carousel, partial_carousel */\n tags?: ResultTag[];\n message?: string;\n}\n\nexport interface ErrorResponse {\n code: number;\n message: string;\n meta?: ResponseMeta;\n /** Hint for clients when a background fetch is still running. */\n retryAfterMs?: number;\n}\n\nexport type ApiResponse = DownloadResponse | ErrorResponse;\n\nexport interface UltraIgdlOptions {\n cache?: boolean;\n cacheTtlMs?: number;\n /** How long stale cache may be served while revalidating (default 24h). */\n staleCacheTtlMs?: number;\n cacheMaxSize?: number;\n redis?: RedisAdapter;\n maxConcurrency?: number;\n timeoutMs?: number;\n retries?: number;\n userAgentRotation?: boolean;\n verbose?: boolean;\n /**\n * Target max time for `download()` to return. Uses instant cache/stale hits;\n * on cold URLs returns 503 + `retryAfterMs` while fetch continues in background.\n * Set `fastMode: true` for 500ms budget.\n */\n responseBudgetMs?: number;\n /** Shorthand: `responseBudgetMs: 500`, `retries: 0`, aggressive cache. */\n fastMode?: boolean;\n /**\n * Instagram `sessionid` cookie value (from a logged-in browser).\n * Required for story downloads — Instagram does not embed story media in public HTML.\n */\n sessionId?: string;\n /** Full Cookie header override (includes sessionid, csrftoken, etc.). */\n cookies?: string;\n}\n\nexport interface RedisAdapter {\n get(key: string): Promise<string | null>;\n set(key: string, value: string, ttlMs?: number): Promise<void>;\n del?(key: string): Promise<void>;\n}\n\nexport interface ParsedUrl {\n type: \"reel\" | \"post\" | \"story\" | \"highlight\" | \"tv\" | \"unknown\";\n shortcode?: string;\n username?: string;\n storyId?: string;\n highlightId?: string;\n storyMediaId?: string;\n normalized: string;\n}\n\nexport interface ExtractionContext {\n html: string;\n url: string;\n parsed: ParsedUrl;\n sessionCookie?: string;\n}\n\nexport interface ExtractedPostData {\n media: Media[];\n caption: string;\n username: string;\n engagement?: Engagement;\n tags?: ResultTag[];\n isPrivate?: boolean;\n}\n\nexport interface HealthStatus {\n status: \"ok\" | \"degraded\" | \"error\";\n version: string;\n uptime: number;\n cache: {\n size: number;\n maxSize: number;\n hitRate?: number;\n };\n pool: {\n connections: number;\n pending: number;\n };\n}\n\nexport interface BatchResult {\n url: string;\n result: ApiResponse;\n durationMs: number;\n}\n\nexport { PACKAGE_VERSION } from \"../version.js\";\nexport const EXTRACTOR_NAME = \"ultra-igdl\";","/** Auto-generated by scripts/sync-version.mjs — do not edit */\nexport const PACKAGE_VERSION = \"1.0.0\";\n","import { request } from \"./request.js\";\nimport { buildHeaders, buildInstagramPageHeaders } from \"./headers.js\";\nimport { withRetry } from \"./retry.js\";\nimport { getAgent } from \"./pool.js\";\nimport { logger } from \"../utils/logger.js\";\n\nexport interface FetchResult {\n body: string;\n statusCode: number;\n headers: Record<string, string>;\n}\n\nexport interface HttpClientOptions {\n timeoutMs?: number;\n retries?: number;\n userAgentRotation?: boolean;\n}\n\nconst inFlight = new Map<string, Promise<FetchResult>>();\nconst inFlightCookie = new Map<string, Promise<FetchResult>>();\n\nexport class HttpClient {\n private timeoutMs: number;\n private retries: number;\n private userAgentRotation: boolean;\n\n constructor(options: HttpClientOptions = {}) {\n this.timeoutMs = options.timeoutMs ?? 8_000;\n this.retries = options.retries ?? 2;\n this.userAgentRotation = options.userAgentRotation ?? true;\n }\n\n async fetchWithCookie(url: string, cookie: string, dedupe = true): Promise<FetchResult> {\n const key = `${url}\\0${cookie.slice(0, 48)}`;\n if (dedupe && inFlightCookie.has(key)) {\n return inFlightCookie.get(key)!;\n }\n\n const promise = this.fetchWithCookieInternal(url, cookie);\n if (dedupe) {\n inFlightCookie.set(key, promise);\n promise.finally(() => inFlightCookie.delete(key));\n }\n return promise;\n }\n\n private async fetchWithCookieInternal(url: string, cookie: string): Promise<FetchResult> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n try {\n const response = await request(url, {\n method: \"GET\",\n headers: { ...buildInstagramPageHeaders(), Cookie: cookie },\n signal: controller.signal,\n });\n const body = await response.body.text();\n const resHeaders: Record<string, string> = {};\n for (const [key, value] of Object.entries(response.headers)) {\n if (typeof value === \"string\") resHeaders[key] = value;\n else if (Array.isArray(value)) resHeaders[key] = value.join(\", \");\n }\n return { body, statusCode: response.statusCode, headers: resHeaders };\n } finally {\n clearTimeout(timer);\n }\n }\n\n async fetch(url: string, dedupe = true): Promise<FetchResult> {\n if (dedupe && inFlight.has(url)) {\n return inFlight.get(url)!;\n }\n\n const promise = this.fetchInternal(url);\n if (dedupe) {\n inFlight.set(url, promise);\n promise.finally(() => inFlight.delete(url));\n }\n return promise;\n }\n\n private async fetchInternal(url: string): Promise<FetchResult> {\n return withRetry(\n async (attempt) => {\n const headers = buildHeaders(url, this.userAgentRotation || attempt > 0);\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n\n try {\n logger.debug(`Fetching ${url} (attempt ${attempt + 1})`);\n // Page HTML must not use the shared pool agent — Instagram serves\n // minimal/blocked markup through pooled connections.\n const usePool =\n url.includes(\"cdninstagram\") ||\n url.includes(\"fbcdn.net\") ||\n url.includes(\"fbsbx.com\");\n\n const response = await request(url, {\n method: \"GET\",\n headers,\n ...(usePool ? { dispatcher: getAgent() } : {}),\n signal: controller.signal,\n });\n\n const body = await response.body.text();\n const statusCode = response.statusCode;\n const resHeaders: Record<string, string> = {};\n for (const [key, value] of Object.entries(response.headers)) {\n if (typeof value === \"string\") resHeaders[key] = value;\n else if (Array.isArray(value)) resHeaders[key] = value.join(\", \");\n }\n\n if (statusCode === 429) {\n const err = new Error(\"Rate limited\") as Error & { statusCode: number };\n err.statusCode = 429;\n throw err;\n }\n\n if (statusCode >= 500) {\n const err = new Error(`Server error ${statusCode}`) as Error & {\n statusCode: number;\n };\n err.statusCode = statusCode;\n throw err;\n }\n\n return { body, statusCode, headers: resHeaders };\n } finally {\n clearTimeout(timer);\n }\n },\n { maxRetries: this.retries }\n );\n }\n\n getInFlightCount(): number {\n return inFlight.size;\n }\n}","export { request } from \"undici\";","const USER_AGENTS = [\n \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36\",\n \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36\",\n \"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36\",\n \"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:133.0) Gecko/20100101 Firefox/133.0\",\n \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:133.0) Gecko/20100101 Firefox/133.0\",\n \"Mozilla/5.0 (iPhone; CPU iPhone OS 17_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Mobile/15E148 Safari/604.1\",\n];\n\nconst ACCEPT_LANGUAGES = [\n \"en-US,en;q=0.9\",\n \"en-GB,en;q=0.9\",\n \"en-US,en;q=0.8,es;q=0.6\",\n];\n\nconst SEC_CH_UA = [\n '\"Google Chrome\";v=\"131\", \"Chromium\";v=\"131\", \"Not_A Brand\";v=\"24\"',\n '\"Chromium\";v=\"131\", \"Not_A Brand\";v=\"24\"',\n];\n\nlet rotationIndex = 0;\n\nexport function rotateIndex(max: number): number {\n const idx = rotationIndex % max;\n rotationIndex += 1;\n return idx;\n}\n\nconst MOBILE_UA = USER_AGENTS[5]!;\n\n/** Instagram serves richer OG/media markup to mobile Safari user agents. */\nexport function buildInstagramPageHeaders(_rotate = false): Record<string, string> {\n const ua = MOBILE_UA;\n return {\n \"User-Agent\": ua,\n Accept:\n \"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8\",\n \"Accept-Language\": \"en-US,en;q=0.9\",\n // Do not request br — undici/IG combo returns stripped HTML without OG tags.\n Referer: \"https://www.instagram.com/\",\n };\n}\n\nexport function buildHeaders(url: string, rotate = true): Record<string, string> {\n if (url.includes(\"instagram.com\") && !url.includes(\"cdninstagram\") && !url.includes(\"fbcdn\")) {\n return buildInstagramPageHeaders(rotate);\n }\n\n const uaIdx = rotate ? rotateIndex(USER_AGENTS.length) : 0;\n const langIdx = rotate ? rotateIndex(ACCEPT_LANGUAGES.length) : 0;\n const secIdx = rotate ? rotateIndex(SEC_CH_UA.length) : 0;\n\n return {\n \"User-Agent\": USER_AGENTS[uaIdx]!,\n Accept:\n \"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8\",\n \"Accept-Language\": ACCEPT_LANGUAGES[langIdx]!,\n \"Accept-Encoding\": \"gzip, deflate, br\",\n \"Cache-Control\": \"no-cache\",\n Pragma: \"no-cache\",\n \"Sec-Fetch-Dest\": \"document\",\n \"Sec-Fetch-Mode\": \"navigate\",\n \"Sec-Fetch-Site\": \"none\",\n \"Sec-Fetch-User\": \"?1\",\n \"Upgrade-Insecure-Requests\": \"1\",\n \"Sec-Ch-Ua\": SEC_CH_UA[secIdx]!,\n \"Sec-Ch-Ua-Mobile\": \"?0\",\n \"Sec-Ch-Ua-Platform\": '\"Windows\"',\n Referer: \"https://www.instagram.com/\",\n Origin: \"https://www.instagram.com\",\n ...(url.includes(\"cdninstagram\") || url.includes(\"fbcdn\")\n ? { Referer: \"https://www.instagram.com/\" }\n : {}),\n };\n}\n\n/** Headers for downloading signed CDN media (fbcdn / scontent). */\nexport function buildCdnDownloadHeaders(url: string): Record<string, string> {\n return {\n \"User-Agent\": MOBILE_UA,\n Accept: \"*/*\",\n \"Accept-Language\": \"en-US,en;q=0.9\",\n Referer: \"https://www.instagram.com/\",\n Origin: \"https://www.instagram.com\",\n \"Sec-Fetch-Dest\": url.includes(\".mp4\") ? \"video\" : \"image\",\n \"Sec-Fetch-Mode\": \"no-cors\",\n \"Sec-Fetch-Site\": \"cross-site\",\n };\n}\n\nexport function buildApiHeaders(): Record<string, string> {\n const base = buildHeaders(\"https://www.instagram.com/\");\n return {\n ...base,\n \"X-Requested-With\": \"XMLHttpRequest\",\n \"X-IG-App-ID\": \"936619743392459\",\n \"X-ASBD-ID\": \"129477\",\n Accept: \"*/*\",\n };\n}","export interface RetryOptions {\n maxRetries: number;\n baseDelayMs: number;\n maxDelayMs: number;\n retryOn?: (error: unknown, statusCode?: number) => boolean;\n}\n\nconst DEFAULT_RETRY_ON = (error: unknown, statusCode?: number): boolean => {\n if (statusCode === 429 || statusCode === 503 || statusCode === 502) return true;\n if (error instanceof Error) {\n const msg = error.message.toLowerCase();\n return (\n msg.includes(\"timeout\") ||\n msg.includes(\"econnreset\") ||\n msg.includes(\"socket\") ||\n msg.includes(\"network\")\n );\n }\n return false;\n};\n\nexport async function withRetry<T>(\n fn: (attempt: number) => Promise<T>,\n options: Partial<RetryOptions> = {}\n): Promise<T> {\n const {\n maxRetries = 3,\n baseDelayMs = 300,\n maxDelayMs = 8000,\n retryOn = DEFAULT_RETRY_ON,\n } = options;\n\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await fn(attempt);\n } catch (error) {\n lastError = error;\n const statusCode =\n error && typeof error === \"object\" && \"statusCode\" in error\n ? (error as { statusCode: number }).statusCode\n : undefined;\n\n if (attempt >= maxRetries || !retryOn(error, statusCode)) {\n throw error;\n }\n\n const jitter = Math.random() * 100;\n const delay = Math.min(\n baseDelayMs * Math.pow(2, attempt) + jitter,\n maxDelayMs\n );\n await sleep(delay);\n }\n }\n\n throw lastError;\n}\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}","import { Agent, Pool } from \"undici\";\n\nconst DEFAULT_CONNECTIONS = 100;\n\nlet sharedAgent: Agent | null = null;\nlet sharedPool: Pool | null = null;\n\nexport interface PoolStats {\n connections: number;\n pending: number;\n}\n\nexport function getAgent(maxConnections = DEFAULT_CONNECTIONS): Agent {\n if (!sharedAgent) {\n sharedAgent = new Agent({\n connections: maxConnections,\n pipelining: 1,\n keepAliveTimeout: 60_000,\n keepAliveMaxTimeout: 120_000,\n connect: { rejectUnauthorized: true },\n });\n }\n return sharedAgent;\n}\n\nexport function getPool(origin = \"https://www.instagram.com\", maxConnections = DEFAULT_CONNECTIONS): Pool {\n if (!sharedPool) {\n sharedPool = new Pool(origin, {\n connections: maxConnections,\n pipelining: 1,\n keepAliveTimeout: 60_000,\n keepAliveMaxTimeout: 120_000,\n });\n }\n return sharedPool;\n}\n\nexport function getPoolStats(): PoolStats {\n return {\n connections: DEFAULT_CONNECTIONS,\n pending: 0,\n };\n}\n\nexport async function closePool(): Promise<void> {\n if (sharedPool) {\n await sharedPool.close();\n sharedPool = null;\n }\n if (sharedAgent) {\n await sharedAgent.close();\n sharedAgent = null;\n }\n}","import { LRUCache } from \"lru-cache\";\nimport type { RedisAdapter } from \"../types/index.js\";\n\nexport interface CacheOptions {\n maxSize?: number;\n ttlMs?: number;\n /** Serve expired-but-stale entries while revalidating (default: 24h). */\n staleTtlMs?: number;\n redis?: RedisAdapter;\n}\n\nexport interface CacheStats {\n size: number;\n maxSize: number;\n hits: number;\n misses: number;\n staleHits: number;\n hitRate: number;\n}\n\ninterface CacheEnvelope {\n payload: string;\n freshUntil: number;\n staleUntil: number;\n}\n\nexport class ResponseCache {\n private lru: LRUCache<string, CacheEnvelope>;\n private redis?: RedisAdapter;\n private freshTtlMs: number;\n private staleTtlMs: number;\n private hits = 0;\n private misses = 0;\n private staleHits = 0;\n\n constructor(options: CacheOptions = {}) {\n this.freshTtlMs = options.ttlMs ?? 300_000;\n this.staleTtlMs = options.staleTtlMs ?? 86_400_000;\n this.lru = new LRUCache<string, CacheEnvelope>({\n max: options.maxSize ?? 500,\n ttl: this.staleTtlMs,\n });\n this.redis = options.redis;\n }\n\n private wrap<T>(value: T): CacheEnvelope {\n const now = Date.now();\n return {\n payload: JSON.stringify(value),\n freshUntil: now + this.freshTtlMs,\n staleUntil: now + this.staleTtlMs,\n };\n }\n\n /** Instant in-memory fresh hit (sub-ms). */\n getFreshSync<T>(key: string): T | null {\n const entry = this.lru.get(key);\n if (!entry || Date.now() > entry.freshUntil) return null;\n this.hits++;\n return JSON.parse(entry.payload) as T;\n }\n\n /** Instant stale hit for stale-while-revalidate. */\n getStaleSync<T>(key: string): T | null {\n const entry = this.lru.get(key);\n if (!entry || Date.now() > entry.staleUntil) return null;\n if (Date.now() <= entry.freshUntil) return null;\n this.staleHits++;\n return JSON.parse(entry.payload) as T;\n }\n\n async get<T>(key: string): Promise<T | null> {\n const fresh = this.getFreshSync<T>(key);\n if (fresh) return fresh;\n\n if (this.redis) {\n const remote = await this.redis.get(`ultra-igdl:${key}`);\n if (remote) {\n this.hits++;\n const parsed = JSON.parse(remote) as T;\n this.lru.set(key, this.wrap(parsed));\n return parsed;\n }\n }\n\n this.misses++;\n return null;\n }\n\n set<T>(key: string, value: T): void {\n this.lru.set(key, this.wrap(value));\n if (this.redis) {\n void this.redis.set(`ultra-igdl:${key}`, JSON.stringify(value), this.staleTtlMs);\n }\n }\n\n delete(key: string): void {\n this.lru.delete(key);\n this.redis?.del?.(`ultra-igdl:${key}`);\n }\n\n clear(): void {\n this.lru.clear();\n }\n\n getStats(): CacheStats {\n const total = this.hits + this.misses + this.staleHits;\n return {\n size: this.lru.size,\n maxSize: this.lru.max,\n hits: this.hits,\n misses: this.misses,\n staleHits: this.staleHits,\n hitRate: total > 0 ? (this.hits + this.staleHits) / total : 0,\n };\n }\n}","import type { ExtractionContext, ExtractedPostData, ParsedUrl } from \"../types/index.js\";\nimport { extractReel } from \"../extractors/reel.js\";\nimport { extractPost } from \"../extractors/post.js\";\nimport { extractStory } from \"../extractors/story.js\";\nimport { extractHighlight } from \"../extractors/highlight.js\";\n\nexport async function runExtractor(ctx: ExtractionContext): Promise<ExtractedPostData | null> {\n const { parsed } = ctx;\n\n switch (parsed.type) {\n case \"reel\":\n case \"tv\":\n return extractReel(ctx);\n case \"post\":\n return extractPost(ctx);\n case \"story\":\n return extractStory(ctx);\n case \"highlight\":\n return extractHighlight(ctx);\n default:\n return extractPost(ctx);\n }\n}\n\nexport function resolveFetchUrl(parsed: ParsedUrl): string {\n if (parsed.type === \"story\" && parsed.username && !parsed.storyId) {\n return `https://www.instagram.com/stories/${parsed.username}/`;\n }\n return parsed.normalized;\n}\n\nexport function resolveEmbedUrl(parsed: ParsedUrl): string | null {\n if (!parsed.shortcode) return null;\n if (parsed.type === \"reel\") {\n return `https://www.instagram.com/reel/${parsed.shortcode}/embed/`;\n }\n if (parsed.type === \"post\") {\n return `https://www.instagram.com/p/${parsed.shortcode}/embed/`;\n }\n if (parsed.type === \"tv\") {\n return `https://www.instagram.com/tv/${parsed.shortcode}/embed/`;\n }\n return null;\n}\n\nexport function resolveStoryEmbedUrl(parsed: ParsedUrl): string | null {\n if (parsed.type !== \"story\" || !parsed.username || !parsed.storyId) return null;\n return `https://www.instagram.com/stories/${parsed.username}/${parsed.storyId}/embed/`;\n}","import type { ExtractionContext, ExtractedPostData } from \"../types/index.js\";\nimport { extractPost } from \"./post.js\";\n\nexport async function extractReel(ctx: ExtractionContext): Promise<ExtractedPostData | null> {\n return extractPost(ctx);\n}","import type { ExtractionContext, ExtractedPostData } from \"../types/index.js\";\nimport { parseHtml, detectNotFound, detectRateLimit } from \"../core/parser.js\";\n\nexport async function extractPost(ctx: ExtractionContext): Promise<ExtractedPostData | null> {\n if (detectRateLimit(ctx.html)) {\n throw Object.assign(new Error(\"Rate limited\"), { code: 429 });\n }\n if (detectNotFound(ctx.html, 200)) {\n return null;\n }\n return parseHtml(ctx.html, ctx.parsed.type);\n}","import type { ExtractionContext, ExtractedPostData, Media } from \"../types/index.js\";\nimport { parseHtml, detectRateLimit, detectNotFound } from \"../core/parser.js\";\nimport { isStoryProfileImage } from \"../utils/media-quality.js\";\nimport { extractStoryMediaFromHtml } from \"../network/instagram-api.js\";\n\nexport async function extractStory(ctx: ExtractionContext): Promise<ExtractedPostData | null> {\n if (detectRateLimit(ctx.html)) {\n throw Object.assign(new Error(\"Rate limited\"), { code: 429 });\n }\n if (detectNotFound(ctx.html, 200)) {\n return null;\n }\n\n const nearId = extractStoryMediaFromHtml(ctx.html, ctx.parsed.storyId);\n const parsed = parseHtml(ctx.html, \"story\");\n\n const media: Media[] = [\n ...nearId,\n ...(parsed?.media.filter((m) => !isStoryProfileImage(m.url)) ?? []),\n ];\n\n const seen = new Set<string>();\n const unique = media.filter((m) => {\n const k = m.url.split(\"?\")[0]!;\n if (seen.has(k)) return false;\n seen.add(k);\n return true;\n });\n\n if (!unique.length && parsed) {\n return {\n media: [],\n caption: \"\",\n username: ctx.parsed.username ?? \"\",\n };\n }\n\n if (!unique.length) return null;\n\n return {\n media: unique,\n caption: parsed?.caption ?? \"\",\n username: ctx.parsed.username ?? parsed?.username ?? \"\",\n };\n}","import type { Media } from \"../types/index.js\";\nimport { enrichImageDimensions } from \"./media-dimensions.js\";\n\nexport function isValidMediaUrl(url: string): boolean {\n if (!isCdnMediaUrl(url)) return false;\n if (/\\.js(?:\\?|$)/i.test(url) || /rsrc\\.php/i.test(url)) return false;\n if (/static\\.cdninstagram\\.com/i.test(url)) return false;\n return true;\n}\n\nexport function filterValidMedia(media: Media[]): Media[] {\n return media.filter((m) => isValidMediaUrl(m.url));\n}\n\n/**\n * Keep CDN URLs unchanged — Instagram signs query params; editing them causes\n * \"URL signature mismatch\" (403) when downloading.\n */\nexport function upgradeImageUrl(url: string): string {\n return url;\n}\n\nexport function dimensionsFromImageUrl(url: string): { width?: number; height?: number } {\n const crop = url.match(/stp=c[\\d.]+?\\.(\\d+)\\.(\\d+)a/i);\n if (crop) {\n return { width: parseInt(crop[1]!, 10), height: parseInt(crop[2]!, 10) };\n }\n const size = url.match(/_s(\\d+)x(\\d+)_/i);\n if (size) {\n return { width: parseInt(size[1]!, 10), height: parseInt(size[2]!, 10) };\n }\n return {};\n}\n\nexport function upgradeMediaItem(media: Media, html?: string): Media {\n if (media.type !== \"image\") return media;\n if (html) return enrichImageDimensions(media, html);\n const dims = dimensionsFromImageUrl(media.url);\n return {\n ...media,\n url: media.url,\n width: media.width ?? dims.width,\n height: media.height ?? dims.height,\n };\n}\n\nexport function isStoryProfileImage(url: string): boolean {\n return (\n /\\/t51\\.2885-19\\//.test(url) ||\n /stp=dst-jpg_s\\d+x\\d+/.test(url) ||\n /profile_pic/i.test(url)\n );\n}\n\nexport function isCdnMediaUrl(url: string): boolean {\n return /cdninstagram\\.com|fbcdn\\.net|fbsbx\\.com/i.test(url);\n}\n\nexport function isValidThumbnailUrl(url: string | undefined): boolean {\n if (!url) return false;\n if (/\\.js(?:\\?|$)/i.test(url) || /rsrc\\.php/i.test(url)) return false;\n return isCdnMediaUrl(url);\n}","import type { Media } from \"../types/index.js\";\nimport { decodeEscapedUrl } from \"../core/parser.js\";\nimport {\n dimensionsFromImageUrl,\n isValidMediaUrl,\n} from \"./media-quality.js\";\n\nexport interface ImageCandidate {\n url: string;\n width: number;\n height: number;\n}\n\n/** Largest original_width / original_height pair embedded in Instagram HTML/JSON. */\nexport function maxOriginalDimensionsFromHtml(html: string): {\n width?: number;\n height?: number;\n} {\n let bestArea = 0;\n let width: number | undefined;\n let height: number | undefined;\n\n const patterns = [\n /\"original_width\":\\s*(\\d+)\\s*,\\s*\"original_height\":\\s*(\\d+)/g,\n /\"original_width\":(\\d+),\"original_height\":(\\d+)/g,\n /original_width\\\\\":(\\d+),\\\\\"original_height\\\\\":(\\d+)/g,\n ];\n\n for (const re of patterns) {\n let m: RegExpExecArray | null;\n while ((m = re.exec(html)) !== null) {\n const w = parseInt(m[1]!, 10);\n const h = parseInt(m[2]!, 10);\n const area = w * h;\n if (area > bestArea) {\n bestArea = area;\n width = w;\n height = h;\n }\n }\n }\n\n return { width, height };\n}\n\n/** Collect image_versions2 / display_resources candidates from raw HTML. */\nexport function scrapeImageCandidates(html: string): ImageCandidate[] {\n const candidates: ImageCandidate[] = [];\n const seen = new Set<string>();\n\n const add = (url: string, w: number, h: number) => {\n const decoded = decodeEscapedUrl(url.replace(/\\\\u0026/g, \"&\").replace(/\\\\\\//g, \"/\"));\n if (!decoded.startsWith(\"http\")) return;\n const key = decoded.split(\"?\")[0]!;\n if (seen.has(key)) return;\n seen.add(key);\n candidates.push({ url: decoded, width: w, height: h });\n };\n\n const iv2 =\n /\"width\":\\s*(\\d+)\\s*,\\s*\"height\":\\s*(\\d+)[\\s\\S]*?\"url\":\\s*\"([^\"]+)\"/g;\n let m: RegExpExecArray | null;\n while ((m = iv2.exec(html)) !== null) {\n add(m[3]!, parseInt(m[1]!, 10), parseInt(m[2]!, 10));\n }\n\n const iv2t =\n /\"url\":\\s*\"([^\"]+)\"[\\s\\S]*?\"width\":\\s*(\\d+)\\s*,\\s*\"height\":\\s*(\\d+)/g;\n while ((m = iv2t.exec(html)) !== null) {\n add(m[1]!, parseInt(m[2]!, 10), parseInt(m[3]!, 10));\n }\n\n const resources =\n /\"config_width\":\\s*(\\d+)\\s*,\\s*\"config_height\":\\s*(\\d+)[^}]*\"src\":\\s*\"([^\"]+)\"/g;\n while ((m = resources.exec(html)) !== null) {\n add(m[3]!, parseInt(m[1]!, 10), parseInt(m[2]!, 10));\n }\n\n const displayUrl =\n /\"display_url\":\\s*\"([^\"]+)\"[\\s\\S]{0,400}?\"original_width\":\\s*(\\d+)\\s*,\\s*\"original_height\":\\s*(\\d+)/g;\n while ((m = displayUrl.exec(html)) !== null) {\n add(m[1]!, parseInt(m[2]!, 10), parseInt(m[3]!, 10));\n }\n\n return candidates;\n}\n\nfunction mediaAssetKey(url: string): string | null {\n const m = url.match(/\\/(\\d+)_(\\d+)_/);\n return m ? `${m[1]}_${m[2]}` : null;\n}\n\nexport function isLowResDeliveryUrl(url: string): boolean {\n return /_s640x640|_s\\d{3}x\\d{3}_|e\\d+_s640x640/i.test(url);\n}\n\nexport function bestImageCandidate(html: string): ImageCandidate | null {\n const candidates = scrapeImageCandidates(html);\n if (!candidates.length) return null;\n return pickLargestCandidate(candidates);\n}\n\nexport function bestImageCandidateForMedia(\n html: string,\n mediaUrl: string\n): ImageCandidate | null {\n const candidates = scrapeImageCandidates(html);\n if (!candidates.length) return null;\n\n const key = mediaAssetKey(mediaUrl);\n if (key) {\n const matched = candidates.filter((c) => c.url.includes(key));\n if (matched.length) return pickLargestCandidate(matched);\n }\n\n return pickLargestCandidate(candidates);\n}\n\nfunction pickLargestCandidate(candidates: ImageCandidate[]): ImageCandidate {\n const valid = candidates.filter((c) => isValidMediaUrl(c.url));\n const pool = valid.length ? valid : candidates;\n const sorted = [...pool].sort((a, b) => b.width * b.height - a.width * a.height);\n const withoutLow = sorted.find((c) => !isLowResDeliveryUrl(c.url));\n return withoutLow ?? sorted[0]!;\n}\n\nfunction scrapeAssetUrlsFromHtml(html: string, assetKey: string): string[] {\n const urls: string[] = [];\n const patterns = [\n new RegExp(`\"(https?:[^\"]*${assetKey}[^\"]*)\"`, \"gi\"),\n new RegExp(`(https?:\\\\\\\\/\\\\\\\\/[^\"\\\\\\\\]*${assetKey}[^\"\\\\\\\\]*)`, \"gi\"),\n ];\n for (const re of patterns) {\n let m: RegExpExecArray | null;\n while ((m = re.exec(html)) !== null) {\n const decoded = decodeEscapedUrl(m[1]!);\n if (isValidMediaUrl(decoded)) urls.push(decoded);\n }\n }\n return urls;\n}\n\nexport function enrichImageDimensions(media: Media, html: string): Media {\n if (media.type !== \"image\") return media;\n\n const best = bestImageCandidateForMedia(html, media.url);\n const fromOriginal = maxOriginalDimensionsFromHtml(html);\n const fromStp = dimensionsFromImageUrl(media.url);\n\n let width = media.width;\n let height = media.height;\n let url = media.url;\n\n const apply = (w?: number, h?: number, candidateUrl?: string) => {\n if (!w || !h) return;\n const area = w * h;\n const cur = (width ?? 0) * (height ?? 0);\n const urlArea = dimensionsFromImageUrl(url);\n const curUrlArea = (urlArea.width ?? 0) * (urlArea.height ?? 0);\n const betterDims = area > cur;\n const betterUrl =\n candidateUrl &&\n (!isLowResDeliveryUrl(candidateUrl) ||\n (isLowResDeliveryUrl(url) && area >= curUrlArea));\n if (betterDims) {\n width = w;\n height = h;\n }\n if (betterUrl && (betterDims || area >= curUrlArea)) {\n url = candidateUrl;\n }\n };\n\n apply(fromOriginal.width, fromOriginal.height);\n apply(fromStp.width, fromStp.height);\n if (best) apply(best.width, best.height, best.url);\n\n const assetKey = mediaAssetKey(media.url);\n if (assetKey && isLowResDeliveryUrl(url)) {\n const alternates = scrapeAssetUrlsFromHtml(html, assetKey);\n const better = alternates\n .filter((u) => !isLowResDeliveryUrl(u))\n .map((u) => ({ url: u, ...dimensionsFromImageUrl(u) }))\n .filter((c) => c.width && c.height)\n .sort((a, b) => b.width! * b.height! - a.width! * a.height!)[0];\n if (better) apply(better.width, better.height, better.url);\n }\n\n if ((!width || !height) && fromStp.width && fromStp.height) {\n width = fromStp.width;\n height = fromStp.height;\n }\n\n if (!isValidMediaUrl(url)) {\n url = media.url;\n }\n\n return { ...media, url, width, height };\n}\n\nexport function applyPageHtmlToMedia(media: Media[], html: string): Media[] {\n const images = media.filter((m) => m.type === \"image\");\n // Carousel: do not run per-slide URL upgrade — HTML scrape picks one \"best\" URL for all slides.\n if (images.length > 1) {\n return media.map((m) => {\n if (m.type !== \"image\") return m;\n const dims = dimensionsFromImageUrl(m.url);\n return {\n ...m,\n width: m.width ?? dims.width,\n height: m.height ?? dims.height,\n };\n });\n }\n return media.map((m) => (m.type === \"image\" ? enrichImageDimensions(m, html) : m));\n}\n\nexport function mediaArea(m: Media): number {\n return (m.width ?? 0) * (m.height ?? 0);\n}\n\nexport function imageNeedsDimensions(media: Media[]): boolean {\n const img = media.find((m) => m.type === \"image\");\n return Boolean(img && (!img.width || !img.height));\n}\n\n/** True when metadata says full-size but CDN URL is still a 640-class delivery variant. */\nexport function imageNeedsHigherResolution(media: Media[]): boolean {\n const img = media.find((m) => m.type === \"image\");\n if (!img) return false;\n if (!isLowResDeliveryUrl(img.url)) return false;\n const area = (img.width ?? 0) * (img.height ?? 0);\n if (area > 640 * 640) return true;\n const fromStp = dimensionsFromImageUrl(img.url);\n return ((fromStp.width ?? 0) * (fromStp.height ?? 0)) > 640 * 640;\n}\n\n/** Fetch embed when dimensions are missing or CDN URL is still a 640-class delivery variant. */\nexport function postNeedsEmbedFetch(media: Media[]): boolean {\n return imageNeedsDimensions(media) || imageNeedsHigherResolution(media);\n}","import type { ExtractedPostData, Media, ParsedUrl } from \"../types/index.js\";\nimport { decodeEscapedUrl, parseHtml } from \"../core/parser.js\";\nimport { extractCaptionFromApiItem } from \"../utils/caption.js\";\nimport { engagementFromApiItem } from \"../utils/engagement-tags.js\";\nimport { buildApiHeaders, buildInstagramPageHeaders } from \"./headers.js\";\nimport { request } from \"./request.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { isCdnMediaUrl, isStoryProfileImage } from \"../utils/media-quality.js\";\n\nconst IG_APP_ID = \"936619743392459\";\nconst API_HOSTS = [\"https://www.instagram.com\", \"https://i.instagram.com\"] as const;\n\nexport function normalizeSessionId(sessionId: string): string {\n const trimmed = sessionId.trim();\n try {\n return decodeURIComponent(trimmed);\n } catch {\n return trimmed;\n }\n}\n\nexport function buildSessionCookie(sessionId?: string, cookies?: string): string | undefined {\n if (cookies?.trim()) {\n const map = new Map<string, string>();\n for (const part of cookies.trim().split(\";\")) {\n const [k, ...rest] = part.trim().split(\"=\");\n if (k) map.set(k.trim(), rest.join(\"=\").trim());\n }\n if (map.has(\"sessionid\")) {\n map.set(\"sessionid\", normalizeSessionId(map.get(\"sessionid\")!));\n }\n return [...map.entries()].map(([k, v]) => `${k}=${v}`).join(\"; \");\n }\n if (sessionId?.trim()) return `sessionid=${normalizeSessionId(sessionId)}`;\n return undefined;\n}\n\nfunction mergeSetCookie(existing: string, setCookieHeader: string | string[] | undefined): string {\n const map = new Map<string, string>();\n for (const part of existing.split(\";\")) {\n const [k, ...rest] = part.trim().split(\"=\");\n if (k) map.set(k.trim(), rest.join(\"=\").trim());\n }\n const headers = Array.isArray(setCookieHeader)\n ? setCookieHeader\n : setCookieHeader\n ? [setCookieHeader]\n : [];\n for (const h of headers) {\n const first = h.split(\";\")[0]!;\n const eq = first.indexOf(\"=\");\n if (eq > 0) map.set(first.slice(0, eq).trim(), first.slice(eq + 1).trim());\n }\n return [...map.entries()].map(([k, v]) => `${k}=${v}`).join(\"; \");\n}\n\nexport function userIdFromCookie(sessionCookie: string): string | null {\n const id = sessionCookie.match(/ds_user_id=([^;]+)/)?.[1];\n return id && /^\\d+$/.test(id) ? id : null;\n}\n\n/** Add csrftoken/ds_user_id from Instagram when only sessionid is known. */\nexport function sessionCookieReady(cookie: string): boolean {\n return cookie.includes(\"csrftoken=\") && cookie.includes(\"ds_user_id=\");\n}\n\nexport async function enrichSessionCookie(cookie: string): Promise<string> {\n if (sessionCookieReady(cookie)) return cookie;\n const res = await request(\"https://www.instagram.com/\", {\n headers: {\n ...buildInstagramPageHeaders(),\n Cookie: cookie,\n },\n });\n await res.body.text();\n return mergeSetCookie(cookie, res.headers[\"set-cookie\"]);\n}\n\nfunction parseCsrfFromCookie(cookie: string): string {\n return cookie.match(/csrftoken=([^;]+)/)?.[1] ?? \"\";\n}\n\nfunction mediaFromStoryItem(item: Record<string, unknown>): Media[] {\n const media: Media[] = [];\n const isVideo = item.media_type === 2 || item.is_video === true;\n\n if (isVideo && Array.isArray(item.video_versions)) {\n const versions = item.video_versions as Array<Record<string, unknown>>;\n const best = versions.reduce((a, b) =>\n ((b.width as number) ?? 0) > ((a.width as number) ?? 0) ? b : a\n );\n if (typeof best.url === \"string\") {\n media.push({\n type: \"video\",\n url: decodeEscapedUrl(best.url),\n width: best.width as number | undefined,\n height: best.height as number | undefined,\n duration: item.video_duration as number | undefined,\n });\n }\n }\n\n const candidates = (item.image_versions2 as Record<string, unknown> | undefined)\n ?.candidates as Array<Record<string, unknown>> | undefined;\n if (candidates?.length) {\n const best = candidates.reduce((a, b) =>\n ((b.width as number) ?? 0) > ((a.width as number) ?? 0) ? b : a\n );\n if (typeof best.url === \"string\") {\n const image = {\n type: \"image\" as const,\n url: decodeEscapedUrl(best.url),\n width:\n (best.width as number | undefined) ??\n (item.original_width as number | undefined),\n height:\n (best.height as number | undefined) ??\n (item.original_height as number | undefined),\n };\n if (!media.length || !isVideo) media.push(image);\n else if (media[0] && !media[0].thumbnail) media[0].thumbnail = image.url;\n }\n }\n\n return media;\n}\n\nfunction mediaFromApiItem(item: Record<string, unknown>): Media[] {\n const carousel = item.carousel_media as Array<Record<string, unknown>> | undefined;\n if (Array.isArray(carousel) && carousel.length > 0) {\n const media: Media[] = [];\n for (const slide of carousel) {\n if (slide && typeof slide === \"object\") {\n media.push(...mediaFromStoryItem(slide));\n }\n }\n return media;\n }\n return mediaFromStoryItem(item);\n}\n\nconst API_TIMEOUT_MS = 6_000;\n\nasync function igApiGet(\n path: string,\n sessionCookie: string,\n referer: string,\n host: (typeof API_HOSTS)[number] = API_HOSTS[0],\n timeoutMs = API_TIMEOUT_MS\n): Promise<{ statusCode: number; body: string }> {\n const csrf = parseCsrfFromCookie(sessionCookie);\n const headers = {\n ...buildApiHeaders(),\n Cookie: sessionCookie,\n Referer: referer,\n \"X-CSRFToken\": csrf,\n \"X-IG-App-ID\": IG_APP_ID,\n };\n\n const url = path.startsWith(\"http\") ? path : `${host}${path}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const response = await request(url, {\n method: \"GET\",\n headers,\n signal: controller.signal,\n });\n const body = await response.body.text();\n return { statusCode: response.statusCode, body };\n } finally {\n clearTimeout(timer);\n }\n}\n\nexport async function fetchStoryPageWithSession(\n url: string,\n sessionCookie: string\n): Promise<{ statusCode: number; body: string }> {\n const response = await request(url, {\n headers: {\n ...buildInstagramPageHeaders(),\n Cookie: sessionCookie,\n },\n });\n const body = await response.body.text();\n return { statusCode: response.statusCode, body };\n}\n\nexport function extractStoryMediaFromHtml(html: string, storyId?: string): Media[] {\n const media: Media[] = [];\n const seen = new Set<string>();\n\n const add = (item: Media) => {\n if (isStoryProfileImage(item.url)) return;\n const key = item.url.split(\"?\")[0]!;\n if (seen.has(key)) return;\n seen.add(key);\n media.push(item);\n };\n\n if (storyId) {\n let pos = 0;\n while ((pos = html.indexOf(storyId, pos)) !== -1) {\n const chunk = html.slice(Math.max(0, pos - 12000), pos + 16000);\n collectFromChunk(chunk, add);\n pos += storyId.length;\n }\n }\n\n collectFromChunk(html, add);\n return media;\n}\n\nfunction collectFromChunk(chunk: string, add: (m: Media) => void): void {\n const patterns = [\n /\"video_versions\":\\s*\\[[^\\]]*?\"url\":\\s*\"([^\"]+)\"/g,\n /video_url\\\\\":\\\\\"([^\"]+)/g,\n /\"playback_url\":\"(https?:[^\"]+)\"/g,\n /\"url\":\"(https?:\\\\\\/\\\\\\/[^\"]*?fbcdn[^\"]+)\"/g,\n /\"url\":\"(https?:\\\\\\/\\\\\\/[^\"]*?cdninstagram[^\"]+)\"/g,\n ];\n\n for (const pattern of patterns) {\n let m: RegExpExecArray | null;\n while ((m = pattern.exec(chunk)) !== null) {\n let url = decodeEscapedUrl(m[1]!);\n if (!url.startsWith(\"http\")) url = `https://${url.replace(/^\\/+/, \"\")}`;\n if (url.includes(\".mp4\") || url.includes(\"video\")) {\n add({ type: \"video\", url });\n } else if (url.includes(\"cdninstagram\") || url.includes(\"fbcdn\")) {\n add({ type: \"image\", url });\n }\n }\n }\n}\n\nexport async function fetchUserId(\n username: string,\n sessionCookie: string,\n referer: string\n): Promise<string | null> {\n const fromCookie = userIdFromCookie(sessionCookie);\n if (fromCookie) return fromCookie;\n\n for (const host of API_HOSTS) {\n const { statusCode, body } = await igApiGet(\n `/api/v1/users/web_profile_info/?username=${encodeURIComponent(username)}`,\n sessionCookie,\n referer,\n host\n );\n if (statusCode === 429) break;\n if (statusCode !== 200) continue;\n try {\n const data = JSON.parse(body) as Record<string, unknown>;\n const user = (data.data as Record<string, unknown> | undefined)?.user as\n | Record<string, unknown>\n | undefined;\n const id = user?.id ?? user?.pk;\n if (id != null) return String(id);\n } catch {\n const m = body.match(/\"id\":\"(\\d+)\"/);\n if (m) return m[1]!;\n }\n }\n return null;\n}\n\nfunction storyItemMatches(item: Record<string, unknown>, storyPk: string): boolean {\n const ids = [item.pk, item.id, item.media_id, item.story_media_id, item.fbid, item.code].map(\n (v) => (v != null ? String(v) : \"\")\n );\n return ids.some(\n (id) =>\n id === storyPk ||\n id.startsWith(`${storyPk}_`) ||\n storyPk.startsWith(`${id}_`) ||\n id.includes(storyPk)\n );\n}\n\nfunction parseMediaInfoBody(body: string): ExtractedPostData | null {\n try {\n const payload = JSON.parse(body) as Record<string, unknown>;\n const items = payload.items as Array<Record<string, unknown>> | undefined;\n const item = items?.[0] ?? payload;\n if (!item || typeof item !== \"object\") return null;\n const media = mediaFromApiItem(item as Record<string, unknown>);\n if (!media.length) return null;\n const user = (item as Record<string, unknown>).user as Record<string, unknown> | undefined;\n return {\n media,\n caption: extractCaptionFromApiItem(item as Record<string, unknown>),\n username: typeof user?.username === \"string\" ? user.username : \"\",\n engagement: engagementFromApiItem(item as Record<string, unknown>),\n };\n } catch {\n return null;\n }\n}\n\nasync function fetchMediaInfoOnce(\n id: string,\n sessionCookie: string,\n referer: string,\n host: (typeof API_HOSTS)[number],\n timeoutMs?: number\n): Promise<ExtractedPostData | null> {\n const { statusCode, body } = await igApiGet(\n `/api/v1/media/${id}/info/?media_id=${id}`,\n sessionCookie,\n referer,\n host,\n timeoutMs ?? API_TIMEOUT_MS\n );\n if (statusCode !== 200) {\n logger.debug(`media info ${statusCode} ${host} id=${id}`);\n return null;\n }\n const parsed = parseMediaInfoBody(body);\n return parsed?.media.length ? parsed : null;\n}\n\n/** Return on first successful media/info response (parallel hosts/ids). */\nexport async function fetchMediaInfoByPk(\n mediaPk: string,\n sessionCookie: string,\n referer: string,\n ownerUserId?: string | null,\n timeoutMs?: number\n): Promise<ExtractedPostData | null> {\n const ids = ownerUserId ? [mediaPk, `${mediaPk}_${ownerUserId}`] : [mediaPk];\n const perAttempt = timeoutMs ?? API_TIMEOUT_MS;\n\n const attempts: Array<Promise<ExtractedPostData>> = [];\n for (const host of API_HOSTS) {\n for (const id of ids) {\n attempts.push(\n fetchMediaInfoOnce(id, sessionCookie, referer, host, perAttempt).then((r) => {\n if (!r?.media.length) throw new Error(\"miss\");\n return r;\n })\n );\n }\n }\n\n try {\n return await Promise.any(attempts);\n } catch {\n return null;\n }\n}\n\nasync function fetchUserStoryFeed(\n userId: string,\n sessionCookie: string,\n referer: string,\n storyPk?: string\n): Promise<ExtractedPostData | null> {\n for (const host of API_HOSTS) {\n const { statusCode, body } = await igApiGet(\n `/api/v1/feed/user/${userId}/story/`,\n sessionCookie,\n referer,\n host\n );\n if (statusCode !== 200) {\n logger.debug(`user story feed ${statusCode} ${host}`);\n continue;\n }\n try {\n const payload = JSON.parse(body) as Record<string, unknown>;\n const reel = payload.reel as Record<string, unknown> | undefined;\n const items = (reel?.items ?? payload.items) as Array<Record<string, unknown>> | undefined;\n if (!items?.length) continue;\n\n const item =\n (storyPk ? items.find((i) => storyItemMatches(i, storyPk)) : undefined) ?? items[0];\n const media = mediaFromStoryItem(item);\n if (!media.length) continue;\n return { media, caption: \"\", username: \"\" };\n } catch {\n continue;\n }\n }\n return null;\n}\n\nasync function fetchReelsMedia(\n userId: string,\n sessionCookie: string,\n referer: string,\n storyPk?: string\n): Promise<ExtractedPostData | null> {\n for (const host of API_HOSTS) {\n const { statusCode, body } = await igApiGet(\n `/api/v1/feed/reels_media/?reel_ids=${userId}`,\n sessionCookie,\n referer,\n host\n );\n if (statusCode !== 200) {\n logger.debug(`reels_media ${statusCode} ${host}`);\n continue;\n }\n try {\n const payload = JSON.parse(body) as Record<string, unknown>;\n const reels = payload.reels as Record<string, unknown> | undefined;\n const reel = (reels?.[userId] ?? Object.values(reels ?? {})[0]) as\n | Record<string, unknown>\n | undefined;\n const items = reel?.items as Array<Record<string, unknown>> | undefined;\n if (!items?.length) continue;\n\n const item =\n (storyPk ? items.find((i) => storyItemMatches(i, storyPk)) : undefined) ?? items[0];\n const media = mediaFromStoryItem(item);\n if (!media.length) continue;\n return { media, caption: \"\", username: \"\" };\n } catch {\n continue;\n }\n }\n return null;\n}\n\nfunction storyMediaFromPageHtml(\n html: string,\n storyPk?: string\n): ExtractedPostData | null {\n const fromHtml = extractStoryMediaFromHtml(html, storyPk);\n const videos = fromHtml.filter((m) => m.type === \"video\" && isCdnMediaUrl(m.url));\n if (videos.length) {\n return { media: videos, caption: \"\", username: \"\" };\n }\n\n const parsedHtml = parseHtml(html, \"story\");\n const ogMedia =\n parsedHtml?.media.filter(\n (m) =>\n !isStoryProfileImage(m.url) &&\n (m.type === \"video\" ? isCdnMediaUrl(m.url) : true)\n ) ?? [];\n if (ogMedia.length) {\n return { media: ogMedia, caption: \"\", username: \"\" };\n }\n return null;\n}\n\nexport async function fetchStoryViaSession(\n parsed: ParsedUrl,\n sessionCookie: string,\n existingPageHtml?: string\n): Promise<ExtractedPostData | null> {\n if (!parsed.username) return null;\n\n const referer = parsed.normalized;\n const storyPk = parsed.storyId;\n const ownerUserId = userIdFromCookie(sessionCookie);\n\n if (storyPk) {\n const direct = await fetchMediaInfoByPk(\n storyPk,\n sessionCookie,\n referer,\n ownerUserId ?? undefined\n );\n if (direct?.media.length) {\n return { ...direct, username: parsed.username };\n }\n }\n\n if (existingPageHtml) {\n const fromPage = storyMediaFromPageHtml(existingPageHtml, storyPk);\n if (fromPage?.media.length) {\n return { ...fromPage, username: parsed.username };\n }\n }\n\n if (!existingPageHtml) {\n const authPage = await fetchStoryPageWithSession(referer, sessionCookie);\n if (authPage.statusCode === 200) {\n const fromPage = storyMediaFromPageHtml(authPage.body, storyPk);\n if (fromPage?.media.length) {\n return { ...fromPage, username: parsed.username };\n }\n }\n }\n\n const userId =\n ownerUserId ?? (await fetchUserId(parsed.username, sessionCookie, referer));\n if (!userId) return null;\n\n const feed = await fetchUserStoryFeed(userId, sessionCookie, referer, storyPk);\n if (feed?.media.length) {\n return { ...feed, username: parsed.username };\n }\n\n const reels = await fetchReelsMedia(userId, sessionCookie, referer, storyPk);\n if (reels?.media.length) {\n return { ...reels, username: parsed.username };\n }\n\n if (storyPk) {\n const retry = await fetchMediaInfoByPk(storyPk, sessionCookie, referer, userId);\n if (retry?.media.length) {\n return { ...retry, username: parsed.username };\n }\n }\n\n return null;\n}","import type { Engagement, ParsedUrl } from \"../types/index.js\";\nimport type { EngagementTag } from \"../types/index.js\";\n\n/** OG line starts with \"12K likes, …\" when counts are public. */\nexport function ogDescriptionHasPublicCounts(ogDescription: string): boolean {\n return /^\\d[\\d.KMB,\\s]*(?:likes?|comments?|views?)/i.test(ogDescription.trim());\n}\n\n/** Creator hid like/view counts in embedded JSON. */\nexport function scrapeEngagementFlagsFromHtml(html: string): {\n likesHidden: boolean;\n commentsHidden: boolean;\n} {\n let likesHidden = false;\n let commentsHidden = false;\n if (!html) return { likesHidden, commentsHidden };\n\n if (\n /like_and_view_counts_disabled\":\\s*true/i.test(html) ||\n /\"hide_like_and_view_counts\":\\s*true/i.test(html)\n ) {\n likesHidden = true;\n }\n if (/comments_disabled\":\\s*true/i.test(html)) {\n commentsHidden = true;\n }\n return { likesHidden, commentsHidden };\n}\n\nexport function engagementFromApiItem(item: Record<string, unknown>): Engagement | undefined {\n const engagement: Engagement = {};\n\n if (typeof item.like_count === \"number\") engagement.likes = item.like_count;\n if (typeof item.comment_count === \"number\") engagement.comments = item.comment_count;\n if (typeof item.view_count === \"number\") engagement.views = item.view_count;\n if (typeof item.play_count === \"number\" && engagement.views == null) {\n engagement.views = item.play_count;\n }\n\n if (item.like_and_view_counts_disabled === true) {\n engagement.likesHidden = true;\n }\n if (item.comments_disabled === true) {\n engagement.commentsHidden = true;\n }\n\n const hasMetric =\n engagement.likes != null ||\n engagement.comments != null ||\n engagement.views != null;\n const hasFlags = engagement.likesHidden || engagement.commentsHidden;\n\n return hasMetric || hasFlags ? engagement : undefined;\n}\n\nexport function buildEngagementTags(\n parsedType: ParsedUrl[\"type\"],\n ogDescription: string | undefined,\n engagement: Engagement,\n html: string\n): EngagementTag[] {\n const tags = new Set<EngagementTag>();\n const countable = parsedType === \"reel\" || parsedType === \"post\" || parsedType === \"tv\";\n\n if (engagement.likesHidden) tags.add(\"likes_hidden\");\n if (engagement.commentsHidden) tags.add(\"comments_hidden\");\n\n const fromHtml = scrapeEngagementFlagsFromHtml(html);\n if (fromHtml.likesHidden) tags.add(\"likes_hidden\");\n if (fromHtml.commentsHidden) tags.add(\"comments_hidden\");\n\n if (!countable || !ogDescription?.trim()) {\n return [...tags];\n }\n\n const publicCounts = ogDescriptionHasPublicCounts(ogDescription);\n const captionOnlyOg = /\\bon\\s+[\\w\\s\\d,.]+:\\s*[\"']/i.test(ogDescription);\n\n if (captionOnlyOg && !publicCounts) {\n if (engagement.likes == null) tags.add(\"likes_hidden\");\n if (engagement.comments == null) tags.add(\"comments_hidden\");\n }\n\n if (tags.has(\"likes_hidden\") && tags.has(\"comments_hidden\")) {\n tags.add(\"engagement_hidden\");\n }\n\n return [...tags];\n}","import type { ExtractionContext, ExtractedPostData, Media } from \"../types/index.js\";\nimport { parseHtml, detectRateLimit, detectNotFound, decodeEscapedUrl } from \"../core/parser.js\";\nimport { enrichImageDimensions } from \"../utils/media-dimensions.js\";\n\nfunction parseMediaBlock(chunk: string): Media | null {\n const isVideo = /\"media_type\":\\s*2/.test(chunk) || /\"is_video\":\\s*true/.test(chunk);\n if (isVideo) {\n const videoRe = /\"video_versions\":\\s*\\[[^\\]]*?\"width\":\\s*(\\d+)[^}]*\"height\":\\s*(\\d+)[^}]*\"url\":\\s*\"([^\"]+)\"/;\n const vm = chunk.match(videoRe);\n if (vm) {\n return {\n type: \"video\",\n url: decodeEscapedUrl(vm[3]!.replace(/\\\\u0026/g, \"&\").replace(/\\\\\\//g, \"/\")),\n width: parseInt(vm[1]!, 10),\n height: parseInt(vm[2]!, 10),\n };\n }\n const urlOnly = /\"video_versions\":\\[[^\\]]*?\"url\":\"([^\"]+)\"/.exec(chunk);\n if (urlOnly) {\n return {\n type: \"video\",\n url: decodeEscapedUrl(urlOnly[1]!.replace(/\\\\u0026/g, \"&\").replace(/\\\\\\//g, \"/\")),\n };\n }\n }\n\n const imgRe =\n /\"image_versions2\":\\s*\\{\\s*\"candidates\":\\s*\\[[^\\]]*?\"width\":\\s*(\\d+)\\s*,\\s*\"height\":\\s*(\\d+)[^}]*\"url\":\\s*\"([^\"]+)\"/;\n const im = chunk.match(imgRe);\n if (im) {\n return {\n type: \"image\",\n url: decodeEscapedUrl(im[3]!.replace(/\\\\u0026/g, \"&\").replace(/\\\\\\//g, \"/\")),\n width: parseInt(im[1]!, 10),\n height: parseInt(im[2]!, 10),\n };\n }\n return null;\n}\n\nfunction extractNearMediaId(html: string, storyMediaId?: string): Media[] {\n const pk = storyMediaId?.split(\"_\")[0];\n if (!pk) return [];\n const media: Media[] = [];\n let pos = 0;\n while ((pos = html.indexOf(pk, pos)) !== -1 && media.length < 8) {\n const chunk = html.slice(Math.max(0, pos - 14000), pos + 18000);\n const item = parseMediaBlock(chunk);\n if (item && !media.some((m) => m.url === item.url)) {\n media.push(item);\n }\n pos += pk.length;\n }\n return media;\n}\n\nfunction dedupeMediaList(media: Media[]): Media[] {\n const seen = new Set<string>();\n return media.filter((m) => {\n const k = m.url.split(\"?\")[0]!;\n if (seen.has(k)) return false;\n seen.add(k);\n return true;\n });\n}\n\nexport async function extractHighlight(ctx: ExtractionContext): Promise<ExtractedPostData | null> {\n if (detectRateLimit(ctx.html)) {\n throw Object.assign(new Error(\"Rate limited\"), { code: 429 });\n }\n if (detectNotFound(ctx.html, 200)) {\n return null;\n }\n\n const parsed = parseHtml(ctx.html, \"highlight\");\n const allMedia: Media[] = [];\n\n allMedia.push(...extractNearMediaId(ctx.html, ctx.parsed.storyMediaId));\n if (parsed?.media.length) {\n allMedia.push(...parsed.media);\n }\n\n const itemRegex = /\"media_type\":\\s*(\\d+)[\\s\\S]{0,4000}?(?=\"media_type\":|$)/g;\n let match: RegExpExecArray | null;\n while ((match = itemRegex.exec(ctx.html)) !== null) {\n const block = match[0]!;\n const item = parseMediaBlock(block);\n if (item && !allMedia.some((m) => m.url === item.url)) {\n allMedia.push(item);\n }\n }\n\n const unique = dedupeMediaList(allMedia).map((m) =>\n m.type === \"image\" ? enrichImageDimensions(m, ctx.html) : m\n );\n\n if (!unique.length) return parsed;\n\n return {\n media: unique,\n caption: parsed?.caption ?? \"\",\n username: ctx.parsed.username ?? parsed?.username ?? \"\",\n };\n}","import * as cheerio from \"cheerio\";\nimport type {\n ExtractedPostData,\n ParsedUrl,\n Engagement,\n ResultTag,\n Media,\n} from \"../types/index.js\";\nimport { buildEngagementTags } from \"../utils/engagement-tags.js\";\nimport { applyPageHtmlToMedia, mediaArea } from \"../utils/media-dimensions.js\";\nimport {\n parseInstagramDescription,\n parseInstagramTitle,\n} from \"../utils/engagement.js\";\nimport {\n normalizeCaptionText,\n normalizePostCaptionText,\n resolveCaptionForContent,\n scrapeCaptionFromHtml,\n} from \"../utils/caption.js\";\nimport {\n upgradeMediaItem,\n isStoryProfileImage,\n dimensionsFromImageUrl,\n isValidThumbnailUrl,\n filterValidMedia,\n} from \"../utils/media-quality.js\";\nimport { pickBestImage, pickBestVideo, decodeHtmlEntities } from \"./parser.js\";\nimport { pickPostMedia } from \"../utils/post-carousel.js\";\n\nexport interface PageMeta {\n ogDescription?: string;\n ogTitle?: string;\n html?: string;\n /** Caption from /embed/captioned/ (Instagram UI text). */\n embedCaption?: string;\n}\n\nfunction pickBestMedia(\n media: Media[],\n contentType: ParsedUrl[\"type\"],\n pageHtml = \"\"\n): Media[] {\n const videos = media.filter((m) => m.type === \"video\");\n const images = media.filter((m) => m.type === \"image\");\n\n const preferVideo = contentType === \"highlight\" || contentType === \"story\";\n\n const thumbUrl = (video: Media, fallback?: Media | null) => {\n if (isValidThumbnailUrl(video.thumbnail)) return video.thumbnail;\n if (fallback) {\n const upgraded = upgradeMediaItem(fallback, pageHtml).url;\n return isValidThumbnailUrl(upgraded) ? upgraded : undefined;\n }\n return undefined;\n };\n\n const isReelOrTv = contentType === \"reel\" || contentType === \"tv\";\n\n const bestVideo = pickBestVideo(videos);\n if (bestVideo && (preferVideo || isReelOrTv)) {\n const thumb = pickBestImage(images);\n return [{ ...bestVideo, thumbnail: thumbUrl(bestVideo, thumb) }];\n }\n\n // Reels/TV must expose video — never return a poster/thumbnail as primary media.\n if (isReelOrTv) {\n return bestVideo ? [bestVideo] : [];\n }\n\n if (contentType === \"post\") {\n if (!images.length) return bestVideo ? [bestVideo] : [];\n return pickPostMedia(media, pageHtml);\n }\n\n if (!images.length) return bestVideo ? [bestVideo] : [];\n\n const enriched = images.map((m) => upgradeMediaItem(m, pageHtml));\n const sorted = [...enriched].sort((a, b) => mediaArea(b) - mediaArea(a));\n const bestImage = sorted[0] ?? pickBestImage(enriched);\n return bestImage ? [bestImage] : [];\n}\n\n/** OG meta parse (cheerio handles multiline attribute values). */\nexport function extractPageMeta(html: string): PageMeta {\n if (!html) return {};\n const $ = cheerio.load(html);\n const ogDescription = decodeHtmlEntities(\n $('meta[property=\"og:description\"]').attr(\"content\") ?? \"\"\n );\n const ogTitle = decodeHtmlEntities($('meta[property=\"og:title\"]').attr(\"content\") ?? \"\");\n return { ogDescription, ogTitle };\n}\n\nexport function normalizeExtraction(\n data: ExtractedPostData | null,\n parsed: ParsedUrl,\n pageMeta: PageMeta = {},\n pageHtml = \"\"\n): ExtractedPostData | null {\n if (!data) return null;\n\n data = { ...data, media: filterValidMedia(data.media) };\n if (!data.media.length && !data.isPrivate) return null;\n\n const html = pageMeta.html ?? pageHtml;\n const scrapedCaption = scrapeCaptionFromHtml(html);\n let ogCaption = \"\";\n let username = data.username;\n let engagement: Engagement = data.engagement ?? {};\n\n if (pageMeta.ogDescription) {\n const parsedDesc = parseInstagramDescription(pageMeta.ogDescription);\n ogCaption = parsedDesc.caption;\n if (parsedDesc.username) username = parsedDesc.username;\n engagement = { ...engagement, ...parsedDesc.engagement };\n }\n\n let caption = resolveCaptionForContent(parsed.type, {\n embed: pageMeta.embedCaption,\n scraped: scrapedCaption,\n extracted: data.caption,\n og: ogCaption,\n });\n\n if (pageMeta.ogTitle) {\n const fromTitle = parseInstagramTitle(pageMeta.ogTitle);\n if (fromTitle.username && !username) {\n username = fromTitle.username;\n }\n if (fromTitle.caption) {\n caption =\n parsed.type === \"highlight\"\n ? normalizeCaptionText(fromTitle.caption) || caption\n : resolveCaptionForContent(parsed.type, {\n embed: pageMeta.embedCaption,\n scraped: scrapedCaption,\n extracted: caption,\n og: fromTitle.caption,\n });\n }\n }\n\n if (parsed.type === \"story\") {\n if (parsed.username) username = parsed.username;\n if (/^\\d[\\d.KMB,\\s]*(?:likes?|comments?|views?)/i.test(caption)) {\n const parsedDesc = parseInstagramDescription(caption);\n caption = parsedDesc.caption;\n engagement = { ...engagement, ...parsedDesc.engagement };\n }\n data.media = data.media.filter((m) => !isStoryProfileImage(m.url));\n }\n\n if (parsed.username && (parsed.type === \"story\" || parsed.type === \"highlight\")) {\n username = parsed.username;\n }\n\n const skipHtmlEnrich = !html && (parsed.type === \"story\" || parsed.type === \"highlight\");\n const enrichedMedia = (skipHtmlEnrich ? data.media : applyPageHtmlToMedia(data.media, html)).map(\n (m) => {\n if (m.type !== \"image\" || (m.width && m.height)) return m;\n const dims = dimensionsFromImageUrl(m.url);\n if (!dims.width || !dims.height) return m;\n return { ...m, width: dims.width, height: dims.height };\n });\n const media = pickBestMedia(enrichedMedia, parsed.type, html);\n\n const tags = [\n ...new Set<ResultTag>([\n ...(data.tags ?? []),\n ...buildEngagementTags(parsed.type, pageMeta.ogDescription, engagement, html),\n ]),\n ];\n if (tags.includes(\"likes_hidden\")) engagement.likesHidden = true;\n if (tags.includes(\"comments_hidden\")) engagement.commentsHidden = true;\n\n const hasEngagementMetrics =\n engagement.likes != null ||\n engagement.comments != null ||\n engagement.views != null ||\n engagement.shares != null ||\n Boolean(engagement.raw);\n const hasEngagement =\n hasEngagementMetrics || engagement.likesHidden || engagement.commentsHidden;\n\n return {\n ...data,\n media,\n caption:\n parsed.type === \"post\" ? normalizePostCaptionText(caption) : normalizeCaptionText(caption),\n username: username.replace(/^@/, \"\").trim(),\n engagement: hasEngagement ? engagement : undefined,\n tags: tags.length ? tags : undefined,\n };\n}","import type { Media } from \"../types/index.js\";\nimport { mediaArea } from \"./media-dimensions.js\";\nimport { upgradeMediaItem } from \"./media-quality.js\";\nimport { pickBestImage } from \"../core/parser.js\";\n\nfunction imageQualityScore(item: Media): number {\n const area = mediaArea(item);\n if (area > 0) return area;\n return item.width ?? 0;\n}\n\nfunction encodeTagFromUrl(url: string): string | null {\n const raw = url.match(/[?&]efg=([^&]+)/i)?.[1];\n if (!raw) return null;\n try {\n const b64 = decodeURIComponent(raw);\n const json = JSON.parse(Buffer.from(b64, \"base64\").toString(\"utf8\")) as {\n encode_tag?: string;\n vencode_tag?: string;\n efg_tag?: string;\n };\n return json.encode_tag ?? json.vencode_tag ?? json.efg_tag ?? null;\n } catch {\n return null;\n }\n}\n\n/** OG/HTML carousel preview — not a real sidecar slide (e.g. CAROUSEL_BEST_IMAGE_URLGEN). */\nexport function isCarouselAuxiliaryImage(url: string): boolean {\n if (/CAROUSEL_BEST_IMAGE|best_image_urlgen|cover_photo/i.test(url)) return true;\n const tag = encodeTagFromUrl(url);\n if (tag && /BEST_IMAGE|COVER|THUMBNAIL/i.test(tag)) return true;\n return false;\n}\n\nexport function stripCarouselAuxiliaryImages(media: Media[]): Media[] {\n return media.filter((m) => m.type !== \"image\" || !isCarouselAuxiliaryImage(m.url));\n}\n\n/** Stable key per carousel slide (groups resolution variants of the same photo). */\nexport function slideKeyFromMediaUrl(url: string): string {\n const cacheKey = url.match(/ig_cache_key=([^&]+)/i)?.[1];\n if (cacheKey) {\n try {\n return `ck:${decodeURIComponent(cacheKey)}`;\n } catch {\n return `ck:${cacheKey}`;\n }\n }\n const base = (url.split(\"?\")[0] ?? url).replace(/\\\\/g, \"\");\n const fileId = base.match(/\\/(\\d{8,12})_(\\d{10,})_\\d+_n\\./i);\n if (fileId) return `file:${fileId[1]}_${fileId[2]}`;\n const idMatch = base.match(/\\/(\\d{11,})(?:_\\d+)?[_/]/);\n if (idMatch) return `id:${idMatch[1]}`;\n return base.replace(/_s\\d+x\\d+/gi, \"\").replace(/p\\d+x\\d+/gi, \"\");\n}\n\n/** One image per slide (largest resolution); preserve order; keep all videos. */\nexport function dedupePostSlides(media: Media[]): Media[] {\n if (media.length <= 1) return media;\n\n const bestByKey = new Map<string, Media>();\n for (const item of media) {\n if (item.type !== \"image\") continue;\n const key = slideKeyFromMediaUrl(item.url);\n const prev = bestByKey.get(key);\n if (!prev || imageQualityScore(item) > imageQualityScore(prev)) bestByKey.set(key, item);\n }\n\n const out: Media[] = [];\n const usedImageKeys = new Set<string>();\n\n for (const item of media) {\n if (item.type === \"video\") {\n out.push(item);\n continue;\n }\n const key = slideKeyFromMediaUrl(item.url);\n if (usedImageKeys.has(key)) continue;\n usedImageKeys.add(key);\n out.push(bestByKey.get(key) ?? item);\n }\n\n return out.length ? out : media;\n}\n\n/** All carousel slides for posts (1, 2, or more photos/videos). */\nexport function pickPostMedia(media: Media[], pageHtml = \"\"): Media[] {\n const filtered = stripCarouselAuxiliaryImages(media);\n const imageCount = filtered.filter((m) => m.type === \"image\").length;\n const upgraded = filtered.map((m) => {\n if (m.type !== \"image\") return m;\n return imageCount > 1 ? upgradeMediaItem(m) : upgradeMediaItem(m, pageHtml);\n });\n const slides = dedupePostSlides(upgraded);\n\n if (slides.length <= 1) {\n const only = slides[0];\n if (!only) return [];\n if (only.type === \"video\") return [only];\n return [pickBestImage(upgraded) ?? only];\n }\n\n return slides;\n}","import type { Media } from \"../types/index.js\";\nimport { request } from \"./request.js\";\nimport { buildInstagramPageHeaders } from \"./headers.js\";\nimport { dimensionsFromImageUrl, isValidMediaUrl } from \"../utils/media-quality.js\";\nimport { isLowResDeliveryUrl } from \"../utils/media-dimensions.js\";\n\nconst REDIRECT_TIMEOUT_MS = 6_000;\n\nfunction dimensionsFromRedirectUrl(url: string): { width?: number; height?: number } {\n const p = url.match(/p(\\d+)x(\\d+)/i);\n if (p) {\n return { width: parseInt(p[1]!, 10), height: parseInt(p[2]!, 10) };\n }\n return dimensionsFromImageUrl(url);\n}\n\n/** Instagram 302 to a signed CDN URL (typically p1080, no s640 token). */\nexport async function fetchPostLargeImageUrl(\n shortcode: string,\n timeoutMs = REDIRECT_TIMEOUT_MS\n): Promise<{ url: string; width?: number; height?: number } | null> {\n const pageUrl = `https://www.instagram.com/p/${shortcode}/media/?size=l`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const response = await request(pageUrl, {\n method: \"GET\",\n headers: buildInstagramPageHeaders(),\n signal: controller.signal,\n // undici supports this; @types omit maxRedirections on RequestOptions\n maxRedirections: 0,\n } as Parameters<typeof request>[1]);\n await response.body.text();\n\n if (response.statusCode !== 301 && response.statusCode !== 302) return null;\n const raw = response.headers.location;\n const target = (Array.isArray(raw) ? raw[0] : raw)?.trim();\n if (\n !target ||\n !isValidMediaUrl(target) ||\n isLowResDeliveryUrl(target) ||\n !/\\.(jpe?g|webp|png)/i.test(target.split(\"?\")[0] ?? \"\")\n ) {\n return null;\n }\n\n return { url: target, ...dimensionsFromRedirectUrl(target) };\n } catch {\n return null;\n } finally {\n clearTimeout(timer);\n }\n}\n\nexport function applyLargePostImage(\n media: Media[],\n large: { url: string; width?: number; height?: number }\n): Media[] {\n if (!isValidMediaUrl(large.url)) return media;\n const multiImage = media.filter((m) => m.type === \"image\").length > 1;\n let firstImageUpgraded = false;\n return media.map((item) => {\n if (item.type !== \"image\") return item;\n if (multiImage && firstImageUpgraded) return item;\n const fromUrl = dimensionsFromImageUrl(item.url);\n const width = Math.max(item.width ?? 0, large.width ?? 0, fromUrl.width ?? 0) || item.width;\n const height = Math.max(item.height ?? 0, large.height ?? 0, fromUrl.height ?? 0) || item.height;\n firstImageUpgraded = true;\n return { ...item, url: large.url, width, height };\n });\n}","import * as cheerio from \"cheerio\";\nimport type { ParsedUrl } from \"../types/index.js\";\nimport { normalizeCaptionText } from \"../utils/caption-normalize.js\";\n\nexport function captionedEmbedUrl(parsed: ParsedUrl): string | null {\n if (!parsed.shortcode) return null;\n const segment =\n parsed.type === \"reel\" ? \"reel\" : parsed.type === \"tv\" ? \"tv\" : \"p\";\n return `https://www.instagram.com/${segment}/${parsed.shortcode}/embed/captioned/`;\n}\n\n/** Caption text as shown on Instagram embed (single block, includes emoji). */\nexport function parseCaptionFromCaptionedEmbed(\n html: string,\n contentType: ParsedUrl[\"type\"] = \"reel\"\n): string {\n const $ = cheerio.load(html);\n const block = $(\".Caption\").first().text().trim();\n if (!block) return \"\";\n\n const user = $(\".CaptionUsername\").first().text().trim();\n let caption = block;\n if (user && caption.startsWith(user)) {\n caption = caption.slice(user.length);\n }\n caption = caption.replace(/View all [\\d,.]+[KMB]?\\s+comments?.*$/i, \"\").trim();\n\n if (contentType === \"post\") {\n caption = caption.replace(/\\n{3,}/g, \"\\n\\n\").trim();\n } else {\n caption = caption.replace(/\\n+/g, \" \").replace(/\\s+/g, \" \").trim();\n }\n\n return normalizeCaptionText(caption);\n}\n\nexport function contentTypesWithEmbedCaption(type: ParsedUrl[\"type\"]): boolean {\n return type === \"reel\" || type === \"post\" || type === \"tv\";\n}","/** Instagram numeric media PK from page or embed HTML. */\nexport function extractMediaPkFromHtml(html: string): string | null {\n if (!html) return null;\n\n const cacheKey = html.match(/ig_cache_key=([A-Za-z0-9%_+=]+)/i)?.[1];\n if (cacheKey) {\n try {\n const decoded = Buffer.from(\n decodeURIComponent(cacheKey.replace(/ /g, \"+\")),\n \"base64\"\n ).toString(\"utf8\");\n if (/^\\d{10,}$/.test(decoded)) return decoded;\n } catch {\n /* ignore */\n }\n }\n\n const patterns = [\n /data-media-id=\"(\\d+)\"/,\n /data-media-id\\\\\":\\\\\"(\\d+)\\\\\"/,\n /\"media_id\":\"(\\d+)\"/,\n /\"pk\":\"(\\d+)\"/,\n /\"pk\":\"(\\d+)\"[^}]{0,120}\"media_type\":\\s*2/,\n ];\n\n for (const re of patterns) {\n const m = html.match(re);\n if (m?.[1]) return m[1];\n }\n return null;\n}","import type { Media } from \"../types/index.js\";\nimport { extractMediaPkFromHtml } from \"./media-id.js\";\nimport { shortcodeToMediaPk } from \"./shortcode.js\";\n\n/** PK candidates for post media/info (carousel needs parent id, not a child cache key). */\nexport function postMediaPkCandidates(\n shortcode: string,\n html = \"\",\n media: Media[] = []\n): string[] {\n const seen = new Set<string>();\n const add = (pk: string | null | undefined) => {\n if (pk && !seen.has(pk)) {\n seen.add(pk);\n return pk;\n }\n return null;\n };\n\n const out: string[] = [];\n const fromShortcode = add(shortcodeToMediaPk(shortcode));\n if (fromShortcode) {\n out.push(fromShortcode);\n return out;\n }\n\n const fromHtml = add(extractMediaPkFromHtml(html));\n if (fromHtml) out.push(fromHtml);\n\n for (const item of media) {\n const fromUrl = add(extractMediaPkFromHtml(item.url));\n if (fromUrl) out.push(fromUrl);\n }\n\n return out;\n}","const SHORTCODE_ALPHABET =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\n/** Instagram shortcode → numeric media PK (for media/info API). */\nexport function shortcodeToMediaPk(shortcode: string): string | null {\n if (!shortcode?.trim()) return null;\n try {\n let id = 0n;\n for (const char of shortcode.trim()) {\n const idx = SHORTCODE_ALPHABET.indexOf(char);\n if (idx < 0) return null;\n id = id * 64n + BigInt(idx);\n }\n return id > 0n ? id.toString() : null;\n } catch {\n return null;\n }\n}","import type { ParsedUrl, PostContentTag, ResultTag } from \"../types/index.js\";\n\n/** Instagram marks carousel/sidecar posts in embedded JSON and CDN encode tags. */\nexport function htmlIndicatesCarouselPost(html: string): boolean {\n if (!html) return false;\n if (/edge_sidecar_to_children/.test(html)) return true;\n if (/\"carousel_media\"\\s*:/.test(html)) return true;\n if (/carousel_media_count/.test(html)) return true;\n if (/GraphSidecar/.test(html)) return true;\n if (/CAROUSEL_ITEM/.test(html)) return true;\n if (/media_type[\"\\s]*:[\"\\s]*8\\b/.test(html)) return true;\n if (/product_type[\"\\s]*:[\"\\s]*carousel/.test(html)) return true;\n return false;\n}\n\nexport function buildPostContentTags(\n parsedType: ParsedUrl[\"type\"],\n mediaCount: number,\n html: string,\n hasSession: boolean\n): PostContentTag[] {\n if (parsedType !== \"post\") return [];\n if (mediaCount > 1) return [\"carousel\"];\n if (!htmlIndicatesCarouselPost(html)) return [];\n const tags: PostContentTag[] = [\"partial_carousel\"];\n if (!hasSession) tags.push(\"session_recommended\");\n return tags;\n}\n\nexport function mergeResultTags(\n existing: ResultTag[] | undefined,\n content: PostContentTag[]\n): ResultTag[] | undefined {\n const merged = [...new Set<ResultTag>([...(existing ?? []), ...content])];\n return merged.length ? merged : undefined;\n}","import type { ParsedUrl } from \"../types/index.js\";\n\nconst IG_HOST = /^(?:www\\.)?instagram\\.com$/i;\n\nfunction decodeShareSlug(slug: string): { type: \"highlight\"; id: string } | null {\n try {\n const decoded = Buffer.from(slug, \"base64\").toString(\"utf8\");\n const match = decoded.match(/^highlight:(\\d+)$/);\n if (match) return { type: \"highlight\", id: match[1]! };\n } catch {\n return null;\n }\n return null;\n}\n\nfunction buildNormalizedPath(pathname: string): string {\n let path = pathname.replace(/\\/+$/, \"\");\n if (!path.endsWith(\"/\")) path += \"/\";\n return `https://www.instagram.com${path}`;\n}\n\nexport function normalizeInstagramUrl(input: string): string {\n return parseInstagramUrl(input).normalized;\n}\n\nexport function parseInstagramUrl(input: string): ParsedUrl {\n let raw = input.trim();\n if (!/^https?:\\/\\//i.test(raw)) {\n const pathOnly = !raw.includes(\"instagram.com\");\n raw = pathOnly\n ? `https://www.instagram.com/${raw.replace(/^\\//, \"\")}`\n : `https://${raw.replace(/^\\//, \"\")}`;\n }\n\n let url: URL;\n try {\n url = new URL(raw);\n } catch {\n return { type: \"unknown\", normalized: raw };\n }\n\n if (!IG_HOST.test(url.hostname)) {\n return { type: \"unknown\", normalized: raw };\n }\n\n const storyMediaId = url.searchParams.get(\"story_media_id\") ?? undefined;\n const parts = url.pathname.split(\"/\").filter(Boolean);\n\n if (parts[0] === \"s\" && parts[1]) {\n const share = decodeShareSlug(parts[1]);\n if (share?.type === \"highlight\") {\n return {\n type: \"highlight\",\n highlightId: share.id,\n storyMediaId,\n normalized: buildNormalizedPath(`/stories/highlights/${share.id}`),\n };\n }\n }\n\n if (parts[0] === \"reel\" && parts[1]) {\n return {\n type: \"reel\",\n shortcode: parts[1],\n normalized: buildNormalizedPath(`/reel/${parts[1]}`),\n };\n }\n\n if (parts[0] === \"p\" && parts[1]) {\n return {\n type: \"post\",\n shortcode: parts[1],\n normalized: buildNormalizedPath(`/p/${parts[1]}`),\n };\n }\n\n if (parts[0] === \"tv\" && parts[1]) {\n return {\n type: \"tv\",\n shortcode: parts[1],\n normalized: buildNormalizedPath(`/tv/${parts[1]}`),\n };\n }\n\n if (parts[0] === \"stories\" && parts[1]) {\n if (parts[1] === \"highlights\" && parts[2]) {\n return {\n type: \"highlight\",\n highlightId: parts[2],\n storyMediaId,\n normalized: buildNormalizedPath(`/stories/highlights/${parts[2]}`),\n };\n }\n if (parts[2]) {\n return {\n type: \"story\",\n username: parts[1],\n storyId: parts[2],\n normalized: buildNormalizedPath(`/stories/${parts[1]}/${parts[2]}`),\n };\n }\n return {\n type: \"story\",\n username: parts[1],\n normalized: buildNormalizedPath(`/stories/${parts[1]}`),\n };\n }\n\n return { type: \"unknown\", normalized: buildNormalizedPath(url.pathname || \"/\") };\n}\n\nexport function isInstagramUrl(input: string): boolean {\n try {\n const normalized = normalizeInstagramUrl(\n input.startsWith(\"http\") ? input : `https://${input}`\n );\n const parsed = parseInstagramUrl(normalized);\n return parsed.type !== \"unknown\";\n } catch {\n return false;\n }\n}\n\nexport function shortcodeToMediaUrl(shortcode: string, type: \"reel\" | \"post\" | \"tv\" = \"post\"): string {\n const segment = type === \"reel\" ? \"reel\" : type === \"tv\" ? \"tv\" : \"p\";\n return `https://www.instagram.com/${segment}/${shortcode}/`;\n}","import { isInstagramUrl, parseInstagramUrl } from \"./urls.js\";\n\nexport interface ValidationResult {\n valid: boolean;\n type?: string;\n normalized?: string;\n error?: string;\n}\n\nexport function validateUrl(input: string): ValidationResult {\n if (!input || typeof input !== \"string\") {\n return { valid: false, error: \"URL must be a non-empty string\" };\n }\n\n try {\n new URL(input.startsWith(\"http\") ? input : `https://${input}`);\n } catch {\n return { valid: false, error: \"Invalid URL format\" };\n }\n\n if (!isInstagramUrl(input)) {\n return { valid: false, error: \"Not a supported Instagram URL\" };\n }\n\n const parsed = parseInstagramUrl(input);\n return {\n valid: true,\n type: parsed.type,\n normalized: parsed.normalized,\n };\n}","import { createWriteStream } from \"node:fs\";\nimport { mkdir, stat } from \"node:fs/promises\";\nimport { dirname, join, extname } from \"node:path\";\nimport { request } from \"../network/request.js\";\nimport type { Media } from \"../types/index.js\";\nimport { buildCdnDownloadHeaders } from \"../network/headers.js\";\nimport { getAgent } from \"../network/pool.js\";\n\nexport interface FileDownloadOptions {\n outputDir: string;\n onProgress?: (info: ProgressInfo) => void;\n retries?: number;\n}\n\nexport interface ProgressInfo {\n filename: string;\n downloaded: number;\n total: number;\n speed: number;\n}\n\nexport function generateFilename(media: Media, index: number): string {\n const ext = media.type === \"video\" ? \".mp4\" : extname(new URL(media.url).pathname) || \".jpg\";\n const base = `${media.type}_${index + 1}_${Date.now()}`;\n return `${base}${ext.startsWith(\".\") ? ext : `.${ext}`}`;\n}\n\nexport async function downloadMediaFile(\n media: Media,\n outputPath: string,\n retries = 3\n): Promise<{ path: string; size: number; durationMs: number }> {\n const start = Date.now();\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n await mkdir(dirname(outputPath), { recursive: true });\n const response = await request(media.url, {\n method: \"GET\",\n headers: buildCdnDownloadHeaders(media.url),\n dispatcher: getAgent(),\n });\n\n if (response.statusCode >= 400) {\n const hint =\n response.statusCode === 403\n ? \" (URL signature mismatch — media URL may be expired; re-fetch the post)\"\n : \"\";\n throw new Error(`HTTP ${response.statusCode}${hint}`);\n }\n\n const contentLength = parseInt(\n String(response.headers[\"content-length\"] ?? \"0\"),\n 10\n );\n let downloaded = 0;\n\n const writeStream = createWriteStream(outputPath);\n for await (const chunk of response.body) {\n downloaded += chunk.length;\n writeStream.write(chunk);\n }\n writeStream.end();\n await new Promise<void>((resolve, reject) => {\n writeStream.on(\"finish\", resolve);\n writeStream.on(\"error\", reject);\n });\n\n const fileStat = await stat(outputPath);\n return {\n path: outputPath,\n size: fileStat.size || contentLength || downloaded,\n durationMs: Date.now() - start,\n };\n } catch (err) {\n lastError = err;\n if (attempt < retries) {\n await new Promise((r) => setTimeout(r, 500 * (attempt + 1)));\n }\n }\n }\n\n throw lastError;\n}\n\nexport async function downloadAllMedia(\n mediaList: Media[],\n options: FileDownloadOptions\n): Promise<Array<{ path: string; size: number }>> {\n const results: Array<{ path: string; size: number }> = [];\n\n for (let i = 0; i < mediaList.length; i++) {\n const media = mediaList[i]!;\n const filename = generateFilename(media, i);\n const outputPath = join(options.outputDir, filename);\n const result = await downloadMediaFile(media, outputPath, options.retries);\n results.push({ path: result.path, size: result.size });\n options.onProgress?.({\n filename,\n downloaded: result.size,\n total: result.size,\n speed: result.size / (result.durationMs / 1000),\n });\n }\n\n return results;\n}"],"mappings":"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","names":["import_promises","import_node_fs","import_node_path","resolve","import_undici","area","c","area","cheerio","area","cheerio","resolve","inFlight","extracted","pageMeta","apiMedia","parseHtml","resolve"]}