varfetch 0.1.0 → 0.2.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/README.md CHANGED
@@ -31,6 +31,7 @@ const result = await fireRequest({ connector, request, variables: { date: '2026-
31
31
 
32
32
  - **Interpolation:** `{{name}}` in path, query values, header values, auth values and body. Missing variables become an empty string.
33
33
  - **JSON path:** `$`, `$.a.b`, `$.items[0].name`, `$['key']`. Own properties only.
34
+ - **Binary:** `responseType: "binary"` (or `"image"`) returns the raw bytes as `body` (a Buffer) and the `contentType`, with the same guard, redirect and size limits; `mappings` are not applied.
34
35
  - **Mapping:** each mapping writes a string (or JSON text for objects and arrays) to a variable; `skipIfNull` (default true) leaves unresolved paths out.
35
36
  - **SSRF guard:** every URL, redirects included, is resolved and checked. Loopback, private, link-local, CGNAT, reserved and multicast addresses are blocked unless you allow them: `network: { allow: ['10.1.0.0/16', 'anno.internal:3000'], deny: ['*.blocked.example'] }`. `deny` wins over `allow`. The check happens before the connection and does not defend against DNS rebinding.
36
37
  - **Limits:** 10 s timeout and 5 MiB response by default (`timeoutMs`, `maxBytes`), at most 5 redirects, credentials and other connector headers are not forwarded to another origin.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "varfetch",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Fire configured HTTP requests with {{variable}} interpolation, an SSRF guard and JSON path mapping of the response onto named variables.",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
package/src/fire.js CHANGED
@@ -60,10 +60,14 @@ export async function fireRequest({ connector, request, variables = {}, network
60
60
  url = next;
61
61
  }
62
62
 
63
- const text = await readLimited(response, maxBytes);
63
+ const bytes = await readLimited(response, maxBytes);
64
64
  if (!response.ok) return { ok: false, status: response.status, values: {}, error: `HTTP ${response.status}` };
65
65
 
66
66
  const contentType = response.headers.get('content-type') || '';
67
+ if (request.responseType === 'binary' || request.responseType === 'image') {
68
+ return { ok: true, status: response.status, values: {}, body: bytes, contentType };
69
+ }
70
+ const text = bytes.toString('utf8');
67
71
  const wantsJson = request.responseType === 'json' || ((request.responseType ?? 'auto') === 'auto' && /json/i.test(contentType));
68
72
  let parsed = text;
69
73
  if (wantsJson) {
@@ -83,7 +87,7 @@ export async function fireRequest({ connector, request, variables = {}, network
83
87
  async function readLimited(response, maxBytes) {
84
88
  const declared = Number(response.headers.get('content-length'));
85
89
  if (declared > maxBytes) throw new Error(`Response larger than ${maxBytes} bytes`);
86
- if (!response.body) return '';
90
+ if (!response.body) return Buffer.alloc(0);
87
91
  const reader = response.body.getReader();
88
92
  const chunks = [];
89
93
  let size = 0;
@@ -97,5 +101,5 @@ async function readLimited(response, maxBytes) {
97
101
  }
98
102
  chunks.push(value);
99
103
  }
100
- return Buffer.concat(chunks).toString('utf8');
104
+ return Buffer.concat(chunks);
101
105
  }
package/src/index.d.ts CHANGED
@@ -31,7 +31,8 @@ export interface RequestDef {
31
31
  query?: Pair[];
32
32
  bodyType?: 'none' | 'json' | 'text';
33
33
  body?: string;
34
- responseType?: 'auto' | 'json' | 'text';
34
+ /** `binary` and `image` return the raw bytes as `body` (a Buffer) and skip `mappings`. */
35
+ responseType?: 'auto' | 'json' | 'text' | 'binary' | 'image';
35
36
  mappings?: Mapping[];
36
37
  timeoutMs?: number;
37
38
  }
@@ -43,8 +44,10 @@ export interface FireResult {
43
44
  status?: number;
44
45
  /** Variable name to value; non-string values are JSON text. */
45
46
  values: Record<string, string | null>;
46
- /** Parsed JSON, or the text for a non-JSON response. */
47
+ /** Parsed JSON, the text for a non-JSON response, or a Buffer for a `binary`/`image` request. */
47
48
  body?: unknown;
49
+ /** Response content-type, set for a `binary`/`image` request. */
50
+ contentType?: string;
48
51
  error?: string;
49
52
  }
50
53