@dnsid-ai/transport 0.27.0 → 0.29.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.
package/dist/index.cjs CHANGED
@@ -217,8 +217,31 @@ function createSsrfSafeFetch(config = {}, options = {}) {
217
217
  for (const item of Array.isArray(value) ? value : value === void 0 ? [] : [value]) headers.append(name, item);
218
218
  }
219
219
  const noBody = request.method === "HEAD" || [204, 205, 304].includes(response.statusCode);
220
+ let body = null;
220
221
  if (noBody) await response.body.dump();
221
- return new Response(noBody ? null : import_node_stream.Readable.toWeb(response.body), { status: response.statusCode, statusText: response.statusText, headers });
222
+ else {
223
+ const iterator = response.body[Symbol.asyncIterator]();
224
+ let canceled = false;
225
+ response.body.on("error", () => {
226
+ });
227
+ body = new ReadableStream({
228
+ async pull(controller) {
229
+ try {
230
+ const { value, done } = await iterator.next();
231
+ if (canceled) return;
232
+ if (done) controller.close();
233
+ else controller.enqueue(new Uint8Array(value));
234
+ } catch (error) {
235
+ if (!canceled) controller.error(error);
236
+ }
237
+ },
238
+ cancel() {
239
+ canceled = true;
240
+ response.body.destroy();
241
+ }
242
+ });
243
+ }
244
+ return new Response(body, { status: response.statusCode, statusText: response.statusText, headers });
222
245
  }
223
246
  return fetchWithSafeLookup(input, { ...init, redirect: "manual" });
224
247
  };
@@ -259,7 +282,9 @@ function createDnsResolverFromServer(server) {
259
282
  let hostPromise;
260
283
  return {
261
284
  async fetchTXT(name, options) {
262
- hostPromise ??= net2.isIP(parsed.host) ? Promise.resolve(parsed.host) : dnsPromises.lookup(parsed.host).then(({ address }) => address);
285
+ hostPromise ??= net2.isIP(parsed.host) ? Promise.resolve(parsed.host) : dnsPromises.lookup(parsed.host).then(({ address }) => address).catch((cause) => {
286
+ throw new import_protocol2.VerificationError("DNS server hostname lookup failed", { code: import_protocol2.VerificationCode.DNSResolution, transient: true, cause });
287
+ });
263
288
  return resolveTxtWithTtl(name, await hostPromise, port, options?.signal);
264
289
  }
265
290
  };
@@ -523,7 +548,8 @@ function fetchWithRedirects(url, opts, depth) {
523
548
  signal: opts.signal,
524
549
  rejectUnauthorized: true,
525
550
  headers: {
526
- "User-Agent": DNSID_USER_AGENT
551
+ "User-Agent": DNSID_USER_AGENT,
552
+ ...opts.revalidate ? { "Cache-Control": "no-cache" } : {}
527
553
  },
528
554
  lookup: createSsrfSafeLookup(opts.dnsServer, (opts.privateAddressHosts ?? []).map(import_protocol2.normalizePrivateAddressHost))
529
555
  };
package/dist/index.d.cts CHANGED
@@ -13,6 +13,8 @@ interface FetchResult {
13
13
  }
14
14
  /** Options controlling {@link fetchJson}. */
15
15
  interface HTTPSFetchOptions {
16
+ /** Bypass local caches and revalidate upstream evidence. */
17
+ revalidate?: boolean;
16
18
  /** Shared verification deadline/cancellation, including redirects. */
17
19
  signal?: AbortSignal;
18
20
  /** If set, the URL host (and every redirect host) must match this host exactly. */
package/dist/index.d.ts CHANGED
@@ -13,6 +13,8 @@ interface FetchResult {
13
13
  }
14
14
  /** Options controlling {@link fetchJson}. */
15
15
  interface HTTPSFetchOptions {
16
+ /** Bypass local caches and revalidate upstream evidence. */
17
+ revalidate?: boolean;
16
18
  /** Shared verification deadline/cancellation, including redirects. */
17
19
  signal?: AbortSignal;
18
20
  /** If set, the URL host (and every redirect host) must match this host exactly. */
package/dist/index.js CHANGED
@@ -175,8 +175,31 @@ function createSsrfSafeFetch(config = {}, options = {}) {
175
175
  for (const item of Array.isArray(value) ? value : value === void 0 ? [] : [value]) headers.append(name, item);
176
176
  }
177
177
  const noBody = request.method === "HEAD" || [204, 205, 304].includes(response.statusCode);
178
+ let body = null;
178
179
  if (noBody) await response.body.dump();
179
- return new Response(noBody ? null : Readable.toWeb(response.body), { status: response.statusCode, statusText: response.statusText, headers });
180
+ else {
181
+ const iterator = response.body[Symbol.asyncIterator]();
182
+ let canceled = false;
183
+ response.body.on("error", () => {
184
+ });
185
+ body = new ReadableStream({
186
+ async pull(controller) {
187
+ try {
188
+ const { value, done } = await iterator.next();
189
+ if (canceled) return;
190
+ if (done) controller.close();
191
+ else controller.enqueue(new Uint8Array(value));
192
+ } catch (error) {
193
+ if (!canceled) controller.error(error);
194
+ }
195
+ },
196
+ cancel() {
197
+ canceled = true;
198
+ response.body.destroy();
199
+ }
200
+ });
201
+ }
202
+ return new Response(body, { status: response.statusCode, statusText: response.statusText, headers });
180
203
  }
181
204
  return fetchWithSafeLookup(input, { ...init, redirect: "manual" });
182
205
  };
@@ -217,7 +240,9 @@ function createDnsResolverFromServer(server) {
217
240
  let hostPromise;
218
241
  return {
219
242
  async fetchTXT(name, options) {
220
- hostPromise ??= net2.isIP(parsed.host) ? Promise.resolve(parsed.host) : dnsPromises.lookup(parsed.host).then(({ address }) => address);
243
+ hostPromise ??= net2.isIP(parsed.host) ? Promise.resolve(parsed.host) : dnsPromises.lookup(parsed.host).then(({ address }) => address).catch((cause) => {
244
+ throw new VerificationError("DNS server hostname lookup failed", { code: VerificationCode.DNSResolution, transient: true, cause });
245
+ });
221
246
  return resolveTxtWithTtl(name, await hostPromise, port, options?.signal);
222
247
  }
223
248
  };
@@ -481,7 +506,8 @@ function fetchWithRedirects(url, opts, depth) {
481
506
  signal: opts.signal,
482
507
  rejectUnauthorized: true,
483
508
  headers: {
484
- "User-Agent": DNSID_USER_AGENT
509
+ "User-Agent": DNSID_USER_AGENT,
510
+ ...opts.revalidate ? { "Cache-Control": "no-cache" } : {}
485
511
  },
486
512
  lookup: createSsrfSafeLookup(opts.dnsServer, (opts.privateAddressHosts ?? []).map(normalizePrivateAddressHost))
487
513
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dnsid-ai/transport",
3
- "version": "0.27.0",
3
+ "version": "0.29.0",
4
4
  "description": "Node.js DNS and HTTPS transport implementations for DNSid.",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
@@ -38,7 +38,7 @@
38
38
  "typecheck": "tsc --noEmit"
39
39
  },
40
40
  "dependencies": {
41
- "@dnsid-ai/protocol": "^0.27.0",
41
+ "@dnsid-ai/protocol": "^0.29.0",
42
42
  "dns-packet": "5.6.1",
43
43
  "undici": "^8.11.0"
44
44
  },