fetch-har 8.1.4 → 8.1.5
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/.vscode/settings.json +5 -0
- package/CHANGELOG.md +7 -0
- package/dist/index.d.ts +14 -1
- package/dist/index.js +31 -2
- package/package.json +6 -6
- package/src/index.ts +47 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## <small>8.1.5 (2023-01-23)</small>
|
|
2
|
+
|
|
3
|
+
* fix: support urls with hashes that also have query params (#363) ([7a51342](https://github.com/readmeio/fetch-har/commit/7a51342)), closes [#363](https://github.com/readmeio/fetch-har/issues/363)
|
|
4
|
+
* chore(deps-dev): bumping deps (#362) ([3279246](https://github.com/readmeio/fetch-har/commit/3279246)), closes [#362](https://github.com/readmeio/fetch-har/issues/362)
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
1
8
|
## <small>8.1.4 (2023-01-03)</small>
|
|
2
9
|
|
|
3
10
|
* chore(deps-dev): bump @readme/eslint-config from 10.1.0 to 10.1.1 (#331) ([75de615](https://github.com/readmeio/fetch-har/commit/75de615)), closes [#331](https://github.com/readmeio/fetch-har/issues/331)
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import type { Har } from 'har-format';
|
|
3
|
+
interface RequestInitWithDuplex extends RequestInit {
|
|
4
|
+
/**
|
|
5
|
+
* `RequestInit#duplex` does not yet exist in the TS `lib.dom.d.ts` definition yet the native
|
|
6
|
+
* fetch implementation in Node 18+, `undici`, requires it for certain POST payloads.
|
|
7
|
+
*
|
|
8
|
+
* @see {@link https://github.com/microsoft/TypeScript-DOM-lib-generator/issues/1483}
|
|
9
|
+
* @see {@link https://github.com/nodejs/node/issues/46221}
|
|
10
|
+
* @see {@link https://fetch.spec.whatwg.org/#request-class}
|
|
11
|
+
* @see {@link https://github.com/microsoft/TypeScript/blob/main/lib/lib.dom.d.ts}
|
|
12
|
+
*/
|
|
13
|
+
duplex?: 'half';
|
|
14
|
+
}
|
|
3
15
|
export interface FetchHAROptions {
|
|
4
16
|
userAgent?: string;
|
|
5
17
|
files?: Record<string, Blob | Buffer>;
|
|
6
18
|
multipartEncoder?: any;
|
|
7
|
-
init?:
|
|
19
|
+
init?: RequestInitWithDuplex;
|
|
8
20
|
}
|
|
9
21
|
export default function fetchHAR(har: Har, opts?: FetchHAROptions): Promise<Response>;
|
|
22
|
+
export {};
|
package/dist/index.js
CHANGED
|
@@ -101,6 +101,7 @@ function fetchHAR(har, opts) {
|
|
|
101
101
|
var request = har.log.entries[0].request;
|
|
102
102
|
var url = request.url;
|
|
103
103
|
var querystring = '';
|
|
104
|
+
var shouldSetDuplex = false;
|
|
104
105
|
var options = __assign(__assign({}, (opts.init ? opts.init : {})), { method: request.method });
|
|
105
106
|
if (!options.headers) {
|
|
106
107
|
options.headers = new Headers();
|
|
@@ -260,6 +261,7 @@ function fetchHAR(har, opts) {
|
|
|
260
261
|
});
|
|
261
262
|
// @ts-expect-error "Property 'from' does not exist on type 'typeof Readable'." but it does!
|
|
262
263
|
options.body = readable_stream_1.Readable.from(encoder_1);
|
|
264
|
+
shouldSetDuplex = true;
|
|
263
265
|
}
|
|
264
266
|
else {
|
|
265
267
|
options.body = form_1;
|
|
@@ -300,6 +302,7 @@ function fetchHAR(har, opts) {
|
|
|
300
302
|
else {
|
|
301
303
|
// @ts-expect-error "Property 'from' does not exist on type 'typeof Readable'." but it does!
|
|
302
304
|
options.body = readable_stream_1.Readable.from(fileContents.stream());
|
|
305
|
+
shouldSetDuplex = true;
|
|
303
306
|
// Supplying a polyfilled `File` stream into `Request.body` doesn't automatically
|
|
304
307
|
// add `Content-Length`.
|
|
305
308
|
if (!headers.has('content-length')) {
|
|
@@ -315,11 +318,27 @@ function fetchHAR(har, opts) {
|
|
|
315
318
|
options.body = request.postData.text;
|
|
316
319
|
}
|
|
317
320
|
}
|
|
321
|
+
/**
|
|
322
|
+
* The fetch spec, which Node 18+ strictly abides by, now requires that `duplex` be sent with
|
|
323
|
+
* requests that have payloads.
|
|
324
|
+
*
|
|
325
|
+
* As `RequestInit#duplex` isn't supported by any browsers, or even mentioned on MDN, we aren't
|
|
326
|
+
* sending it in browser environments. This work is purely to support Node 18+ and `undici`
|
|
327
|
+
* environments.
|
|
328
|
+
*
|
|
329
|
+
* @see {@link https://github.com/nodejs/node/issues/46221}
|
|
330
|
+
* @see {@link https://github.com/whatwg/fetch/pull/1457}
|
|
331
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Request/Request}
|
|
332
|
+
*/
|
|
333
|
+
if (shouldSetDuplex && !isBrowser()) {
|
|
334
|
+
options.duplex = 'half';
|
|
335
|
+
}
|
|
318
336
|
}
|
|
319
337
|
// We automaticaly assume that the HAR that we have already has query parameters encoded within
|
|
320
338
|
// it so we do **not** use the `URLSearchParams` API here for composing the query string.
|
|
339
|
+
var requestURL = url;
|
|
321
340
|
if ('queryString' in request && request.queryString.length) {
|
|
322
|
-
var urlObj = new URL(
|
|
341
|
+
var urlObj = new URL(requestURL);
|
|
323
342
|
var queryParams_1 = Array.from(urlObj.searchParams).map(function (_a) {
|
|
324
343
|
var k = _a[0], v = _a[1];
|
|
325
344
|
return "".concat(k, "=").concat(v);
|
|
@@ -328,11 +347,21 @@ function fetchHAR(har, opts) {
|
|
|
328
347
|
queryParams_1.push("".concat(q.name, "=").concat(q.value));
|
|
329
348
|
});
|
|
330
349
|
querystring = queryParams_1.join('&');
|
|
350
|
+
// Because anchor hashes before query strings will prevent query strings from being delivered
|
|
351
|
+
// we need to pop them off and re-add them after.
|
|
352
|
+
if (urlObj.hash) {
|
|
353
|
+
var urlWithoutHashes = requestURL.replace(urlObj.hash, '');
|
|
354
|
+
requestURL = "".concat(urlWithoutHashes.split('?')[0]).concat(querystring ? "?".concat(querystring) : '');
|
|
355
|
+
requestURL += urlObj.hash;
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
requestURL = "".concat(requestURL.split('?')[0]).concat(querystring ? "?".concat(querystring) : '');
|
|
359
|
+
}
|
|
331
360
|
}
|
|
332
361
|
if (opts.userAgent) {
|
|
333
362
|
headers.append('User-Agent', opts.userAgent);
|
|
334
363
|
}
|
|
335
364
|
options.headers = headers;
|
|
336
|
-
return fetch(
|
|
365
|
+
return fetch(requestURL, options);
|
|
337
366
|
}
|
|
338
367
|
exports["default"] = fetchHAR;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fetch-har",
|
|
3
|
-
"version": "8.1.
|
|
3
|
+
"version": "8.1.5",
|
|
4
4
|
"description": "Make a fetch request from a HAR definition",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@jsdevtools/host-environment": "^2.1.2",
|
|
42
42
|
"@jsdevtools/karma-config": "^3.1.7",
|
|
43
|
-
"@readme/eslint-config": "^10.
|
|
43
|
+
"@readme/eslint-config": "^10.4.5",
|
|
44
44
|
"@types/chai": "^4.3.1",
|
|
45
45
|
"@types/express": "^4.17.15",
|
|
46
46
|
"@types/mocha": "^10.0.0",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"@types/readable-stream": "^2.3.15",
|
|
50
50
|
"chai": "^4.3.4",
|
|
51
51
|
"datauri": "^4.1.0",
|
|
52
|
-
"eslint": "^8.
|
|
52
|
+
"eslint": "^8.32.0",
|
|
53
53
|
"express": "^4.18.1",
|
|
54
54
|
"fetch-mock": "^9.11.0",
|
|
55
55
|
"form-data": "^4.0.0",
|
|
@@ -59,15 +59,15 @@
|
|
|
59
59
|
"isomorphic-fetch": "^3.0.0",
|
|
60
60
|
"mocha": "^10.2.0",
|
|
61
61
|
"multer": "^1.4.5-lts.1",
|
|
62
|
-
"nock": "^13.
|
|
62
|
+
"nock": "^13.3.0",
|
|
63
63
|
"node-fetch": "^2.6.0",
|
|
64
64
|
"nyc": "^15.1.0",
|
|
65
|
-
"prettier": "^2.8.
|
|
65
|
+
"prettier": "^2.8.3",
|
|
66
66
|
"temp-dir": "^2.0.0",
|
|
67
67
|
"ts-loader": "^8.4.0",
|
|
68
68
|
"ts-node": "^10.7.0",
|
|
69
69
|
"typescript": "^4.9.4",
|
|
70
|
-
"undici": "^5.
|
|
70
|
+
"undici": "^5.16.0",
|
|
71
71
|
"webpack": "^4.46.0"
|
|
72
72
|
},
|
|
73
73
|
"browserslist": [
|
package/src/index.ts
CHANGED
|
@@ -37,11 +37,24 @@ if (!globalThis.FormData) {
|
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
interface RequestInitWithDuplex extends RequestInit {
|
|
41
|
+
/**
|
|
42
|
+
* `RequestInit#duplex` does not yet exist in the TS `lib.dom.d.ts` definition yet the native
|
|
43
|
+
* fetch implementation in Node 18+, `undici`, requires it for certain POST payloads.
|
|
44
|
+
*
|
|
45
|
+
* @see {@link https://github.com/microsoft/TypeScript-DOM-lib-generator/issues/1483}
|
|
46
|
+
* @see {@link https://github.com/nodejs/node/issues/46221}
|
|
47
|
+
* @see {@link https://fetch.spec.whatwg.org/#request-class}
|
|
48
|
+
* @see {@link https://github.com/microsoft/TypeScript/blob/main/lib/lib.dom.d.ts}
|
|
49
|
+
*/
|
|
50
|
+
duplex?: 'half';
|
|
51
|
+
}
|
|
52
|
+
|
|
40
53
|
export interface FetchHAROptions {
|
|
41
54
|
userAgent?: string;
|
|
42
55
|
files?: Record<string, Blob | Buffer>;
|
|
43
56
|
multipartEncoder?: any; // form-data-encoder
|
|
44
|
-
init?:
|
|
57
|
+
init?: RequestInitWithDuplex;
|
|
45
58
|
}
|
|
46
59
|
|
|
47
60
|
type DataURL = npmDataURL & {
|
|
@@ -117,8 +130,9 @@ export default function fetchHAR(har: Har, opts: FetchHAROptions = {}) {
|
|
|
117
130
|
const { request } = har.log.entries[0];
|
|
118
131
|
const { url } = request;
|
|
119
132
|
let querystring = '';
|
|
133
|
+
let shouldSetDuplex = false;
|
|
120
134
|
|
|
121
|
-
const options:
|
|
135
|
+
const options: RequestInitWithDuplex = {
|
|
122
136
|
// If we have custom options for the `Request` API we need to add them in here now before we
|
|
123
137
|
// fill it in with everything we need from the HAR.
|
|
124
138
|
...(opts.init ? opts.init : {}),
|
|
@@ -309,6 +323,7 @@ export default function fetchHAR(har: Har, opts: FetchHAROptions = {}) {
|
|
|
309
323
|
|
|
310
324
|
// @ts-expect-error "Property 'from' does not exist on type 'typeof Readable'." but it does!
|
|
311
325
|
options.body = Readable.from(encoder);
|
|
326
|
+
shouldSetDuplex = true;
|
|
312
327
|
} else {
|
|
313
328
|
options.body = form;
|
|
314
329
|
}
|
|
@@ -347,6 +362,7 @@ export default function fetchHAR(har: Har, opts: FetchHAROptions = {}) {
|
|
|
347
362
|
} else {
|
|
348
363
|
// @ts-expect-error "Property 'from' does not exist on type 'typeof Readable'." but it does!
|
|
349
364
|
options.body = Readable.from((fileContents as File).stream());
|
|
365
|
+
shouldSetDuplex = true;
|
|
350
366
|
|
|
351
367
|
// Supplying a polyfilled `File` stream into `Request.body` doesn't automatically
|
|
352
368
|
// add `Content-Length`.
|
|
@@ -364,12 +380,29 @@ export default function fetchHAR(har: Har, opts: FetchHAROptions = {}) {
|
|
|
364
380
|
options.body = request.postData.text;
|
|
365
381
|
}
|
|
366
382
|
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* The fetch spec, which Node 18+ strictly abides by, now requires that `duplex` be sent with
|
|
386
|
+
* requests that have payloads.
|
|
387
|
+
*
|
|
388
|
+
* As `RequestInit#duplex` isn't supported by any browsers, or even mentioned on MDN, we aren't
|
|
389
|
+
* sending it in browser environments. This work is purely to support Node 18+ and `undici`
|
|
390
|
+
* environments.
|
|
391
|
+
*
|
|
392
|
+
* @see {@link https://github.com/nodejs/node/issues/46221}
|
|
393
|
+
* @see {@link https://github.com/whatwg/fetch/pull/1457}
|
|
394
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Request/Request}
|
|
395
|
+
*/
|
|
396
|
+
if (shouldSetDuplex && !isBrowser()) {
|
|
397
|
+
options.duplex = 'half';
|
|
398
|
+
}
|
|
367
399
|
}
|
|
368
400
|
|
|
369
401
|
// We automaticaly assume that the HAR that we have already has query parameters encoded within
|
|
370
402
|
// it so we do **not** use the `URLSearchParams` API here for composing the query string.
|
|
403
|
+
let requestURL = url;
|
|
371
404
|
if ('queryString' in request && request.queryString.length) {
|
|
372
|
-
const urlObj = new URL(
|
|
405
|
+
const urlObj = new URL(requestURL);
|
|
373
406
|
|
|
374
407
|
const queryParams = Array.from(urlObj.searchParams).map(([k, v]) => `${k}=${v}`);
|
|
375
408
|
request.queryString.forEach(q => {
|
|
@@ -377,6 +410,16 @@ export default function fetchHAR(har: Har, opts: FetchHAROptions = {}) {
|
|
|
377
410
|
});
|
|
378
411
|
|
|
379
412
|
querystring = queryParams.join('&');
|
|
413
|
+
|
|
414
|
+
// Because anchor hashes before query strings will prevent query strings from being delivered
|
|
415
|
+
// we need to pop them off and re-add them after.
|
|
416
|
+
if (urlObj.hash) {
|
|
417
|
+
const urlWithoutHashes = requestURL.replace(urlObj.hash, '');
|
|
418
|
+
requestURL = `${urlWithoutHashes.split('?')[0]}${querystring ? `?${querystring}` : ''}`;
|
|
419
|
+
requestURL += urlObj.hash;
|
|
420
|
+
} else {
|
|
421
|
+
requestURL = `${requestURL.split('?')[0]}${querystring ? `?${querystring}` : ''}`;
|
|
422
|
+
}
|
|
380
423
|
}
|
|
381
424
|
|
|
382
425
|
if (opts.userAgent) {
|
|
@@ -385,5 +428,5 @@ export default function fetchHAR(har: Har, opts: FetchHAROptions = {}) {
|
|
|
385
428
|
|
|
386
429
|
options.headers = headers;
|
|
387
430
|
|
|
388
|
-
return fetch(
|
|
431
|
+
return fetch(requestURL, options);
|
|
389
432
|
}
|