@absolutejs/rag 0.11.0 → 0.12.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.
@@ -1,5 +1,37 @@
1
1
  // @bun
2
+ var __create = Object.create;
3
+ var __getProtoOf = Object.getPrototypeOf;
2
4
  var __defProp = Object.defineProperty;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ function __accessProp(key) {
8
+ return this[key];
9
+ }
10
+ var __toESMCache_node;
11
+ var __toESMCache_esm;
12
+ var __toESM = (mod, isNodeMode, target) => {
13
+ var canCache = mod != null && typeof mod === "object";
14
+ if (canCache) {
15
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
16
+ var cached = cache.get(mod);
17
+ if (cached)
18
+ return cached;
19
+ }
20
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
21
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
22
+ if (mod && typeof mod === "object" || typeof mod === "function") {
23
+ for (let key of __getOwnPropNames(mod))
24
+ if (!__hasOwnProp.call(to, key))
25
+ __defProp(to, key, {
26
+ get: __accessProp.bind(mod, key),
27
+ enumerable: true
28
+ });
29
+ }
30
+ if (canCache)
31
+ cache.set(mod, to);
32
+ return to;
33
+ };
34
+ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
3
35
  var __returnValue = (v) => v;
4
36
  function __exportSetter(name, newValue) {
5
37
  this[name] = __returnValue.bind(null, newValue);
@@ -13,6 +45,7 @@ var __export = (target, all) => {
13
45
  set: __exportSetter.bind(all, name)
14
46
  });
15
47
  };
48
+ var __require = import.meta.require;
16
49
 
17
50
  // src/web/playwright.ts
18
51
  import { chromium } from "playwright-core";
@@ -58,6 +91,7 @@ var fetchPublicWebResource = async (raw, options = {}) => {
58
91
  const signal = options.signal ?? AbortSignal.timeout(15000);
59
92
  const maxBytes = options.maxBytes ?? 5000000;
60
93
  let url = validatePublicWebUrl(raw);
94
+ const redirects = [];
61
95
  let method = options.method ?? "GET";
62
96
  let body = options.body;
63
97
  for (let hop = 0;hop <= 5; hop++) {
@@ -139,14 +173,21 @@ var fetchPublicWebResource = async (raw, options = {}) => {
139
173
  if (options.redirect === "manual")
140
174
  return response;
141
175
  if ([301, 302, 303, 307, 308].includes(response.status) && response.headers.location) {
142
- url = validatePublicWebUrl(new URL(response.headers.location, url).href);
176
+ const next = validatePublicWebUrl(new URL(response.headers.location, url).href);
177
+ redirects.push({
178
+ from: url.href,
179
+ to: next.href,
180
+ kind: "http",
181
+ status: response.status
182
+ });
183
+ url = next;
143
184
  if (response.status === 303 || [301, 302].includes(response.status) && method === "POST") {
144
185
  method = "GET";
145
186
  body = undefined;
146
187
  }
147
188
  continue;
148
189
  }
149
- return response;
190
+ return { ...response, redirects };
150
191
  }
151
192
  throw new WebReadError("redirect_limit", "The site exceeded the redirect limit.");
152
193
  };
@@ -182,6 +223,7 @@ var createPlaywrightWebRenderer = (options = {}) => {
182
223
  context.close().catch(() => {});
183
224
  };
184
225
  signal.addEventListener("abort", abort, { once: true });
226
+ const redirects = [];
185
227
  let count = 0, bytes = 0;
186
228
  try {
187
229
  await context.routeWebSocket("**/*", (socket) => socket.close());
@@ -206,6 +248,14 @@ var createPlaywrightWebRenderer = (options = {}) => {
206
248
  headers,
207
249
  redirect: "manual"
208
250
  });
251
+ if (request.isNavigationRequest() && request.frame() === context.pages()[0]?.mainFrame() && [301, 302, 303, 307, 308].includes(response2.status) && response2.headers.location) {
252
+ redirects.push({
253
+ from: request.url(),
254
+ to: new URL(response2.headers.location, request.url()).href,
255
+ kind: "http",
256
+ status: response2.status
257
+ });
258
+ }
209
259
  bytes += response2.body.byteLength;
210
260
  await route.fulfill({
211
261
  status: response2.status,
@@ -217,22 +267,43 @@ var createPlaywrightWebRenderer = (options = {}) => {
217
267
  }
218
268
  });
219
269
  const page = await context.newPage();
270
+ let previousUrl = url;
271
+ page.on("framenavigated", (frame) => {
272
+ if (frame !== page.mainFrame() || !/^https?:/u.test(frame.url()))
273
+ return;
274
+ const next = frame.url();
275
+ if (next !== previousUrl && !redirects.some((hop) => hop.to === next))
276
+ redirects.push({ from: previousUrl, to: next, kind: "client" });
277
+ previousUrl = next;
278
+ });
220
279
  const response = await page.goto(url, {
221
280
  waitUntil: "domcontentloaded",
222
281
  timeout: 25000
223
282
  });
224
- await page.waitForFunction(() => {
283
+ const settled = await page.waitForFunction(() => {
225
284
  const root = document.querySelector("#root,#app,#__next,app-root,[ng-version]");
226
285
  const rootText = root?.textContent?.trim() ?? "";
227
286
  return document.body.innerText.trim().length > 100 && (!root || rootText.length > 20 && !/^(loading|please wait)/i.test(rootText));
228
- }, undefined, { timeout: 8000 }).catch(() => {});
287
+ }, undefined, { timeout: 8000 }).then(() => true, () => false);
229
288
  await page.waitForTimeout(1200);
289
+ for (let step = 0;step < 3; step++) {
290
+ await page.evaluate(() => window.scrollBy(0, window.innerHeight));
291
+ await page.waitForTimeout(350);
292
+ }
293
+ await page.evaluate(() => {
294
+ document.querySelectorAll("details").forEach((element) => {
295
+ element.open = true;
296
+ });
297
+ window.scrollTo(0, 0);
298
+ });
230
299
  signal.throwIfAborted();
231
300
  const html = await page.content();
232
301
  if (html.length > 5000000)
233
302
  throw new WebReadError("too_large", "Rendered page exceeded the content limit.");
234
303
  return {
235
304
  html,
305
+ redirects,
306
+ settled,
236
307
  text: await page.locator("body").innerText(),
237
308
  url: page.url(),
238
309
  status: response?.status() ?? 200
@@ -266,5 +337,5 @@ export {
266
337
  createPlaywrightWebRenderer
267
338
  };
268
339
 
269
- //# debugId=9C078CEF671DE2C764756E2164756E21
340
+ //# debugId=7A89F48E5D741A4264756E2164756E21
270
341
  //# sourceMappingURL=playwright.js.map
@@ -2,10 +2,10 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/web/playwright.ts", "../src/web/transport.ts"],
4
4
  "sourcesContent": [
5
- "import { chromium, type Browser } from \"playwright-core\";\nimport {\n fetchPublicWebResource,\n validatePublicWebUrl,\n WebReadError,\n} from \"./transport\";\nimport type { WebRenderer } from \"./index\";\n/** Fresh contexts share a browser, never cookies; all HTTP traffic uses pinned public DNS. */\nexport const createPlaywrightWebRenderer = (\n options: { executablePath?: string } = {},\n) => {\n let browser: Browser | undefined;\n let launching: Promise<Browser> | undefined;\n const launch = async () => {\n if (browser?.isConnected()) return browser;\n launching ??= chromium.launch({\n headless: true,\n executablePath: options.executablePath,\n args: [\"--disable-dev-shm-usage\"],\n });\n try {\n browser = await launching;\n return browser;\n } finally {\n launching = undefined;\n }\n };\n const renderOnce: WebRenderer = async (url, { signal }) => {\n validatePublicWebUrl(url);\n signal.throwIfAborted();\n const instance = await launch();\n const context = await instance.newContext({\n serviceWorkers: \"block\",\n acceptDownloads: false,\n });\n const abort = () => {\n void context.close().catch(() => {});\n };\n signal.addEventListener(\"abort\", abort, { once: true });\n let count = 0,\n bytes = 0;\n try {\n await context.routeWebSocket(\"**/*\", (socket) => socket.close());\n await context.route(\"**/*\", async (route) => {\n const request = route.request();\n try {\n if (\n ++count > 80 ||\n bytes > 20_000_000 ||\n [\"image\", \"media\", \"font\"].includes(request.resourceType())\n )\n return await route.abort();\n const body = request.postData() ?? undefined;\n if (body && body.length > 100_000) return await route.abort();\n const original = request.headers();\n const headers: Record<string, string> = {};\n for (const key of [\"accept\", \"content-type\", \"origin\", \"user-agent\"])\n if (original[key]) headers[key] = original[key];\n const response = await fetchPublicWebResource(request.url(), {\n signal,\n maxBytes: 5_000_000,\n method: request.method(),\n body,\n headers,\n redirect: \"manual\",\n });\n bytes += response.body.byteLength;\n await route.fulfill({\n status: response.status,\n headers: response.headers,\n body: Buffer.from(response.body),\n });\n } catch {\n await route.abort().catch(() => {});\n }\n });\n const page = await context.newPage();\n const response = await page.goto(url, {\n waitUntil: \"domcontentloaded\",\n timeout: 25000,\n });\n await page\n .waitForFunction(\n () => {\n const root = document.querySelector(\n \"#root,#app,#__next,app-root,[ng-version]\",\n );\n const rootText = root?.textContent?.trim() ?? \"\";\n return (\n document.body.innerText.trim().length > 100 &&\n (!root ||\n (rootText.length > 20 &&\n !/^(loading|please wait)/i.test(rootText)))\n );\n },\n undefined,\n { timeout: 8000 },\n )\n .catch(() => {});\n // Allow hydration and async content to settle after the first readable frame.\n await page.waitForTimeout(1200);\n signal.throwIfAborted();\n const html = await page.content();\n if (html.length > 5_000_000)\n throw new WebReadError(\n \"too_large\",\n \"Rendered page exceeded the content limit.\",\n );\n return {\n html,\n text: await page.locator(\"body\").innerText(),\n url: page.url(),\n status: response?.status() ?? 200,\n };\n } finally {\n signal.removeEventListener(\"abort\", abort);\n await context.close().catch(() => {});\n }\n };\n const render: WebRenderer = async (url, options) => {\n try {\n return await renderOnce(url, options);\n } catch (error) {\n if (options.signal.aborted || browser?.isConnected()) throw error;\n // A crashed worker may be replaced once; the same total deadline still applies.\n return renderOnce(url, options);\n }\n };\n return {\n render,\n ready: async () => {\n await launch();\n },\n close: async () => {\n await browser?.close();\n browser = undefined;\n },\n };\n};\n",
6
- "import { lookup } from \"node:dns/promises\";\nimport { isIP } from \"node:net\";\nimport { request as httpRequest } from \"node:http\";\nimport { request as httpsRequest } from \"node:https\";\nimport { brotliDecompressSync, gunzipSync, inflateSync } from \"node:zlib\";\n\nexport class WebReadError extends Error {\n constructor(\n public code: string,\n message: string,\n ) {\n super(message);\n this.name = \"WebReadError\";\n }\n}\nexport const isPublicWebAddress = (address: string) => {\n if (isIP(address) === 4) {\n const [a = 0, b = 0, c = 0] = address.split(\".\").map(Number);\n return !(\n a === 0 ||\n a === 10 ||\n a === 127 ||\n a >= 224 ||\n (a === 100 && b >= 64 && b <= 127) ||\n (a === 169 && b === 254) ||\n (a === 172 && b >= 16 && b <= 31) ||\n (a === 192 && (b === 168 || b === 0 || (b === 88 && c === 99))) ||\n (a === 198 && (b === 18 || b === 19 || (b === 51 && c === 100))) ||\n (a === 203 && b === 0 && c === 113)\n );\n }\n const value = address.toLowerCase();\n return (\n isIP(value) === 6 &&\n /^[23]/u.test(value) &&\n !/^2001:(?:db8|0):/u.test(value) &&\n !value.startsWith(\"2002:\")\n );\n};\nexport type WebFetchResult = {\n url: string;\n status: number;\n headers: Record<string, string>;\n body: Uint8Array;\n};\nexport type WebFetchOptions = {\n signal?: AbortSignal;\n redirect?: \"follow\" | \"manual\";\n maxBytes?: number;\n method?: string;\n body?: string;\n headers?: Record<string, string>;\n};\nexport const validatePublicWebUrl = (raw: string) => {\n let url: URL;\n try {\n url = new URL(raw);\n } catch {\n throw new WebReadError(\n \"invalid_url\",\n \"Provide a valid public HTTP or HTTPS URL.\",\n );\n }\n if (\n ![\"http:\", \"https:\"].includes(url.protocol) ||\n url.username ||\n url.password ||\n (url.port && ![\"80\", \"443\"].includes(url.port))\n )\n throw new WebReadError(\n \"blocked_url\",\n \"Only public HTTP/HTTPS URLs on standard ports are supported.\",\n );\n const host = url.hostname.replace(/^\\[|\\]$/gu, \"\").toLowerCase();\n if (\n host === \"localhost\" ||\n /\\.(?:localhost|local|internal)$/u.test(host) ||\n (isIP(host) && !isPublicWebAddress(host))\n )\n throw new WebReadError(\n \"blocked_url\",\n \"Private and local network destinations are not allowed.\",\n );\n return url;\n};\n/** Pin the validated DNS answer into the connection, including every redirect. */\nexport const fetchPublicWebResource = async (\n raw: string,\n options: WebFetchOptions = {},\n): Promise<WebFetchResult> => {\n const signal = options.signal ?? AbortSignal.timeout(15000);\n const maxBytes = options.maxBytes ?? 5_000_000;\n let url = validatePublicWebUrl(raw);\n let method = options.method ?? \"GET\";\n let body = options.body;\n for (let hop = 0; hop <= 5; hop++) {\n signal.throwIfAborted();\n const host = url.hostname.replace(/^\\[|\\]$/gu, \"\");\n const addresses = await lookup(host, { all: true });\n if (\n !addresses.length ||\n addresses.some(({ address }) => !isPublicWebAddress(address))\n )\n throw new WebReadError(\n \"blocked_url\",\n \"The destination resolved to a private or reserved network.\",\n );\n signal.throwIfAborted();\n const selected =\n addresses.find(({ family }) => family === 4) ?? addresses[0]!;\n const response = await new Promise<WebFetchResult>((resolve, reject) => {\n const request = url.protocol === \"https:\" ? httpsRequest : httpRequest;\n const req = request(\n {\n protocol: url.protocol,\n hostname: selected.address,\n family: selected.family,\n servername: isIP(host) ? undefined : host,\n port: url.port || undefined,\n path: url.pathname + url.search,\n method,\n signal,\n agent: false,\n headers: {\n \"user-agent\": \"onSparkReader/1.0 (+https://onspark.com)\",\n accept: \"*/*\",\n \"accept-encoding\": \"identity\",\n ...options.headers,\n host: url.host,\n },\n },\n (res) => {\n const chunks: Buffer[] = [];\n let bytes = 0;\n res.on(\"error\", reject);\n res.on(\"data\", (chunk: Buffer) => {\n bytes += chunk.length;\n if (bytes > maxBytes) {\n const error = new WebReadError(\n \"too_large\",\n \"The response exceeded the website read limit.\",\n );\n res.destroy(error);\n reject(error);\n } else chunks.push(chunk);\n });\n res.on(\"end\", () => {\n try {\n let data: Uint8Array = Buffer.concat(chunks);\n const encoding = res.headers[\"content-encoding\"];\n const limits = { maxOutputLength: maxBytes };\n if (encoding === \"gzip\") data = gunzipSync(data, limits);\n else if (encoding === \"br\")\n data = brotliDecompressSync(data, limits);\n else if (encoding === \"deflate\") data = inflateSync(data, limits);\n const headers = Object.fromEntries(\n Object.entries(res.headers)\n .filter(\n ([key]) =>\n ![\n \"content-encoding\",\n \"content-length\",\n \"transfer-encoding\",\n \"set-cookie\",\n ].includes(key),\n )\n .map(([key, value]) => [\n key,\n Array.isArray(value) ? value.join(\", \") : (value ?? \"\"),\n ]),\n );\n resolve({\n url: url.href,\n status: res.statusCode ?? 502,\n headers,\n body: data,\n });\n } catch (error) {\n reject(error);\n }\n });\n },\n );\n req.on(\"error\", reject);\n if (body) req.write(body);\n req.end();\n });\n if (options.redirect === \"manual\") return response;\n if (\n [301, 302, 303, 307, 308].includes(response.status) &&\n response.headers.location\n ) {\n url = validatePublicWebUrl(new URL(response.headers.location, url).href);\n if (\n response.status === 303 ||\n ([301, 302].includes(response.status) && method === \"POST\")\n ) {\n method = \"GET\";\n body = undefined;\n }\n continue;\n }\n return response;\n }\n throw new WebReadError(\n \"redirect_limit\",\n \"The site exceeded the redirect limit.\",\n );\n};\n"
5
+ "import { chromium, type Browser } from \"playwright-core\";\nimport {\n fetchPublicWebResource,\n validatePublicWebUrl,\n WebReadError,\n} from \"./transport\";\nimport type { WebRedirect } from \"./transport\";\nimport type { WebRenderer } from \"./index\";\n/** Fresh contexts share a browser, never cookies; all HTTP traffic uses pinned public DNS. */\nexport const createPlaywrightWebRenderer = (\n options: { executablePath?: string } = {},\n) => {\n let browser: Browser | undefined;\n let launching: Promise<Browser> | undefined;\n const launch = async () => {\n if (browser?.isConnected()) return browser;\n launching ??= chromium.launch({\n headless: true,\n executablePath: options.executablePath,\n args: [\"--disable-dev-shm-usage\"],\n });\n try {\n browser = await launching;\n return browser;\n } finally {\n launching = undefined;\n }\n };\n const renderOnce: WebRenderer = async (url, { signal }) => {\n validatePublicWebUrl(url);\n signal.throwIfAborted();\n const instance = await launch();\n const context = await instance.newContext({\n serviceWorkers: \"block\",\n acceptDownloads: false,\n });\n const abort = () => {\n void context.close().catch(() => {});\n };\n signal.addEventListener(\"abort\", abort, { once: true });\n const redirects: WebRedirect[] = [];\n let count = 0,\n bytes = 0;\n try {\n await context.routeWebSocket(\"**/*\", (socket) => socket.close());\n await context.route(\"**/*\", async (route) => {\n const request = route.request();\n try {\n if (\n ++count > 80 ||\n bytes > 20_000_000 ||\n [\"image\", \"media\", \"font\"].includes(request.resourceType())\n )\n return await route.abort();\n const body = request.postData() ?? undefined;\n if (body && body.length > 100_000) return await route.abort();\n const original = request.headers();\n const headers: Record<string, string> = {};\n for (const key of [\"accept\", \"content-type\", \"origin\", \"user-agent\"])\n if (original[key]) headers[key] = original[key];\n const response = await fetchPublicWebResource(request.url(), {\n signal,\n maxBytes: 5_000_000,\n method: request.method(),\n body,\n headers,\n redirect: \"manual\",\n });\n if (\n request.isNavigationRequest() &&\n request.frame() === context.pages()[0]?.mainFrame() &&\n [301, 302, 303, 307, 308].includes(response.status) &&\n response.headers.location\n ) {\n redirects.push({\n from: request.url(),\n to: new URL(response.headers.location, request.url()).href,\n kind: \"http\",\n status: response.status,\n });\n }\n bytes += response.body.byteLength;\n await route.fulfill({\n status: response.status,\n headers: response.headers,\n body: Buffer.from(response.body),\n });\n } catch {\n await route.abort().catch(() => {});\n }\n });\n const page = await context.newPage();\n let previousUrl = url;\n page.on(\"framenavigated\", (frame) => {\n if (frame !== page.mainFrame() || !/^https?:/u.test(frame.url()))\n return;\n const next = frame.url();\n if (next !== previousUrl && !redirects.some((hop) => hop.to === next))\n redirects.push({ from: previousUrl, to: next, kind: \"client\" });\n previousUrl = next;\n });\n const response = await page.goto(url, {\n waitUntil: \"domcontentloaded\",\n timeout: 25000,\n });\n const settled = await page\n .waitForFunction(\n () => {\n const root = document.querySelector(\n \"#root,#app,#__next,app-root,[ng-version]\",\n );\n const rootText = root?.textContent?.trim() ?? \"\";\n return (\n document.body.innerText.trim().length > 100 &&\n (!root ||\n (rootText.length > 20 &&\n !/^(loading|please wait)/i.test(rootText)))\n );\n },\n undefined,\n { timeout: 8000 },\n )\n .then(\n () => true,\n () => false,\n );\n // Allow hydration and async content to settle after the first readable frame.\n await page.waitForTimeout(1200);\n // Bounded scrolling exposes common lazy-loaded sections without clicking actions.\n for (let step = 0; step < 3; step++) {\n await page.evaluate(() => window.scrollBy(0, window.innerHeight));\n await page.waitForTimeout(350);\n }\n await page.evaluate(() => {\n document.querySelectorAll(\"details\").forEach((element) => {\n element.open = true;\n });\n window.scrollTo(0, 0);\n });\n signal.throwIfAborted();\n const html = await page.content();\n if (html.length > 5_000_000)\n throw new WebReadError(\n \"too_large\",\n \"Rendered page exceeded the content limit.\",\n );\n return {\n html,\n redirects,\n settled,\n text: await page.locator(\"body\").innerText(),\n url: page.url(),\n status: response?.status() ?? 200,\n };\n } finally {\n signal.removeEventListener(\"abort\", abort);\n await context.close().catch(() => {});\n }\n };\n const render: WebRenderer = async (url, options) => {\n try {\n return await renderOnce(url, options);\n } catch (error) {\n if (options.signal.aborted || browser?.isConnected()) throw error;\n // A crashed worker may be replaced once; the same total deadline still applies.\n return renderOnce(url, options);\n }\n };\n return {\n render,\n ready: async () => {\n await launch();\n },\n close: async () => {\n await browser?.close();\n browser = undefined;\n },\n };\n};\n",
6
+ "import { lookup } from \"node:dns/promises\";\nimport { isIP } from \"node:net\";\nimport { request as httpRequest } from \"node:http\";\nimport { request as httpsRequest } from \"node:https\";\nimport { brotliDecompressSync, gunzipSync, inflateSync } from \"node:zlib\";\n\nexport class WebReadError extends Error {\n constructor(\n public code: string,\n message: string,\n ) {\n super(message);\n this.name = \"WebReadError\";\n }\n}\nexport const isPublicWebAddress = (address: string) => {\n if (isIP(address) === 4) {\n const [a = 0, b = 0, c = 0] = address.split(\".\").map(Number);\n return !(\n a === 0 ||\n a === 10 ||\n a === 127 ||\n a >= 224 ||\n (a === 100 && b >= 64 && b <= 127) ||\n (a === 169 && b === 254) ||\n (a === 172 && b >= 16 && b <= 31) ||\n (a === 192 && (b === 168 || b === 0 || (b === 88 && c === 99))) ||\n (a === 198 && (b === 18 || b === 19 || (b === 51 && c === 100))) ||\n (a === 203 && b === 0 && c === 113)\n );\n }\n const value = address.toLowerCase();\n return (\n isIP(value) === 6 &&\n /^[23]/u.test(value) &&\n !/^2001:(?:db8|0):/u.test(value) &&\n !value.startsWith(\"2002:\")\n );\n};\nexport type WebRedirect = {\n from: string;\n to: string;\n kind: \"http\" | \"client\";\n status?: number;\n};\nexport type WebFetchResult = {\n redirects?: WebRedirect[];\n url: string;\n status: number;\n headers: Record<string, string>;\n body: Uint8Array;\n};\nexport type WebFetchOptions = {\n signal?: AbortSignal;\n redirect?: \"follow\" | \"manual\";\n maxBytes?: number;\n method?: string;\n body?: string;\n headers?: Record<string, string>;\n};\nexport const validatePublicWebUrl = (raw: string) => {\n let url: URL;\n try {\n url = new URL(raw);\n } catch {\n throw new WebReadError(\n \"invalid_url\",\n \"Provide a valid public HTTP or HTTPS URL.\",\n );\n }\n if (\n ![\"http:\", \"https:\"].includes(url.protocol) ||\n url.username ||\n url.password ||\n (url.port && ![\"80\", \"443\"].includes(url.port))\n )\n throw new WebReadError(\n \"blocked_url\",\n \"Only public HTTP/HTTPS URLs on standard ports are supported.\",\n );\n const host = url.hostname.replace(/^\\[|\\]$/gu, \"\").toLowerCase();\n if (\n host === \"localhost\" ||\n /\\.(?:localhost|local|internal)$/u.test(host) ||\n (isIP(host) && !isPublicWebAddress(host))\n )\n throw new WebReadError(\n \"blocked_url\",\n \"Private and local network destinations are not allowed.\",\n );\n return url;\n};\n/** Pin the validated DNS answer into the connection, including every redirect. */\nexport const fetchPublicWebResource = async (\n raw: string,\n options: WebFetchOptions = {},\n): Promise<WebFetchResult> => {\n const signal = options.signal ?? AbortSignal.timeout(15000);\n const maxBytes = options.maxBytes ?? 5_000_000;\n let url = validatePublicWebUrl(raw);\n const redirects: WebRedirect[] = [];\n let method = options.method ?? \"GET\";\n let body = options.body;\n for (let hop = 0; hop <= 5; hop++) {\n signal.throwIfAborted();\n const host = url.hostname.replace(/^\\[|\\]$/gu, \"\");\n const addresses = await lookup(host, { all: true });\n if (\n !addresses.length ||\n addresses.some(({ address }) => !isPublicWebAddress(address))\n )\n throw new WebReadError(\n \"blocked_url\",\n \"The destination resolved to a private or reserved network.\",\n );\n signal.throwIfAborted();\n const selected =\n addresses.find(({ family }) => family === 4) ?? addresses[0]!;\n const response = await new Promise<WebFetchResult>((resolve, reject) => {\n const request = url.protocol === \"https:\" ? httpsRequest : httpRequest;\n const req = request(\n {\n protocol: url.protocol,\n hostname: selected.address,\n family: selected.family,\n servername: isIP(host) ? undefined : host,\n port: url.port || undefined,\n path: url.pathname + url.search,\n method,\n signal,\n agent: false,\n headers: {\n \"user-agent\": \"onSparkReader/1.0 (+https://onspark.com)\",\n accept: \"*/*\",\n \"accept-encoding\": \"identity\",\n ...options.headers,\n host: url.host,\n },\n },\n (res) => {\n const chunks: Buffer[] = [];\n let bytes = 0;\n res.on(\"error\", reject);\n res.on(\"data\", (chunk: Buffer) => {\n bytes += chunk.length;\n if (bytes > maxBytes) {\n const error = new WebReadError(\n \"too_large\",\n \"The response exceeded the website read limit.\",\n );\n res.destroy(error);\n reject(error);\n } else chunks.push(chunk);\n });\n res.on(\"end\", () => {\n try {\n let data: Uint8Array = Buffer.concat(chunks);\n const encoding = res.headers[\"content-encoding\"];\n const limits = { maxOutputLength: maxBytes };\n if (encoding === \"gzip\") data = gunzipSync(data, limits);\n else if (encoding === \"br\")\n data = brotliDecompressSync(data, limits);\n else if (encoding === \"deflate\") data = inflateSync(data, limits);\n const headers = Object.fromEntries(\n Object.entries(res.headers)\n .filter(\n ([key]) =>\n ![\n \"content-encoding\",\n \"content-length\",\n \"transfer-encoding\",\n \"set-cookie\",\n ].includes(key),\n )\n .map(([key, value]) => [\n key,\n Array.isArray(value) ? value.join(\", \") : (value ?? \"\"),\n ]),\n );\n resolve({\n url: url.href,\n status: res.statusCode ?? 502,\n headers,\n body: data,\n });\n } catch (error) {\n reject(error);\n }\n });\n },\n );\n req.on(\"error\", reject);\n if (body) req.write(body);\n req.end();\n });\n if (options.redirect === \"manual\") return response;\n if (\n [301, 302, 303, 307, 308].includes(response.status) &&\n response.headers.location\n ) {\n const next = validatePublicWebUrl(\n new URL(response.headers.location, url).href,\n );\n redirects.push({\n from: url.href,\n to: next.href,\n kind: \"http\",\n status: response.status,\n });\n url = next;\n if (\n response.status === 303 ||\n ([301, 302].includes(response.status) && method === \"POST\")\n ) {\n method = \"GET\";\n body = undefined;\n }\n continue;\n }\n return { ...response, redirects };\n }\n throw new WebReadError(\n \"redirect_limit\",\n \"The site exceeded the redirect limit.\",\n );\n};\n"
7
7
  ],
8
- "mappings": "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",
9
- "debugId": "9C078CEF671DE2C764756E2164756E21",
8
+ "mappings": "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",
9
+ "debugId": "7A89F48E5D741A4264756E2164756E21",
10
10
  "names": []
11
11
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/rag",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "homepage": "https://github.com/absolutejs/rag",
5
5
  "bugs": {
6
6
  "url": "https://github.com/absolutejs/rag/issues"
@@ -76,7 +76,8 @@
76
76
  },
77
77
  "dependencies": {
78
78
  "@absolutejs/manifest": "^0.9.0",
79
- "@sinclair/typebox": "^0.34.0"
79
+ "@sinclair/typebox": "^0.34.0",
80
+ "linkedom": "0.18.13"
80
81
  },
81
82
  "peerDependencies": {
82
83
  "@angular/core": "^21.0.0",