fetch-har 11.0.0 → 11.1.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
@@ -6,7 +6,7 @@ Make a [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) reque
6
6
  [![](https://img.shields.io/npm/v/fetch-har)](https://npm.im/fetch-har)
7
7
  [![License](https://img.shields.io/npm/l/fetch-har.svg)](LICENSE)
8
8
 
9
- [![](https://d3vv6lp55qjaqc.cloudfront.net/items/1M3C3j0I0s0j3T362344/Untitled-2.png)](https://readme.io)
9
+ [![](https://raw.githubusercontent.com/readmeio/.github/main/oss-header.png)](https://readme.io)
10
10
 
11
11
  ## Features
12
12
 
package/dist/index.cjs ADDED
@@ -0,0 +1,261 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } }var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ var __async = (__this, __arguments, generator) => {
21
+ return new Promise((resolve, reject) => {
22
+ var fulfilled = (value) => {
23
+ try {
24
+ step(generator.next(value));
25
+ } catch (e) {
26
+ reject(e);
27
+ }
28
+ };
29
+ var rejected = (value) => {
30
+ try {
31
+ step(generator.throw(value));
32
+ } catch (e) {
33
+ reject(e);
34
+ }
35
+ };
36
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
37
+ step((generator = generator.apply(__this, __arguments)).next());
38
+ });
39
+ };
40
+
41
+ // src/index.ts
42
+ var _dataurls = require('@readme/data-urls');
43
+ function isBrowser() {
44
+ return typeof window !== "undefined" && typeof document !== "undefined";
45
+ }
46
+ function isBuffer(value) {
47
+ return typeof Buffer !== "undefined" && Buffer.isBuffer(value);
48
+ }
49
+ function isFile(value) {
50
+ if (value instanceof File) {
51
+ return value.constructor.name === "File";
52
+ }
53
+ return false;
54
+ }
55
+ function getFileFromSuppliedFiles(filename, files) {
56
+ if (files && filename in files) {
57
+ return files[filename];
58
+ } else if (files && decodeURIComponent(filename) in files) {
59
+ return files[decodeURIComponent(filename)];
60
+ }
61
+ return false;
62
+ }
63
+ function fetchHAR(_0) {
64
+ return __async(this, arguments, function* (har, opts = {}) {
65
+ var _a, _b, _c, _d, _e;
66
+ if (!har)
67
+ throw new Error("Missing HAR definition");
68
+ if (!har.log || !har.log.entries || !har.log.entries.length)
69
+ throw new Error("Missing log.entries array");
70
+ if (!globalThis.Blob) {
71
+ try {
72
+ const NodeBlob = (yield Promise.resolve().then(() => _interopRequireWildcard(require("buffer")))).Blob;
73
+ globalThis.Blob = NodeBlob;
74
+ } catch (e) {
75
+ throw new Error(
76
+ "The Blob API is required for this library. https://developer.mozilla.org/en-US/docs/Web/API/Blob"
77
+ );
78
+ }
79
+ }
80
+ if (!globalThis.File) {
81
+ try {
82
+ const NodeFile = (yield Promise.resolve().then(() => _interopRequireWildcard(require("buffer")))).File;
83
+ globalThis.File = NodeFile;
84
+ } catch (e) {
85
+ throw new Error(
86
+ "The File API is required for this library. https://developer.mozilla.org/en-US/docs/Web/API/File"
87
+ );
88
+ }
89
+ }
90
+ const { request } = har.log.entries[0];
91
+ const { url } = request;
92
+ let querystring = "";
93
+ let shouldSetDuplex = false;
94
+ const options = __spreadProps(__spreadValues({}, opts.init ? opts.init : {}), {
95
+ method: request.method
96
+ });
97
+ if (!options.headers) {
98
+ options.headers = new Headers();
99
+ } else if (typeof options.headers === "object" && !(options.headers instanceof Headers) && options.headers !== null) {
100
+ options.headers = new Headers(options.headers);
101
+ }
102
+ const headers = options.headers;
103
+ if ("headers" in request && request.headers.length) {
104
+ request.headers.forEach((header) => {
105
+ try {
106
+ return headers.append(header.name, header.value);
107
+ } catch (err) {
108
+ }
109
+ });
110
+ }
111
+ if ("cookies" in request && request.cookies.length) {
112
+ if (isBrowser()) {
113
+ request.cookies.forEach((cookie) => {
114
+ document.cookie = `${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`;
115
+ });
116
+ options.credentials = "include";
117
+ } else {
118
+ headers.append(
119
+ "cookie",
120
+ request.cookies.map((cookie) => `${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`).join("; ")
121
+ );
122
+ }
123
+ }
124
+ if ("postData" in request) {
125
+ if (request.postData && "params" in request.postData) {
126
+ if (!("mimeType" in request.postData)) {
127
+ request.postData.mimeType = "application/octet-stream";
128
+ }
129
+ switch (request.postData.mimeType) {
130
+ case "application/x-www-form-urlencoded":
131
+ headers.set("Content-Type", request.postData.mimeType);
132
+ const encodedParams = new URLSearchParams();
133
+ (_a = request.postData.params) == null ? void 0 : _a.forEach((param) => {
134
+ if (param.value)
135
+ encodedParams.set(param.name, param.value);
136
+ });
137
+ options.body = encodedParams.toString();
138
+ break;
139
+ case "multipart/alternative":
140
+ case "multipart/form-data":
141
+ case "multipart/mixed":
142
+ case "multipart/related":
143
+ if (headers.has("Content-Type")) {
144
+ headers.delete("Content-Type");
145
+ }
146
+ const form = new FormData();
147
+ (_b = request.postData.params) == null ? void 0 : _b.forEach((param) => {
148
+ if ("fileName" in param && param.fileName) {
149
+ if (opts.files) {
150
+ const fileContents = getFileFromSuppliedFiles(param.fileName, opts.files);
151
+ if (fileContents) {
152
+ if (isBuffer(fileContents)) {
153
+ form.append(
154
+ param.name,
155
+ new File([fileContents], param.fileName, {
156
+ type: param.contentType || void 0
157
+ }),
158
+ param.fileName
159
+ );
160
+ return;
161
+ } else if (isFile(fileContents)) {
162
+ form.append(param.name, fileContents, param.fileName);
163
+ return;
164
+ }
165
+ throw new TypeError(
166
+ "An unknown object has been supplied into the `files` config for use. We only support instances of the File API and Node Buffer objects."
167
+ );
168
+ }
169
+ }
170
+ if ("value" in param && param.value) {
171
+ let paramBlob;
172
+ const parsed = _dataurls.parse.call(void 0, param.value);
173
+ if (parsed) {
174
+ paramBlob = new Blob([param.value], { type: parsed.contentType || param.contentType || void 0 });
175
+ } else {
176
+ paramBlob = new Blob([param.value], { type: param.contentType || void 0 });
177
+ }
178
+ form.append(param.name, paramBlob, param.fileName);
179
+ return;
180
+ }
181
+ throw new Error(
182
+ "The supplied HAR has a postData parameter with `fileName`, but neither `value` content within the HAR or any file buffers were supplied with the `files` option. Since this library doesn't have access to the filesystem, it can't fetch that file."
183
+ );
184
+ }
185
+ if (param.value)
186
+ form.append(param.name, param.value);
187
+ });
188
+ options.body = form;
189
+ break;
190
+ default:
191
+ const formBody = {};
192
+ (_c = request.postData.params) == null ? void 0 : _c.map((param) => {
193
+ try {
194
+ formBody[param.name] = JSON.parse(param.value || "");
195
+ } catch (e) {
196
+ formBody[param.name] = param.value;
197
+ }
198
+ return true;
199
+ });
200
+ options.body = JSON.stringify(formBody);
201
+ }
202
+ } else if ((_e = (_d = request.postData) == null ? void 0 : _d.text) == null ? void 0 : _e.length) {
203
+ if (opts.files) {
204
+ const parsed = _dataurls.parse.call(void 0, request.postData.text);
205
+ if (parsed) {
206
+ if ((parsed == null ? void 0 : parsed.name) && parsed.name in opts.files) {
207
+ const fileContents = getFileFromSuppliedFiles(parsed.name, opts.files);
208
+ if (fileContents) {
209
+ if (isBuffer(fileContents)) {
210
+ options.body = fileContents;
211
+ } else if (isFile(fileContents)) {
212
+ if (isBrowser()) {
213
+ options.body = fileContents;
214
+ } else {
215
+ options.body = fileContents.stream();
216
+ shouldSetDuplex = true;
217
+ if (!headers.has("content-length")) {
218
+ headers.set("content-length", String(fileContents.size));
219
+ }
220
+ }
221
+ }
222
+ }
223
+ }
224
+ }
225
+ }
226
+ if (typeof options.body === "undefined") {
227
+ options.body = request.postData.text;
228
+ }
229
+ }
230
+ if (shouldSetDuplex && !isBrowser()) {
231
+ options.duplex = "half";
232
+ }
233
+ }
234
+ let requestURL = url;
235
+ if ("queryString" in request && request.queryString.length) {
236
+ const urlObj = new URL(requestURL);
237
+ const queryParams = Array.from(urlObj.searchParams).map(([k, v]) => `${k}=${v}`);
238
+ request.queryString.forEach((q) => {
239
+ queryParams.push(`${q.name}=${q.value}`);
240
+ });
241
+ querystring = queryParams.join("&");
242
+ if (urlObj.hash) {
243
+ const urlWithoutHashes = requestURL.replace(urlObj.hash, "");
244
+ requestURL = `${urlWithoutHashes.split("?")[0]}${querystring ? `?${querystring}` : ""}`;
245
+ requestURL += urlObj.hash;
246
+ } else {
247
+ requestURL = `${requestURL.split("?")[0]}${querystring ? `?${querystring}` : ""}`;
248
+ }
249
+ }
250
+ if (opts.userAgent) {
251
+ headers.append("User-Agent", opts.userAgent);
252
+ }
253
+ options.headers = headers;
254
+ return fetch(requestURL, options);
255
+ });
256
+ }
257
+
258
+
259
+ exports.default = fetchHAR;
260
+
261
+ module.exports = exports.default//# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { FetchHAROptions, RequestInitWithDuplex } from './types.js';\nimport type { DataURL as npmDataURL } from '@readme/data-urls';\nimport type { Har } from 'har-format';\n\nimport { parse as parseDataUrl } from '@readme/data-urls';\n\ntype DataURL = npmDataURL & {\n // `parse-data-url` doesn't explicitly support `name` in data URLs but if it's there it'll be\n // returned back to us.\n name?: string;\n};\n\nfunction isBrowser() {\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n\nfunction isBuffer(value: any) {\n return typeof Buffer !== 'undefined' && Buffer.isBuffer(value);\n}\n\nfunction isFile(value: any) {\n if (value instanceof File) {\n /**\n * The `Blob` polyfill on Node comes back as being an instanceof `File`. Because passing a Blob\n * into a File will end up with a corrupted file we want to prevent this.\n *\n * This object identity crisis does not happen in the browser.\n */\n return value.constructor.name === 'File';\n }\n\n return false;\n}\n\nfunction getFileFromSuppliedFiles(filename: string, files: FetchHAROptions['files']) {\n if (files && filename in files) {\n return files[filename];\n } else if (files && decodeURIComponent(filename) in files) {\n return files[decodeURIComponent(filename)];\n }\n\n return false;\n}\n\nexport default async function fetchHAR(har: Har, opts: FetchHAROptions = {}): Promise<Response> {\n if (!har) throw new Error('Missing HAR definition');\n if (!har.log || !har.log.entries || !har.log.entries.length) throw new Error('Missing log.entries array');\n\n if (!globalThis.Blob) {\n try {\n const NodeBlob = (await import('node:buffer')).Blob;\n // @ts-expect-error the types don't match exactly, which is expected!\n globalThis.Blob = NodeBlob;\n } catch (e) {\n throw new Error(\n 'The Blob API is required for this library. https://developer.mozilla.org/en-US/docs/Web/API/Blob',\n );\n }\n }\n\n if (!globalThis.File) {\n try {\n const NodeFile = (await import('node:buffer')).File;\n // @ts-expect-error the types don't match exactly, which is expected!\n globalThis.File = NodeFile;\n } catch (e) {\n throw new Error(\n 'The File API is required for this library. https://developer.mozilla.org/en-US/docs/Web/API/File',\n );\n }\n }\n\n const { request } = har.log.entries[0];\n const { url } = request;\n let querystring = '';\n let shouldSetDuplex = false;\n\n const options: RequestInitWithDuplex = {\n // If we have custom options for the `Request` API we need to add them in here now before we\n // fill it in with everything we need from the HAR.\n ...(opts.init ? opts.init : {}),\n method: request.method,\n };\n\n if (!options.headers) {\n options.headers = new Headers();\n } else if (typeof options.headers === 'object' && !(options.headers instanceof Headers) && options.headers !== null) {\n options.headers = new Headers(options.headers);\n }\n\n const headers = options.headers as Headers;\n if ('headers' in request && request.headers.length) {\n // eslint-disable-next-line consistent-return\n request.headers.forEach(header => {\n try {\n return headers.append(header.name, header.value);\n } catch (err) {\n /**\n * `Headers.append()` will throw errors if the header name is not a legal HTTP header name,\n * like `X-API-KEY (Header)`. If that happens instead of tossing the error back out, we\n * should silently just ignore\n * it.\n */\n }\n });\n }\n\n if ('cookies' in request && request.cookies.length) {\n /**\n * As the browser fetch API can't set custom cookies for requests, they instead need to be\n * defined on the document and passed into the request via `credentials: include`. Since this\n * is a browser-specific quirk, that should only\n * happen in browsers!\n */\n if (isBrowser()) {\n request.cookies.forEach(cookie => {\n document.cookie = `${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`;\n });\n\n options.credentials = 'include';\n } else {\n headers.append(\n 'cookie',\n request.cookies\n .map(cookie => `${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`)\n .join('; '),\n );\n }\n }\n\n if ('postData' in request) {\n if (request.postData && 'params' in request.postData) {\n if (!('mimeType' in request.postData)) {\n // @ts-expect-error HAR spec requires that `mimeType` is always present but it might not be.\n request.postData.mimeType = 'application/octet-stream';\n }\n\n switch (request.postData.mimeType) {\n case 'application/x-www-form-urlencoded':\n /**\n * Since the content we're handling here is to be encoded as\n * `application/x-www-form-urlencoded`, this should override any other `Content-Type`\n * headers that are present in the HAR. This is how Postman handles this case when\n * building code snippets!\n *\n * @see {@link https://github.com/github/fetch/issues/263#issuecomment-209530977}\n */\n headers.set('Content-Type', request.postData.mimeType);\n\n const encodedParams = new URLSearchParams();\n request.postData.params?.forEach(param => {\n if (param.value) encodedParams.set(param.name, param.value);\n });\n\n options.body = encodedParams.toString();\n break;\n\n case 'multipart/alternative':\n case 'multipart/form-data':\n case 'multipart/mixed':\n case 'multipart/related':\n /**\n * If there's a `Content-Type` header set we need to remove it. We're doing this because\n * when we pass the form data object into `fetch` that'll set a proper `Content-Type`\n * header for this request that also includes the boundary used on the content.\n *\n * If we don't do this, then consumers won't be able to parse out the payload because\n * they won't know what the boundary to split on it.\n */\n if (headers.has('Content-Type')) {\n headers.delete('Content-Type');\n }\n\n const form = new FormData();\n\n request.postData.params?.forEach(param => {\n if ('fileName' in param && param.fileName) {\n if (opts.files) {\n const fileContents = getFileFromSuppliedFiles(param.fileName, opts.files);\n if (fileContents) {\n // If the file we've got available to us is a Buffer then we need to convert it so\n // that the FormData API can use it.\n if (isBuffer(fileContents)) {\n form.append(\n param.name,\n new File([fileContents], param.fileName, {\n type: param.contentType || undefined,\n }),\n param.fileName,\n );\n\n return;\n } else if (isFile(fileContents)) {\n form.append(param.name, fileContents as Blob, param.fileName);\n return;\n }\n\n throw new TypeError(\n 'An unknown object has been supplied into the `files` config for use. We only support instances of the File API and Node Buffer objects.',\n );\n }\n }\n\n if ('value' in param && param.value) {\n let paramBlob;\n const parsed = parseDataUrl(param.value);\n if (parsed) {\n // If we were able to parse out this data URL we don't need to transform its data\n // into a buffer for `Blob` because that supports data URLs already.\n paramBlob = new Blob([param.value], { type: parsed.contentType || param.contentType || undefined });\n } else {\n paramBlob = new Blob([param.value], { type: param.contentType || undefined });\n }\n\n form.append(param.name, paramBlob, param.fileName);\n return;\n }\n\n throw new Error(\n \"The supplied HAR has a postData parameter with `fileName`, but neither `value` content within the HAR or any file buffers were supplied with the `files` option. Since this library doesn't have access to the filesystem, it can't fetch that file.\",\n );\n }\n\n if (param.value) form.append(param.name, param.value);\n });\n\n options.body = form;\n break;\n\n default:\n const formBody: Record<string, unknown> = {};\n request.postData.params?.map(param => {\n try {\n formBody[param.name] = JSON.parse(param.value || '');\n } catch (e) {\n formBody[param.name] = param.value;\n }\n\n return true;\n });\n\n options.body = JSON.stringify(formBody);\n }\n } else if (request.postData?.text?.length) {\n // If we've got `files` map content present, and this post data content contains a valid data\n // URL then we can substitute the payload with that file instead of the using data URL.\n if (opts.files) {\n const parsed = parseDataUrl(request.postData.text) as DataURL;\n if (parsed) {\n if (parsed?.name && parsed.name in opts.files) {\n const fileContents = getFileFromSuppliedFiles(parsed.name, opts.files);\n if (fileContents) {\n if (isBuffer(fileContents)) {\n options.body = fileContents;\n } else if (isFile(fileContents)) {\n // `Readable.from` isn't available in browsers but the browser `Request` object can\n // handle `File` objects just fine without us having to mold it into shape.\n if (isBrowser()) {\n options.body = fileContents;\n } else {\n options.body = (fileContents as File).stream();\n shouldSetDuplex = true;\n\n // Supplying a polyfilled `File` stream into `Request.body` doesn't automatically\n // add `Content-Length`.\n if (!headers.has('content-length')) {\n headers.set('content-length', String((fileContents as File).size));\n }\n }\n }\n }\n }\n }\n }\n\n if (typeof options.body === 'undefined') {\n options.body = request.postData.text;\n }\n }\n\n /**\n * The fetch spec, which Node 18+ strictly abides by, now requires that `duplex` be sent with\n * requests that have payloads.\n *\n * As `RequestInit#duplex` isn't supported by any browsers, or even mentioned on MDN, we aren't\n * sending it in browser environments. This work is purely to support Node 18+ and `undici`\n * environments.\n *\n * @see {@link https://github.com/nodejs/node/issues/46221}\n * @see {@link https://github.com/whatwg/fetch/pull/1457}\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Request/Request}\n */\n if (shouldSetDuplex && !isBrowser()) {\n options.duplex = 'half';\n }\n }\n\n // We automaticaly assume that the HAR that we have already has query parameters encoded within\n // it so we do **not** use the `URLSearchParams` API here for composing the query string.\n let requestURL = url;\n if ('queryString' in request && request.queryString.length) {\n const urlObj = new URL(requestURL);\n\n const queryParams = Array.from(urlObj.searchParams).map(([k, v]) => `${k}=${v}`);\n request.queryString.forEach(q => {\n queryParams.push(`${q.name}=${q.value}`);\n });\n\n querystring = queryParams.join('&');\n\n // Because anchor hashes before query strings will prevent query strings from being delivered\n // we need to pop them off and re-add them after.\n if (urlObj.hash) {\n const urlWithoutHashes = requestURL.replace(urlObj.hash, '');\n requestURL = `${urlWithoutHashes.split('?')[0]}${querystring ? `?${querystring}` : ''}`;\n requestURL += urlObj.hash;\n } else {\n requestURL = `${requestURL.split('?')[0]}${querystring ? `?${querystring}` : ''}`;\n }\n }\n\n if (opts.userAgent) {\n headers.append('User-Agent', opts.userAgent);\n }\n\n options.headers = headers;\n\n return fetch(requestURL, options);\n}\n"]}
@@ -1,6 +1,6 @@
1
- import { FetchHAROptions } from './types.mjs';
1
+ import { FetchHAROptions } from './types.cjs';
2
2
  import { Har } from 'har-format';
3
3
 
4
4
  declare function fetchHAR(har: Har, opts?: FetchHAROptions): Promise<Response>;
5
5
 
6
- export { fetchHAR as default };
6
+ export = fetchHAR;
package/dist/index.d.ts CHANGED
@@ -3,4 +3,4 @@ import { Har } from 'har-format';
3
3
 
4
4
  declare function fetchHAR(har: Har, opts?: FetchHAROptions): Promise<Response>;
5
5
 
6
- export = fetchHAR;
6
+ export { fetchHAR as default };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});var __defProp = Object.defineProperty;
1
+ var __defProp = Object.defineProperty;
2
2
  var __defProps = Object.defineProperties;
3
3
  var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
4
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
@@ -17,30 +17,29 @@ var __spreadValues = (a, b) => {
17
17
  return a;
18
18
  };
19
19
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
21
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
22
- }) : x)(function(x) {
23
- if (typeof require !== "undefined")
24
- return require.apply(this, arguments);
25
- throw Error('Dynamic require of "' + x + '" is not supported');
26
- });
20
+ var __async = (__this, __arguments, generator) => {
21
+ return new Promise((resolve, reject) => {
22
+ var fulfilled = (value) => {
23
+ try {
24
+ step(generator.next(value));
25
+ } catch (e) {
26
+ reject(e);
27
+ }
28
+ };
29
+ var rejected = (value) => {
30
+ try {
31
+ step(generator.throw(value));
32
+ } catch (e) {
33
+ reject(e);
34
+ }
35
+ };
36
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
37
+ step((generator = generator.apply(__this, __arguments)).next());
38
+ });
39
+ };
27
40
 
28
41
  // src/index.ts
29
- var _dataurls = require('@readme/data-urls');
30
- if (!globalThis.Blob) {
31
- try {
32
- globalThis.Blob = __require("buffer").Blob;
33
- } catch (e) {
34
- throw new Error("The Blob API is required for this library. https://developer.mozilla.org/en-US/docs/Web/API/Blob");
35
- }
36
- }
37
- if (!globalThis.File) {
38
- try {
39
- globalThis.File = __require("undici").File;
40
- } catch (e) {
41
- throw new Error("The File API is required for this library. https://developer.mozilla.org/en-US/docs/Web/API/File");
42
- }
43
- }
42
+ import { parse as parseDataUrl } from "@readme/data-urls";
44
43
  function isBrowser() {
45
44
  return typeof window !== "undefined" && typeof document !== "undefined";
46
45
  }
@@ -61,180 +60,201 @@ function getFileFromSuppliedFiles(filename, files) {
61
60
  }
62
61
  return false;
63
62
  }
64
- function fetchHAR(har, opts = {}) {
65
- var _a, _b, _c, _d, _e;
66
- if (!har)
67
- throw new Error("Missing HAR definition");
68
- if (!har.log || !har.log.entries || !har.log.entries.length)
69
- throw new Error("Missing log.entries array");
70
- const { request } = har.log.entries[0];
71
- const { url } = request;
72
- let querystring = "";
73
- let shouldSetDuplex = false;
74
- const options = __spreadProps(__spreadValues({}, opts.init ? opts.init : {}), {
75
- method: request.method
76
- });
77
- if (!options.headers) {
78
- options.headers = new Headers();
79
- } else if (typeof options.headers === "object" && !(options.headers instanceof Headers) && options.headers !== null) {
80
- options.headers = new Headers(options.headers);
81
- }
82
- const headers = options.headers;
83
- if ("headers" in request && request.headers.length) {
84
- request.headers.forEach((header) => {
63
+ function fetchHAR(_0) {
64
+ return __async(this, arguments, function* (har, opts = {}) {
65
+ var _a, _b, _c, _d, _e;
66
+ if (!har)
67
+ throw new Error("Missing HAR definition");
68
+ if (!har.log || !har.log.entries || !har.log.entries.length)
69
+ throw new Error("Missing log.entries array");
70
+ if (!globalThis.Blob) {
71
+ try {
72
+ const NodeBlob = (yield import("buffer")).Blob;
73
+ globalThis.Blob = NodeBlob;
74
+ } catch (e) {
75
+ throw new Error(
76
+ "The Blob API is required for this library. https://developer.mozilla.org/en-US/docs/Web/API/Blob"
77
+ );
78
+ }
79
+ }
80
+ if (!globalThis.File) {
85
81
  try {
86
- return headers.append(header.name, header.value);
87
- } catch (err) {
82
+ const NodeFile = (yield import("buffer")).File;
83
+ globalThis.File = NodeFile;
84
+ } catch (e) {
85
+ throw new Error(
86
+ "The File API is required for this library. https://developer.mozilla.org/en-US/docs/Web/API/File"
87
+ );
88
88
  }
89
+ }
90
+ const { request } = har.log.entries[0];
91
+ const { url } = request;
92
+ let querystring = "";
93
+ let shouldSetDuplex = false;
94
+ const options = __spreadProps(__spreadValues({}, opts.init ? opts.init : {}), {
95
+ method: request.method
89
96
  });
90
- }
91
- if ("cookies" in request && request.cookies.length) {
92
- if (isBrowser()) {
93
- request.cookies.forEach((cookie) => {
94
- document.cookie = `${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`;
97
+ if (!options.headers) {
98
+ options.headers = new Headers();
99
+ } else if (typeof options.headers === "object" && !(options.headers instanceof Headers) && options.headers !== null) {
100
+ options.headers = new Headers(options.headers);
101
+ }
102
+ const headers = options.headers;
103
+ if ("headers" in request && request.headers.length) {
104
+ request.headers.forEach((header) => {
105
+ try {
106
+ return headers.append(header.name, header.value);
107
+ } catch (err) {
108
+ }
95
109
  });
96
- options.credentials = "include";
97
- } else {
98
- headers.append(
99
- "cookie",
100
- request.cookies.map((cookie) => `${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`).join("; ")
101
- );
102
110
  }
103
- }
104
- if ("postData" in request) {
105
- if (request.postData && "params" in request.postData) {
106
- if (!("mimeType" in request.postData)) {
107
- request.postData.mimeType = "application/octet-stream";
111
+ if ("cookies" in request && request.cookies.length) {
112
+ if (isBrowser()) {
113
+ request.cookies.forEach((cookie) => {
114
+ document.cookie = `${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`;
115
+ });
116
+ options.credentials = "include";
117
+ } else {
118
+ headers.append(
119
+ "cookie",
120
+ request.cookies.map((cookie) => `${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`).join("; ")
121
+ );
108
122
  }
109
- switch (request.postData.mimeType) {
110
- case "application/x-www-form-urlencoded":
111
- headers.set("Content-Type", request.postData.mimeType);
112
- const encodedParams = new URLSearchParams();
113
- (_a = request.postData.params) == null ? void 0 : _a.forEach((param) => {
114
- if (param.value)
115
- encodedParams.set(param.name, param.value);
116
- });
117
- options.body = encodedParams.toString();
118
- break;
119
- case "multipart/alternative":
120
- case "multipart/form-data":
121
- case "multipart/mixed":
122
- case "multipart/related":
123
- if (headers.has("Content-Type")) {
124
- headers.delete("Content-Type");
125
- }
126
- const form = new FormData();
127
- (_b = request.postData.params) == null ? void 0 : _b.forEach((param) => {
128
- if ("fileName" in param && param.fileName) {
129
- if (opts.files) {
130
- const fileContents = getFileFromSuppliedFiles(param.fileName, opts.files);
131
- if (fileContents) {
132
- if (isBuffer(fileContents)) {
133
- form.append(
134
- param.name,
135
- new File([fileContents], param.fileName, {
136
- type: param.contentType || void 0
137
- }),
138
- param.fileName
123
+ }
124
+ if ("postData" in request) {
125
+ if (request.postData && "params" in request.postData) {
126
+ if (!("mimeType" in request.postData)) {
127
+ request.postData.mimeType = "application/octet-stream";
128
+ }
129
+ switch (request.postData.mimeType) {
130
+ case "application/x-www-form-urlencoded":
131
+ headers.set("Content-Type", request.postData.mimeType);
132
+ const encodedParams = new URLSearchParams();
133
+ (_a = request.postData.params) == null ? void 0 : _a.forEach((param) => {
134
+ if (param.value)
135
+ encodedParams.set(param.name, param.value);
136
+ });
137
+ options.body = encodedParams.toString();
138
+ break;
139
+ case "multipart/alternative":
140
+ case "multipart/form-data":
141
+ case "multipart/mixed":
142
+ case "multipart/related":
143
+ if (headers.has("Content-Type")) {
144
+ headers.delete("Content-Type");
145
+ }
146
+ const form = new FormData();
147
+ (_b = request.postData.params) == null ? void 0 : _b.forEach((param) => {
148
+ if ("fileName" in param && param.fileName) {
149
+ if (opts.files) {
150
+ const fileContents = getFileFromSuppliedFiles(param.fileName, opts.files);
151
+ if (fileContents) {
152
+ if (isBuffer(fileContents)) {
153
+ form.append(
154
+ param.name,
155
+ new File([fileContents], param.fileName, {
156
+ type: param.contentType || void 0
157
+ }),
158
+ param.fileName
159
+ );
160
+ return;
161
+ } else if (isFile(fileContents)) {
162
+ form.append(param.name, fileContents, param.fileName);
163
+ return;
164
+ }
165
+ throw new TypeError(
166
+ "An unknown object has been supplied into the `files` config for use. We only support instances of the File API and Node Buffer objects."
139
167
  );
140
- return;
141
- } else if (isFile(fileContents)) {
142
- form.append(param.name, fileContents, param.fileName);
143
- return;
144
168
  }
145
- throw new TypeError(
146
- "An unknown object has been supplied into the `files` config for use. We only support instances of the File API and Node Buffer objects."
147
- );
148
169
  }
149
- }
150
- if ("value" in param && param.value) {
151
- let paramBlob;
152
- const parsed = _dataurls.parse.call(void 0, param.value);
153
- if (parsed) {
154
- paramBlob = new Blob([param.value], { type: parsed.contentType || param.contentType || void 0 });
155
- } else {
156
- paramBlob = new Blob([param.value], { type: param.contentType || void 0 });
170
+ if ("value" in param && param.value) {
171
+ let paramBlob;
172
+ const parsed = parseDataUrl(param.value);
173
+ if (parsed) {
174
+ paramBlob = new Blob([param.value], { type: parsed.contentType || param.contentType || void 0 });
175
+ } else {
176
+ paramBlob = new Blob([param.value], { type: param.contentType || void 0 });
177
+ }
178
+ form.append(param.name, paramBlob, param.fileName);
179
+ return;
157
180
  }
158
- form.append(param.name, paramBlob, param.fileName);
159
- return;
181
+ throw new Error(
182
+ "The supplied HAR has a postData parameter with `fileName`, but neither `value` content within the HAR or any file buffers were supplied with the `files` option. Since this library doesn't have access to the filesystem, it can't fetch that file."
183
+ );
160
184
  }
161
- throw new Error(
162
- "The supplied HAR has a postData parameter with `fileName`, but neither `value` content within the HAR or any file buffers were supplied with the `files` option. Since this library doesn't have access to the filesystem, it can't fetch that file."
163
- );
164
- }
165
- if (param.value)
166
- form.append(param.name, param.value);
167
- });
168
- options.body = form;
169
- break;
170
- default:
171
- const formBody = {};
172
- (_c = request.postData.params) == null ? void 0 : _c.map((param) => {
173
- try {
174
- formBody[param.name] = JSON.parse(param.value || "");
175
- } catch (e) {
176
- formBody[param.name] = param.value;
177
- }
178
- return true;
179
- });
180
- options.body = JSON.stringify(formBody);
181
- }
182
- } else if ((_e = (_d = request.postData) == null ? void 0 : _d.text) == null ? void 0 : _e.length) {
183
- if (opts.files) {
184
- const parsed = _dataurls.parse.call(void 0, request.postData.text);
185
- if (parsed) {
186
- if ((parsed == null ? void 0 : parsed.name) && parsed.name in opts.files) {
187
- const fileContents = getFileFromSuppliedFiles(parsed.name, opts.files);
188
- if (fileContents) {
189
- if (isBuffer(fileContents)) {
190
- options.body = fileContents;
191
- } else if (isFile(fileContents)) {
192
- if (isBrowser()) {
185
+ if (param.value)
186
+ form.append(param.name, param.value);
187
+ });
188
+ options.body = form;
189
+ break;
190
+ default:
191
+ const formBody = {};
192
+ (_c = request.postData.params) == null ? void 0 : _c.map((param) => {
193
+ try {
194
+ formBody[param.name] = JSON.parse(param.value || "");
195
+ } catch (e) {
196
+ formBody[param.name] = param.value;
197
+ }
198
+ return true;
199
+ });
200
+ options.body = JSON.stringify(formBody);
201
+ }
202
+ } else if ((_e = (_d = request.postData) == null ? void 0 : _d.text) == null ? void 0 : _e.length) {
203
+ if (opts.files) {
204
+ const parsed = parseDataUrl(request.postData.text);
205
+ if (parsed) {
206
+ if ((parsed == null ? void 0 : parsed.name) && parsed.name in opts.files) {
207
+ const fileContents = getFileFromSuppliedFiles(parsed.name, opts.files);
208
+ if (fileContents) {
209
+ if (isBuffer(fileContents)) {
193
210
  options.body = fileContents;
194
- } else {
195
- options.body = fileContents.stream();
196
- shouldSetDuplex = true;
197
- if (!headers.has("content-length")) {
198
- headers.set("content-length", String(fileContents.size));
211
+ } else if (isFile(fileContents)) {
212
+ if (isBrowser()) {
213
+ options.body = fileContents;
214
+ } else {
215
+ options.body = fileContents.stream();
216
+ shouldSetDuplex = true;
217
+ if (!headers.has("content-length")) {
218
+ headers.set("content-length", String(fileContents.size));
219
+ }
199
220
  }
200
221
  }
201
222
  }
202
223
  }
203
224
  }
204
225
  }
226
+ if (typeof options.body === "undefined") {
227
+ options.body = request.postData.text;
228
+ }
205
229
  }
206
- if (typeof options.body === "undefined") {
207
- options.body = request.postData.text;
230
+ if (shouldSetDuplex && !isBrowser()) {
231
+ options.duplex = "half";
208
232
  }
209
233
  }
210
- if (shouldSetDuplex && !isBrowser()) {
211
- options.duplex = "half";
234
+ let requestURL = url;
235
+ if ("queryString" in request && request.queryString.length) {
236
+ const urlObj = new URL(requestURL);
237
+ const queryParams = Array.from(urlObj.searchParams).map(([k, v]) => `${k}=${v}`);
238
+ request.queryString.forEach((q) => {
239
+ queryParams.push(`${q.name}=${q.value}`);
240
+ });
241
+ querystring = queryParams.join("&");
242
+ if (urlObj.hash) {
243
+ const urlWithoutHashes = requestURL.replace(urlObj.hash, "");
244
+ requestURL = `${urlWithoutHashes.split("?")[0]}${querystring ? `?${querystring}` : ""}`;
245
+ requestURL += urlObj.hash;
246
+ } else {
247
+ requestURL = `${requestURL.split("?")[0]}${querystring ? `?${querystring}` : ""}`;
248
+ }
212
249
  }
213
- }
214
- let requestURL = url;
215
- if ("queryString" in request && request.queryString.length) {
216
- const urlObj = new URL(requestURL);
217
- const queryParams = Array.from(urlObj.searchParams).map(([k, v]) => `${k}=${v}`);
218
- request.queryString.forEach((q) => {
219
- queryParams.push(`${q.name}=${q.value}`);
220
- });
221
- querystring = queryParams.join("&");
222
- if (urlObj.hash) {
223
- const urlWithoutHashes = requestURL.replace(urlObj.hash, "");
224
- requestURL = `${urlWithoutHashes.split("?")[0]}${querystring ? `?${querystring}` : ""}`;
225
- requestURL += urlObj.hash;
226
- } else {
227
- requestURL = `${requestURL.split("?")[0]}${querystring ? `?${querystring}` : ""}`;
250
+ if (opts.userAgent) {
251
+ headers.append("User-Agent", opts.userAgent);
228
252
  }
229
- }
230
- if (opts.userAgent) {
231
- headers.append("User-Agent", opts.userAgent);
232
- }
233
- options.headers = headers;
234
- return fetch(requestURL, options);
253
+ options.headers = headers;
254
+ return fetch(requestURL, options);
255
+ });
235
256
  }
236
-
237
-
238
- exports.default = fetchHAR;
239
-
240
- module.exports = exports.default//# sourceMappingURL=index.js.map
257
+ export {
258
+ fetchHAR as default
259
+ };
260
+ //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { FetchHAROptions, RequestInitWithDuplex } from './types';\nimport type { DataURL as npmDataURL } from '@readme/data-urls';\nimport type { Har } from 'har-format';\n\nimport { parse as parseDataUrl } from '@readme/data-urls';\n\nif (!globalThis.Blob) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n globalThis.Blob = require('node:buffer').Blob;\n } catch (e) {\n throw new Error('The Blob API is required for this library. https://developer.mozilla.org/en-US/docs/Web/API/Blob');\n }\n}\n\nif (!globalThis.File) {\n try {\n // Node's native `fetch` implementation unfortunately does not make this API global so we need\n // to pull it in if we don't have it.\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n globalThis.File = require('undici').File;\n } catch (e) {\n throw new Error('The File API is required for this library. https://developer.mozilla.org/en-US/docs/Web/API/File');\n }\n}\n\ntype DataURL = npmDataURL & {\n // `parse-data-url` doesn't explicitly support `name` in data URLs but if it's there it'll be\n // returned back to us.\n name?: string;\n};\n\nfunction isBrowser() {\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n\nfunction isBuffer(value: any) {\n return typeof Buffer !== 'undefined' && Buffer.isBuffer(value);\n}\n\nfunction isFile(value: any) {\n if (value instanceof File) {\n /**\n * The `Blob` polyfill on Node comes back as being an instanceof `File`. Because passing a Blob\n * into a File will end up with a corrupted file we want to prevent this.\n *\n * This object identity crisis does not happen in the browser.\n */\n return value.constructor.name === 'File';\n }\n\n return false;\n}\n\nfunction getFileFromSuppliedFiles(filename: string, files: FetchHAROptions['files']) {\n if (files && filename in files) {\n return files[filename];\n } else if (files && decodeURIComponent(filename) in files) {\n return files[decodeURIComponent(filename)];\n }\n\n return false;\n}\n\nexport default function fetchHAR(har: Har, opts: FetchHAROptions = {}) {\n if (!har) throw new Error('Missing HAR definition');\n if (!har.log || !har.log.entries || !har.log.entries.length) throw new Error('Missing log.entries array');\n\n const { request } = har.log.entries[0];\n const { url } = request;\n let querystring = '';\n let shouldSetDuplex = false;\n\n const options: RequestInitWithDuplex = {\n // If we have custom options for the `Request` API we need to add them in here now before we\n // fill it in with everything we need from the HAR.\n ...(opts.init ? opts.init : {}),\n method: request.method,\n };\n\n if (!options.headers) {\n options.headers = new Headers();\n } else if (typeof options.headers === 'object' && !(options.headers instanceof Headers) && options.headers !== null) {\n options.headers = new Headers(options.headers);\n }\n\n const headers = options.headers as Headers;\n if ('headers' in request && request.headers.length) {\n // eslint-disable-next-line consistent-return\n request.headers.forEach(header => {\n try {\n return headers.append(header.name, header.value);\n } catch (err) {\n /**\n * `Headers.append()` will throw errors if the header name is not a legal HTTP header name,\n * like `X-API-KEY (Header)`. If that happens instead of tossing the error back out, we\n * should silently just ignore\n * it.\n */\n }\n });\n }\n\n if ('cookies' in request && request.cookies.length) {\n /**\n * As the browser fetch API can't set custom cookies for requests, they instead need to be\n * defined on the document and passed into the request via `credentials: include`. Since this\n * is a browser-specific quirk, that should only\n * happen in browsers!\n */\n if (isBrowser()) {\n request.cookies.forEach(cookie => {\n document.cookie = `${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`;\n });\n\n options.credentials = 'include';\n } else {\n headers.append(\n 'cookie',\n request.cookies\n .map(cookie => `${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`)\n .join('; '),\n );\n }\n }\n\n if ('postData' in request) {\n if (request.postData && 'params' in request.postData) {\n if (!('mimeType' in request.postData)) {\n // @ts-expect-error HAR spec requires that `mimeType` is always present but it might not be.\n request.postData.mimeType = 'application/octet-stream';\n }\n\n switch (request.postData.mimeType) {\n case 'application/x-www-form-urlencoded':\n /**\n * Since the content we're handling here is to be encoded as\n * `application/x-www-form-urlencoded`, this should override any other `Content-Type`\n * headers that are present in the HAR. This is how Postman handles this case when\n * building code snippets!\n *\n * @see {@link https://github.com/github/fetch/issues/263#issuecomment-209530977}\n */\n headers.set('Content-Type', request.postData.mimeType);\n\n const encodedParams = new URLSearchParams();\n request.postData.params?.forEach(param => {\n if (param.value) encodedParams.set(param.name, param.value);\n });\n\n options.body = encodedParams.toString();\n break;\n\n case 'multipart/alternative':\n case 'multipart/form-data':\n case 'multipart/mixed':\n case 'multipart/related':\n /**\n * If there's a `Content-Type` header set we need to remove it. We're doing this because\n * when we pass the form data object into `fetch` that'll set a proper `Content-Type`\n * header for this request that also includes the boundary used on the content.\n *\n * If we don't do this, then consumers won't be able to parse out the payload because\n * they won't know what the boundary to split on it.\n */\n if (headers.has('Content-Type')) {\n headers.delete('Content-Type');\n }\n\n const form = new FormData();\n\n request.postData.params?.forEach(param => {\n if ('fileName' in param && param.fileName) {\n if (opts.files) {\n const fileContents = getFileFromSuppliedFiles(param.fileName, opts.files);\n if (fileContents) {\n // If the file we've got available to us is a Buffer then we need to convert it so\n // that the FormData API can use it.\n if (isBuffer(fileContents)) {\n form.append(\n param.name,\n new File([fileContents], param.fileName, {\n type: param.contentType || undefined,\n }),\n param.fileName,\n );\n\n return;\n } else if (isFile(fileContents)) {\n form.append(param.name, fileContents as Blob, param.fileName);\n return;\n }\n\n throw new TypeError(\n 'An unknown object has been supplied into the `files` config for use. We only support instances of the File API and Node Buffer objects.',\n );\n }\n }\n\n if ('value' in param && param.value) {\n let paramBlob;\n const parsed = parseDataUrl(param.value);\n if (parsed) {\n // If we were able to parse out this data URL we don't need to transform its data\n // into a buffer for `Blob` because that supports data URLs already.\n paramBlob = new Blob([param.value], { type: parsed.contentType || param.contentType || undefined });\n } else {\n paramBlob = new Blob([param.value], { type: param.contentType || undefined });\n }\n\n form.append(param.name, paramBlob, param.fileName);\n return;\n }\n\n throw new Error(\n \"The supplied HAR has a postData parameter with `fileName`, but neither `value` content within the HAR or any file buffers were supplied with the `files` option. Since this library doesn't have access to the filesystem, it can't fetch that file.\",\n );\n }\n\n if (param.value) form.append(param.name, param.value);\n });\n\n options.body = form;\n break;\n\n default:\n const formBody: Record<string, unknown> = {};\n request.postData.params?.map(param => {\n try {\n formBody[param.name] = JSON.parse(param.value || '');\n } catch (e) {\n formBody[param.name] = param.value;\n }\n\n return true;\n });\n\n options.body = JSON.stringify(formBody);\n }\n } else if (request.postData?.text?.length) {\n // If we've got `files` map content present, and this post data content contains a valid data\n // URL then we can substitute the payload with that file instead of the using data URL.\n if (opts.files) {\n const parsed = parseDataUrl(request.postData.text) as DataURL;\n if (parsed) {\n if (parsed?.name && parsed.name in opts.files) {\n const fileContents = getFileFromSuppliedFiles(parsed.name, opts.files);\n if (fileContents) {\n if (isBuffer(fileContents)) {\n options.body = fileContents;\n } else if (isFile(fileContents)) {\n // `Readable.from` isn't available in browsers but the browser `Request` object can\n // handle `File` objects just fine without us having to mold it into shape.\n if (isBrowser()) {\n options.body = fileContents;\n } else {\n options.body = (fileContents as File).stream();\n shouldSetDuplex = true;\n\n // Supplying a polyfilled `File` stream into `Request.body` doesn't automatically\n // add `Content-Length`.\n if (!headers.has('content-length')) {\n headers.set('content-length', String((fileContents as File).size));\n }\n }\n }\n }\n }\n }\n }\n\n if (typeof options.body === 'undefined') {\n options.body = request.postData.text;\n }\n }\n\n /**\n * The fetch spec, which Node 18+ strictly abides by, now requires that `duplex` be sent with\n * requests that have payloads.\n *\n * As `RequestInit#duplex` isn't supported by any browsers, or even mentioned on MDN, we aren't\n * sending it in browser environments. This work is purely to support Node 18+ and `undici`\n * environments.\n *\n * @see {@link https://github.com/nodejs/node/issues/46221}\n * @see {@link https://github.com/whatwg/fetch/pull/1457}\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Request/Request}\n */\n if (shouldSetDuplex && !isBrowser()) {\n options.duplex = 'half';\n }\n }\n\n // We automaticaly assume that the HAR that we have already has query parameters encoded within\n // it so we do **not** use the `URLSearchParams` API here for composing the query string.\n let requestURL = url;\n if ('queryString' in request && request.queryString.length) {\n const urlObj = new URL(requestURL);\n\n const queryParams = Array.from(urlObj.searchParams).map(([k, v]) => `${k}=${v}`);\n request.queryString.forEach(q => {\n queryParams.push(`${q.name}=${q.value}`);\n });\n\n querystring = queryParams.join('&');\n\n // Because anchor hashes before query strings will prevent query strings from being delivered\n // we need to pop them off and re-add them after.\n if (urlObj.hash) {\n const urlWithoutHashes = requestURL.replace(urlObj.hash, '');\n requestURL = `${urlWithoutHashes.split('?')[0]}${querystring ? `?${querystring}` : ''}`;\n requestURL += urlObj.hash;\n } else {\n requestURL = `${requestURL.split('?')[0]}${querystring ? `?${querystring}` : ''}`;\n }\n }\n\n if (opts.userAgent) {\n headers.append('User-Agent', opts.userAgent);\n }\n\n options.headers = headers;\n\n return fetch(requestURL, options);\n}\n"]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { FetchHAROptions, RequestInitWithDuplex } from './types.js';\nimport type { DataURL as npmDataURL } from '@readme/data-urls';\nimport type { Har } from 'har-format';\n\nimport { parse as parseDataUrl } from '@readme/data-urls';\n\ntype DataURL = npmDataURL & {\n // `parse-data-url` doesn't explicitly support `name` in data URLs but if it's there it'll be\n // returned back to us.\n name?: string;\n};\n\nfunction isBrowser() {\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n\nfunction isBuffer(value: any) {\n return typeof Buffer !== 'undefined' && Buffer.isBuffer(value);\n}\n\nfunction isFile(value: any) {\n if (value instanceof File) {\n /**\n * The `Blob` polyfill on Node comes back as being an instanceof `File`. Because passing a Blob\n * into a File will end up with a corrupted file we want to prevent this.\n *\n * This object identity crisis does not happen in the browser.\n */\n return value.constructor.name === 'File';\n }\n\n return false;\n}\n\nfunction getFileFromSuppliedFiles(filename: string, files: FetchHAROptions['files']) {\n if (files && filename in files) {\n return files[filename];\n } else if (files && decodeURIComponent(filename) in files) {\n return files[decodeURIComponent(filename)];\n }\n\n return false;\n}\n\nexport default async function fetchHAR(har: Har, opts: FetchHAROptions = {}): Promise<Response> {\n if (!har) throw new Error('Missing HAR definition');\n if (!har.log || !har.log.entries || !har.log.entries.length) throw new Error('Missing log.entries array');\n\n if (!globalThis.Blob) {\n try {\n const NodeBlob = (await import('node:buffer')).Blob;\n // @ts-expect-error the types don't match exactly, which is expected!\n globalThis.Blob = NodeBlob;\n } catch (e) {\n throw new Error(\n 'The Blob API is required for this library. https://developer.mozilla.org/en-US/docs/Web/API/Blob',\n );\n }\n }\n\n if (!globalThis.File) {\n try {\n const NodeFile = (await import('node:buffer')).File;\n // @ts-expect-error the types don't match exactly, which is expected!\n globalThis.File = NodeFile;\n } catch (e) {\n throw new Error(\n 'The File API is required for this library. https://developer.mozilla.org/en-US/docs/Web/API/File',\n );\n }\n }\n\n const { request } = har.log.entries[0];\n const { url } = request;\n let querystring = '';\n let shouldSetDuplex = false;\n\n const options: RequestInitWithDuplex = {\n // If we have custom options for the `Request` API we need to add them in here now before we\n // fill it in with everything we need from the HAR.\n ...(opts.init ? opts.init : {}),\n method: request.method,\n };\n\n if (!options.headers) {\n options.headers = new Headers();\n } else if (typeof options.headers === 'object' && !(options.headers instanceof Headers) && options.headers !== null) {\n options.headers = new Headers(options.headers);\n }\n\n const headers = options.headers as Headers;\n if ('headers' in request && request.headers.length) {\n // eslint-disable-next-line consistent-return\n request.headers.forEach(header => {\n try {\n return headers.append(header.name, header.value);\n } catch (err) {\n /**\n * `Headers.append()` will throw errors if the header name is not a legal HTTP header name,\n * like `X-API-KEY (Header)`. If that happens instead of tossing the error back out, we\n * should silently just ignore\n * it.\n */\n }\n });\n }\n\n if ('cookies' in request && request.cookies.length) {\n /**\n * As the browser fetch API can't set custom cookies for requests, they instead need to be\n * defined on the document and passed into the request via `credentials: include`. Since this\n * is a browser-specific quirk, that should only\n * happen in browsers!\n */\n if (isBrowser()) {\n request.cookies.forEach(cookie => {\n document.cookie = `${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`;\n });\n\n options.credentials = 'include';\n } else {\n headers.append(\n 'cookie',\n request.cookies\n .map(cookie => `${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`)\n .join('; '),\n );\n }\n }\n\n if ('postData' in request) {\n if (request.postData && 'params' in request.postData) {\n if (!('mimeType' in request.postData)) {\n // @ts-expect-error HAR spec requires that `mimeType` is always present but it might not be.\n request.postData.mimeType = 'application/octet-stream';\n }\n\n switch (request.postData.mimeType) {\n case 'application/x-www-form-urlencoded':\n /**\n * Since the content we're handling here is to be encoded as\n * `application/x-www-form-urlencoded`, this should override any other `Content-Type`\n * headers that are present in the HAR. This is how Postman handles this case when\n * building code snippets!\n *\n * @see {@link https://github.com/github/fetch/issues/263#issuecomment-209530977}\n */\n headers.set('Content-Type', request.postData.mimeType);\n\n const encodedParams = new URLSearchParams();\n request.postData.params?.forEach(param => {\n if (param.value) encodedParams.set(param.name, param.value);\n });\n\n options.body = encodedParams.toString();\n break;\n\n case 'multipart/alternative':\n case 'multipart/form-data':\n case 'multipart/mixed':\n case 'multipart/related':\n /**\n * If there's a `Content-Type` header set we need to remove it. We're doing this because\n * when we pass the form data object into `fetch` that'll set a proper `Content-Type`\n * header for this request that also includes the boundary used on the content.\n *\n * If we don't do this, then consumers won't be able to parse out the payload because\n * they won't know what the boundary to split on it.\n */\n if (headers.has('Content-Type')) {\n headers.delete('Content-Type');\n }\n\n const form = new FormData();\n\n request.postData.params?.forEach(param => {\n if ('fileName' in param && param.fileName) {\n if (opts.files) {\n const fileContents = getFileFromSuppliedFiles(param.fileName, opts.files);\n if (fileContents) {\n // If the file we've got available to us is a Buffer then we need to convert it so\n // that the FormData API can use it.\n if (isBuffer(fileContents)) {\n form.append(\n param.name,\n new File([fileContents], param.fileName, {\n type: param.contentType || undefined,\n }),\n param.fileName,\n );\n\n return;\n } else if (isFile(fileContents)) {\n form.append(param.name, fileContents as Blob, param.fileName);\n return;\n }\n\n throw new TypeError(\n 'An unknown object has been supplied into the `files` config for use. We only support instances of the File API and Node Buffer objects.',\n );\n }\n }\n\n if ('value' in param && param.value) {\n let paramBlob;\n const parsed = parseDataUrl(param.value);\n if (parsed) {\n // If we were able to parse out this data URL we don't need to transform its data\n // into a buffer for `Blob` because that supports data URLs already.\n paramBlob = new Blob([param.value], { type: parsed.contentType || param.contentType || undefined });\n } else {\n paramBlob = new Blob([param.value], { type: param.contentType || undefined });\n }\n\n form.append(param.name, paramBlob, param.fileName);\n return;\n }\n\n throw new Error(\n \"The supplied HAR has a postData parameter with `fileName`, but neither `value` content within the HAR or any file buffers were supplied with the `files` option. Since this library doesn't have access to the filesystem, it can't fetch that file.\",\n );\n }\n\n if (param.value) form.append(param.name, param.value);\n });\n\n options.body = form;\n break;\n\n default:\n const formBody: Record<string, unknown> = {};\n request.postData.params?.map(param => {\n try {\n formBody[param.name] = JSON.parse(param.value || '');\n } catch (e) {\n formBody[param.name] = param.value;\n }\n\n return true;\n });\n\n options.body = JSON.stringify(formBody);\n }\n } else if (request.postData?.text?.length) {\n // If we've got `files` map content present, and this post data content contains a valid data\n // URL then we can substitute the payload with that file instead of the using data URL.\n if (opts.files) {\n const parsed = parseDataUrl(request.postData.text) as DataURL;\n if (parsed) {\n if (parsed?.name && parsed.name in opts.files) {\n const fileContents = getFileFromSuppliedFiles(parsed.name, opts.files);\n if (fileContents) {\n if (isBuffer(fileContents)) {\n options.body = fileContents;\n } else if (isFile(fileContents)) {\n // `Readable.from` isn't available in browsers but the browser `Request` object can\n // handle `File` objects just fine without us having to mold it into shape.\n if (isBrowser()) {\n options.body = fileContents;\n } else {\n options.body = (fileContents as File).stream();\n shouldSetDuplex = true;\n\n // Supplying a polyfilled `File` stream into `Request.body` doesn't automatically\n // add `Content-Length`.\n if (!headers.has('content-length')) {\n headers.set('content-length', String((fileContents as File).size));\n }\n }\n }\n }\n }\n }\n }\n\n if (typeof options.body === 'undefined') {\n options.body = request.postData.text;\n }\n }\n\n /**\n * The fetch spec, which Node 18+ strictly abides by, now requires that `duplex` be sent with\n * requests that have payloads.\n *\n * As `RequestInit#duplex` isn't supported by any browsers, or even mentioned on MDN, we aren't\n * sending it in browser environments. This work is purely to support Node 18+ and `undici`\n * environments.\n *\n * @see {@link https://github.com/nodejs/node/issues/46221}\n * @see {@link https://github.com/whatwg/fetch/pull/1457}\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Request/Request}\n */\n if (shouldSetDuplex && !isBrowser()) {\n options.duplex = 'half';\n }\n }\n\n // We automaticaly assume that the HAR that we have already has query parameters encoded within\n // it so we do **not** use the `URLSearchParams` API here for composing the query string.\n let requestURL = url;\n if ('queryString' in request && request.queryString.length) {\n const urlObj = new URL(requestURL);\n\n const queryParams = Array.from(urlObj.searchParams).map(([k, v]) => `${k}=${v}`);\n request.queryString.forEach(q => {\n queryParams.push(`${q.name}=${q.value}`);\n });\n\n querystring = queryParams.join('&');\n\n // Because anchor hashes before query strings will prevent query strings from being delivered\n // we need to pop them off and re-add them after.\n if (urlObj.hash) {\n const urlWithoutHashes = requestURL.replace(urlObj.hash, '');\n requestURL = `${urlWithoutHashes.split('?')[0]}${querystring ? `?${querystring}` : ''}`;\n requestURL += urlObj.hash;\n } else {\n requestURL = `${requestURL.split('?')[0]}${querystring ? `?${querystring}` : ''}`;\n }\n }\n\n if (opts.userAgent) {\n headers.append('User-Agent', opts.userAgent);\n }\n\n options.headers = headers;\n\n return fetch(requestURL, options);\n}\n"],"mappings":"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","names":[]}
package/dist/types.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";//# sourceMappingURL=types.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":""}
package/dist/types.js CHANGED
@@ -1 +1 @@
1
- "use strict";//# sourceMappingURL=types.js.map
1
+ //# sourceMappingURL=types.js.map
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":""}
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/package.json CHANGED
@@ -1,24 +1,25 @@
1
1
  {
2
2
  "name": "fetch-har",
3
- "version": "11.0.0",
3
+ "version": "11.1.0",
4
4
  "description": "Make a fetch request from a HAR definition",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
7
- "module": "dist/index.mjs",
5
+ "main": "dist/index.cjs",
6
+ "types": "dist/index.d.cts",
7
+ "module": "dist/index.js",
8
+ "type": "module",
8
9
  "sideEffects": false,
9
10
  "exports": {
10
11
  ".": {
11
- "import": "./dist/index.mjs",
12
- "require": "./dist/index.js"
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
13
14
  },
14
15
  "./types": {
15
- "import": "./dist/types.mjs",
16
- "require": "./dist/types.js"
16
+ "import": "./dist/types.js",
17
+ "require": "./dist/types.cjs"
17
18
  },
18
19
  "./package.json": "./package.json"
19
20
  },
20
21
  "engines": {
21
- "node": ">=18"
22
+ "node": ">=18.13.0"
22
23
  },
23
24
  "files": [
24
25
  "dist"
@@ -37,7 +38,7 @@
37
38
  },
38
39
  "repository": {
39
40
  "type": "git",
40
- "url": "git@github.com:readmeio/fetch-har.git"
41
+ "url": "git+ssh://git@github.com/readmeio/fetch-har.git"
41
42
  },
42
43
  "license": "ISC",
43
44
  "bugs": {
@@ -46,12 +47,11 @@
46
47
  "homepage": "https://github.com/readmeio/fetch-har#readme",
47
48
  "dependencies": {
48
49
  "@readme/data-urls": "^3.0.0",
49
- "@types/har-format": "^1.2.13",
50
- "undici": "^5.25.1"
50
+ "@types/har-format": "^1.2.13"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@jsdevtools/host-environment": "^2.1.2",
54
- "@readme/eslint-config": "^13.0.1",
54
+ "@readme/eslint-config": "^13.4.0",
55
55
  "@types/express": "^4.17.17",
56
56
  "@types/multer": "^1.4.7",
57
57
  "@types/node": "^20.6.3",
@@ -62,7 +62,7 @@
62
62
  "express": "^4.18.1",
63
63
  "fetch-mock": "^9.11.0",
64
64
  "har-examples": "^3.1.1",
65
- "msw": "^1.3.1",
65
+ "msw": "^2.0.2",
66
66
  "multer": "^1.4.5-lts.1",
67
67
  "prettier": "^3.0.3",
68
68
  "temp-dir": "^3.0.0",
package/dist/index.mjs DELETED
@@ -1,239 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __defProps = Object.defineProperties;
3
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
- var __spreadValues = (a, b) => {
9
- for (var prop in b || (b = {}))
10
- if (__hasOwnProp.call(b, prop))
11
- __defNormalProp(a, prop, b[prop]);
12
- if (__getOwnPropSymbols)
13
- for (var prop of __getOwnPropSymbols(b)) {
14
- if (__propIsEnum.call(b, prop))
15
- __defNormalProp(a, prop, b[prop]);
16
- }
17
- return a;
18
- };
19
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
21
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
22
- }) : x)(function(x) {
23
- if (typeof require !== "undefined")
24
- return require.apply(this, arguments);
25
- throw Error('Dynamic require of "' + x + '" is not supported');
26
- });
27
-
28
- // src/index.ts
29
- import { parse as parseDataUrl } from "@readme/data-urls";
30
- if (!globalThis.Blob) {
31
- try {
32
- globalThis.Blob = __require("buffer").Blob;
33
- } catch (e) {
34
- throw new Error("The Blob API is required for this library. https://developer.mozilla.org/en-US/docs/Web/API/Blob");
35
- }
36
- }
37
- if (!globalThis.File) {
38
- try {
39
- globalThis.File = __require("undici").File;
40
- } catch (e) {
41
- throw new Error("The File API is required for this library. https://developer.mozilla.org/en-US/docs/Web/API/File");
42
- }
43
- }
44
- function isBrowser() {
45
- return typeof window !== "undefined" && typeof document !== "undefined";
46
- }
47
- function isBuffer(value) {
48
- return typeof Buffer !== "undefined" && Buffer.isBuffer(value);
49
- }
50
- function isFile(value) {
51
- if (value instanceof File) {
52
- return value.constructor.name === "File";
53
- }
54
- return false;
55
- }
56
- function getFileFromSuppliedFiles(filename, files) {
57
- if (files && filename in files) {
58
- return files[filename];
59
- } else if (files && decodeURIComponent(filename) in files) {
60
- return files[decodeURIComponent(filename)];
61
- }
62
- return false;
63
- }
64
- function fetchHAR(har, opts = {}) {
65
- var _a, _b, _c, _d, _e;
66
- if (!har)
67
- throw new Error("Missing HAR definition");
68
- if (!har.log || !har.log.entries || !har.log.entries.length)
69
- throw new Error("Missing log.entries array");
70
- const { request } = har.log.entries[0];
71
- const { url } = request;
72
- let querystring = "";
73
- let shouldSetDuplex = false;
74
- const options = __spreadProps(__spreadValues({}, opts.init ? opts.init : {}), {
75
- method: request.method
76
- });
77
- if (!options.headers) {
78
- options.headers = new Headers();
79
- } else if (typeof options.headers === "object" && !(options.headers instanceof Headers) && options.headers !== null) {
80
- options.headers = new Headers(options.headers);
81
- }
82
- const headers = options.headers;
83
- if ("headers" in request && request.headers.length) {
84
- request.headers.forEach((header) => {
85
- try {
86
- return headers.append(header.name, header.value);
87
- } catch (err) {
88
- }
89
- });
90
- }
91
- if ("cookies" in request && request.cookies.length) {
92
- if (isBrowser()) {
93
- request.cookies.forEach((cookie) => {
94
- document.cookie = `${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`;
95
- });
96
- options.credentials = "include";
97
- } else {
98
- headers.append(
99
- "cookie",
100
- request.cookies.map((cookie) => `${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`).join("; ")
101
- );
102
- }
103
- }
104
- if ("postData" in request) {
105
- if (request.postData && "params" in request.postData) {
106
- if (!("mimeType" in request.postData)) {
107
- request.postData.mimeType = "application/octet-stream";
108
- }
109
- switch (request.postData.mimeType) {
110
- case "application/x-www-form-urlencoded":
111
- headers.set("Content-Type", request.postData.mimeType);
112
- const encodedParams = new URLSearchParams();
113
- (_a = request.postData.params) == null ? void 0 : _a.forEach((param) => {
114
- if (param.value)
115
- encodedParams.set(param.name, param.value);
116
- });
117
- options.body = encodedParams.toString();
118
- break;
119
- case "multipart/alternative":
120
- case "multipart/form-data":
121
- case "multipart/mixed":
122
- case "multipart/related":
123
- if (headers.has("Content-Type")) {
124
- headers.delete("Content-Type");
125
- }
126
- const form = new FormData();
127
- (_b = request.postData.params) == null ? void 0 : _b.forEach((param) => {
128
- if ("fileName" in param && param.fileName) {
129
- if (opts.files) {
130
- const fileContents = getFileFromSuppliedFiles(param.fileName, opts.files);
131
- if (fileContents) {
132
- if (isBuffer(fileContents)) {
133
- form.append(
134
- param.name,
135
- new File([fileContents], param.fileName, {
136
- type: param.contentType || void 0
137
- }),
138
- param.fileName
139
- );
140
- return;
141
- } else if (isFile(fileContents)) {
142
- form.append(param.name, fileContents, param.fileName);
143
- return;
144
- }
145
- throw new TypeError(
146
- "An unknown object has been supplied into the `files` config for use. We only support instances of the File API and Node Buffer objects."
147
- );
148
- }
149
- }
150
- if ("value" in param && param.value) {
151
- let paramBlob;
152
- const parsed = parseDataUrl(param.value);
153
- if (parsed) {
154
- paramBlob = new Blob([param.value], { type: parsed.contentType || param.contentType || void 0 });
155
- } else {
156
- paramBlob = new Blob([param.value], { type: param.contentType || void 0 });
157
- }
158
- form.append(param.name, paramBlob, param.fileName);
159
- return;
160
- }
161
- throw new Error(
162
- "The supplied HAR has a postData parameter with `fileName`, but neither `value` content within the HAR or any file buffers were supplied with the `files` option. Since this library doesn't have access to the filesystem, it can't fetch that file."
163
- );
164
- }
165
- if (param.value)
166
- form.append(param.name, param.value);
167
- });
168
- options.body = form;
169
- break;
170
- default:
171
- const formBody = {};
172
- (_c = request.postData.params) == null ? void 0 : _c.map((param) => {
173
- try {
174
- formBody[param.name] = JSON.parse(param.value || "");
175
- } catch (e) {
176
- formBody[param.name] = param.value;
177
- }
178
- return true;
179
- });
180
- options.body = JSON.stringify(formBody);
181
- }
182
- } else if ((_e = (_d = request.postData) == null ? void 0 : _d.text) == null ? void 0 : _e.length) {
183
- if (opts.files) {
184
- const parsed = parseDataUrl(request.postData.text);
185
- if (parsed) {
186
- if ((parsed == null ? void 0 : parsed.name) && parsed.name in opts.files) {
187
- const fileContents = getFileFromSuppliedFiles(parsed.name, opts.files);
188
- if (fileContents) {
189
- if (isBuffer(fileContents)) {
190
- options.body = fileContents;
191
- } else if (isFile(fileContents)) {
192
- if (isBrowser()) {
193
- options.body = fileContents;
194
- } else {
195
- options.body = fileContents.stream();
196
- shouldSetDuplex = true;
197
- if (!headers.has("content-length")) {
198
- headers.set("content-length", String(fileContents.size));
199
- }
200
- }
201
- }
202
- }
203
- }
204
- }
205
- }
206
- if (typeof options.body === "undefined") {
207
- options.body = request.postData.text;
208
- }
209
- }
210
- if (shouldSetDuplex && !isBrowser()) {
211
- options.duplex = "half";
212
- }
213
- }
214
- let requestURL = url;
215
- if ("queryString" in request && request.queryString.length) {
216
- const urlObj = new URL(requestURL);
217
- const queryParams = Array.from(urlObj.searchParams).map(([k, v]) => `${k}=${v}`);
218
- request.queryString.forEach((q) => {
219
- queryParams.push(`${q.name}=${q.value}`);
220
- });
221
- querystring = queryParams.join("&");
222
- if (urlObj.hash) {
223
- const urlWithoutHashes = requestURL.replace(urlObj.hash, "");
224
- requestURL = `${urlWithoutHashes.split("?")[0]}${querystring ? `?${querystring}` : ""}`;
225
- requestURL += urlObj.hash;
226
- } else {
227
- requestURL = `${requestURL.split("?")[0]}${querystring ? `?${querystring}` : ""}`;
228
- }
229
- }
230
- if (opts.userAgent) {
231
- headers.append("User-Agent", opts.userAgent);
232
- }
233
- options.headers = headers;
234
- return fetch(requestURL, options);
235
- }
236
- export {
237
- fetchHAR as default
238
- };
239
- //# sourceMappingURL=index.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { FetchHAROptions, RequestInitWithDuplex } from './types';\nimport type { DataURL as npmDataURL } from '@readme/data-urls';\nimport type { Har } from 'har-format';\n\nimport { parse as parseDataUrl } from '@readme/data-urls';\n\nif (!globalThis.Blob) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n globalThis.Blob = require('node:buffer').Blob;\n } catch (e) {\n throw new Error('The Blob API is required for this library. https://developer.mozilla.org/en-US/docs/Web/API/Blob');\n }\n}\n\nif (!globalThis.File) {\n try {\n // Node's native `fetch` implementation unfortunately does not make this API global so we need\n // to pull it in if we don't have it.\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n globalThis.File = require('undici').File;\n } catch (e) {\n throw new Error('The File API is required for this library. https://developer.mozilla.org/en-US/docs/Web/API/File');\n }\n}\n\ntype DataURL = npmDataURL & {\n // `parse-data-url` doesn't explicitly support `name` in data URLs but if it's there it'll be\n // returned back to us.\n name?: string;\n};\n\nfunction isBrowser() {\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n\nfunction isBuffer(value: any) {\n return typeof Buffer !== 'undefined' && Buffer.isBuffer(value);\n}\n\nfunction isFile(value: any) {\n if (value instanceof File) {\n /**\n * The `Blob` polyfill on Node comes back as being an instanceof `File`. Because passing a Blob\n * into a File will end up with a corrupted file we want to prevent this.\n *\n * This object identity crisis does not happen in the browser.\n */\n return value.constructor.name === 'File';\n }\n\n return false;\n}\n\nfunction getFileFromSuppliedFiles(filename: string, files: FetchHAROptions['files']) {\n if (files && filename in files) {\n return files[filename];\n } else if (files && decodeURIComponent(filename) in files) {\n return files[decodeURIComponent(filename)];\n }\n\n return false;\n}\n\nexport default function fetchHAR(har: Har, opts: FetchHAROptions = {}) {\n if (!har) throw new Error('Missing HAR definition');\n if (!har.log || !har.log.entries || !har.log.entries.length) throw new Error('Missing log.entries array');\n\n const { request } = har.log.entries[0];\n const { url } = request;\n let querystring = '';\n let shouldSetDuplex = false;\n\n const options: RequestInitWithDuplex = {\n // If we have custom options for the `Request` API we need to add them in here now before we\n // fill it in with everything we need from the HAR.\n ...(opts.init ? opts.init : {}),\n method: request.method,\n };\n\n if (!options.headers) {\n options.headers = new Headers();\n } else if (typeof options.headers === 'object' && !(options.headers instanceof Headers) && options.headers !== null) {\n options.headers = new Headers(options.headers);\n }\n\n const headers = options.headers as Headers;\n if ('headers' in request && request.headers.length) {\n // eslint-disable-next-line consistent-return\n request.headers.forEach(header => {\n try {\n return headers.append(header.name, header.value);\n } catch (err) {\n /**\n * `Headers.append()` will throw errors if the header name is not a legal HTTP header name,\n * like `X-API-KEY (Header)`. If that happens instead of tossing the error back out, we\n * should silently just ignore\n * it.\n */\n }\n });\n }\n\n if ('cookies' in request && request.cookies.length) {\n /**\n * As the browser fetch API can't set custom cookies for requests, they instead need to be\n * defined on the document and passed into the request via `credentials: include`. Since this\n * is a browser-specific quirk, that should only\n * happen in browsers!\n */\n if (isBrowser()) {\n request.cookies.forEach(cookie => {\n document.cookie = `${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`;\n });\n\n options.credentials = 'include';\n } else {\n headers.append(\n 'cookie',\n request.cookies\n .map(cookie => `${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`)\n .join('; '),\n );\n }\n }\n\n if ('postData' in request) {\n if (request.postData && 'params' in request.postData) {\n if (!('mimeType' in request.postData)) {\n // @ts-expect-error HAR spec requires that `mimeType` is always present but it might not be.\n request.postData.mimeType = 'application/octet-stream';\n }\n\n switch (request.postData.mimeType) {\n case 'application/x-www-form-urlencoded':\n /**\n * Since the content we're handling here is to be encoded as\n * `application/x-www-form-urlencoded`, this should override any other `Content-Type`\n * headers that are present in the HAR. This is how Postman handles this case when\n * building code snippets!\n *\n * @see {@link https://github.com/github/fetch/issues/263#issuecomment-209530977}\n */\n headers.set('Content-Type', request.postData.mimeType);\n\n const encodedParams = new URLSearchParams();\n request.postData.params?.forEach(param => {\n if (param.value) encodedParams.set(param.name, param.value);\n });\n\n options.body = encodedParams.toString();\n break;\n\n case 'multipart/alternative':\n case 'multipart/form-data':\n case 'multipart/mixed':\n case 'multipart/related':\n /**\n * If there's a `Content-Type` header set we need to remove it. We're doing this because\n * when we pass the form data object into `fetch` that'll set a proper `Content-Type`\n * header for this request that also includes the boundary used on the content.\n *\n * If we don't do this, then consumers won't be able to parse out the payload because\n * they won't know what the boundary to split on it.\n */\n if (headers.has('Content-Type')) {\n headers.delete('Content-Type');\n }\n\n const form = new FormData();\n\n request.postData.params?.forEach(param => {\n if ('fileName' in param && param.fileName) {\n if (opts.files) {\n const fileContents = getFileFromSuppliedFiles(param.fileName, opts.files);\n if (fileContents) {\n // If the file we've got available to us is a Buffer then we need to convert it so\n // that the FormData API can use it.\n if (isBuffer(fileContents)) {\n form.append(\n param.name,\n new File([fileContents], param.fileName, {\n type: param.contentType || undefined,\n }),\n param.fileName,\n );\n\n return;\n } else if (isFile(fileContents)) {\n form.append(param.name, fileContents as Blob, param.fileName);\n return;\n }\n\n throw new TypeError(\n 'An unknown object has been supplied into the `files` config for use. We only support instances of the File API and Node Buffer objects.',\n );\n }\n }\n\n if ('value' in param && param.value) {\n let paramBlob;\n const parsed = parseDataUrl(param.value);\n if (parsed) {\n // If we were able to parse out this data URL we don't need to transform its data\n // into a buffer for `Blob` because that supports data URLs already.\n paramBlob = new Blob([param.value], { type: parsed.contentType || param.contentType || undefined });\n } else {\n paramBlob = new Blob([param.value], { type: param.contentType || undefined });\n }\n\n form.append(param.name, paramBlob, param.fileName);\n return;\n }\n\n throw new Error(\n \"The supplied HAR has a postData parameter with `fileName`, but neither `value` content within the HAR or any file buffers were supplied with the `files` option. Since this library doesn't have access to the filesystem, it can't fetch that file.\",\n );\n }\n\n if (param.value) form.append(param.name, param.value);\n });\n\n options.body = form;\n break;\n\n default:\n const formBody: Record<string, unknown> = {};\n request.postData.params?.map(param => {\n try {\n formBody[param.name] = JSON.parse(param.value || '');\n } catch (e) {\n formBody[param.name] = param.value;\n }\n\n return true;\n });\n\n options.body = JSON.stringify(formBody);\n }\n } else if (request.postData?.text?.length) {\n // If we've got `files` map content present, and this post data content contains a valid data\n // URL then we can substitute the payload with that file instead of the using data URL.\n if (opts.files) {\n const parsed = parseDataUrl(request.postData.text) as DataURL;\n if (parsed) {\n if (parsed?.name && parsed.name in opts.files) {\n const fileContents = getFileFromSuppliedFiles(parsed.name, opts.files);\n if (fileContents) {\n if (isBuffer(fileContents)) {\n options.body = fileContents;\n } else if (isFile(fileContents)) {\n // `Readable.from` isn't available in browsers but the browser `Request` object can\n // handle `File` objects just fine without us having to mold it into shape.\n if (isBrowser()) {\n options.body = fileContents;\n } else {\n options.body = (fileContents as File).stream();\n shouldSetDuplex = true;\n\n // Supplying a polyfilled `File` stream into `Request.body` doesn't automatically\n // add `Content-Length`.\n if (!headers.has('content-length')) {\n headers.set('content-length', String((fileContents as File).size));\n }\n }\n }\n }\n }\n }\n }\n\n if (typeof options.body === 'undefined') {\n options.body = request.postData.text;\n }\n }\n\n /**\n * The fetch spec, which Node 18+ strictly abides by, now requires that `duplex` be sent with\n * requests that have payloads.\n *\n * As `RequestInit#duplex` isn't supported by any browsers, or even mentioned on MDN, we aren't\n * sending it in browser environments. This work is purely to support Node 18+ and `undici`\n * environments.\n *\n * @see {@link https://github.com/nodejs/node/issues/46221}\n * @see {@link https://github.com/whatwg/fetch/pull/1457}\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Request/Request}\n */\n if (shouldSetDuplex && !isBrowser()) {\n options.duplex = 'half';\n }\n }\n\n // We automaticaly assume that the HAR that we have already has query parameters encoded within\n // it so we do **not** use the `URLSearchParams` API here for composing the query string.\n let requestURL = url;\n if ('queryString' in request && request.queryString.length) {\n const urlObj = new URL(requestURL);\n\n const queryParams = Array.from(urlObj.searchParams).map(([k, v]) => `${k}=${v}`);\n request.queryString.forEach(q => {\n queryParams.push(`${q.name}=${q.value}`);\n });\n\n querystring = queryParams.join('&');\n\n // Because anchor hashes before query strings will prevent query strings from being delivered\n // we need to pop them off and re-add them after.\n if (urlObj.hash) {\n const urlWithoutHashes = requestURL.replace(urlObj.hash, '');\n requestURL = `${urlWithoutHashes.split('?')[0]}${querystring ? `?${querystring}` : ''}`;\n requestURL += urlObj.hash;\n } else {\n requestURL = `${requestURL.split('?')[0]}${querystring ? `?${querystring}` : ''}`;\n }\n }\n\n if (opts.userAgent) {\n headers.append('User-Agent', opts.userAgent);\n }\n\n options.headers = headers;\n\n return fetch(requestURL, options);\n}\n"],"mappings":"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","names":[]}
package/dist/types.mjs DELETED
@@ -1 +0,0 @@
1
- //# sourceMappingURL=types.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
File without changes