diff --git a/bun.lockb b/bun.lockb
index 8a2e724..8c92f2a 100755
Binary files a/bun.lockb and b/bun.lockb differ
diff --git a/node_modules/data-uri-to-buffer/README.md b/node_modules/data-uri-to-buffer/README.md
new file mode 100644
index 0000000..2463f1f
--- /dev/null
+++ b/node_modules/data-uri-to-buffer/README.md
@@ -0,0 +1,88 @@
+data-uri-to-buffer
+==================
+### Generate a Buffer instance from a [Data URI][rfc] string
+[](https://travis-ci.org/TooTallNate/node-data-uri-to-buffer)
+
+This module accepts a ["data" URI][rfc] String of data, and returns a
+node.js `Buffer` instance with the decoded data.
+
+
+Installation
+------------
+
+Install with `npm`:
+
+``` bash
+$ npm install data-uri-to-buffer
+```
+
+
+Example
+-------
+
+``` js
+var dataUriToBuffer = require('data-uri-to-buffer');
+
+// plain-text data is supported
+var uri = 'data:,Hello%2C%20World!';
+var decoded = dataUriToBuffer(uri);
+console.log(decoded.toString());
+// 'Hello, World!'
+
+// base64-encoded data is supported
+uri = 'data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D';
+decoded = dataUriToBuffer(uri);
+console.log(decoded.toString());
+// 'Hello, World!'
+```
+
+
+API
+---
+
+### dataUriToBuffer(String uri) → Buffer
+
+The `type` property on the Buffer instance gets set to the main type portion of
+the "mediatype" portion of the "data" URI, or defaults to `"text/plain"` if not
+specified.
+
+The `typeFull` property on the Buffer instance gets set to the entire
+"mediatype" portion of the "data" URI (including all parameters), or defaults
+to `"text/plain;charset=US-ASCII"` if not specified.
+
+The `charset` property on the Buffer instance gets set to the Charset portion of
+the "mediatype" portion of the "data" URI, or defaults to `"US-ASCII"` if the
+entire type is not specified, or defaults to `""` otherwise.
+
+*Note*: If the only the main type is specified but not the charset, e.g.
+`"data:text/plain,abc"`, the charset is set to the empty string. The spec only
+defaults to US-ASCII as charset if the entire type is not specified.
+
+
+License
+-------
+
+(The MIT License)
+
+Copyright (c) 2014 Nathan Rajlich <nathan@tootallnate.net>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+[rfc]: http://tools.ietf.org/html/rfc2397
diff --git a/node_modules/data-uri-to-buffer/dist/index.d.ts b/node_modules/data-uri-to-buffer/dist/index.d.ts
new file mode 100644
index 0000000..2a3d91e
--- /dev/null
+++ b/node_modules/data-uri-to-buffer/dist/index.d.ts
@@ -0,0 +1,15 @@
+///
+export interface MimeBuffer extends Buffer {
+ type: string;
+ typeFull: string;
+ charset: string;
+}
+/**
+ * Returns a `Buffer` instance from the given data URI `uri`.
+ *
+ * @param {String} uri Data URI to turn into a Buffer instance
+ * @returns {Buffer} Buffer instance from Data URI
+ * @api public
+ */
+export declare function dataUriToBuffer(uri: string): MimeBuffer;
+export default dataUriToBuffer;
diff --git a/node_modules/data-uri-to-buffer/dist/index.js b/node_modules/data-uri-to-buffer/dist/index.js
new file mode 100644
index 0000000..341b151
--- /dev/null
+++ b/node_modules/data-uri-to-buffer/dist/index.js
@@ -0,0 +1,53 @@
+/**
+ * Returns a `Buffer` instance from the given data URI `uri`.
+ *
+ * @param {String} uri Data URI to turn into a Buffer instance
+ * @returns {Buffer} Buffer instance from Data URI
+ * @api public
+ */
+export function dataUriToBuffer(uri) {
+ if (!/^data:/i.test(uri)) {
+ throw new TypeError('`uri` does not appear to be a Data URI (must begin with "data:")');
+ }
+ // strip newlines
+ uri = uri.replace(/\r?\n/g, '');
+ // split the URI up into the "metadata" and the "data" portions
+ const firstComma = uri.indexOf(',');
+ if (firstComma === -1 || firstComma <= 4) {
+ throw new TypeError('malformed data: URI');
+ }
+ // remove the "data:" scheme and parse the metadata
+ const meta = uri.substring(5, firstComma).split(';');
+ let charset = '';
+ let base64 = false;
+ const type = meta[0] || 'text/plain';
+ let typeFull = type;
+ for (let i = 1; i < meta.length; i++) {
+ if (meta[i] === 'base64') {
+ base64 = true;
+ }
+ else {
+ typeFull += `;${meta[i]}`;
+ if (meta[i].indexOf('charset=') === 0) {
+ charset = meta[i].substring(8);
+ }
+ }
+ }
+ // defaults to US-ASCII only if type is not provided
+ if (!meta[0] && !charset.length) {
+ typeFull += ';charset=US-ASCII';
+ charset = 'US-ASCII';
+ }
+ // get the encoded data portion and decode URI-encoded chars
+ const encoding = base64 ? 'base64' : 'ascii';
+ const data = unescape(uri.substring(firstComma + 1));
+ const buffer = Buffer.from(data, encoding);
+ // set `.type` and `.typeFull` properties to MIME type
+ buffer.type = type;
+ buffer.typeFull = typeFull;
+ // set the `.charset` property
+ buffer.charset = charset;
+ return buffer;
+}
+export default dataUriToBuffer;
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/node_modules/data-uri-to-buffer/dist/index.js.map b/node_modules/data-uri-to-buffer/dist/index.js.map
new file mode 100644
index 0000000..5392b25
--- /dev/null
+++ b/node_modules/data-uri-to-buffer/dist/index.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,GAAW;IAC1C,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;QACzB,MAAM,IAAI,SAAS,CAClB,kEAAkE,CAClE,CAAC;KACF;IAED,iBAAiB;IACjB,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAEhC,+DAA+D;IAC/D,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,UAAU,KAAK,CAAC,CAAC,IAAI,UAAU,IAAI,CAAC,EAAE;QACzC,MAAM,IAAI,SAAS,CAAC,qBAAqB,CAAC,CAAC;KAC3C;IAED,mDAAmD;IACnD,MAAM,IAAI,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAErD,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,YAAY,CAAC;IACrC,IAAI,QAAQ,GAAG,IAAI,CAAC;IACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACrC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE;YACzB,MAAM,GAAG,IAAI,CAAC;SACd;aAAM;YACN,QAAQ,IAAI,IAAM,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5B,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE;gBACtC,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;aAC/B;SACD;KACD;IACD,oDAAoD;IACpD,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE;QAChC,QAAQ,IAAI,mBAAmB,CAAC;QAChC,OAAO,GAAG,UAAU,CAAC;KACrB;IAED,4DAA4D;IAC5D,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;IAC7C,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAe,CAAC;IAEzD,sDAAsD;IACtD,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAE3B,8BAA8B;IAC9B,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC;IAEzB,OAAO,MAAM,CAAC;AACf,CAAC;AAED,eAAe,eAAe,CAAC"}
\ No newline at end of file
diff --git a/node_modules/data-uri-to-buffer/dist/src/index.d.ts b/node_modules/data-uri-to-buffer/dist/src/index.d.ts
new file mode 100644
index 0000000..2a3d91e
--- /dev/null
+++ b/node_modules/data-uri-to-buffer/dist/src/index.d.ts
@@ -0,0 +1,15 @@
+///
+export interface MimeBuffer extends Buffer {
+ type: string;
+ typeFull: string;
+ charset: string;
+}
+/**
+ * Returns a `Buffer` instance from the given data URI `uri`.
+ *
+ * @param {String} uri Data URI to turn into a Buffer instance
+ * @returns {Buffer} Buffer instance from Data URI
+ * @api public
+ */
+export declare function dataUriToBuffer(uri: string): MimeBuffer;
+export default dataUriToBuffer;
diff --git a/node_modules/data-uri-to-buffer/dist/src/index.js b/node_modules/data-uri-to-buffer/dist/src/index.js
new file mode 100644
index 0000000..341b151
--- /dev/null
+++ b/node_modules/data-uri-to-buffer/dist/src/index.js
@@ -0,0 +1,53 @@
+/**
+ * Returns a `Buffer` instance from the given data URI `uri`.
+ *
+ * @param {String} uri Data URI to turn into a Buffer instance
+ * @returns {Buffer} Buffer instance from Data URI
+ * @api public
+ */
+export function dataUriToBuffer(uri) {
+ if (!/^data:/i.test(uri)) {
+ throw new TypeError('`uri` does not appear to be a Data URI (must begin with "data:")');
+ }
+ // strip newlines
+ uri = uri.replace(/\r?\n/g, '');
+ // split the URI up into the "metadata" and the "data" portions
+ const firstComma = uri.indexOf(',');
+ if (firstComma === -1 || firstComma <= 4) {
+ throw new TypeError('malformed data: URI');
+ }
+ // remove the "data:" scheme and parse the metadata
+ const meta = uri.substring(5, firstComma).split(';');
+ let charset = '';
+ let base64 = false;
+ const type = meta[0] || 'text/plain';
+ let typeFull = type;
+ for (let i = 1; i < meta.length; i++) {
+ if (meta[i] === 'base64') {
+ base64 = true;
+ }
+ else {
+ typeFull += `;${meta[i]}`;
+ if (meta[i].indexOf('charset=') === 0) {
+ charset = meta[i].substring(8);
+ }
+ }
+ }
+ // defaults to US-ASCII only if type is not provided
+ if (!meta[0] && !charset.length) {
+ typeFull += ';charset=US-ASCII';
+ charset = 'US-ASCII';
+ }
+ // get the encoded data portion and decode URI-encoded chars
+ const encoding = base64 ? 'base64' : 'ascii';
+ const data = unescape(uri.substring(firstComma + 1));
+ const buffer = Buffer.from(data, encoding);
+ // set `.type` and `.typeFull` properties to MIME type
+ buffer.type = type;
+ buffer.typeFull = typeFull;
+ // set the `.charset` property
+ buffer.charset = charset;
+ return buffer;
+}
+export default dataUriToBuffer;
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/node_modules/data-uri-to-buffer/dist/src/index.js.map b/node_modules/data-uri-to-buffer/dist/src/index.js.map
new file mode 100644
index 0000000..f3363a7
--- /dev/null
+++ b/node_modules/data-uri-to-buffer/dist/src/index.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAMA;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,GAAW;IAC1C,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;QACzB,MAAM,IAAI,SAAS,CAClB,kEAAkE,CAClE,CAAC;KACF;IAED,iBAAiB;IACjB,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAEhC,+DAA+D;IAC/D,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,UAAU,KAAK,CAAC,CAAC,IAAI,UAAU,IAAI,CAAC,EAAE;QACzC,MAAM,IAAI,SAAS,CAAC,qBAAqB,CAAC,CAAC;KAC3C;IAED,mDAAmD;IACnD,MAAM,IAAI,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAErD,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,YAAY,CAAC;IACrC,IAAI,QAAQ,GAAG,IAAI,CAAC;IACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACrC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE;YACzB,MAAM,GAAG,IAAI,CAAC;SACd;aAAM;YACN,QAAQ,IAAI,IAAM,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5B,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE;gBACtC,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;aAC/B;SACD;KACD;IACD,oDAAoD;IACpD,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE;QAChC,QAAQ,IAAI,mBAAmB,CAAC;QAChC,OAAO,GAAG,UAAU,CAAC;KACrB;IAED,4DAA4D;IAC5D,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;IAC7C,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAe,CAAC;IAEzD,sDAAsD;IACtD,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAE3B,8BAA8B;IAC9B,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC;IAEzB,OAAO,MAAM,CAAC;AACf,CAAC;AAED,eAAe,eAAe,CAAC"}
\ No newline at end of file
diff --git a/node_modules/data-uri-to-buffer/dist/test/test.d.ts b/node_modules/data-uri-to-buffer/dist/test/test.d.ts
new file mode 100644
index 0000000..a672ba1
--- /dev/null
+++ b/node_modules/data-uri-to-buffer/dist/test/test.d.ts
@@ -0,0 +1,4 @@
+/**
+ * Module dependencies.
+ */
+export {};
diff --git a/node_modules/data-uri-to-buffer/dist/test/test.js b/node_modules/data-uri-to-buffer/dist/test/test.js
new file mode 100644
index 0000000..8e59ebb
--- /dev/null
+++ b/node_modules/data-uri-to-buffer/dist/test/test.js
@@ -0,0 +1,144 @@
+/**
+ * Module dependencies.
+ */
+import assert from 'assert';
+import dataUriToBuffer from '../src';
+describe('data-uri-to-buffer', function () {
+ it('should decode bare-bones Data URIs', function () {
+ var uri = 'data:,Hello%2C%20World!';
+ var buf = dataUriToBuffer(uri);
+ assert.equal('text/plain', buf.type);
+ assert.equal('text/plain;charset=US-ASCII', buf.typeFull);
+ assert.equal('US-ASCII', buf.charset);
+ assert.equal('Hello, World!', buf.toString());
+ });
+ it('should decode bare-bones "base64" Data URIs', function () {
+ var uri = 'data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D';
+ var buf = dataUriToBuffer(uri);
+ assert.equal('text/plain', buf.type);
+ assert.equal('Hello, World!', buf.toString());
+ });
+ it('should decode plain-text Data URIs', function () {
+ var html = '' +
+ '' +
+ '
Embedded Window' +
+ '42
' +
+ '';
+ // Escape the HTML for URL formatting
+ var uri = 'data:text/html;charset=utf-8,' + encodeURIComponent(html);
+ var buf = dataUriToBuffer(uri);
+ assert.equal('text/html', buf.type);
+ assert.equal('utf-8', buf.charset);
+ assert.equal(html, buf.toString());
+ });
+ // the next 4 tests are from:
+ // https://bug161965.bugzilla.mozilla.org/attachment.cgi?id=94670&action=view
+ it('should decode "ISO-8859-8 in Base64" URIs', function () {
+ var uri = 'data:text/plain;charset=iso-8859-8-i;base64,+ezl7Q==';
+ var buf = dataUriToBuffer(uri);
+ assert.equal('text/plain', buf.type);
+ assert.equal('iso-8859-8-i', buf.charset);
+ assert.equal(4, buf.length);
+ assert.equal(0xf9, buf[0]);
+ assert.equal(0xec, buf[1]);
+ assert.equal(0xe5, buf[2]);
+ assert.equal(0xed, buf[3]);
+ });
+ it('should decode "ISO-8859-8 in URL-encoding" URIs', function () {
+ var uri = 'data:text/plain;charset=iso-8859-8-i,%f9%ec%e5%ed';
+ var buf = dataUriToBuffer(uri);
+ assert.equal('text/plain', buf.type);
+ assert.equal('iso-8859-8-i', buf.charset);
+ assert.equal(4, buf.length);
+ assert.equal(0xf9, buf[0]);
+ assert.equal(0xec, buf[1]);
+ assert.equal(0xe5, buf[2]);
+ assert.equal(0xed, buf[3]);
+ });
+ it('should decode "UTF-8 in Base64" URIs', function () {
+ var uri = 'data:text/plain;charset=UTF-8;base64,16nXnNeV150=';
+ var buf = dataUriToBuffer(uri);
+ assert.equal('text/plain', buf.type);
+ assert.equal('UTF-8', buf.charset);
+ assert.equal(8, buf.length);
+ assert.equal('שלום', buf.toString('utf8'));
+ });
+ it('should decode "UTF-8 in URL-encoding" URIs', function () {
+ var uri = 'data:text/plain;charset=UTF-8,%d7%a9%d7%9c%d7%95%d7%9d';
+ var buf = dataUriToBuffer(uri);
+ assert.equal('text/plain', buf.type);
+ assert.equal('UTF-8', buf.charset);
+ assert.equal(8, buf.length);
+ assert.equal('שלום', buf.toString('utf8'));
+ });
+ // this next one is from Wikipedia IIRC
+ it('should decode "base64" Data URIs with newlines', function () {
+ var uri = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA\n' +
+ 'AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO\n' +
+ '9TXL0Y4OHwAAAABJRU5ErkJggg==';
+ var buf = dataUriToBuffer(uri);
+ assert.equal('image/png', buf.type);
+ assert.equal('iVBORw0KGgoAAAANSUhEUgAAAAUA' +
+ 'AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO' +
+ '9TXL0Y4OHwAAAABJRU5ErkJggg==', buf.toString('base64'));
+ });
+ it('should decode a plain-text URI with a space character in it', function () {
+ var uri = 'data:,foo bar';
+ var buf = dataUriToBuffer(uri);
+ assert.equal('text/plain', buf.type);
+ assert.equal('foo bar', buf.toString());
+ });
+ it('should decode data with a "," comma char', function () {
+ var uri = 'data:,a,b';
+ var buf = dataUriToBuffer(uri);
+ assert.equal('text/plain', buf.type);
+ assert.equal('a,b', buf.toString());
+ });
+ it('should decode data with traditionally reserved characters like ";"', function () {
+ var uri = 'data:,;test';
+ var buf = dataUriToBuffer(uri);
+ assert.equal('text/plain', buf.type);
+ assert.equal(';test', buf.toString());
+ });
+ it('should not default to US-ASCII if main type is provided', function () {
+ var uri = 'data:text/plain,abc';
+ var buf = dataUriToBuffer(uri);
+ assert.equal('text/plain', buf.type);
+ assert.equal('text/plain', buf.typeFull);
+ assert.equal('', buf.charset);
+ assert.equal('abc', buf.toString());
+ });
+ it('should default to text/plain if main type is not provided', function () {
+ var uri = 'data:;charset=UTF-8,abc';
+ var buf = dataUriToBuffer(uri);
+ assert.equal('text/plain', buf.type);
+ assert.equal('text/plain;charset=UTF-8', buf.typeFull);
+ assert.equal('UTF-8', buf.charset);
+ assert.equal('abc', buf.toString());
+ });
+ it('should not allow charset without a leading ;', function () {
+ var uri = 'data:charset=UTF-8,abc';
+ var buf = dataUriToBuffer(uri);
+ assert.equal('charset=UTF-8', buf.type);
+ assert.equal('charset=UTF-8', buf.typeFull);
+ assert.equal('', buf.charset);
+ assert.equal('abc', buf.toString());
+ });
+ it('should allow custom media type parameters', function () {
+ var uri = 'data:application/javascript;version=1.8;charset=UTF-8,abc';
+ var buf = dataUriToBuffer(uri);
+ assert.equal('application/javascript', buf.type);
+ assert.equal('application/javascript;version=1.8;charset=UTF-8', buf.typeFull);
+ assert.equal('UTF-8', buf.charset);
+ assert.equal('abc', buf.toString());
+ });
+ it('should allow base64 annotation anywhere', function () {
+ var uri = 'data:text/plain;base64;charset=UTF-8,YWJj';
+ var buf = dataUriToBuffer(uri);
+ assert.equal('text/plain', buf.type);
+ assert.equal('text/plain;charset=UTF-8', buf.typeFull);
+ assert.equal('UTF-8', buf.charset);
+ assert.equal('abc', buf.toString());
+ });
+});
+//# sourceMappingURL=test.js.map
\ No newline at end of file
diff --git a/node_modules/data-uri-to-buffer/dist/test/test.js.map b/node_modules/data-uri-to-buffer/dist/test/test.js.map
new file mode 100644
index 0000000..3786864
--- /dev/null
+++ b/node_modules/data-uri-to-buffer/dist/test/test.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"test.js","sourceRoot":"","sources":["../../test/test.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/node_modules/data-uri-to-buffer/package.json b/node_modules/data-uri-to-buffer/package.json
new file mode 100644
index 0000000..e4f7357
--- /dev/null
+++ b/node_modules/data-uri-to-buffer/package.json
@@ -0,0 +1,62 @@
+{
+ "name": "data-uri-to-buffer",
+ "version": "4.0.0",
+ "description": "Generate a Buffer instance from a Data URI string",
+ "type": "module",
+ "main": "dist/index.js",
+ "types": "dist/index.d.ts",
+ "files": [
+ "dist",
+ "src"
+ ],
+ "scripts": {
+ "build": "tsc",
+ "test": "jest",
+ "prepublishOnly": "npm run build"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/TooTallNate/node-data-uri-to-buffer.git"
+ },
+ "engines": {
+ "node": ">= 12"
+ },
+ "keywords": [
+ "data",
+ "uri",
+ "datauri",
+ "data-uri",
+ "buffer",
+ "convert",
+ "rfc2397",
+ "2397"
+ ],
+ "author": "Nathan Rajlich (http://n8.io/)",
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/TooTallNate/node-data-uri-to-buffer/issues"
+ },
+ "homepage": "https://github.com/TooTallNate/node-data-uri-to-buffer",
+ "devDependencies": {
+ "@types/es6-promisify": "^5.0.0",
+ "@types/mocha": "^9.0.0",
+ "@types/node": "^10.5.3",
+ "jest": "^27.2.2",
+ "ts-jest": "^27.0.5",
+ "typescript": "^4.4.3"
+ },
+ "jest": {
+ "preset": "ts-jest",
+ "globals": {
+ "ts-jest": {
+ "diagnostics": false,
+ "isolatedModules": true
+ }
+ },
+ "verbose": false,
+ "testEnvironment": "node",
+ "testMatch": [
+ "/test/**/*.test.ts"
+ ]
+ }
+}
diff --git a/node_modules/data-uri-to-buffer/src/index.ts b/node_modules/data-uri-to-buffer/src/index.ts
new file mode 100644
index 0000000..00e4446
--- /dev/null
+++ b/node_modules/data-uri-to-buffer/src/index.ts
@@ -0,0 +1,68 @@
+export interface MimeBuffer extends Buffer {
+ type: string;
+ typeFull: string;
+ charset: string;
+}
+
+/**
+ * Returns a `Buffer` instance from the given data URI `uri`.
+ *
+ * @param {String} uri Data URI to turn into a Buffer instance
+ * @returns {Buffer} Buffer instance from Data URI
+ * @api public
+ */
+export function dataUriToBuffer(uri: string): MimeBuffer {
+ if (!/^data:/i.test(uri)) {
+ throw new TypeError(
+ '`uri` does not appear to be a Data URI (must begin with "data:")'
+ );
+ }
+
+ // strip newlines
+ uri = uri.replace(/\r?\n/g, '');
+
+ // split the URI up into the "metadata" and the "data" portions
+ const firstComma = uri.indexOf(',');
+ if (firstComma === -1 || firstComma <= 4) {
+ throw new TypeError('malformed data: URI');
+ }
+
+ // remove the "data:" scheme and parse the metadata
+ const meta = uri.substring(5, firstComma).split(';');
+
+ let charset = '';
+ let base64 = false;
+ const type = meta[0] || 'text/plain';
+ let typeFull = type;
+ for (let i = 1; i < meta.length; i++) {
+ if (meta[i] === 'base64') {
+ base64 = true;
+ } else {
+ typeFull += `;${ meta[i]}`;
+ if (meta[i].indexOf('charset=') === 0) {
+ charset = meta[i].substring(8);
+ }
+ }
+ }
+ // defaults to US-ASCII only if type is not provided
+ if (!meta[0] && !charset.length) {
+ typeFull += ';charset=US-ASCII';
+ charset = 'US-ASCII';
+ }
+
+ // get the encoded data portion and decode URI-encoded chars
+ const encoding = base64 ? 'base64' : 'ascii';
+ const data = unescape(uri.substring(firstComma + 1));
+ const buffer = Buffer.from(data, encoding) as MimeBuffer;
+
+ // set `.type` and `.typeFull` properties to MIME type
+ buffer.type = type;
+ buffer.typeFull = typeFull;
+
+ // set the `.charset` property
+ buffer.charset = charset;
+
+ return buffer;
+}
+
+export default dataUriToBuffer;
diff --git a/node_modules/undici/lib/fetch/LICENSE b/node_modules/fetch-blob/LICENSE
similarity index 96%
rename from node_modules/undici/lib/fetch/LICENSE
rename to node_modules/fetch-blob/LICENSE
index 2943500..0d31723 100644
--- a/node_modules/undici/lib/fetch/LICENSE
+++ b/node_modules/fetch-blob/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2020 Ethan Arrowood
+Copyright (c) 2019 David Frank
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/node_modules/fetch-blob/README.md b/node_modules/fetch-blob/README.md
new file mode 100644
index 0000000..fb3e198
--- /dev/null
+++ b/node_modules/fetch-blob/README.md
@@ -0,0 +1,106 @@
+# fetch-blob
+
+[![npm version][npm-image]][npm-url]
+[![build status][ci-image]][ci-url]
+[![coverage status][codecov-image]][codecov-url]
+[![install size][install-size-image]][install-size-url]
+
+A Blob implementation in Node.js, originally from [node-fetch](https://github.com/node-fetch/node-fetch).
+
+## Installation
+
+```sh
+npm install fetch-blob
+```
+
+
+ Upgrading from 2x to 3x
+
+ Updating from 2 to 3 should be a breeze since there is not many changes to the blob specification.
+ The major cause of a major release is coding standards.
+ - internal WeakMaps was replaced with private fields
+ - internal Buffer.from was replaced with TextEncoder/Decoder
+ - internal buffers was replaced with Uint8Arrays
+ - CommonJS was replaced with ESM
+ - The node stream returned by calling `blob.stream()` was replaced with whatwg streams
+ - (Read "Differences from other blobs" for more info.)
+
+
+
+
+ Differences from other Blobs
+
+ - Unlike NodeJS `buffer.Blob` (Added in: v15.7.0) and browser native Blob this polyfilled version can't be sent via PostMessage
+ - This blob version is more arbitrary, it can be constructed with blob parts that isn't a instance of itself
+ it has to look and behave as a blob to be accepted as a blob part.
+ - The benefit of this is that you can create other types of blobs that don't contain any internal data that has to be read in other ways, such as the `BlobDataItem` created in `from.js` that wraps a file path into a blob-like item and read lazily (nodejs plans to [implement this][fs-blobs] as well)
+ - The `blob.stream()` is the most noticeable differences. It returns a WHATWG stream now. to keep it as a node stream you would have to do:
+
+ ```js
+ import {Readable} from 'stream'
+ const stream = Readable.from(blob.stream())
+ ```
+
+
+## Usage
+
+```js
+// Ways to import
+// (PS it's dependency free ESM package so regular http-import from CDN works too)
+import Blob from 'fetch-blob'
+import File from 'fetch-blob/file.js'
+
+import {Blob} from 'fetch-blob'
+import {File} from 'fetch-blob/file.js'
+
+const {Blob} = await import('fetch-blob')
+
+
+// Ways to read the blob:
+const blob = new Blob(['hello, world'])
+
+await blob.text()
+await blob.arrayBuffer()
+for await (let chunk of blob.stream()) { ... }
+blob.stream().getReader().read()
+blob.stream().getReader({mode: 'byob'}).read(view)
+```
+
+### Blob part backed up by filesystem
+
+`fetch-blob/from.js` comes packed with tools to convert any filepath into either a Blob or a File
+It will not read the content into memory. It will only stat the file for last modified date and file size.
+
+```js
+// The default export is sync and use fs.stat to retrieve size & last modified as a blob
+import blobFromSync from 'fetch-blob/from.js'
+import {File, Blob, blobFrom, blobFromSync, fileFrom, fileFromSync} from 'fetch-blob/from.js'
+
+const fsFile = fileFromSync('./2-GiB-file.bin', 'application/octet-stream')
+const fsBlob = await blobFrom('./2-GiB-file.mp4')
+
+// Not a 4 GiB memory snapshot, just holds references
+// points to where data is located on the disk
+const blob = new Blob([fsFile, fsBlob, 'memory', new Uint8Array(10)])
+console.log(blob.size) // ~4 GiB
+```
+
+`blobFrom|blobFromSync|fileFrom|fileFromSync(path, [mimetype])`
+
+### Creating Blobs backed up by other async sources
+Our Blob & File class are more generic then any other polyfills in the way that it can accept any blob look-a-like item
+An example of this is that our blob implementation can be constructed with parts coming from [BlobDataItem](https://github.com/node-fetch/fetch-blob/blob/8ef89adad40d255a3bbd55cf38b88597c1cd5480/from.js#L32) (aka a filepath) or from [buffer.Blob](https://nodejs.org/api/buffer.html#buffer_new_buffer_blob_sources_options), It dose not have to implement all the methods - just enough that it can be read/understood by our Blob implementation. The minium requirements is that it has `Symbol.toStringTag`, `size`, `slice()` and either a `stream()` or a `arrayBuffer()` method. If you then wrap it in our Blob or File `new Blob([blobDataItem])` then you get all of the other methods that should be implemented in a blob or file
+
+An example of this could be to create a file or blob like item coming from a remote HTTP request. Or from a DataBase
+
+See the [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/Blob) and [tests](https://github.com/node-fetch/fetch-blob/blob/master/test.js) for more details of how to use the Blob.
+
+[npm-image]: https://flat.badgen.net/npm/v/fetch-blob
+[npm-url]: https://www.npmjs.com/package/fetch-blob
+[ci-image]: https://github.com/node-fetch/fetch-blob/workflows/CI/badge.svg
+[ci-url]: https://github.com/node-fetch/fetch-blob/actions
+[codecov-image]: https://flat.badgen.net/codecov/c/github/node-fetch/fetch-blob/master
+[codecov-url]: https://codecov.io/gh/node-fetch/fetch-blob
+[install-size-image]: https://flat.badgen.net/packagephobia/install/fetch-blob
+[install-size-url]: https://packagephobia.now.sh/result?p=fetch-blob
+[fs-blobs]: https://github.com/nodejs/node/issues/37340
diff --git a/node_modules/fetch-blob/file.d.ts b/node_modules/fetch-blob/file.d.ts
new file mode 100644
index 0000000..d4b89bc
--- /dev/null
+++ b/node_modules/fetch-blob/file.d.ts
@@ -0,0 +1,2 @@
+/** @type {typeof globalThis.File} */ export const File: typeof globalThis.File;
+export default File;
diff --git a/node_modules/fetch-blob/file.js b/node_modules/fetch-blob/file.js
new file mode 100644
index 0000000..7b26538
--- /dev/null
+++ b/node_modules/fetch-blob/file.js
@@ -0,0 +1,49 @@
+import Blob from './index.js'
+
+const _File = class File extends Blob {
+ #lastModified = 0
+ #name = ''
+
+ /**
+ * @param {*[]} fileBits
+ * @param {string} fileName
+ * @param {{lastModified?: number, type?: string}} options
+ */// @ts-ignore
+ constructor (fileBits, fileName, options = {}) {
+ if (arguments.length < 2) {
+ throw new TypeError(`Failed to construct 'File': 2 arguments required, but only ${arguments.length} present.`)
+ }
+ super(fileBits, options)
+
+ if (options === null) options = {}
+
+ // Simulate WebIDL type casting for NaN value in lastModified option.
+ const lastModified = options.lastModified === undefined ? Date.now() : Number(options.lastModified)
+ if (!Number.isNaN(lastModified)) {
+ this.#lastModified = lastModified
+ }
+
+ this.#name = String(fileName)
+ }
+
+ get name () {
+ return this.#name
+ }
+
+ get lastModified () {
+ return this.#lastModified
+ }
+
+ get [Symbol.toStringTag] () {
+ return 'File'
+ }
+
+ static [Symbol.hasInstance] (object) {
+ return !!object && object instanceof Blob &&
+ /^(File)$/.test(object[Symbol.toStringTag])
+ }
+}
+
+/** @type {typeof globalThis.File} */// @ts-ignore
+export const File = _File
+export default File
diff --git a/node_modules/fetch-blob/from.d.ts b/node_modules/fetch-blob/from.d.ts
new file mode 100644
index 0000000..530b99b
--- /dev/null
+++ b/node_modules/fetch-blob/from.d.ts
@@ -0,0 +1,26 @@
+export default blobFromSync;
+/**
+ * @param {string} path filepath on the disk
+ * @param {string} [type] mimetype to use
+ */
+export function blobFromSync(path: string, type?: string): Blob;
+import File from "./file.js";
+import Blob from "./index.js";
+/**
+ * @param {string} path filepath on the disk
+ * @param {string} [type] mimetype to use
+ * @returns {Promise}
+ */
+export function blobFrom(path: string, type?: string): Promise;
+/**
+ * @param {string} path filepath on the disk
+ * @param {string} [type] mimetype to use
+ * @returns {Promise}
+ */
+export function fileFrom(path: string, type?: string): Promise;
+/**
+ * @param {string} path filepath on the disk
+ * @param {string} [type] mimetype to use
+ */
+export function fileFromSync(path: string, type?: string): File;
+export { File, Blob };
diff --git a/node_modules/fetch-blob/from.js b/node_modules/fetch-blob/from.js
new file mode 100644
index 0000000..9eaf8bf
--- /dev/null
+++ b/node_modules/fetch-blob/from.js
@@ -0,0 +1,100 @@
+import { statSync, createReadStream, promises as fs } from 'node:fs'
+import { basename } from 'node:path'
+import DOMException from 'node-domexception'
+
+import File from './file.js'
+import Blob from './index.js'
+
+const { stat } = fs
+
+/**
+ * @param {string} path filepath on the disk
+ * @param {string} [type] mimetype to use
+ */
+const blobFromSync = (path, type) => fromBlob(statSync(path), path, type)
+
+/**
+ * @param {string} path filepath on the disk
+ * @param {string} [type] mimetype to use
+ * @returns {Promise}
+ */
+const blobFrom = (path, type) => stat(path).then(stat => fromBlob(stat, path, type))
+
+/**
+ * @param {string} path filepath on the disk
+ * @param {string} [type] mimetype to use
+ * @returns {Promise}
+ */
+const fileFrom = (path, type) => stat(path).then(stat => fromFile(stat, path, type))
+
+/**
+ * @param {string} path filepath on the disk
+ * @param {string} [type] mimetype to use
+ */
+const fileFromSync = (path, type) => fromFile(statSync(path), path, type)
+
+// @ts-ignore
+const fromBlob = (stat, path, type = '') => new Blob([new BlobDataItem({
+ path,
+ size: stat.size,
+ lastModified: stat.mtimeMs,
+ start: 0
+})], { type })
+
+// @ts-ignore
+const fromFile = (stat, path, type = '') => new File([new BlobDataItem({
+ path,
+ size: stat.size,
+ lastModified: stat.mtimeMs,
+ start: 0
+})], basename(path), { type, lastModified: stat.mtimeMs })
+
+/**
+ * This is a blob backed up by a file on the disk
+ * with minium requirement. Its wrapped around a Blob as a blobPart
+ * so you have no direct access to this.
+ *
+ * @private
+ */
+class BlobDataItem {
+ #path
+ #start
+
+ constructor (options) {
+ this.#path = options.path
+ this.#start = options.start
+ this.size = options.size
+ this.lastModified = options.lastModified
+ }
+
+ /**
+ * Slicing arguments is first validated and formatted
+ * to not be out of range by Blob.prototype.slice
+ */
+ slice (start, end) {
+ return new BlobDataItem({
+ path: this.#path,
+ lastModified: this.lastModified,
+ size: end - start,
+ start: this.#start + start
+ })
+ }
+
+ async * stream () {
+ const { mtimeMs } = await stat(this.#path)
+ if (mtimeMs > this.lastModified) {
+ throw new DOMException('The requested file could not be read, typically due to permission problems that have occurred after a reference to a file was acquired.', 'NotReadableError')
+ }
+ yield * createReadStream(this.#path, {
+ start: this.#start,
+ end: this.#start + this.size - 1
+ })
+ }
+
+ get [Symbol.toStringTag] () {
+ return 'Blob'
+ }
+}
+
+export default blobFromSync
+export { File, Blob, blobFrom, blobFromSync, fileFrom, fileFromSync }
diff --git a/node_modules/fetch-blob/index.d.ts b/node_modules/fetch-blob/index.d.ts
new file mode 100644
index 0000000..7a68957
--- /dev/null
+++ b/node_modules/fetch-blob/index.d.ts
@@ -0,0 +1,3 @@
+/** @type {typeof globalThis.Blob} */
+export const Blob: typeof globalThis.Blob;
+export default Blob;
diff --git a/node_modules/fetch-blob/index.js b/node_modules/fetch-blob/index.js
new file mode 100644
index 0000000..2542ac2
--- /dev/null
+++ b/node_modules/fetch-blob/index.js
@@ -0,0 +1,250 @@
+/*! fetch-blob. MIT License. Jimmy Wärting */
+
+// TODO (jimmywarting): in the feature use conditional loading with top level await (requires 14.x)
+// Node has recently added whatwg stream into core
+
+import './streams.cjs'
+
+// 64 KiB (same size chrome slice theirs blob into Uint8array's)
+const POOL_SIZE = 65536
+
+/** @param {(Blob | Uint8Array)[]} parts */
+async function * toIterator (parts, clone = true) {
+ for (const part of parts) {
+ if ('stream' in part) {
+ yield * (/** @type {AsyncIterableIterator} */ (part.stream()))
+ } else if (ArrayBuffer.isView(part)) {
+ if (clone) {
+ let position = part.byteOffset
+ const end = part.byteOffset + part.byteLength
+ while (position !== end) {
+ const size = Math.min(end - position, POOL_SIZE)
+ const chunk = part.buffer.slice(position, position + size)
+ position += chunk.byteLength
+ yield new Uint8Array(chunk)
+ }
+ } else {
+ yield part
+ }
+ /* c8 ignore next 10 */
+ } else {
+ // For blobs that have arrayBuffer but no stream method (nodes buffer.Blob)
+ let position = 0, b = (/** @type {Blob} */ (part))
+ while (position !== b.size) {
+ const chunk = b.slice(position, Math.min(b.size, position + POOL_SIZE))
+ const buffer = await chunk.arrayBuffer()
+ position += buffer.byteLength
+ yield new Uint8Array(buffer)
+ }
+ }
+ }
+}
+
+const _Blob = class Blob {
+ /** @type {Array.<(Blob|Uint8Array)>} */
+ #parts = []
+ #type = ''
+ #size = 0
+ #endings = 'transparent'
+
+ /**
+ * The Blob() constructor returns a new Blob object. The content
+ * of the blob consists of the concatenation of the values given
+ * in the parameter array.
+ *
+ * @param {*} blobParts
+ * @param {{ type?: string, endings?: string }} [options]
+ */
+ constructor (blobParts = [], options = {}) {
+ if (typeof blobParts !== 'object' || blobParts === null) {
+ throw new TypeError('Failed to construct \'Blob\': The provided value cannot be converted to a sequence.')
+ }
+
+ if (typeof blobParts[Symbol.iterator] !== 'function') {
+ throw new TypeError('Failed to construct \'Blob\': The object must have a callable @@iterator property.')
+ }
+
+ if (typeof options !== 'object' && typeof options !== 'function') {
+ throw new TypeError('Failed to construct \'Blob\': parameter 2 cannot convert to dictionary.')
+ }
+
+ if (options === null) options = {}
+
+ const encoder = new TextEncoder()
+ for (const element of blobParts) {
+ let part
+ if (ArrayBuffer.isView(element)) {
+ part = new Uint8Array(element.buffer.slice(element.byteOffset, element.byteOffset + element.byteLength))
+ } else if (element instanceof ArrayBuffer) {
+ part = new Uint8Array(element.slice(0))
+ } else if (element instanceof Blob) {
+ part = element
+ } else {
+ part = encoder.encode(`${element}`)
+ }
+
+ this.#size += ArrayBuffer.isView(part) ? part.byteLength : part.size
+ this.#parts.push(part)
+ }
+
+ this.#endings = `${options.endings === undefined ? 'transparent' : options.endings}`
+ const type = options.type === undefined ? '' : String(options.type)
+ this.#type = /^[\x20-\x7E]*$/.test(type) ? type : ''
+ }
+
+ /**
+ * The Blob interface's size property returns the
+ * size of the Blob in bytes.
+ */
+ get size () {
+ return this.#size
+ }
+
+ /**
+ * The type property of a Blob object returns the MIME type of the file.
+ */
+ get type () {
+ return this.#type
+ }
+
+ /**
+ * The text() method in the Blob interface returns a Promise
+ * that resolves with a string containing the contents of
+ * the blob, interpreted as UTF-8.
+ *
+ * @return {Promise}
+ */
+ async text () {
+ // More optimized than using this.arrayBuffer()
+ // that requires twice as much ram
+ const decoder = new TextDecoder()
+ let str = ''
+ for await (const part of toIterator(this.#parts, false)) {
+ str += decoder.decode(part, { stream: true })
+ }
+ // Remaining
+ str += decoder.decode()
+ return str
+ }
+
+ /**
+ * The arrayBuffer() method in the Blob interface returns a
+ * Promise that resolves with the contents of the blob as
+ * binary data contained in an ArrayBuffer.
+ *
+ * @return {Promise}
+ */
+ async arrayBuffer () {
+ // Easier way... Just a unnecessary overhead
+ // const view = new Uint8Array(this.size);
+ // await this.stream().getReader({mode: 'byob'}).read(view);
+ // return view.buffer;
+
+ const data = new Uint8Array(this.size)
+ let offset = 0
+ for await (const chunk of toIterator(this.#parts, false)) {
+ data.set(chunk, offset)
+ offset += chunk.length
+ }
+
+ return data.buffer
+ }
+
+ stream () {
+ const it = toIterator(this.#parts, true)
+
+ return new globalThis.ReadableStream({
+ // @ts-ignore
+ type: 'bytes',
+ async pull (ctrl) {
+ const chunk = await it.next()
+ chunk.done ? ctrl.close() : ctrl.enqueue(chunk.value)
+ },
+
+ async cancel () {
+ await it.return()
+ }
+ })
+ }
+
+ /**
+ * The Blob interface's slice() method creates and returns a
+ * new Blob object which contains data from a subset of the
+ * blob on which it's called.
+ *
+ * @param {number} [start]
+ * @param {number} [end]
+ * @param {string} [type]
+ */
+ slice (start = 0, end = this.size, type = '') {
+ const { size } = this
+
+ let relativeStart = start < 0 ? Math.max(size + start, 0) : Math.min(start, size)
+ let relativeEnd = end < 0 ? Math.max(size + end, 0) : Math.min(end, size)
+
+ const span = Math.max(relativeEnd - relativeStart, 0)
+ const parts = this.#parts
+ const blobParts = []
+ let added = 0
+
+ for (const part of parts) {
+ // don't add the overflow to new blobParts
+ if (added >= span) {
+ break
+ }
+
+ const size = ArrayBuffer.isView(part) ? part.byteLength : part.size
+ if (relativeStart && size <= relativeStart) {
+ // Skip the beginning and change the relative
+ // start & end position as we skip the unwanted parts
+ relativeStart -= size
+ relativeEnd -= size
+ } else {
+ let chunk
+ if (ArrayBuffer.isView(part)) {
+ chunk = part.subarray(relativeStart, Math.min(size, relativeEnd))
+ added += chunk.byteLength
+ } else {
+ chunk = part.slice(relativeStart, Math.min(size, relativeEnd))
+ added += chunk.size
+ }
+ relativeEnd -= size
+ blobParts.push(chunk)
+ relativeStart = 0 // All next sequential parts should start at 0
+ }
+ }
+
+ const blob = new Blob([], { type: String(type).toLowerCase() })
+ blob.#size = span
+ blob.#parts = blobParts
+
+ return blob
+ }
+
+ get [Symbol.toStringTag] () {
+ return 'Blob'
+ }
+
+ static [Symbol.hasInstance] (object) {
+ return (
+ object &&
+ typeof object === 'object' &&
+ typeof object.constructor === 'function' &&
+ (
+ typeof object.stream === 'function' ||
+ typeof object.arrayBuffer === 'function'
+ ) &&
+ /^(Blob|File)$/.test(object[Symbol.toStringTag])
+ )
+ }
+}
+
+Object.defineProperties(_Blob.prototype, {
+ size: { enumerable: true },
+ type: { enumerable: true },
+ slice: { enumerable: true }
+})
+
+/** @type {typeof globalThis.Blob} */
+export const Blob = _Blob
+export default Blob
diff --git a/node_modules/fetch-blob/package.json b/node_modules/fetch-blob/package.json
new file mode 100644
index 0000000..9d07f39
--- /dev/null
+++ b/node_modules/fetch-blob/package.json
@@ -0,0 +1,56 @@
+{
+ "name": "fetch-blob",
+ "version": "3.2.0",
+ "description": "Blob & File implementation in Node.js, originally from node-fetch.",
+ "main": "index.js",
+ "type": "module",
+ "files": [
+ "from.js",
+ "file.js",
+ "file.d.ts",
+ "index.js",
+ "index.d.ts",
+ "from.d.ts",
+ "streams.cjs"
+ ],
+ "scripts": {
+ "test": "node --experimental-loader ./test/http-loader.js ./test/test-wpt-in-node.js",
+ "report": "c8 --reporter json --reporter text npm run test",
+ "coverage": "npm run report && codecov -f coverage/coverage-final.json",
+ "prepublishOnly": "tsc --declaration --emitDeclarationOnly --allowJs index.js from.js"
+ },
+ "repository": "https://github.com/node-fetch/fetch-blob.git",
+ "keywords": [
+ "blob",
+ "file",
+ "node-fetch"
+ ],
+ "engines": {
+ "node": "^12.20 || >= 14.13"
+ },
+ "author": "Jimmy Wärting (https://jimmy.warting.se)",
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/node-fetch/fetch-blob/issues"
+ },
+ "homepage": "https://github.com/node-fetch/fetch-blob#readme",
+ "devDependencies": {
+ "@types/node": "^17.0.9",
+ "c8": "^7.11.0",
+ "typescript": "^4.5.4"
+ },
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/jimmywarting"
+ },
+ {
+ "type": "paypal",
+ "url": "https://paypal.me/jimmywarting"
+ }
+ ],
+ "dependencies": {
+ "node-domexception": "^1.0.0",
+ "web-streams-polyfill": "^3.0.3"
+ }
+}
diff --git a/node_modules/fetch-blob/streams.cjs b/node_modules/fetch-blob/streams.cjs
new file mode 100644
index 0000000..f760959
--- /dev/null
+++ b/node_modules/fetch-blob/streams.cjs
@@ -0,0 +1,51 @@
+/* c8 ignore start */
+// 64 KiB (same size chrome slice theirs blob into Uint8array's)
+const POOL_SIZE = 65536
+
+if (!globalThis.ReadableStream) {
+ // `node:stream/web` got introduced in v16.5.0 as experimental
+ // and it's preferred over the polyfilled version. So we also
+ // suppress the warning that gets emitted by NodeJS for using it.
+ try {
+ const process = require('node:process')
+ const { emitWarning } = process
+ try {
+ process.emitWarning = () => {}
+ Object.assign(globalThis, require('node:stream/web'))
+ process.emitWarning = emitWarning
+ } catch (error) {
+ process.emitWarning = emitWarning
+ throw error
+ }
+ } catch (error) {
+ // fallback to polyfill implementation
+ Object.assign(globalThis, require('web-streams-polyfill/dist/ponyfill.es2018.js'))
+ }
+}
+
+try {
+ // Don't use node: prefix for this, require+node: is not supported until node v14.14
+ // Only `import()` can use prefix in 12.20 and later
+ const { Blob } = require('buffer')
+ if (Blob && !Blob.prototype.stream) {
+ Blob.prototype.stream = function name (params) {
+ let position = 0
+ const blob = this
+
+ return new ReadableStream({
+ type: 'bytes',
+ async pull (ctrl) {
+ const chunk = blob.slice(position, Math.min(blob.size, position + POOL_SIZE))
+ const buffer = await chunk.arrayBuffer()
+ position += buffer.byteLength
+ ctrl.enqueue(new Uint8Array(buffer))
+
+ if (position === blob.size) {
+ ctrl.close()
+ }
+ }
+ })
+ }
+ }
+} catch (error) {}
+/* c8 ignore end */
diff --git a/node_modules/formdata-polyfill/FormData.js b/node_modules/formdata-polyfill/FormData.js
new file mode 100644
index 0000000..8e73660
--- /dev/null
+++ b/node_modules/formdata-polyfill/FormData.js
@@ -0,0 +1,441 @@
+/* formdata-polyfill. MIT License. Jimmy Wärting */
+
+/* global FormData self Blob File */
+/* eslint-disable no-inner-declarations */
+
+if (typeof Blob !== 'undefined' && (typeof FormData === 'undefined' || !FormData.prototype.keys)) {
+ const global = typeof globalThis === 'object'
+ ? globalThis
+ : typeof window === 'object'
+ ? window
+ : typeof self === 'object' ? self : this
+
+ // keep a reference to native implementation
+ const _FormData = global.FormData
+
+ // To be monkey patched
+ const _send = global.XMLHttpRequest && global.XMLHttpRequest.prototype.send
+ const _fetch = global.Request && global.fetch
+ const _sendBeacon = global.navigator && global.navigator.sendBeacon
+ // Might be a worker thread...
+ const _match = global.Element && global.Element.prototype
+
+ // Unable to patch Request/Response constructor correctly #109
+ // only way is to use ES6 class extend
+ // https://github.com/babel/babel/issues/1966
+
+ const stringTag = global.Symbol && Symbol.toStringTag
+
+ // Add missing stringTags to blob and files
+ if (stringTag) {
+ if (!Blob.prototype[stringTag]) {
+ Blob.prototype[stringTag] = 'Blob'
+ }
+
+ if ('File' in global && !File.prototype[stringTag]) {
+ File.prototype[stringTag] = 'File'
+ }
+ }
+
+ // Fix so you can construct your own File
+ try {
+ new File([], '') // eslint-disable-line
+ } catch (a) {
+ global.File = function File (b, d, c) {
+ const blob = new Blob(b, c || {})
+ const t = c && void 0 !== c.lastModified ? new Date(c.lastModified) : new Date()
+
+ Object.defineProperties(blob, {
+ name: {
+ value: d
+ },
+ lastModified: {
+ value: +t
+ },
+ toString: {
+ value () {
+ return '[object File]'
+ }
+ }
+ })
+
+ if (stringTag) {
+ Object.defineProperty(blob, stringTag, {
+ value: 'File'
+ })
+ }
+
+ return blob
+ }
+ }
+
+ function ensureArgs (args, expected) {
+ if (args.length < expected) {
+ throw new TypeError(`${expected} argument required, but only ${args.length} present.`)
+ }
+ }
+
+ /**
+ * @param {string} name
+ * @param {string | undefined} filename
+ * @returns {[string, File|string]}
+ */
+ function normalizeArgs (name, value, filename) {
+ if (value instanceof Blob) {
+ filename = filename !== undefined
+ ? String(filename + '')
+ : typeof value.name === 'string'
+ ? value.name
+ : 'blob'
+
+ if (value.name !== filename || Object.prototype.toString.call(value) === '[object Blob]') {
+ value = new File([value], filename)
+ }
+ return [String(name), value]
+ }
+ return [String(name), String(value)]
+ }
+
+ // normalize line feeds for textarea
+ // https://html.spec.whatwg.org/multipage/form-elements.html#textarea-line-break-normalisation-transformation
+ function normalizeLinefeeds (value) {
+ return value.replace(/\r?\n|\r/g, '\r\n')
+ }
+
+ /**
+ * @template T
+ * @param {ArrayLike} arr
+ * @param {{ (elm: T): void; }} cb
+ */
+ function each (arr, cb) {
+ for (let i = 0; i < arr.length; i++) {
+ cb(arr[i])
+ }
+ }
+
+ const escape = str => str.replace(/\n/g, '%0A').replace(/\r/g, '%0D').replace(/"/g, '%22')
+
+ /**
+ * @implements {Iterable}
+ */
+ class FormDataPolyfill {
+ /**
+ * FormData class
+ *
+ * @param {HTMLFormElement=} form
+ */
+ constructor (form) {
+ /** @type {[string, string|File][]} */
+ this._data = []
+
+ const self = this
+ form && each(form.elements, (/** @type {HTMLInputElement} */ elm) => {
+ if (
+ !elm.name ||
+ elm.disabled ||
+ elm.type === 'submit' ||
+ elm.type === 'button' ||
+ elm.matches('form fieldset[disabled] *')
+ ) return
+
+ if (elm.type === 'file') {
+ const files = elm.files && elm.files.length
+ ? elm.files
+ : [new File([], '', { type: 'application/octet-stream' })] // #78
+
+ each(files, file => {
+ self.append(elm.name, file)
+ })
+ } else if (elm.type === 'select-multiple' || elm.type === 'select-one') {
+ each(elm.options, opt => {
+ !opt.disabled && opt.selected && self.append(elm.name, opt.value)
+ })
+ } else if (elm.type === 'checkbox' || elm.type === 'radio') {
+ if (elm.checked) self.append(elm.name, elm.value)
+ } else {
+ const value = elm.type === 'textarea' ? normalizeLinefeeds(elm.value) : elm.value
+ self.append(elm.name, value)
+ }
+ })
+ }
+
+ /**
+ * Append a field
+ *
+ * @param {string} name field name
+ * @param {string|Blob|File} value string / blob / file
+ * @param {string=} filename filename to use with blob
+ * @return {undefined}
+ */
+ append (name, value, filename) {
+ ensureArgs(arguments, 2)
+ this._data.push(normalizeArgs(name, value, filename))
+ }
+
+ /**
+ * Delete all fields values given name
+ *
+ * @param {string} name Field name
+ * @return {undefined}
+ */
+ delete (name) {
+ ensureArgs(arguments, 1)
+ const result = []
+ name = String(name)
+
+ each(this._data, entry => {
+ entry[0] !== name && result.push(entry)
+ })
+
+ this._data = result
+ }
+
+ /**
+ * Iterate over all fields as [name, value]
+ *
+ * @return {Iterator}
+ */
+ * entries () {
+ for (var i = 0; i < this._data.length; i++) {
+ yield this._data[i]
+ }
+ }
+
+ /**
+ * Iterate over all fields
+ *
+ * @param {Function} callback Executed for each item with parameters (value, name, thisArg)
+ * @param {Object=} thisArg `this` context for callback function
+ */
+ forEach (callback, thisArg) {
+ ensureArgs(arguments, 1)
+ for (const [name, value] of this) {
+ callback.call(thisArg, value, name, this)
+ }
+ }
+
+ /**
+ * Return first field value given name
+ * or null if non existent
+ *
+ * @param {string} name Field name
+ * @return {string|File|null} value Fields value
+ */
+ get (name) {
+ ensureArgs(arguments, 1)
+ const entries = this._data
+ name = String(name)
+ for (let i = 0; i < entries.length; i++) {
+ if (entries[i][0] === name) {
+ return entries[i][1]
+ }
+ }
+ return null
+ }
+
+ /**
+ * Return all fields values given name
+ *
+ * @param {string} name Fields name
+ * @return {Array} [{String|File}]
+ */
+ getAll (name) {
+ ensureArgs(arguments, 1)
+ const result = []
+ name = String(name)
+ each(this._data, data => {
+ data[0] === name && result.push(data[1])
+ })
+
+ return result
+ }
+
+ /**
+ * Check for field name existence
+ *
+ * @param {string} name Field name
+ * @return {boolean}
+ */
+ has (name) {
+ ensureArgs(arguments, 1)
+ name = String(name)
+ for (let i = 0; i < this._data.length; i++) {
+ if (this._data[i][0] === name) {
+ return true
+ }
+ }
+ return false
+ }
+
+ /**
+ * Iterate over all fields name
+ *
+ * @return {Iterator}
+ */
+ * keys () {
+ for (const [name] of this) {
+ yield name
+ }
+ }
+
+ /**
+ * Overwrite all values given name
+ *
+ * @param {string} name Filed name
+ * @param {string} value Field value
+ * @param {string=} filename Filename (optional)
+ */
+ set (name, value, filename) {
+ ensureArgs(arguments, 2)
+ name = String(name)
+ /** @type {[string, string|File][]} */
+ const result = []
+ const args = normalizeArgs(name, value, filename)
+ let replace = true
+
+ // - replace the first occurrence with same name
+ // - discards the remaining with same name
+ // - while keeping the same order items where added
+ each(this._data, data => {
+ data[0] === name
+ ? replace && (replace = !result.push(args))
+ : result.push(data)
+ })
+
+ replace && result.push(args)
+
+ this._data = result
+ }
+
+ /**
+ * Iterate over all fields
+ *
+ * @return {Iterator}
+ */
+ * values () {
+ for (const [, value] of this) {
+ yield value
+ }
+ }
+
+ /**
+ * Return a native (perhaps degraded) FormData with only a `append` method
+ * Can throw if it's not supported
+ *
+ * @return {FormData}
+ */
+ ['_asNative'] () {
+ const fd = new _FormData()
+
+ for (const [name, value] of this) {
+ fd.append(name, value)
+ }
+
+ return fd
+ }
+
+ /**
+ * [_blob description]
+ *
+ * @return {Blob} [description]
+ */
+ ['_blob'] () {
+ const boundary = '----formdata-polyfill-' + Math.random(),
+ chunks = [],
+ p = `--${boundary}\r\nContent-Disposition: form-data; name="`
+ this.forEach((value, name) => typeof value == 'string'
+ ? chunks.push(p + escape(normalizeLinefeeds(name)) + `"\r\n\r\n${normalizeLinefeeds(value)}\r\n`)
+ : chunks.push(p + escape(normalizeLinefeeds(name)) + `"; filename="${escape(value.name)}"\r\nContent-Type: ${value.type||"application/octet-stream"}\r\n\r\n`, value, `\r\n`))
+ chunks.push(`--${boundary}--`)
+ return new Blob(chunks, {
+ type: "multipart/form-data; boundary=" + boundary
+ })
+ }
+
+ /**
+ * The class itself is iterable
+ * alias for formdata.entries()
+ *
+ * @return {Iterator}
+ */
+ [Symbol.iterator] () {
+ return this.entries()
+ }
+
+ /**
+ * Create the default string description.
+ *
+ * @return {string} [object FormData]
+ */
+ toString () {
+ return '[object FormData]'
+ }
+ }
+
+ if (_match && !_match.matches) {
+ _match.matches =
+ _match.matchesSelector ||
+ _match.mozMatchesSelector ||
+ _match.msMatchesSelector ||
+ _match.oMatchesSelector ||
+ _match.webkitMatchesSelector ||
+ function (s) {
+ var matches = (this.document || this.ownerDocument).querySelectorAll(s)
+ var i = matches.length
+ while (--i >= 0 && matches.item(i) !== this) {}
+ return i > -1
+ }
+ }
+
+ if (stringTag) {
+ /**
+ * Create the default string description.
+ * It is accessed internally by the Object.prototype.toString().
+ */
+ FormDataPolyfill.prototype[stringTag] = 'FormData'
+ }
+
+ // Patch xhr's send method to call _blob transparently
+ if (_send) {
+ const setRequestHeader = global.XMLHttpRequest.prototype.setRequestHeader
+
+ global.XMLHttpRequest.prototype.setRequestHeader = function (name, value) {
+ setRequestHeader.call(this, name, value)
+ if (name.toLowerCase() === 'content-type') this._hasContentType = true
+ }
+
+ global.XMLHttpRequest.prototype.send = function (data) {
+ // need to patch send b/c old IE don't send blob's type (#44)
+ if (data instanceof FormDataPolyfill) {
+ const blob = data['_blob']()
+ if (!this._hasContentType) this.setRequestHeader('Content-Type', blob.type)
+ _send.call(this, blob)
+ } else {
+ _send.call(this, data)
+ }
+ }
+ }
+
+ // Patch fetch's function to call _blob transparently
+ if (_fetch) {
+ global.fetch = function (input, init) {
+ if (init && init.body && init.body instanceof FormDataPolyfill) {
+ init.body = init.body['_blob']()
+ }
+
+ return _fetch.call(this, input, init)
+ }
+ }
+
+ // Patch navigator.sendBeacon to use native FormData
+ if (_sendBeacon) {
+ global.navigator.sendBeacon = function (url, data) {
+ if (data instanceof FormDataPolyfill) {
+ data = data['_asNative']()
+ }
+ return _sendBeacon.call(this, url, data)
+ }
+ }
+
+ global['FormData'] = FormDataPolyfill
+}
diff --git a/node_modules/undici/LICENSE b/node_modules/formdata-polyfill/LICENSE
similarity index 95%
rename from node_modules/undici/LICENSE
rename to node_modules/formdata-polyfill/LICENSE
index e7323bb..fd0f555 100644
--- a/node_modules/undici/LICENSE
+++ b/node_modules/formdata-polyfill/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) Matteo Collina and Undici contributors
+Copyright (c) 2016 Jimmy Karl Roland Wärting
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/node_modules/formdata-polyfill/README.md b/node_modules/formdata-polyfill/README.md
new file mode 100644
index 0000000..8355299
--- /dev/null
+++ b/node_modules/formdata-polyfill/README.md
@@ -0,0 +1,145 @@
+### A `FormData` polyfill for the browser ...and a module for NodeJS (`New!`)
+
+```bash
+npm install formdata-polyfill
+```
+
+The browser polyfill will likely have done its part already, and i hope you stop supporting old browsers c",)
+But NodeJS still laks a proper FormData
The good old form-data package is a very old and isn't spec compatible and dose some abnormal stuff to construct and read FormData instances that other http libraries are not happy about when it comes to follow the spec.
+
+### The NodeJS / ESM version
+- The modular (~2.3 KiB minified uncompressed) version of this package is independent of any browser stuff and don't patch anything
+- It's as pure/spec compatible as it possible gets the test are run by WPT.
+- It's compatible with [node-fetch](https://github.com/node-fetch/node-fetch).
+- It have higher platform dependencies as it uses classes, symbols, ESM & private fields
+- Only dependency it has is [fetch-blob](https://github.com/node-fetch/fetch-blob)
+
+```js
+// Node example
+import fetch from 'node-fetch'
+import File from 'fetch-blob/file.js'
+import { fileFromSync } from 'fetch-blob/from.js'
+import { FormData } from 'formdata-polyfill/esm.min.js'
+
+const file = fileFromSync('./README.md')
+const fd = new FormData()
+
+fd.append('file-upload', new File(['abc'], 'hello-world.txt'))
+fd.append('file-upload', file)
+
+// it's also possible to append file/blob look-a-like items
+// if you have streams coming from other destinations
+fd.append('file-upload', {
+ size: 123,
+ type: '',
+ name: 'cat-video.mp4',
+ stream() { return stream },
+ [Symbol.toStringTag]: 'File'
+})
+
+fetch('https://httpbin.org/post', { method: 'POST', body: fd })
+```
+
+----
+
+It also comes with way to convert FormData into Blobs - it's not something that every developer should have to deal with.
+It's mainly for [node-fetch](https://github.com/node-fetch/node-fetch) and other http library to ease the process of serializing a FormData into a blob and just wish to deal with Blobs instead (Both Deno and Undici adapted a version of this [formDataToBlob](https://github.com/jimmywarting/FormData/blob/5ddea9e0de2fc5e246ab1b2f9d404dee0c319c02/formdata-to-blob.js) to the core and passes all WPT tests run by the browser itself)
+```js
+import { Readable } from 'node:stream'
+import { FormData, formDataToBlob } from 'formdata-polyfill/esm.min.js'
+
+const blob = formDataToBlob(new FormData())
+fetch('https://httpbin.org/post', { method: 'POST', body: blob })
+
+// node built in http and other similar http library have to do:
+const stream = Readable.from(blob.stream())
+const req = http.request('http://httpbin.org/post', {
+ method: 'post',
+ headers: {
+ 'Content-Length': blob.size,
+ 'Content-Type': blob.type
+ }
+})
+stream.pipe(req)
+```
+
+PS: blob & file that are appended to the FormData will not be read until any of the serialized blob read-methods gets called
+...so uploading very large files is no biggie
+
+### Browser polyfill
+
+usage:
+
+```js
+import 'formdata-polyfill' // that's it
+```
+
+The browser polyfill conditionally replaces the native implementation rather than fixing the missing functions,
+since otherwise there is no way to get or delete existing values in the FormData object.
+Therefore this also patches `XMLHttpRequest.prototype.send` and `fetch` to send the `FormData` as a blob,
+and `navigator.sendBeacon` to send native `FormData`.
+
+I was unable to patch the Response/Request constructor
+so if you are constructing them with FormData then you need to call `fd._blob()` manually.
+
+```js
+new Request(url, {
+ method: 'post',
+ body: fd._blob ? fd._blob() : fd
+})
+```
+
+Dependencies
+---
+
+If you need to support IE <= 9 then I recommend you to include eligrey's [blob.js]
+(which i hope you don't - since IE is now dead)
+
+
+ Updating from 2.x to 3.x
+
+Previously you had to import the polyfill and use that,
+since it didn't replace the global (existing) FormData implementation.
+But now it transparently calls `_blob()` for you when you are sending something with fetch or XHR,
+by way of monkey-patching the `XMLHttpRequest.prototype.send` and `fetch` functions.
+
+So you maybe had something like this:
+
+```javascript
+var FormData = require('formdata-polyfill')
+var fd = new FormData(form)
+xhr.send(fd._blob())
+```
+
+There is no longer anything exported from the module
+(though you of course still need to import it to install the polyfill),
+so you can now use the FormData object as normal:
+
+```javascript
+require('formdata-polyfill')
+var fd = new FormData(form)
+xhr.send(fd)
+```
+
+
+
+
+
+Native Browser compatibility (as of 2021-05-08)
+---
+Based on this you can decide for yourself if you need this polyfill.
+
+[](https://developer.mozilla.org/en-US/docs/Web/API/FormData#Browser_compatibility)
+
+
+
+This normalizes support for the FormData API:
+
+ - `append` with filename
+ - `delete()`, `get()`, `getAll()`, `has()`, `set()`
+ - `entries()`, `keys()`, `values()`, and support for `for...of`
+ - Available in web workers (just include the polyfill)
+
+ [npm-image]: https://img.shields.io/npm/v/formdata-polyfill.svg
+ [npm-url]: https://www.npmjs.com/package/formdata-polyfill
+ [blob.js]: https://github.com/eligrey/Blob.js
diff --git a/node_modules/formdata-polyfill/esm.min.d.ts b/node_modules/formdata-polyfill/esm.min.d.ts
new file mode 100644
index 0000000..b45f42e
--- /dev/null
+++ b/node_modules/formdata-polyfill/esm.min.d.ts
@@ -0,0 +1,5 @@
+export declare const FormData: {
+ new (): FormData;
+ prototype: FormData;
+};
+export declare function formDataToBlob(formData: FormData): Blob;
diff --git a/node_modules/formdata-polyfill/esm.min.js b/node_modules/formdata-polyfill/esm.min.js
new file mode 100644
index 0000000..745ca29
--- /dev/null
+++ b/node_modules/formdata-polyfill/esm.min.js
@@ -0,0 +1,40 @@
+/*! formdata-polyfill. MIT License. Jimmy Wärting */
+
+import C from 'fetch-blob'
+import F from 'fetch-blob/file.js'
+
+var {toStringTag:t,iterator:i,hasInstance:h}=Symbol,
+r=Math.random,
+m='append,set,get,getAll,delete,keys,values,entries,forEach,constructor'.split(','),
+f=(a,b,c)=>(a+='',/^(Blob|File)$/.test(b && b[t])?[(c=c!==void 0?c+'':b[t]=='File'?b.name:'blob',a),b.name!==c||b[t]=='blob'?new F([b],c,b):b]:[a,b+'']),
+e=(c,f)=>(f?c:c.replace(/\r?\n|\r/g,'\r\n')).replace(/\n/g,'%0A').replace(/\r/g,'%0D').replace(/"/g,'%22'),
+x=(n, a, e)=>{if(a.lengthtypeof o[m]!='function')}
+append(...a){x('append',arguments,2);this.#d.push(f(...a))}
+delete(a){x('delete',arguments,1);a+='';this.#d=this.#d.filter(([b])=>b!==a)}
+get(a){x('get',arguments,1);a+='';for(var b=this.#d,l=b.length,c=0;cc[0]===a&&b.push(c[1]));return b}
+has(a){x('has',arguments,1);a+='';return this.#d.some(b=>b[0]===a)}
+forEach(a,b){x('forEach',arguments,1);for(var [c,d]of this)a.call(b,d,c,this)}
+set(...a){x('set',arguments,2);var b=[],c=!0;a=f(...a);this.#d.forEach(d=>{d[0]===a[0]?c&&(c=!b.push(a)):b.push(d)});c&&b.push(a);this.#d=b}
+*entries(){yield*this.#d}
+*keys(){for(var[a]of this)yield a}
+*values(){for(var[,a]of this)yield a}}
+
+/** @param {FormData} F */
+export function formDataToBlob (F,B=C){
+var b=`${r()}${r()}`.replace(/\./g, '').slice(-28).padStart(32, '-'),c=[],p=`--${b}\r\nContent-Disposition: form-data; name="`
+F.forEach((v,n)=>typeof v=='string'
+?c.push(p+e(n)+`"\r\n\r\n${v.replace(/\r(?!\n)|(? */
+
+const escape = (str, filename) =>
+ (filename ? str : str.replace(/\r?\n|\r/g, '\r\n'))
+ .replace(/\n/g, '%0A')
+ .replace(/\r/g, '%0D')
+ .replace(/"/g, '%22')
+
+/**
+ * pure function to convert any formData instance to a Blob
+ * instances synchronous without reading all of the files
+ *
+ * @param {FormData|*} formData an instance of a formData Class
+ * @param {Blob|*} [BlobClass=Blob] the Blob class to use when constructing it
+ */
+export function formDataToBlob (formData, BlobClass = Blob) {
+ const boundary = ('----formdata-polyfill-' + Math.random())
+ const chunks = []
+ const prefix = `--${boundary}\r\nContent-Disposition: form-data; name="`
+
+ for (let [name, value] of formData) {
+ if (typeof value === 'string') {
+ chunks.push(prefix + escape(name) + `"\r\n\r\n${value.replace(/\r(?!\n)|(? */
+;(function(){var h;function l(a){var b=0;return function(){return b>>0)+"_",e=0;return b});
+r("Symbol.iterator",function(a){if(a)return a;a=Symbol("Symbol.iterator");for(var b="Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array".split(" "),c=0;c=12.20.0"
+ },
+ "keywords": [
+ "formdata",
+ "fetch",
+ "node-fetch",
+ "html5",
+ "browser",
+ "polyfill"
+ ],
+ "author": "Jimmy Wärting",
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/jimmywarting/FormData/issues"
+ },
+ "homepage": "https://github.com/jimmywarting/FormData#readme",
+ "dependencies": {
+ "fetch-blob": "^3.1.2"
+ },
+ "devDependencies": {
+ "@types/google-closure-compiler": "^0.0.19",
+ "@types/node": "^16.7.10",
+ "google-closure-compiler": "^20210808.0.0"
+ }
+}
diff --git a/node_modules/node-domexception/.history/README_20210527203617.md b/node_modules/node-domexception/.history/README_20210527203617.md
new file mode 100644
index 0000000..38d8f85
--- /dev/null
+++ b/node_modules/node-domexception/.history/README_20210527203617.md
@@ -0,0 +1,2 @@
+# node-domexception
+An implementation of the DOMException class from NodeJS
diff --git a/node_modules/node-domexception/.history/README_20210527212714.md b/node_modules/node-domexception/.history/README_20210527212714.md
new file mode 100644
index 0000000..eed1d13
--- /dev/null
+++ b/node_modules/node-domexception/.history/README_20210527212714.md
@@ -0,0 +1,41 @@
+# DOMException
+An implementation of the DOMException class from NodeJS
+
+This package implements the [`DOMException`](https://developer.mozilla.org/en-US/docs/Web/API/DOMException) class, from NodeJS itself.
+NodeJS has DOMException built in, but it's not globally available, and you can't require/import it from somewhere.
+
+The only possible way is to use some web-ish tools that have been introduced into NodeJS that throws an error and catch the constructor.
+This way you will have the same class that NodeJS has and you can check if the error is a instance of DOMException.
+The instanceof check would not have worked with a custom class such as the DOMexception provided by domenic which also is much larger in size.
+
+```js
+import DOMException from 'node-domexception'
+
+hello().catch(err => {
+ if (err instanceof DOMException) {
+ ...
+ }
+})
+
+const e1 = new DOMException("Something went wrong", "BadThingsError");
+console.assert(e1.name === "BadThingsError");
+console.assert(e1.code === 0);
+
+const e2 = new DOMException("Another exciting error message", "NoModificationAllowedError");
+console.assert(e2.name === "NoModificationAllowedError");
+console.assert(e2.code === 7);
+
+console.assert(DOMException.INUSE_ATTRIBUTE_ERR === 10);
+```
+
+## APIs
+
+This package exposes two flavors of the `DOMException` interface depending on the imported module.
+
+### `domexception` module
+
+This module default-exports the `DOMException` interface constructor.
+
+### `domexception/webidl2js-wrapper` module
+
+This module exports the `DOMException` [interface wrapper API](https://github.com/jsdom/webidl2js#for-interfaces) generated by [webidl2js](https://github.com/jsdom/webidl2js).
diff --git a/node_modules/node-domexception/.history/README_20210527213345.md b/node_modules/node-domexception/.history/README_20210527213345.md
new file mode 100644
index 0000000..5825416
--- /dev/null
+++ b/node_modules/node-domexception/.history/README_20210527213345.md
@@ -0,0 +1,36 @@
+# DOMException
+An implementation of the DOMException class from NodeJS
+
+This package implements the [`DOMException`](https://developer.mozilla.org/en-US/docs/Web/API/DOMException) class, from NodeJS itself. (including the legacy codes)
+NodeJS has DOMException built in, but it's not globally available, and you can't require/import it from somewhere.
+
+The only possible way is to use some web-ish tools that have been introduced into NodeJS that throws an error and catch the constructor.
+This way you will have the same class that NodeJS has and you can check if the error is a instance of DOMException.
+The instanceof check would not have worked with a custom class such as the DOMException provided by domenic which also is much larger in size.
+
+```js
+import DOMException from 'node-domexception'
+import { MessageChannel } from 'worker_threads'
+
+async function hello() {
+ const port = new MessageChannel().port1
+ const ab = new ArrayBuffer()
+ port.postMessage(ab, [ab, ab])
+}
+
+hello().catch(err => {
+ console.assert(err.name === 'DataCloneError')
+ console.assert(err.code === 25)
+ console.assert(err instanceof DOMException)
+})
+
+const e1 = new DOMException('Something went wrong', 'BadThingsError')
+console.assert(e1.name === 'BadThingsError')
+console.assert(e1.code === 0)
+
+const e2 = new DOMException('Another exciting error message', 'NoModificationAllowedError')
+console.assert(e2.name === 'NoModificationAllowedError')
+console.assert(e2.code === 7)
+
+console.assert(DOMException.INUSE_ATTRIBUTE_ERR === 10)
+```
diff --git a/node_modules/node-domexception/.history/README_20210527213411.md b/node_modules/node-domexception/.history/README_20210527213411.md
new file mode 100644
index 0000000..4c21ec8
--- /dev/null
+++ b/node_modules/node-domexception/.history/README_20210527213411.md
@@ -0,0 +1,36 @@
+# DOMException
+An implementation of the DOMException class from NodeJS
+
+This package implements the [`DOMException`](https://developer.mozilla.org/en-US/docs/Web/API/DOMException) class that comes from NodeJS itself. (including the legacy codes)
+NodeJS has DOMException built in, but it's not globally available, and you can't require/import it from somewhere.
+
+The only possible way is to use some web-ish tools that have been introduced into NodeJS that throws an error and catch the constructor.
+This way you will have the same class that NodeJS has and you can check if the error is a instance of DOMException.
+The instanceof check would not have worked with a custom class such as the DOMException provided by domenic which also is much larger in size.
+
+```js
+import DOMException from 'node-domexception'
+import { MessageChannel } from 'worker_threads'
+
+async function hello() {
+ const port = new MessageChannel().port1
+ const ab = new ArrayBuffer()
+ port.postMessage(ab, [ab, ab])
+}
+
+hello().catch(err => {
+ console.assert(err.name === 'DataCloneError')
+ console.assert(err.code === 25)
+ console.assert(err instanceof DOMException)
+})
+
+const e1 = new DOMException('Something went wrong', 'BadThingsError')
+console.assert(e1.name === 'BadThingsError')
+console.assert(e1.code === 0)
+
+const e2 = new DOMException('Another exciting error message', 'NoModificationAllowedError')
+console.assert(e2.name === 'NoModificationAllowedError')
+console.assert(e2.code === 7)
+
+console.assert(DOMException.INUSE_ATTRIBUTE_ERR === 10)
+```
diff --git a/node_modules/node-domexception/.history/README_20210527213803.md b/node_modules/node-domexception/.history/README_20210527213803.md
new file mode 100644
index 0000000..4cb8571
--- /dev/null
+++ b/node_modules/node-domexception/.history/README_20210527213803.md
@@ -0,0 +1,36 @@
+# DOMException
+An implementation of the DOMException class from NodeJS
+
+This package exposes the [`DOMException`](https://developer.mozilla.org/en-US/docs/Web/API/DOMException) class that comes from NodeJS itself. (including all of the deprecated legacy codes)
+NodeJS has it built in, but it's not globally available, and you can't require/import it from somewhere.
+
+The only possible way is to use some web-ish tools that have been introduced into NodeJS that throws an error and catch the constructor.
+This way you will have the same class that NodeJS has and you can check if the error is a instance of DOMException.
+The instanceof check would not have worked with a custom class such as the DOMException provided by domenic which also is much larger in size since it has to re-construct the hole class from the ground up.
+
+```js
+import DOMException from 'node-domexception'
+import { MessageChannel } from 'worker_threads'
+
+async function hello() {
+ const port = new MessageChannel().port1
+ const ab = new ArrayBuffer()
+ port.postMessage(ab, [ab, ab])
+}
+
+hello().catch(err => {
+ console.assert(err.name === 'DataCloneError')
+ console.assert(err.code === 25)
+ console.assert(err instanceof DOMException)
+})
+
+const e1 = new DOMException('Something went wrong', 'BadThingsError')
+console.assert(e1.name === 'BadThingsError')
+console.assert(e1.code === 0)
+
+const e2 = new DOMException('Another exciting error message', 'NoModificationAllowedError')
+console.assert(e2.name === 'NoModificationAllowedError')
+console.assert(e2.code === 7)
+
+console.assert(DOMException.INUSE_ATTRIBUTE_ERR === 10)
+```
diff --git a/node_modules/node-domexception/.history/README_20210527214323.md b/node_modules/node-domexception/.history/README_20210527214323.md
new file mode 100644
index 0000000..a32a91b
--- /dev/null
+++ b/node_modules/node-domexception/.history/README_20210527214323.md
@@ -0,0 +1,38 @@
+# DOMException
+An implementation of the DOMException class from NodeJS
+
+This package exposes the [`DOMException`](https://developer.mozilla.org/en-US/docs/Web/API/DOMException) class that comes from NodeJS itself. (including all of the deprecated legacy codes)
+NodeJS has it built in, but it's not globally available, and you can't require/import it from somewhere.
+
+The only possible way is to use some web-ish tools that have been introduced into NodeJS that throws an error and catch the constructor.
+This way you will have the same class that NodeJS has and you can check if the error is a instance of DOMException.
+The instanceof check would not have worked with a custom class such as the DOMException provided by domenic which also is much larger in size since it has to re-construct the hole class from the ground up.
+
+(plz don't depend on this package in any other environment other than node >=10.5)
+
+```js
+import DOMException from 'node-domexception'
+import { MessageChannel } from 'worker_threads'
+
+async function hello() {
+ const port = new MessageChannel().port1
+ const ab = new ArrayBuffer()
+ port.postMessage(ab, [ab, ab])
+}
+
+hello().catch(err => {
+ console.assert(err.name === 'DataCloneError')
+ console.assert(err.code === 25)
+ console.assert(err instanceof DOMException)
+})
+
+const e1 = new DOMException('Something went wrong', 'BadThingsError')
+console.assert(e1.name === 'BadThingsError')
+console.assert(e1.code === 0)
+
+const e2 = new DOMException('Another exciting error message', 'NoModificationAllowedError')
+console.assert(e2.name === 'NoModificationAllowedError')
+console.assert(e2.code === 7)
+
+console.assert(DOMException.INUSE_ATTRIBUTE_ERR === 10)
+```
diff --git a/node_modules/node-domexception/.history/README_20210527214408.md b/node_modules/node-domexception/.history/README_20210527214408.md
new file mode 100644
index 0000000..a32a91b
--- /dev/null
+++ b/node_modules/node-domexception/.history/README_20210527214408.md
@@ -0,0 +1,38 @@
+# DOMException
+An implementation of the DOMException class from NodeJS
+
+This package exposes the [`DOMException`](https://developer.mozilla.org/en-US/docs/Web/API/DOMException) class that comes from NodeJS itself. (including all of the deprecated legacy codes)
+NodeJS has it built in, but it's not globally available, and you can't require/import it from somewhere.
+
+The only possible way is to use some web-ish tools that have been introduced into NodeJS that throws an error and catch the constructor.
+This way you will have the same class that NodeJS has and you can check if the error is a instance of DOMException.
+The instanceof check would not have worked with a custom class such as the DOMException provided by domenic which also is much larger in size since it has to re-construct the hole class from the ground up.
+
+(plz don't depend on this package in any other environment other than node >=10.5)
+
+```js
+import DOMException from 'node-domexception'
+import { MessageChannel } from 'worker_threads'
+
+async function hello() {
+ const port = new MessageChannel().port1
+ const ab = new ArrayBuffer()
+ port.postMessage(ab, [ab, ab])
+}
+
+hello().catch(err => {
+ console.assert(err.name === 'DataCloneError')
+ console.assert(err.code === 25)
+ console.assert(err instanceof DOMException)
+})
+
+const e1 = new DOMException('Something went wrong', 'BadThingsError')
+console.assert(e1.name === 'BadThingsError')
+console.assert(e1.code === 0)
+
+const e2 = new DOMException('Another exciting error message', 'NoModificationAllowedError')
+console.assert(e2.name === 'NoModificationAllowedError')
+console.assert(e2.code === 7)
+
+console.assert(DOMException.INUSE_ATTRIBUTE_ERR === 10)
+```
diff --git a/node_modules/node-domexception/.history/index_20210527203842.js b/node_modules/node-domexception/.history/index_20210527203842.js
new file mode 100644
index 0000000..e69de29
diff --git a/node_modules/node-domexception/.history/index_20210527203947.js b/node_modules/node-domexception/.history/index_20210527203947.js
new file mode 100644
index 0000000..b9a8b76
--- /dev/null
+++ b/node_modules/node-domexception/.history/index_20210527203947.js
@@ -0,0 +1,8 @@
+const { MessageChannel } = require('worker_threads')
+
+if (!globalThis.DOMException) {
+ const port = new MessageChannel().port1
+ const ab = new ArrayBuffer()
+ try { port.postMessage(ab, [ab, ab]) }
+ catch (err) { globalThis.DOMException = err.constructor }
+}
diff --git a/node_modules/node-domexception/.history/index_20210527204259.js b/node_modules/node-domexception/.history/index_20210527204259.js
new file mode 100644
index 0000000..e9332a8
--- /dev/null
+++ b/node_modules/node-domexception/.history/index_20210527204259.js
@@ -0,0 +1,9 @@
+if (!globalThis.DOMException) {
+ const { MessageChannel } = require('worker_threads')
+ const port = new MessageChannel().port1
+ const ab = new ArrayBuffer()
+ try { port.postMessage(ab, [ab, ab]) }
+ catch (err) { globalThis.DOMException = err.constructor }
+}
+
+module.exports
diff --git a/node_modules/node-domexception/.history/index_20210527204418.js b/node_modules/node-domexception/.history/index_20210527204418.js
new file mode 100644
index 0000000..cb362cc
--- /dev/null
+++ b/node_modules/node-domexception/.history/index_20210527204418.js
@@ -0,0 +1,9 @@
+if (!globalThis.DOMException) {
+ const { MessageChannel } = require('worker_threads')
+ const port = new MessageChannel().port1
+ const ab = new ArrayBuffer()
+ try { port.postMessage(ab, [ab, ab]) }
+ catch (err) { globalThis.DOMException = err.constructor }
+}
+
+module.exports = globalThis.DOMException
diff --git a/node_modules/node-domexception/.history/index_20210527204756.js b/node_modules/node-domexception/.history/index_20210527204756.js
new file mode 100644
index 0000000..87d2655
--- /dev/null
+++ b/node_modules/node-domexception/.history/index_20210527204756.js
@@ -0,0 +1,11 @@
+/*! blob-to-buffer. MIT License. Jimmy Wärting */
+
+if (!globalThis.DOMException) {
+ const { MessageChannel } = require('worker_threads')
+ const port = new MessageChannel().port1
+ const ab = new ArrayBuffer()
+ try { port.postMessage(ab, [ab, ab]) }
+ catch (err) { globalThis.DOMException = err.constructor }
+}
+
+module.exports = globalThis.DOMException
diff --git a/node_modules/node-domexception/.history/index_20210527204833.js b/node_modules/node-domexception/.history/index_20210527204833.js
new file mode 100644
index 0000000..837ebda
--- /dev/null
+++ b/node_modules/node-domexception/.history/index_20210527204833.js
@@ -0,0 +1,11 @@
+/*! blob-to-buffer. MIT License. Jimmy Wärting */
+
+if (!globalThis.DOMException) {
+ const { MessageChannel } = require('worker_threads')
+ const port = new MessageChannel().port1
+ const ab = new ArrayBuffer()
+ try { port.postMessage(ab, [ab, ab]) }
+ catch (err) { globalThis.DOMException = err.constructor }
+}
+
+module.exports = globalThis.DOMException
diff --git a/node_modules/node-domexception/.history/index_20210527211208.js b/node_modules/node-domexception/.history/index_20210527211208.js
new file mode 100644
index 0000000..ba215ce
--- /dev/null
+++ b/node_modules/node-domexception/.history/index_20210527211208.js
@@ -0,0 +1,15 @@
+/*! blob-to-buffer. MIT License. Jimmy Wärting */
+
+if (!globalThis.DOMException) {
+ var { MessageChannel } = require('worker_threads'),
+ port = new MessageChannel().port1,
+ ab = new ArrayBuffer()
+ try { port.postMessage(ab, [ab, ab]) }
+ catch (err) {
+ err.constructor.name === 'DOMException' && (
+ globalThis.DOMException = err.constructor
+ )
+ }
+}
+
+module.exports = globalThis.DOMException
diff --git a/node_modules/node-domexception/.history/index_20210527211248.js b/node_modules/node-domexception/.history/index_20210527211248.js
new file mode 100644
index 0000000..f5c434e
--- /dev/null
+++ b/node_modules/node-domexception/.history/index_20210527211248.js
@@ -0,0 +1,15 @@
+/*! blob-to-buffer. MIT License. Jimmy Wärting */
+
+if (!globalThis.DOMException) {
+ const { MessageChannel } = require('worker_threads'),
+ port = new MessageChannel().port1,
+ ab = new ArrayBuffer()
+ try { port.postMessage(ab, [ab, ab]) }
+ catch (err) {
+ err.constructor.name === 'DOMException' && (
+ globalThis.DOMException = err.constructor
+ )
+ }
+}
+
+module.exports = globalThis.DOMException
diff --git a/node_modules/node-domexception/.history/index_20210527212722.js b/node_modules/node-domexception/.history/index_20210527212722.js
new file mode 100644
index 0000000..91b3b52
--- /dev/null
+++ b/node_modules/node-domexception/.history/index_20210527212722.js
@@ -0,0 +1,23 @@
+/*! blob-to-buffer. MIT License. Jimmy Wärting */
+
+if (!globalThis.DOMException) {
+ const { MessageChannel } = require('worker_threads'),
+ port = new MessageChannel().port1,
+ ab = new ArrayBuffer()
+ try { port.postMessage(ab, [ab, ab]) }
+ catch (err) {
+ err.constructor.name === 'DOMException' && (
+ globalThis.DOMException = err.constructor
+ )
+ }
+}
+
+module.exports = globalThis.DOMException
+
+const e1 = new DOMException("Something went wrong", "BadThingsError");
+console.assert(e1.name === "BadThingsError");
+console.assert(e1.code === 0);
+
+const e2 = new DOMException("Another exciting error message", "NoModificationAllowedError");
+console.assert(e2.name === "NoModificationAllowedError");
+console.assert(e2.code === 7);
diff --git a/node_modules/node-domexception/.history/index_20210527212731.js b/node_modules/node-domexception/.history/index_20210527212731.js
new file mode 100644
index 0000000..cf28864
--- /dev/null
+++ b/node_modules/node-domexception/.history/index_20210527212731.js
@@ -0,0 +1,23 @@
+/*! blob-to-buffer. MIT License. Jimmy Wärting */
+
+if (!globalThis.DOMException) {
+ const { MessageChannel } = require('worker_threads'),
+ port = new MessageChannel().port1,
+ ab = new ArrayBuffer()
+ try { port.postMessage(ab, [ab, ab]) }
+ catch (err) {
+ err.constructor.name === 'DOMException' && (
+ globalThis.DOMException = err.constructor
+ )
+ }
+}
+
+module.exports = globalThis.DOMException
+
+const e1 = new DOMException("Something went wrong", "BadThingsError");
+console.assert(e1.name === "BadThingsError");
+console.assert(e1.code === 0);
+
+const e2 = new DOMException("Another exciting error message", "NoModificationAllowedError");
+console.assert(e2.name === "NoModificationAllowedError");
+console.assert(e2.code === 2);
diff --git a/node_modules/node-domexception/.history/index_20210527212746.js b/node_modules/node-domexception/.history/index_20210527212746.js
new file mode 100644
index 0000000..f5c434e
--- /dev/null
+++ b/node_modules/node-domexception/.history/index_20210527212746.js
@@ -0,0 +1,15 @@
+/*! blob-to-buffer. MIT License. Jimmy Wärting */
+
+if (!globalThis.DOMException) {
+ const { MessageChannel } = require('worker_threads'),
+ port = new MessageChannel().port1,
+ ab = new ArrayBuffer()
+ try { port.postMessage(ab, [ab, ab]) }
+ catch (err) {
+ err.constructor.name === 'DOMException' && (
+ globalThis.DOMException = err.constructor
+ )
+ }
+}
+
+module.exports = globalThis.DOMException
diff --git a/node_modules/node-domexception/.history/index_20210527212900.js b/node_modules/node-domexception/.history/index_20210527212900.js
new file mode 100644
index 0000000..efa2442
--- /dev/null
+++ b/node_modules/node-domexception/.history/index_20210527212900.js
@@ -0,0 +1,16 @@
+/*! blob-to-buffer. MIT License. Jimmy Wärting */
+
+if (!globalThis.DOMException) {
+ const { MessageChannel } = require('worker_threads'),
+ port = new MessageChannel().port1,
+ ab = new ArrayBuffer()
+ try { port.postMessage(ab, [ab, ab]) }
+ catch (err) {
+ console.log(err.code)
+ err.constructor.name === 'DOMException' && (
+ globalThis.DOMException = err.constructor
+ )
+ }
+}
+
+module.exports = globalThis.DOMException
diff --git a/node_modules/node-domexception/.history/index_20210527213022.js b/node_modules/node-domexception/.history/index_20210527213022.js
new file mode 100644
index 0000000..e59f047
--- /dev/null
+++ b/node_modules/node-domexception/.history/index_20210527213022.js
@@ -0,0 +1,16 @@
+/*! blob-to-buffer. MIT License. Jimmy Wärting */
+
+if (!globalThis.DOMException) {
+ const { MessageChannel } = require('worker_threads'),
+ port = new MessageChannel().port1,
+ ab = new ArrayBuffer()
+ try { port.postMessage(ab, [ab, ab]) }
+ catch (err) {
+ console.log(err.code, err.name, err.message)
+ err.constructor.name === 'DOMException' && (
+ globalThis.DOMException = err.constructor
+ )
+ }
+}
+
+module.exports = globalThis.DOMException
diff --git a/node_modules/node-domexception/.history/index_20210527213822.js b/node_modules/node-domexception/.history/index_20210527213822.js
new file mode 100644
index 0000000..7f4e13d
--- /dev/null
+++ b/node_modules/node-domexception/.history/index_20210527213822.js
@@ -0,0 +1,16 @@
+/*! node-DOMException. MIT License. Jimmy Wärting */
+
+if (!globalThis.DOMException) {
+ const { MessageChannel } = require('worker_threads'),
+ port = new MessageChannel().port1,
+ ab = new ArrayBuffer()
+ try { port.postMessage(ab, [ab, ab]) }
+ catch (err) {
+ console.log(err.code, err.name, err.message)
+ err.constructor.name === 'DOMException' && (
+ globalThis.DOMException = err.constructor
+ )
+ }
+}
+
+module.exports = globalThis.DOMException
diff --git a/node_modules/node-domexception/.history/index_20210527213843.js b/node_modules/node-domexception/.history/index_20210527213843.js
new file mode 100644
index 0000000..ee75b73
--- /dev/null
+++ b/node_modules/node-domexception/.history/index_20210527213843.js
@@ -0,0 +1,17 @@
+/*! node-DOMException. MIT License. Jimmy Wärting */
+
+if (!globalThis.DOMException) {
+ try {
+ const { MessageChannel } = require('worker_threads'),
+ port = new MessageChannel().port1,
+ ab = new ArrayBuffer()
+ port.postMessage(ab, [ab, ab])
+ catch (err) {
+ console.log(err.code, err.name, err.message)
+ err.constructor.name === 'DOMException' && (
+ globalThis.DOMException = err.constructor
+ )
+ }
+}
+
+module.exports = globalThis.DOMException
diff --git a/node_modules/node-domexception/.history/index_20210527213852.js b/node_modules/node-domexception/.history/index_20210527213852.js
new file mode 100644
index 0000000..a82bee3
--- /dev/null
+++ b/node_modules/node-domexception/.history/index_20210527213852.js
@@ -0,0 +1,17 @@
+/*! node-DOMException. MIT License. Jimmy Wärting */
+
+if (!globalThis.DOMException) {
+ try {
+ const { MessageChannel } = require('worker_threads'),
+ port = new MessageChannel().port1,
+ ab = new ArrayBuffer()
+ port.postMessage(ab, [ab, ab])
+ } catch (err) {
+ console.log(err.code, err.name, err.message)
+ err.constructor.name === 'DOMException' && (
+ globalThis.DOMException = err.constructor
+ )
+ }
+}
+
+module.exports = globalThis.DOMException
diff --git a/node_modules/node-domexception/.history/index_20210527213910.js b/node_modules/node-domexception/.history/index_20210527213910.js
new file mode 100644
index 0000000..1e1ca29
--- /dev/null
+++ b/node_modules/node-domexception/.history/index_20210527213910.js
@@ -0,0 +1,16 @@
+/*! node-DOMException. MIT License. Jimmy Wärting */
+
+if (!globalThis.DOMException) {
+ try {
+ const { MessageChannel } = require('worker_threads'),
+ port = new MessageChannel().port1,
+ ab = new ArrayBuffer()
+ port.postMessage(ab, [ab, ab])
+ } catch (err) {
+ err.constructor.name === 'DOMException' && (
+ globalThis.DOMException = err.constructor
+ )
+ }
+}
+
+module.exports = globalThis.DOMException
diff --git a/node_modules/node-domexception/.history/index_20210527214034.js b/node_modules/node-domexception/.history/index_20210527214034.js
new file mode 100644
index 0000000..b7bbe95
--- /dev/null
+++ b/node_modules/node-domexception/.history/index_20210527214034.js
@@ -0,0 +1,16 @@
+/*! node-domexception. MIT License. Jimmy Wärting */
+
+if (!globalThis.DOMException) {
+ try {
+ const { MessageChannel } = require('worker_threads'),
+ port = new MessageChannel().port1,
+ ab = new ArrayBuffer()
+ port.postMessage(ab, [ab, ab])
+ } catch (err) {
+ err.constructor.name === 'DOMException' && (
+ globalThis.DOMException = err.constructor
+ )
+ }
+}
+
+module.exports = globalThis.DOMException
diff --git a/node_modules/node-domexception/.history/index_20210527214643.js b/node_modules/node-domexception/.history/index_20210527214643.js
new file mode 100644
index 0000000..92ed847
--- /dev/null
+++ b/node_modules/node-domexception/.history/index_20210527214643.js
@@ -0,0 +1,41 @@
+/*! node-domexception. MIT License. Jimmy Wärting */
+
+if (!globalThis.DOMException) {
+ try {
+ const { MessageChannel } = require('worker_threads'),
+ port = new MessageChannel().port1,
+ ab = new ArrayBuffer()
+ port.postMessage(ab, [ab, ab])
+ } catch (err) {
+ err.constructor.name === 'DOMException' && (
+ globalThis.DOMException = err.constructor
+ )
+ }
+}
+
+module.exports = globalThis.DOMException
+
+
+const { MessageChannel } = require('worker_threads')
+
+async function hello() {
+ const port = new MessageChannel().port1
+ const ab = new ArrayBuffer()
+ port.postMessage(ab, [ab, ab])
+}
+
+hello().catch(err => {
+ console.assert(err.name === 'DataCloneError')
+ console.assert(err.code === 25)
+ console.assert(err instanceof DOMException)
+})
+
+const e1 = new DOMException('Something went wrong', 'BadThingsError')
+console.assert(e1.name === 'BadThingsError')
+console.assert(e1.code === 0)
+
+const e2 = new DOMException('Another exciting error message', 'NoModificationAllowedError')
+console.assert(e2.name === 'NoModificationAllowedError')
+console.assert(e2.code === 7)
+
+console.assert(DOMException.INUSE_ATTRIBUTE_ERR === 10)
diff --git a/node_modules/node-domexception/.history/index_20210527214654.js b/node_modules/node-domexception/.history/index_20210527214654.js
new file mode 100644
index 0000000..6d5cb8e
--- /dev/null
+++ b/node_modules/node-domexception/.history/index_20210527214654.js
@@ -0,0 +1,41 @@
+/*! node-domexception. MIT License. Jimmy Wärting */
+
+if (!globalThis.DOMException) {
+ try {
+ const { MessageChannel } = require('worker_threads'),
+ port = new MessageChannel().port1,
+ ab = new ArrayBuffer()
+ port.postMessage(ab, [ab, ab])
+ } catch (err) {
+ err.constructor.name === 'DOMException' && (
+ globalThis.DOMException = err.constructor
+ )
+ }
+}
+
+module.exports = globalThis.DOMException
+
+
+const { MessageChannel } = require('worker_threads')
+
+async function hello() {
+ const port = new MessageChannel().port1
+ const ab = new ArrayBuffer()
+ port.postMessage(ab, [ab, ab])
+}
+
+hello().catch(err => {
+ console.assert(err.name === 'DataCloneError')
+ console.assert(err.code === 21)
+ console.assert(err instanceof DOMException)
+})
+
+const e1 = new DOMException('Something went wrong', 'BadThingsError')
+console.assert(e1.name === 'BadThingsError')
+console.assert(e1.code === 0)
+
+const e2 = new DOMException('Another exciting error message', 'NoModificationAllowedError')
+console.assert(e2.name === 'NoModificationAllowedError')
+console.assert(e2.code === 7)
+
+console.assert(DOMException.INUSE_ATTRIBUTE_ERR === 10)
diff --git a/node_modules/node-domexception/.history/index_20210527214700.js b/node_modules/node-domexception/.history/index_20210527214700.js
new file mode 100644
index 0000000..b7bbe95
--- /dev/null
+++ b/node_modules/node-domexception/.history/index_20210527214700.js
@@ -0,0 +1,16 @@
+/*! node-domexception. MIT License. Jimmy Wärting */
+
+if (!globalThis.DOMException) {
+ try {
+ const { MessageChannel } = require('worker_threads'),
+ port = new MessageChannel().port1,
+ ab = new ArrayBuffer()
+ port.postMessage(ab, [ab, ab])
+ } catch (err) {
+ err.constructor.name === 'DOMException' && (
+ globalThis.DOMException = err.constructor
+ )
+ }
+}
+
+module.exports = globalThis.DOMException
diff --git a/node_modules/node-domexception/.history/package_20210527203733.json b/node_modules/node-domexception/.history/package_20210527203733.json
new file mode 100644
index 0000000..5eeb306
--- /dev/null
+++ b/node_modules/node-domexception/.history/package_20210527203733.json
@@ -0,0 +1,19 @@
+{
+ "name": "domexception",
+ "version": "1.0.0",
+ "description": "An implementation of the DOMException class from NodeJS",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/jimmywarting/node-domexception.git"
+ },
+ "author": "",
+ "license": "ISC",
+ "bugs": {
+ "url": "https://github.com/jimmywarting/node-domexception/issues"
+ },
+ "homepage": "https://github.com/jimmywarting/node-domexception#readme"
+}
diff --git a/node_modules/node-domexception/.history/package_20210527203825.json b/node_modules/node-domexception/.history/package_20210527203825.json
new file mode 100644
index 0000000..4ca1713
--- /dev/null
+++ b/node_modules/node-domexception/.history/package_20210527203825.json
@@ -0,0 +1,16 @@
+{
+ "name": "node-domexception",
+ "version": "1.0.0",
+ "description": "An implementation of the DOMException class from NodeJS",
+ "main": "index.js",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/jimmywarting/node-domexception.git"
+ },
+ "author": "Jimmy Wärting",
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/jimmywarting/node-domexception/issues"
+ },
+ "homepage": "https://github.com/jimmywarting/node-domexception#readme"
+}
diff --git a/node_modules/node-domexception/.history/package_20210527204621.json b/node_modules/node-domexception/.history/package_20210527204621.json
new file mode 100644
index 0000000..3c414e9
--- /dev/null
+++ b/node_modules/node-domexception/.history/package_20210527204621.json
@@ -0,0 +1,19 @@
+{
+ "name": "node-domexception",
+ "version": "1.0.0",
+ "description": "An implementation of the DOMException class from NodeJS",
+ "main": "index.js",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/jimmywarting/node-domexception.git"
+ },
+ "engines": {
+ "node": ">=10.5.0"
+ },
+ "author": "Jimmy Wärting",
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/jimmywarting/node-domexception/issues"
+ },
+ "homepage": "https://github.com/jimmywarting/node-domexception#readme"
+}
diff --git a/node_modules/node-domexception/.history/package_20210527204913.json b/node_modules/node-domexception/.history/package_20210527204913.json
new file mode 100644
index 0000000..dbbb5d2
--- /dev/null
+++ b/node_modules/node-domexception/.history/package_20210527204913.json
@@ -0,0 +1,25 @@
+{
+ "name": "node-domexception",
+ "version": "1.0.0",
+ "description": "An implementation of the DOMException class from NodeJS",
+ "main": "index.js",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/jimmywarting/node-domexception.git"
+ },
+ "engines": {
+ "node": ">=10.5.0"
+ },
+ "author": "Jimmy Wärting",
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/jimmywarting/node-domexception/issues"
+ },
+ "homepage": "https://github.com/jimmywarting/node-domexception#readme",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/jimmywarting"
+ }
+ ]
+}
diff --git a/node_modules/node-domexception/.history/package_20210527204925.json b/node_modules/node-domexception/.history/package_20210527204925.json
new file mode 100644
index 0000000..dbbb5d2
--- /dev/null
+++ b/node_modules/node-domexception/.history/package_20210527204925.json
@@ -0,0 +1,25 @@
+{
+ "name": "node-domexception",
+ "version": "1.0.0",
+ "description": "An implementation of the DOMException class from NodeJS",
+ "main": "index.js",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/jimmywarting/node-domexception.git"
+ },
+ "engines": {
+ "node": ">=10.5.0"
+ },
+ "author": "Jimmy Wärting",
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/jimmywarting/node-domexception/issues"
+ },
+ "homepage": "https://github.com/jimmywarting/node-domexception#readme",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/jimmywarting"
+ }
+ ]
+}
diff --git a/node_modules/node-domexception/.history/package_20210527205145.json b/node_modules/node-domexception/.history/package_20210527205145.json
new file mode 100644
index 0000000..cd08e70
--- /dev/null
+++ b/node_modules/node-domexception/.history/package_20210527205145.json
@@ -0,0 +1,29 @@
+{
+ "name": "node-domexception",
+ "version": "1.0.0",
+ "description": "An implementation of the DOMException class from NodeJS",
+ "main": "index.js",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/jimmywarting/node-domexception.git"
+ },
+ "engines": {
+ "node": ">=10.5.0"
+ },
+ "author": "Jimmy Wärting",
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/jimmywarting/node-domexception/issues"
+ },
+ "homepage": "https://github.com/jimmywarting/node-domexception#readme",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/jimmywarting"
+ },
+ {
+ "type": "github",
+ "url": "https://paypal.me/jimmywarting"
+ }
+ ]
+}
diff --git a/node_modules/node-domexception/.history/package_20210527205156.json b/node_modules/node-domexception/.history/package_20210527205156.json
new file mode 100644
index 0000000..cd08e70
--- /dev/null
+++ b/node_modules/node-domexception/.history/package_20210527205156.json
@@ -0,0 +1,29 @@
+{
+ "name": "node-domexception",
+ "version": "1.0.0",
+ "description": "An implementation of the DOMException class from NodeJS",
+ "main": "index.js",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/jimmywarting/node-domexception.git"
+ },
+ "engines": {
+ "node": ">=10.5.0"
+ },
+ "author": "Jimmy Wärting",
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/jimmywarting/node-domexception/issues"
+ },
+ "homepage": "https://github.com/jimmywarting/node-domexception#readme",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/jimmywarting"
+ },
+ {
+ "type": "github",
+ "url": "https://paypal.me/jimmywarting"
+ }
+ ]
+}
diff --git a/node_modules/node-domexception/.history/test_20210527205603.js b/node_modules/node-domexception/.history/test_20210527205603.js
new file mode 100644
index 0000000..e69de29
diff --git a/node_modules/node-domexception/.history/test_20210527205957.js b/node_modules/node-domexception/.history/test_20210527205957.js
new file mode 100644
index 0000000..73feac5
--- /dev/null
+++ b/node_modules/node-domexception/.history/test_20210527205957.js
@@ -0,0 +1,3 @@
+require('./index.js')
+
+console.log(DOMException.INDEX_SIZE_ERR)
diff --git a/node_modules/node-domexception/.history/test_20210527210021.js b/node_modules/node-domexception/.history/test_20210527210021.js
new file mode 100644
index 0000000..be47491
--- /dev/null
+++ b/node_modules/node-domexception/.history/test_20210527210021.js
@@ -0,0 +1,3 @@
+const e = require('./index.js')
+
+console.log(e.INDEX_SIZE_ERR)
diff --git a/node_modules/node-domexception/LICENSE b/node_modules/node-domexception/LICENSE
new file mode 100644
index 0000000..bc8ceb7
--- /dev/null
+++ b/node_modules/node-domexception/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 Jimmy Wärting
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/node_modules/node-domexception/README.md b/node_modules/node-domexception/README.md
new file mode 100644
index 0000000..a369461
--- /dev/null
+++ b/node_modules/node-domexception/README.md
@@ -0,0 +1,46 @@
+# DOMException
+An implementation of the DOMException class from NodeJS
+
+NodeJS has DOMException built in, but it's not globally available, and you can't require/import it from somewhere.
+
+This package exposes the [`DOMException`](https://developer.mozilla.org/en-US/docs/Web/API/DOMException) class that comes from NodeJS itself. (including all of the legacy codes)
+
+(plz don't depend on this package in any other environment other than node >=10.5)
+
+```js
+import DOMException from 'node-domexception'
+import { MessageChannel } from 'worker_threads'
+
+async function hello() {
+ const port = new MessageChannel().port1
+ const ab = new ArrayBuffer()
+ port.postMessage(ab, [ab, ab])
+}
+
+hello().catch(err => {
+ console.assert(err.name === 'DataCloneError')
+ console.assert(err.code === 25)
+ console.assert(err instanceof DOMException)
+})
+
+const e1 = new DOMException('Something went wrong', 'BadThingsError')
+console.assert(e1.name === 'BadThingsError')
+console.assert(e1.code === 0)
+
+const e2 = new DOMException('Another exciting error message', 'NoModificationAllowedError')
+console.assert(e2.name === 'NoModificationAllowedError')
+console.assert(e2.code === 7)
+
+console.assert(DOMException.INUSE_ATTRIBUTE_ERR === 10)
+```
+
+# Background
+
+The only possible way is to use some web-ish tools that have been introduced into NodeJS that throws a DOMException and catch the constructor. This is exactly what this package dose for you and exposes it.
+This way you will have the same class that NodeJS has and you can check if the error is a instance of DOMException.
+The instanceof check would not have worked with a custom class such as the DOMException provided by domenic which also is much larger in size since it has to re-construct the hole class from the ground up.
+
+The DOMException is used in many places such as the Fetch API, File & Blobs, PostMessaging and more.
+Why they decided to call it **DOM**, I don't know
+
+Please consider sponsoring if you find this helpful
diff --git a/node_modules/node-domexception/index.js b/node_modules/node-domexception/index.js
new file mode 100644
index 0000000..b7bbe95
--- /dev/null
+++ b/node_modules/node-domexception/index.js
@@ -0,0 +1,16 @@
+/*! node-domexception. MIT License. Jimmy Wärting */
+
+if (!globalThis.DOMException) {
+ try {
+ const { MessageChannel } = require('worker_threads'),
+ port = new MessageChannel().port1,
+ ab = new ArrayBuffer()
+ port.postMessage(ab, [ab, ab])
+ } catch (err) {
+ err.constructor.name === 'DOMException' && (
+ globalThis.DOMException = err.constructor
+ )
+ }
+}
+
+module.exports = globalThis.DOMException
diff --git a/node_modules/node-domexception/package.json b/node_modules/node-domexception/package.json
new file mode 100644
index 0000000..cd08e70
--- /dev/null
+++ b/node_modules/node-domexception/package.json
@@ -0,0 +1,29 @@
+{
+ "name": "node-domexception",
+ "version": "1.0.0",
+ "description": "An implementation of the DOMException class from NodeJS",
+ "main": "index.js",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/jimmywarting/node-domexception.git"
+ },
+ "engines": {
+ "node": ">=10.5.0"
+ },
+ "author": "Jimmy Wärting",
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/jimmywarting/node-domexception/issues"
+ },
+ "homepage": "https://github.com/jimmywarting/node-domexception#readme",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/jimmywarting"
+ },
+ {
+ "type": "github",
+ "url": "https://paypal.me/jimmywarting"
+ }
+ ]
+}
diff --git a/node_modules/node-fetch/@types/index.d.ts b/node_modules/node-fetch/@types/index.d.ts
new file mode 100644
index 0000000..2a482f6
--- /dev/null
+++ b/node_modules/node-fetch/@types/index.d.ts
@@ -0,0 +1,219 @@
+///
+///
+
+import {RequestOptions} from 'http';
+import {FormData} from 'formdata-polyfill/esm.min.js';
+import {
+ Blob,
+ blobFrom,
+ blobFromSync,
+ File,
+ fileFrom,
+ fileFromSync
+} from 'fetch-blob/from.js';
+
+type AbortSignal = {
+ readonly aborted: boolean;
+
+ addEventListener: (type: 'abort', listener: (this: AbortSignal) => void) => void;
+ removeEventListener: (type: 'abort', listener: (this: AbortSignal) => void) => void;
+};
+
+export type HeadersInit = Headers | Record | Iterable | Iterable>;
+
+export {
+ FormData,
+ Blob,
+ blobFrom,
+ blobFromSync,
+ File,
+ fileFrom,
+ fileFromSync
+};
+
+/**
+ * This Fetch API interface allows you to perform various actions on HTTP request and response headers.
+ * These actions include retrieving, setting, adding to, and removing.
+ * A Headers object has an associated header list, which is initially empty and consists of zero or more name and value pairs.
+ * You can add to this using methods like append() (see Examples.)
+ * In all methods of this interface, header names are matched by case-insensitive byte sequence.
+ * */
+export class Headers {
+ constructor(init?: HeadersInit);
+
+ append(name: string, value: string): void;
+ delete(name: string): void;
+ get(name: string): string | null;
+ has(name: string): boolean;
+ set(name: string, value: string): void;
+ forEach(
+ callbackfn: (value: string, key: string, parent: Headers) => void,
+ thisArg?: any
+ ): void;
+
+ [Symbol.iterator](): IterableIterator<[string, string]>;
+ /**
+ * Returns an iterator allowing to go through all key/value pairs contained in this object.
+ */
+ entries(): IterableIterator<[string, string]>;
+ /**
+ * Returns an iterator allowing to go through all keys of the key/value pairs contained in this object.
+ */
+ keys(): IterableIterator;
+ /**
+ * Returns an iterator allowing to go through all values of the key/value pairs contained in this object.
+ */
+ values(): IterableIterator;
+
+ /** Node-fetch extension */
+ raw(): Record;
+}
+
+export interface RequestInit {
+ /**
+ * A BodyInit object or null to set request's body.
+ */
+ body?: BodyInit | null;
+ /**
+ * A Headers object, an object literal, or an array of two-item arrays to set request's headers.
+ */
+ headers?: HeadersInit;
+ /**
+ * A string to set request's method.
+ */
+ method?: string;
+ /**
+ * A string indicating whether request follows redirects, results in an error upon encountering a redirect, or returns the redirect (in an opaque fashion). Sets request's redirect.
+ */
+ redirect?: RequestRedirect;
+ /**
+ * An AbortSignal to set request's signal.
+ */
+ signal?: AbortSignal | null;
+ /**
+ * A string whose value is a same-origin URL, "about:client", or the empty string, to set request’s referrer.
+ */
+ referrer?: string;
+ /**
+ * A referrer policy to set request’s referrerPolicy.
+ */
+ referrerPolicy?: ReferrerPolicy;
+
+ // Node-fetch extensions to the whatwg/fetch spec
+ agent?: RequestOptions['agent'] | ((parsedUrl: URL) => RequestOptions['agent']);
+ compress?: boolean;
+ counter?: number;
+ follow?: number;
+ hostname?: string;
+ port?: number;
+ protocol?: string;
+ size?: number;
+ highWaterMark?: number;
+ insecureHTTPParser?: boolean;
+}
+
+export interface ResponseInit {
+ headers?: HeadersInit;
+ status?: number;
+ statusText?: string;
+}
+
+export type BodyInit =
+ | Blob
+ | Buffer
+ | URLSearchParams
+ | FormData
+ | NodeJS.ReadableStream
+ | string;
+declare class BodyMixin {
+ constructor(body?: BodyInit, options?: {size?: number});
+
+ readonly body: NodeJS.ReadableStream | null;
+ readonly bodyUsed: boolean;
+ readonly size: number;
+
+ /** @deprecated Use `body.arrayBuffer()` instead. */
+ buffer(): Promise;
+ arrayBuffer(): Promise;
+ formData(): Promise;
+ blob(): Promise;
+ json(): Promise;
+ text(): Promise;
+}
+
+// `Body` must not be exported as a class since it's not exported from the JavaScript code.
+export interface Body extends Pick {}
+
+export type RequestRedirect = 'error' | 'follow' | 'manual';
+export type ReferrerPolicy = '' | 'no-referrer' | 'no-referrer-when-downgrade' | 'same-origin' | 'origin' | 'strict-origin' | 'origin-when-cross-origin' | 'strict-origin-when-cross-origin' | 'unsafe-url';
+export type RequestInfo = string | Request;
+export class Request extends BodyMixin {
+ constructor(input: RequestInfo, init?: RequestInit);
+
+ /**
+ * Returns a Headers object consisting of the headers associated with request. Note that headers added in the network layer by the user agent will not be accounted for in this object, e.g., the "Host" header.
+ */
+ readonly headers: Headers;
+ /**
+ * Returns request's HTTP method, which is "GET" by default.
+ */
+ readonly method: string;
+ /**
+ * Returns the redirect mode associated with request, which is a string indicating how redirects for the request will be handled during fetching. A request will follow redirects by default.
+ */
+ readonly redirect: RequestRedirect;
+ /**
+ * Returns the signal associated with request, which is an AbortSignal object indicating whether or not request has been aborted, and its abort event handler.
+ */
+ readonly signal: AbortSignal;
+ /**
+ * Returns the URL of request as a string.
+ */
+ readonly url: string;
+ /**
+ * A string whose value is a same-origin URL, "about:client", or the empty string, to set request’s referrer.
+ */
+ readonly referrer: string;
+ /**
+ * A referrer policy to set request’s referrerPolicy.
+ */
+ readonly referrerPolicy: ReferrerPolicy;
+ clone(): Request;
+}
+
+type ResponseType = 'basic' | 'cors' | 'default' | 'error' | 'opaque' | 'opaqueredirect';
+
+export class Response extends BodyMixin {
+ constructor(body?: BodyInit | null, init?: ResponseInit);
+
+ readonly headers: Headers;
+ readonly ok: boolean;
+ readonly redirected: boolean;
+ readonly status: number;
+ readonly statusText: string;
+ readonly type: ResponseType;
+ readonly url: string;
+ clone(): Response;
+
+ static error(): Response;
+ static redirect(url: string, status?: number): Response;
+}
+
+export class FetchError extends Error {
+ constructor(message: string, type: string, systemError?: Record);
+
+ name: 'FetchError';
+ [Symbol.toStringTag]: 'FetchError';
+ type: string;
+ code?: string;
+ errno?: string;
+}
+
+export class AbortError extends Error {
+ type: string;
+ name: 'AbortError';
+ [Symbol.toStringTag]: 'AbortError';
+}
+
+export function isRedirect(code: number): boolean;
+export default function fetch(url: RequestInfo, init?: RequestInit): Promise;
diff --git a/node_modules/node-fetch/LICENSE.md b/node_modules/node-fetch/LICENSE.md
new file mode 100644
index 0000000..41ca1b6
--- /dev/null
+++ b/node_modules/node-fetch/LICENSE.md
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 - 2020 Node Fetch Team
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
diff --git a/node_modules/node-fetch/README.md b/node_modules/node-fetch/README.md
new file mode 100644
index 0000000..fce3d8f
--- /dev/null
+++ b/node_modules/node-fetch/README.md
@@ -0,0 +1,871 @@
+
+

+
+
A light-weight module that brings Fetch API to Node.js.
+

+

+

+

+

+

+
+
+
Consider supporting us on our Open Collective:
+
+
+

+
+
+---
+
+**You might be looking for the [v2 docs](https://github.com/node-fetch/node-fetch/tree/2.x#readme)**
+
+
+
+- [Motivation](#motivation)
+- [Features](#features)
+- [Difference from client-side fetch](#difference-from-client-side-fetch)
+- [Installation](#installation)
+- [Loading and configuring the module](#loading-and-configuring-the-module)
+- [Upgrading](#upgrading)
+- [Common Usage](#common-usage)
+ - [Plain text or HTML](#plain-text-or-html)
+ - [JSON](#json)
+ - [Simple Post](#simple-post)
+ - [Post with JSON](#post-with-json)
+ - [Post with form parameters](#post-with-form-parameters)
+ - [Handling exceptions](#handling-exceptions)
+ - [Handling client and server errors](#handling-client-and-server-errors)
+ - [Handling cookies](#handling-cookies)
+- [Advanced Usage](#advanced-usage)
+ - [Streams](#streams)
+ - [Accessing Headers and other Metadata](#accessing-headers-and-other-metadata)
+ - [Extract Set-Cookie Header](#extract-set-cookie-header)
+ - [Post data using a file](#post-data-using-a-file)
+ - [Request cancellation with AbortSignal](#request-cancellation-with-abortsignal)
+- [API](#api)
+ - [fetch(url[, options])](#fetchurl-options)
+ - [Options](#options)
+ - [Default Headers](#default-headers)
+ - [Custom Agent](#custom-agent)
+ - [Custom highWaterMark](#custom-highwatermark)
+ - [Insecure HTTP Parser](#insecure-http-parser)
+ - [Class: Request](#class-request)
+ - [new Request(input[, options])](#new-requestinput-options)
+ - [Class: Response](#class-response)
+ - [new Response([body[, options]])](#new-responsebody-options)
+ - [response.ok](#responseok)
+ - [response.redirected](#responseredirected)
+ - [response.type](#responsetype)
+ - [Class: Headers](#class-headers)
+ - [new Headers([init])](#new-headersinit)
+ - [Interface: Body](#interface-body)
+ - [body.body](#bodybody)
+ - [body.bodyUsed](#bodybodyused)
+ - [body.arrayBuffer()](#bodyarraybuffer)
+ - [body.blob()](#bodyblob)
+ - [body.formData()](#formdata)
+ - [body.json()](#bodyjson)
+ - [body.text()](#bodytext)
+ - [Class: FetchError](#class-fetcherror)
+ - [Class: AbortError](#class-aborterror)
+- [TypeScript](#typescript)
+- [Acknowledgement](#acknowledgement)
+- [Team](#team)
+ - [Former](#former)
+- [License](#license)
+
+
+
+## Motivation
+
+Instead of implementing `XMLHttpRequest` in Node.js to run browser-specific [Fetch polyfill](https://github.com/github/fetch), why not go from native `http` to `fetch` API directly? Hence, `node-fetch`, minimal code for a `window.fetch` compatible API on Node.js runtime.
+
+See Jason Miller's [isomorphic-unfetch](https://www.npmjs.com/package/isomorphic-unfetch) or Leonardo Quixada's [cross-fetch](https://github.com/lquixada/cross-fetch) for isomorphic usage (exports `node-fetch` for server-side, `whatwg-fetch` for client-side).
+
+## Features
+
+- Stay consistent with `window.fetch` API.
+- Make conscious trade-off when following [WHATWG fetch spec][whatwg-fetch] and [stream spec](https://streams.spec.whatwg.org/) implementation details, document known differences.
+- Use native promise and async functions.
+- Use native Node streams for body, on both request and response.
+- Decode content encoding (gzip/deflate/brotli) properly, and convert string output (such as `res.text()` and `res.json()`) to UTF-8 automatically.
+- Useful extensions such as redirect limit, response size limit, [explicit errors][error-handling.md] for troubleshooting.
+
+## Difference from client-side fetch
+
+- See known differences:
+ - [As of v3.x](docs/v3-LIMITS.md)
+ - [As of v2.x](docs/v2-LIMITS.md)
+- If you happen to use a missing feature that `window.fetch` offers, feel free to open an issue.
+- Pull requests are welcomed too!
+
+## Installation
+
+Current stable release (`3.x`) requires at least Node.js 12.20.0.
+
+```sh
+npm install node-fetch
+```
+
+## Loading and configuring the module
+
+### ES Modules (ESM)
+
+```js
+import fetch from 'node-fetch';
+```
+
+### CommonJS
+
+`node-fetch` from v3 is an ESM-only module - you are not able to import it with `require()`.
+
+If you cannot switch to ESM, please use v2 which remains compatible with CommonJS. Critical bug fixes will continue to be published for v2.
+
+```sh
+npm install node-fetch@2
+```
+
+Alternatively, you can use the async `import()` function from CommonJS to load `node-fetch` asynchronously:
+
+```js
+// mod.cjs
+const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args));
+```
+
+### Providing global access
+
+To use `fetch()` without importing it, you can patch the `global` object in node:
+
+```js
+// fetch-polyfill.js
+import fetch, {
+ Blob,
+ blobFrom,
+ blobFromSync,
+ File,
+ fileFrom,
+ fileFromSync,
+ FormData,
+ Headers,
+ Request,
+ Response,
+} from 'node-fetch'
+
+if (!globalThis.fetch) {
+ globalThis.fetch = fetch
+ globalThis.Headers = Headers
+ globalThis.Request = Request
+ globalThis.Response = Response
+}
+
+// index.js
+import './fetch-polyfill'
+
+// ...
+```
+
+## Upgrading
+
+Using an old version of node-fetch? Check out the following files:
+
+- [2.x to 3.x upgrade guide](docs/v3-UPGRADE-GUIDE.md)
+- [1.x to 2.x upgrade guide](docs/v2-UPGRADE-GUIDE.md)
+- [Changelog](https://github.com/node-fetch/node-fetch/releases)
+
+## Common Usage
+
+NOTE: The documentation below is up-to-date with `3.x` releases, if you are using an older version, please check how to [upgrade](#upgrading).
+
+### Plain text or HTML
+
+```js
+import fetch from 'node-fetch';
+
+const response = await fetch('https://github.com/');
+const body = await response.text();
+
+console.log(body);
+```
+
+### JSON
+
+```js
+import fetch from 'node-fetch';
+
+const response = await fetch('https://api.github.com/users/github');
+const data = await response.json();
+
+console.log(data);
+```
+
+### Simple Post
+
+```js
+import fetch from 'node-fetch';
+
+const response = await fetch('https://httpbin.org/post', {method: 'POST', body: 'a=1'});
+const data = await response.json();
+
+console.log(data);
+```
+
+### Post with JSON
+
+```js
+import fetch from 'node-fetch';
+
+const body = {a: 1};
+
+const response = await fetch('https://httpbin.org/post', {
+ method: 'post',
+ body: JSON.stringify(body),
+ headers: {'Content-Type': 'application/json'}
+});
+const data = await response.json();
+
+console.log(data);
+```
+
+### Post with form parameters
+
+`URLSearchParams` is available on the global object in Node.js as of v10.0.0. See [official documentation](https://nodejs.org/api/url.html#url_class_urlsearchparams) for more usage methods.
+
+NOTE: The `Content-Type` header is only set automatically to `x-www-form-urlencoded` when an instance of `URLSearchParams` is given as such:
+
+```js
+import fetch from 'node-fetch';
+
+const params = new URLSearchParams();
+params.append('a', 1);
+
+const response = await fetch('https://httpbin.org/post', {method: 'POST', body: params});
+const data = await response.json();
+
+console.log(data);
+```
+
+### Handling exceptions
+
+NOTE: 3xx-5xx responses are _NOT_ exceptions, and should be handled in `then()`, see the next section.
+
+Wrapping the fetch function into a `try/catch` block will catch _all_ exceptions, such as errors originating from node core libraries, like network errors, and operational errors which are instances of FetchError. See the [error handling document][error-handling.md] for more details.
+
+```js
+import fetch from 'node-fetch';
+
+try {
+ await fetch('https://domain.invalid/');
+} catch (error) {
+ console.log(error);
+}
+```
+
+### Handling client and server errors
+
+It is common to create a helper function to check that the response contains no client (4xx) or server (5xx) error responses:
+
+```js
+import fetch from 'node-fetch';
+
+class HTTPResponseError extends Error {
+ constructor(response, ...args) {
+ super(`HTTP Error Response: ${response.status} ${response.statusText}`, ...args);
+ this.response = response;
+ }
+}
+
+const checkStatus = response => {
+ if (response.ok) {
+ // response.status >= 200 && response.status < 300
+ return response;
+ } else {
+ throw new HTTPResponseError(response);
+ }
+}
+
+const response = await fetch('https://httpbin.org/status/400');
+
+try {
+ checkStatus(response);
+} catch (error) {
+ console.error(error);
+
+ const errorBody = await error.response.text();
+ console.error(`Error body: ${errorBody}`);
+}
+```
+
+### Handling cookies
+
+Cookies are not stored by default. However, cookies can be extracted and passed by manipulating request and response headers. See [Extract Set-Cookie Header](#extract-set-cookie-header) for details.
+
+## Advanced Usage
+
+### Streams
+
+The "Node.js way" is to use streams when possible. You can pipe `res.body` to another stream. This example uses [stream.pipeline](https://nodejs.org/api/stream.html#stream_stream_pipeline_streams_callback) to attach stream error handlers and wait for the download to complete.
+
+```js
+import {createWriteStream} from 'node:fs';
+import {pipeline} from 'node:stream';
+import {promisify} from 'node:util'
+import fetch from 'node-fetch';
+
+const streamPipeline = promisify(pipeline);
+
+const response = await fetch('https://github.githubassets.com/images/modules/logos_page/Octocat.png');
+
+if (!response.ok) throw new Error(`unexpected response ${response.statusText}`);
+
+await streamPipeline(response.body, createWriteStream('./octocat.png'));
+```
+
+In Node.js 14 you can also use async iterators to read `body`; however, be careful to catch
+errors -- the longer a response runs, the more likely it is to encounter an error.
+
+```js
+import fetch from 'node-fetch';
+
+const response = await fetch('https://httpbin.org/stream/3');
+
+try {
+ for await (const chunk of response.body) {
+ console.dir(JSON.parse(chunk.toString()));
+ }
+} catch (err) {
+ console.error(err.stack);
+}
+```
+
+In Node.js 12 you can also use async iterators to read `body`; however, async iterators with streams
+did not mature until Node.js 14, so you need to do some extra work to ensure you handle errors
+directly from the stream and wait on it response to fully close.
+
+```js
+import fetch from 'node-fetch';
+
+const read = async body => {
+ let error;
+ body.on('error', err => {
+ error = err;
+ });
+
+ for await (const chunk of body) {
+ console.dir(JSON.parse(chunk.toString()));
+ }
+
+ return new Promise((resolve, reject) => {
+ body.on('close', () => {
+ error ? reject(error) : resolve();
+ });
+ });
+};
+
+try {
+ const response = await fetch('https://httpbin.org/stream/3');
+ await read(response.body);
+} catch (err) {
+ console.error(err.stack);
+}
+```
+
+### Accessing Headers and other Metadata
+
+```js
+import fetch from 'node-fetch';
+
+const response = await fetch('https://github.com/');
+
+console.log(response.ok);
+console.log(response.status);
+console.log(response.statusText);
+console.log(response.headers.raw());
+console.log(response.headers.get('content-type'));
+```
+
+### Extract Set-Cookie Header
+
+Unlike browsers, you can access raw `Set-Cookie` headers manually using `Headers.raw()`. This is a `node-fetch` only API.
+
+```js
+import fetch from 'node-fetch';
+
+const response = await fetch('https://example.com');
+
+// Returns an array of values, instead of a string of comma-separated values
+console.log(response.headers.raw()['set-cookie']);
+```
+
+### Post data using a file
+
+```js
+import fetch {
+ Blob,
+ blobFrom,
+ blobFromSync,
+ File,
+ fileFrom,
+ fileFromSync,
+} from 'node-fetch'
+
+const mimetype = 'text/plain'
+const blob = fileFromSync('./input.txt', mimetype)
+const url = 'https://httpbin.org/post'
+
+const response = await fetch(url, { method: 'POST', body: blob })
+const data = await response.json()
+
+console.log(data)
+```
+
+node-fetch comes with a spec-compliant [FormData] implementations for posting
+multipart/form-data payloads
+
+```js
+import fetch, { FormData, File, fileFrom } from 'node-fetch'
+
+const httpbin = 'https://httpbin.org/post'
+const formData = new FormData()
+const binary = new Uint8Array([ 97, 98, 99 ])
+const abc = new File([binary], 'abc.txt', { type: 'text/plain' })
+
+formData.set('greeting', 'Hello, world!')
+formData.set('file-upload', abc, 'new name.txt')
+
+const response = await fetch(httpbin, { method: 'POST', body: formData })
+const data = await response.json()
+
+console.log(data)
+```
+
+If you for some reason need to post a stream coming from any arbitrary place,
+then you can append a [Blob] or a [File] look-a-like item.
+
+The minium requirement is that it has:
+1. A `Symbol.toStringTag` getter or property that is either `Blob` or `File`
+2. A known size.
+3. And either a `stream()` method or a `arrayBuffer()` method that returns a ArrayBuffer.
+
+The `stream()` must return any async iterable object as long as it yields Uint8Array (or Buffer)
+so Node.Readable streams and whatwg streams works just fine.
+
+```js
+formData.append('upload', {
+ [Symbol.toStringTag]: 'Blob',
+ size: 3,
+ *stream() {
+ yield new Uint8Array([97, 98, 99])
+ },
+ arrayBuffer() {
+ return new Uint8Array([97, 98, 99]).buffer
+ }
+}, 'abc.txt')
+```
+
+### Request cancellation with AbortSignal
+
+You may cancel requests with `AbortController`. A suggested implementation is [`abort-controller`](https://www.npmjs.com/package/abort-controller).
+
+An example of timing out a request after 150ms could be achieved as the following:
+
+```js
+import fetch, { AbortError } from 'node-fetch';
+
+// AbortController was added in node v14.17.0 globally
+const AbortController = globalThis.AbortController || await import('abort-controller')
+
+const controller = new AbortController();
+const timeout = setTimeout(() => {
+ controller.abort();
+}, 150);
+
+try {
+ const response = await fetch('https://example.com', {signal: controller.signal});
+ const data = await response.json();
+} catch (error) {
+ if (error instanceof AbortError) {
+ console.log('request was aborted');
+ }
+} finally {
+ clearTimeout(timeout);
+}
+```
+
+See [test cases](https://github.com/node-fetch/node-fetch/blob/master/test/) for more examples.
+
+## API
+
+### fetch(url[, options])
+
+- `url` A string representing the URL for fetching
+- `options` [Options](#fetch-options) for the HTTP(S) request
+- Returns: Promise<[Response](#class-response)>
+
+Perform an HTTP(S) fetch.
+
+`url` should be an absolute URL, such as `https://example.com/`. A path-relative URL (`/file/under/root`) or protocol-relative URL (`//can-be-http-or-https.com/`) will result in a rejected `Promise`.
+
+
+
+### Options
+
+The default values are shown after each option key.
+
+```js
+{
+ // These properties are part of the Fetch Standard
+ method: 'GET',
+ headers: {}, // Request headers. format is the identical to that accepted by the Headers constructor (see below)
+ body: null, // Request body. can be null, or a Node.js Readable stream
+ redirect: 'follow', // Set to `manual` to extract redirect headers, `error` to reject redirect
+ signal: null, // Pass an instance of AbortSignal to optionally abort requests
+
+ // The following properties are node-fetch extensions
+ follow: 20, // maximum redirect count. 0 to not follow redirect
+ compress: true, // support gzip/deflate content encoding. false to disable
+ size: 0, // maximum response body size in bytes. 0 to disable
+ agent: null, // http(s).Agent instance or function that returns an instance (see below)
+ highWaterMark: 16384, // the maximum number of bytes to store in the internal buffer before ceasing to read from the underlying resource.
+ insecureHTTPParser: false // Use an insecure HTTP parser that accepts invalid HTTP headers when `true`.
+}
+```
+
+#### Default Headers
+
+If no values are set, the following request headers will be sent automatically:
+
+| Header | Value |
+| ------------------- | ------------------------------------------------------ |
+| `Accept-Encoding` | `gzip, deflate, br` (when `options.compress === true`) |
+| `Accept` | `*/*` |
+| `Connection` | `close` _(when no `options.agent` is present)_ |
+| `Content-Length` | _(automatically calculated, if possible)_ |
+| `Host` | _(host and port information from the target URI)_ |
+| `Transfer-Encoding` | `chunked` _(when `req.body` is a stream)_ |
+| `User-Agent` | `node-fetch` |
+
+
+Note: when `body` is a `Stream`, `Content-Length` is not set automatically.
+
+#### Custom Agent
+
+The `agent` option allows you to specify networking related options which are out of the scope of Fetch, including and not limited to the following:
+
+- Support self-signed certificate
+- Use only IPv4 or IPv6
+- Custom DNS Lookup
+
+See [`http.Agent`](https://nodejs.org/api/http.html#http_new_agent_options) for more information.
+
+In addition, the `agent` option accepts a function that returns `http`(s)`.Agent` instance given current [URL](https://nodejs.org/api/url.html), this is useful during a redirection chain across HTTP and HTTPS protocol.
+
+```js
+import http from 'node:http';
+import https from 'node:https';
+
+const httpAgent = new http.Agent({
+ keepAlive: true
+});
+const httpsAgent = new https.Agent({
+ keepAlive: true
+});
+
+const options = {
+ agent: function(_parsedURL) {
+ if (_parsedURL.protocol == 'http:') {
+ return httpAgent;
+ } else {
+ return httpsAgent;
+ }
+ }
+};
+```
+
+
+
+#### Custom highWaterMark
+
+Stream on Node.js have a smaller internal buffer size (16kB, aka `highWaterMark`) from client-side browsers (>1MB, not consistent across browsers). Because of that, when you are writing an isomorphic app and using `res.clone()`, it will hang with large response in Node.
+
+The recommended way to fix this problem is to resolve cloned response in parallel:
+
+```js
+import fetch from 'node-fetch';
+
+const response = await fetch('https://example.com');
+const r1 = response.clone();
+
+const results = await Promise.all([response.json(), r1.text()]);
+
+console.log(results[0]);
+console.log(results[1]);
+```
+
+If for some reason you don't like the solution above, since `3.x` you are able to modify the `highWaterMark` option:
+
+```js
+import fetch from 'node-fetch';
+
+const response = await fetch('https://example.com', {
+ // About 1MB
+ highWaterMark: 1024 * 1024
+});
+
+const result = await res.clone().arrayBuffer();
+console.dir(result);
+```
+
+#### Insecure HTTP Parser
+
+Passed through to the `insecureHTTPParser` option on http(s).request. See [`http.request`](https://nodejs.org/api/http.html#http_http_request_url_options_callback) for more information.
+
+#### Manual Redirect
+
+The `redirect: 'manual'` option for node-fetch is different from the browser & specification, which
+results in an [opaque-redirect filtered response](https://fetch.spec.whatwg.org/#concept-filtered-response-opaque-redirect).
+node-fetch gives you the typical [basic filtered response](https://fetch.spec.whatwg.org/#concept-filtered-response-basic) instead.
+
+```js
+const fetch = require('node-fetch');
+
+const response = await fetch('https://httpbin.org/status/301', { redirect: 'manual' });
+
+if (response.status === 301 || response.status === 302) {
+ const locationURL = new URL(response.headers.get('location'), response.url);
+ const response2 = await fetch(locationURL, { redirect: 'manual' });
+ console.dir(response2);
+}
+```
+
+
+
+### Class: Request
+
+An HTTP(S) request containing information about URL, method, headers, and the body. This class implements the [Body](#iface-body) interface.
+
+Due to the nature of Node.js, the following properties are not implemented at this moment:
+
+- `type`
+- `destination`
+- `mode`
+- `credentials`
+- `cache`
+- `integrity`
+- `keepalive`
+
+The following node-fetch extension properties are provided:
+
+- `follow`
+- `compress`
+- `counter`
+- `agent`
+- `highWaterMark`
+
+See [options](#fetch-options) for exact meaning of these extensions.
+
+#### new Request(input[, options])
+
+_(spec-compliant)_
+
+- `input` A string representing a URL, or another `Request` (which will be cloned)
+- `options` [Options](#fetch-options) for the HTTP(S) request
+
+Constructs a new `Request` object. The constructor is identical to that in the [browser](https://developer.mozilla.org/en-US/docs/Web/API/Request/Request).
+
+In most cases, directly `fetch(url, options)` is simpler than creating a `Request` object.
+
+
+
+### Class: Response
+
+An HTTP(S) response. This class implements the [Body](#iface-body) interface.
+
+The following properties are not implemented in node-fetch at this moment:
+
+- `trailer`
+
+#### new Response([body[, options]])
+
+_(spec-compliant)_
+
+- `body` A `String` or [`Readable` stream][node-readable]
+- `options` A [`ResponseInit`][response-init] options dictionary
+
+Constructs a new `Response` object. The constructor is identical to that in the [browser](https://developer.mozilla.org/en-US/docs/Web/API/Response/Response).
+
+Because Node.js does not implement service workers (for which this class was designed), one rarely has to construct a `Response` directly.
+
+#### response.ok
+
+_(spec-compliant)_
+
+Convenience property representing if the request ended normally. Will evaluate to true if the response status was greater than or equal to 200 but smaller than 300.
+
+#### response.redirected
+
+_(spec-compliant)_
+
+Convenience property representing if the request has been redirected at least once. Will evaluate to true if the internal redirect counter is greater than 0.
+
+#### response.type
+
+_(deviation from spec)_
+
+Convenience property representing the response's type. node-fetch only supports `'default'` and `'error'` and does not make use of [filtered responses](https://fetch.spec.whatwg.org/#concept-filtered-response).
+
+
+
+### Class: Headers
+
+This class allows manipulating and iterating over a set of HTTP headers. All methods specified in the [Fetch Standard][whatwg-fetch] are implemented.
+
+#### new Headers([init])
+
+_(spec-compliant)_
+
+- `init` Optional argument to pre-fill the `Headers` object
+
+Construct a new `Headers` object. `init` can be either `null`, a `Headers` object, an key-value map object or any iterable object.
+
+```js
+// Example adapted from https://fetch.spec.whatwg.org/#example-headers-class
+import {Headers} from 'node-fetch';
+
+const meta = {
+ 'Content-Type': 'text/xml'
+};
+const headers = new Headers(meta);
+
+// The above is equivalent to
+const meta = [['Content-Type', 'text/xml']];
+const headers = new Headers(meta);
+
+// You can in fact use any iterable objects, like a Map or even another Headers
+const meta = new Map();
+meta.set('Content-Type', 'text/xml');
+const headers = new Headers(meta);
+const copyOfHeaders = new Headers(headers);
+```
+
+
+
+### Interface: Body
+
+`Body` is an abstract interface with methods that are applicable to both `Request` and `Response` classes.
+
+#### body.body
+
+_(deviation from spec)_
+
+- Node.js [`Readable` stream][node-readable]
+
+Data are encapsulated in the `Body` object. Note that while the [Fetch Standard][whatwg-fetch] requires the property to always be a WHATWG `ReadableStream`, in node-fetch it is a Node.js [`Readable` stream][node-readable].
+
+#### body.bodyUsed
+
+_(spec-compliant)_
+
+- `Boolean`
+
+A boolean property for if this body has been consumed. Per the specs, a consumed body cannot be used again.
+
+#### body.arrayBuffer()
+
+#### body.formData()
+
+#### body.blob()
+
+#### body.json()
+
+#### body.text()
+
+`fetch` comes with methods to parse `multipart/form-data` payloads as well as
+`x-www-form-urlencoded` bodies using `.formData()` this comes from the idea that
+Service Worker can intercept such messages before it's sent to the server to
+alter them. This is useful for anybody building a server so you can use it to
+parse & consume payloads.
+
+
+Code example
+
+```js
+import http from 'node:http'
+import { Response } from 'node-fetch'
+
+http.createServer(async function (req, res) {
+ const formData = await new Response(req, {
+ headers: req.headers // Pass along the boundary value
+ }).formData()
+ const allFields = [...formData]
+
+ const file = formData.get('uploaded-files')
+ const arrayBuffer = await file.arrayBuffer()
+ const text = await file.text()
+ const whatwgReadableStream = file.stream()
+
+ // other was to consume the request could be to do:
+ const json = await new Response(req).json()
+ const text = await new Response(req).text()
+ const arrayBuffer = await new Response(req).arrayBuffer()
+ const blob = await new Response(req, {
+ headers: req.headers // So that `type` inherits `Content-Type`
+ }.blob()
+})
+```
+
+
+
+
+
+### Class: FetchError
+
+_(node-fetch extension)_
+
+An operational error in the fetching process. See [ERROR-HANDLING.md][] for more info.
+
+
+
+### Class: AbortError
+
+_(node-fetch extension)_
+
+An Error thrown when the request is aborted in response to an `AbortSignal`'s `abort` event. It has a `name` property of `AbortError`. See [ERROR-HANDLING.MD][] for more info.
+
+## TypeScript
+
+**Since `3.x` types are bundled with `node-fetch`, so you don't need to install any additional packages.**
+
+For older versions please use the type definitions from [DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped):
+
+```sh
+npm install --save-dev @types/node-fetch@2.x
+```
+
+## Acknowledgement
+
+Thanks to [github/fetch](https://github.com/github/fetch) for providing a solid implementation reference.
+
+## Team
+
+| [](https://github.com/bitinn) | [](https://github.com/jimmywarting) | [](https://github.com/xxczaki) | [](https://github.com/Richienb) | [](https://github.com/gr2m) |
+| ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------- |
+| [David Frank](https://bitinn.net/) | [Jimmy Wärting](https://jimmy.warting.se/) | [Antoni Kepinski](https://kepinski.ch) | [Richie Bendall](https://www.richie-bendall.ml/) | [Gregor Martynus](https://twitter.com/gr2m) |
+
+###### Former
+
+- [Timothy Gu](https://github.com/timothygu)
+- [Jared Kantrowitz](https://github.com/jkantr)
+
+## License
+
+[MIT](LICENSE.md)
+
+[whatwg-fetch]: https://fetch.spec.whatwg.org/
+[response-init]: https://fetch.spec.whatwg.org/#responseinit
+[node-readable]: https://nodejs.org/api/stream.html#stream_readable_streams
+[mdn-headers]: https://developer.mozilla.org/en-US/docs/Web/API/Headers
+[error-handling.md]: https://github.com/node-fetch/node-fetch/blob/master/docs/ERROR-HANDLING.md
+[FormData]: https://developer.mozilla.org/en-US/docs/Web/API/FormData
+[Blob]: https://developer.mozilla.org/en-US/docs/Web/API/Blob
+[File]: https://developer.mozilla.org/en-US/docs/Web/API/File
diff --git a/node_modules/node-fetch/package.json b/node_modules/node-fetch/package.json
new file mode 100644
index 0000000..36499f1
--- /dev/null
+++ b/node_modules/node-fetch/package.json
@@ -0,0 +1,131 @@
+{
+ "name": "node-fetch",
+ "version": "3.2.6",
+ "description": "A light-weight module that brings Fetch API to node.js",
+ "main": "./src/index.js",
+ "sideEffects": false,
+ "type": "module",
+ "files": [
+ "src",
+ "@types/index.d.ts"
+ ],
+ "types": "./@types/index.d.ts",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "scripts": {
+ "test": "mocha",
+ "coverage": "c8 report --reporter=text-lcov | coveralls",
+ "test-types": "tsd",
+ "lint": "xo"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/node-fetch/node-fetch.git"
+ },
+ "keywords": [
+ "fetch",
+ "http",
+ "promise",
+ "request",
+ "curl",
+ "wget",
+ "xhr",
+ "whatwg"
+ ],
+ "author": "David Frank",
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/node-fetch/node-fetch/issues"
+ },
+ "homepage": "https://github.com/node-fetch/node-fetch",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/node-fetch"
+ },
+ "devDependencies": {
+ "abort-controller": "^3.0.0",
+ "abortcontroller-polyfill": "^1.7.1",
+ "busboy": "^1.4.0",
+ "c8": "^7.7.2",
+ "chai": "^4.3.4",
+ "chai-as-promised": "^7.1.1",
+ "chai-iterator": "^3.0.2",
+ "chai-string": "^1.5.0",
+ "coveralls": "^3.1.0",
+ "form-data": "^4.0.0",
+ "formdata-node": "^4.2.4",
+ "mocha": "^9.1.3",
+ "p-timeout": "^5.0.0",
+ "stream-consumers": "^1.0.1",
+ "tsd": "^0.14.0",
+ "xo": "^0.39.1"
+ },
+ "dependencies": {
+ "data-uri-to-buffer": "^4.0.0",
+ "fetch-blob": "^3.1.4",
+ "formdata-polyfill": "^4.0.10"
+ },
+ "tsd": {
+ "cwd": "@types",
+ "compilerOptions": {
+ "esModuleInterop": true
+ }
+ },
+ "xo": {
+ "envs": [
+ "node",
+ "browser"
+ ],
+ "ignores": [
+ "example.js"
+ ],
+ "rules": {
+ "complexity": 0,
+ "import/extensions": 0,
+ "import/no-useless-path-segments": 0,
+ "import/no-anonymous-default-export": 0,
+ "import/no-named-as-default": 0,
+ "unicorn/import-index": 0,
+ "unicorn/no-array-reduce": 0,
+ "unicorn/prefer-node-protocol": 0,
+ "unicorn/numeric-separators-style": 0,
+ "unicorn/explicit-length-check": 0,
+ "capitalized-comments": 0,
+ "node/no-unsupported-features/es-syntax": 0,
+ "@typescript-eslint/member-ordering": 0
+ },
+ "overrides": [
+ {
+ "files": "test/**/*.js",
+ "envs": [
+ "node",
+ "mocha"
+ ],
+ "rules": {
+ "max-nested-callbacks": 0,
+ "no-unused-expressions": 0,
+ "no-warning-comments": 0,
+ "new-cap": 0,
+ "guard-for-in": 0,
+ "unicorn/no-array-for-each": 0,
+ "unicorn/prevent-abbreviations": 0,
+ "promise/prefer-await-to-then": 0,
+ "ava/no-import-test-files": 0
+ }
+ }
+ ]
+ },
+ "runkitExampleFilename": "example.js",
+ "release": {
+ "branches": [
+ "+([0-9]).x",
+ "main",
+ "next",
+ {
+ "name": "beta",
+ "prerelease": true
+ }
+ ]
+ }
+}
diff --git a/node_modules/node-fetch/src/body.js b/node_modules/node-fetch/src/body.js
new file mode 100644
index 0000000..714e27e
--- /dev/null
+++ b/node_modules/node-fetch/src/body.js
@@ -0,0 +1,397 @@
+
+/**
+ * Body.js
+ *
+ * Body interface provides common methods for Request and Response
+ */
+
+import Stream, {PassThrough} from 'node:stream';
+import {types, deprecate, promisify} from 'node:util';
+import {Buffer} from 'node:buffer';
+
+import Blob from 'fetch-blob';
+import {FormData, formDataToBlob} from 'formdata-polyfill/esm.min.js';
+
+import {FetchError} from './errors/fetch-error.js';
+import {FetchBaseError} from './errors/base.js';
+import {isBlob, isURLSearchParameters} from './utils/is.js';
+
+const pipeline = promisify(Stream.pipeline);
+const INTERNALS = Symbol('Body internals');
+
+/**
+ * Body mixin
+ *
+ * Ref: https://fetch.spec.whatwg.org/#body
+ *
+ * @param Stream body Readable stream
+ * @param Object opts Response options
+ * @return Void
+ */
+export default class Body {
+ constructor(body, {
+ size = 0
+ } = {}) {
+ let boundary = null;
+
+ if (body === null) {
+ // Body is undefined or null
+ body = null;
+ } else if (isURLSearchParameters(body)) {
+ // Body is a URLSearchParams
+ body = Buffer.from(body.toString());
+ } else if (isBlob(body)) {
+ // Body is blob
+ } else if (Buffer.isBuffer(body)) {
+ // Body is Buffer
+ } else if (types.isAnyArrayBuffer(body)) {
+ // Body is ArrayBuffer
+ body = Buffer.from(body);
+ } else if (ArrayBuffer.isView(body)) {
+ // Body is ArrayBufferView
+ body = Buffer.from(body.buffer, body.byteOffset, body.byteLength);
+ } else if (body instanceof Stream) {
+ // Body is stream
+ } else if (body instanceof FormData) {
+ // Body is FormData
+ body = formDataToBlob(body);
+ boundary = body.type.split('=')[1];
+ } else {
+ // None of the above
+ // coerce to string then buffer
+ body = Buffer.from(String(body));
+ }
+
+ let stream = body;
+
+ if (Buffer.isBuffer(body)) {
+ stream = Stream.Readable.from(body);
+ } else if (isBlob(body)) {
+ stream = Stream.Readable.from(body.stream());
+ }
+
+ this[INTERNALS] = {
+ body,
+ stream,
+ boundary,
+ disturbed: false,
+ error: null
+ };
+ this.size = size;
+
+ if (body instanceof Stream) {
+ body.on('error', error_ => {
+ const error = error_ instanceof FetchBaseError ?
+ error_ :
+ new FetchError(`Invalid response body while trying to fetch ${this.url}: ${error_.message}`, 'system', error_);
+ this[INTERNALS].error = error;
+ });
+ }
+ }
+
+ get body() {
+ return this[INTERNALS].stream;
+ }
+
+ get bodyUsed() {
+ return this[INTERNALS].disturbed;
+ }
+
+ /**
+ * Decode response as ArrayBuffer
+ *
+ * @return Promise
+ */
+ async arrayBuffer() {
+ const {buffer, byteOffset, byteLength} = await consumeBody(this);
+ return buffer.slice(byteOffset, byteOffset + byteLength);
+ }
+
+ async formData() {
+ const ct = this.headers.get('content-type');
+
+ if (ct.startsWith('application/x-www-form-urlencoded')) {
+ const formData = new FormData();
+ const parameters = new URLSearchParams(await this.text());
+
+ for (const [name, value] of parameters) {
+ formData.append(name, value);
+ }
+
+ return formData;
+ }
+
+ const {toFormData} = await import('./utils/multipart-parser.js');
+ return toFormData(this.body, ct);
+ }
+
+ /**
+ * Return raw response as Blob
+ *
+ * @return Promise
+ */
+ async blob() {
+ const ct = (this.headers && this.headers.get('content-type')) || (this[INTERNALS].body && this[INTERNALS].body.type) || '';
+ const buf = await this.arrayBuffer();
+
+ return new Blob([buf], {
+ type: ct
+ });
+ }
+
+ /**
+ * Decode response as json
+ *
+ * @return Promise
+ */
+ async json() {
+ const text = await this.text();
+ return JSON.parse(text);
+ }
+
+ /**
+ * Decode response as text
+ *
+ * @return Promise
+ */
+ async text() {
+ const buffer = await consumeBody(this);
+ return new TextDecoder().decode(buffer);
+ }
+
+ /**
+ * Decode response as buffer (non-spec api)
+ *
+ * @return Promise
+ */
+ buffer() {
+ return consumeBody(this);
+ }
+}
+
+Body.prototype.buffer = deprecate(Body.prototype.buffer, 'Please use \'response.arrayBuffer()\' instead of \'response.buffer()\'', 'node-fetch#buffer');
+
+// In browsers, all properties are enumerable.
+Object.defineProperties(Body.prototype, {
+ body: {enumerable: true},
+ bodyUsed: {enumerable: true},
+ arrayBuffer: {enumerable: true},
+ blob: {enumerable: true},
+ json: {enumerable: true},
+ text: {enumerable: true},
+ data: {get: deprecate(() => {},
+ 'data doesn\'t exist, use json(), text(), arrayBuffer(), or body instead',
+ 'https://github.com/node-fetch/node-fetch/issues/1000 (response)')}
+});
+
+/**
+ * Consume and convert an entire Body to a Buffer.
+ *
+ * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body
+ *
+ * @return Promise
+ */
+async function consumeBody(data) {
+ if (data[INTERNALS].disturbed) {
+ throw new TypeError(`body used already for: ${data.url}`);
+ }
+
+ data[INTERNALS].disturbed = true;
+
+ if (data[INTERNALS].error) {
+ throw data[INTERNALS].error;
+ }
+
+ const {body} = data;
+
+ // Body is null
+ if (body === null) {
+ return Buffer.alloc(0);
+ }
+
+ /* c8 ignore next 3 */
+ if (!(body instanceof Stream)) {
+ return Buffer.alloc(0);
+ }
+
+ // Body is stream
+ // get ready to actually consume the body
+ const accum = [];
+ let accumBytes = 0;
+
+ try {
+ for await (const chunk of body) {
+ if (data.size > 0 && accumBytes + chunk.length > data.size) {
+ const error = new FetchError(`content size at ${data.url} over limit: ${data.size}`, 'max-size');
+ body.destroy(error);
+ throw error;
+ }
+
+ accumBytes += chunk.length;
+ accum.push(chunk);
+ }
+ } catch (error) {
+ const error_ = error instanceof FetchBaseError ? error : new FetchError(`Invalid response body while trying to fetch ${data.url}: ${error.message}`, 'system', error);
+ throw error_;
+ }
+
+ if (body.readableEnded === true || body._readableState.ended === true) {
+ try {
+ if (accum.every(c => typeof c === 'string')) {
+ return Buffer.from(accum.join(''));
+ }
+
+ return Buffer.concat(accum, accumBytes);
+ } catch (error) {
+ throw new FetchError(`Could not create Buffer from response body for ${data.url}: ${error.message}`, 'system', error);
+ }
+ } else {
+ throw new FetchError(`Premature close of server response while trying to fetch ${data.url}`);
+ }
+}
+
+/**
+ * Clone body given Res/Req instance
+ *
+ * @param Mixed instance Response or Request instance
+ * @param String highWaterMark highWaterMark for both PassThrough body streams
+ * @return Mixed
+ */
+export const clone = (instance, highWaterMark) => {
+ let p1;
+ let p2;
+ let {body} = instance[INTERNALS];
+
+ // Don't allow cloning a used body
+ if (instance.bodyUsed) {
+ throw new Error('cannot clone body after it is used');
+ }
+
+ // Check that body is a stream and not form-data object
+ // note: we can't clone the form-data object without having it as a dependency
+ if ((body instanceof Stream) && (typeof body.getBoundary !== 'function')) {
+ // Tee instance body
+ p1 = new PassThrough({highWaterMark});
+ p2 = new PassThrough({highWaterMark});
+ body.pipe(p1);
+ body.pipe(p2);
+ // Set instance body to teed body and return the other teed body
+ instance[INTERNALS].stream = p1;
+ body = p2;
+ }
+
+ return body;
+};
+
+const getNonSpecFormDataBoundary = deprecate(
+ body => body.getBoundary(),
+ 'form-data doesn\'t follow the spec and requires special treatment. Use alternative package',
+ 'https://github.com/node-fetch/node-fetch/issues/1167'
+);
+
+/**
+ * Performs the operation "extract a `Content-Type` value from |object|" as
+ * specified in the specification:
+ * https://fetch.spec.whatwg.org/#concept-bodyinit-extract
+ *
+ * This function assumes that instance.body is present.
+ *
+ * @param {any} body Any options.body input
+ * @returns {string | null}
+ */
+export const extractContentType = (body, request) => {
+ // Body is null or undefined
+ if (body === null) {
+ return null;
+ }
+
+ // Body is string
+ if (typeof body === 'string') {
+ return 'text/plain;charset=UTF-8';
+ }
+
+ // Body is a URLSearchParams
+ if (isURLSearchParameters(body)) {
+ return 'application/x-www-form-urlencoded;charset=UTF-8';
+ }
+
+ // Body is blob
+ if (isBlob(body)) {
+ return body.type || null;
+ }
+
+ // Body is a Buffer (Buffer, ArrayBuffer or ArrayBufferView)
+ if (Buffer.isBuffer(body) || types.isAnyArrayBuffer(body) || ArrayBuffer.isView(body)) {
+ return null;
+ }
+
+ if (body instanceof FormData) {
+ return `multipart/form-data; boundary=${request[INTERNALS].boundary}`;
+ }
+
+ // Detect form data input from form-data module
+ if (body && typeof body.getBoundary === 'function') {
+ return `multipart/form-data;boundary=${getNonSpecFormDataBoundary(body)}`;
+ }
+
+ // Body is stream - can't really do much about this
+ if (body instanceof Stream) {
+ return null;
+ }
+
+ // Body constructor defaults other things to string
+ return 'text/plain;charset=UTF-8';
+};
+
+/**
+ * The Fetch Standard treats this as if "total bytes" is a property on the body.
+ * For us, we have to explicitly get it with a function.
+ *
+ * ref: https://fetch.spec.whatwg.org/#concept-body-total-bytes
+ *
+ * @param {any} obj.body Body object from the Body instance.
+ * @returns {number | null}
+ */
+export const getTotalBytes = request => {
+ const {body} = request[INTERNALS];
+
+ // Body is null or undefined
+ if (body === null) {
+ return 0;
+ }
+
+ // Body is Blob
+ if (isBlob(body)) {
+ return body.size;
+ }
+
+ // Body is Buffer
+ if (Buffer.isBuffer(body)) {
+ return body.length;
+ }
+
+ // Detect form data input from form-data module
+ if (body && typeof body.getLengthSync === 'function') {
+ return body.hasKnownLength && body.hasKnownLength() ? body.getLengthSync() : null;
+ }
+
+ // Body is stream
+ return null;
+};
+
+/**
+ * Write a Body to a Node.js WritableStream (e.g. http.Request) object.
+ *
+ * @param {Stream.Writable} dest The stream to write to.
+ * @param obj.body Body object from the Body instance.
+ * @returns {Promise}
+ */
+export const writeToStream = async (dest, {body}) => {
+ if (body === null) {
+ // Body is null
+ dest.end();
+ } else {
+ // Body is stream
+ await pipeline(body, dest);
+ }
+};
diff --git a/node_modules/node-fetch/src/errors/abort-error.js b/node_modules/node-fetch/src/errors/abort-error.js
new file mode 100644
index 0000000..0b62f1c
--- /dev/null
+++ b/node_modules/node-fetch/src/errors/abort-error.js
@@ -0,0 +1,10 @@
+import {FetchBaseError} from './base.js';
+
+/**
+ * AbortError interface for cancelled requests
+ */
+export class AbortError extends FetchBaseError {
+ constructor(message, type = 'aborted') {
+ super(message, type);
+ }
+}
diff --git a/node_modules/node-fetch/src/errors/base.js b/node_modules/node-fetch/src/errors/base.js
new file mode 100644
index 0000000..4e66e1b
--- /dev/null
+++ b/node_modules/node-fetch/src/errors/base.js
@@ -0,0 +1,17 @@
+export class FetchBaseError extends Error {
+ constructor(message, type) {
+ super(message);
+ // Hide custom error implementation details from end-users
+ Error.captureStackTrace(this, this.constructor);
+
+ this.type = type;
+ }
+
+ get name() {
+ return this.constructor.name;
+ }
+
+ get [Symbol.toStringTag]() {
+ return this.constructor.name;
+ }
+}
diff --git a/node_modules/node-fetch/src/errors/fetch-error.js b/node_modules/node-fetch/src/errors/fetch-error.js
new file mode 100644
index 0000000..f7ae5cc
--- /dev/null
+++ b/node_modules/node-fetch/src/errors/fetch-error.js
@@ -0,0 +1,26 @@
+
+import {FetchBaseError} from './base.js';
+
+/**
+ * @typedef {{ address?: string, code: string, dest?: string, errno: number, info?: object, message: string, path?: string, port?: number, syscall: string}} SystemError
+*/
+
+/**
+ * FetchError interface for operational errors
+ */
+export class FetchError extends FetchBaseError {
+ /**
+ * @param {string} message - Error message for human
+ * @param {string} [type] - Error type for machine
+ * @param {SystemError} [systemError] - For Node.js system error
+ */
+ constructor(message, type, systemError) {
+ super(message, type);
+ // When err.type is `system`, err.erroredSysCall contains system error and err.code contains system error code
+ if (systemError) {
+ // eslint-disable-next-line no-multi-assign
+ this.code = this.errno = systemError.code;
+ this.erroredSysCall = systemError.syscall;
+ }
+ }
+}
diff --git a/node_modules/node-fetch/src/headers.js b/node_modules/node-fetch/src/headers.js
new file mode 100644
index 0000000..cd69455
--- /dev/null
+++ b/node_modules/node-fetch/src/headers.js
@@ -0,0 +1,267 @@
+/**
+ * Headers.js
+ *
+ * Headers class offers convenient helpers
+ */
+
+import {types} from 'node:util';
+import http from 'node:http';
+
+/* c8 ignore next 9 */
+const validateHeaderName = typeof http.validateHeaderName === 'function' ?
+ http.validateHeaderName :
+ name => {
+ if (!/^[\^`\-\w!#$%&'*+.|~]+$/.test(name)) {
+ const error = new TypeError(`Header name must be a valid HTTP token [${name}]`);
+ Object.defineProperty(error, 'code', {value: 'ERR_INVALID_HTTP_TOKEN'});
+ throw error;
+ }
+ };
+
+/* c8 ignore next 9 */
+const validateHeaderValue = typeof http.validateHeaderValue === 'function' ?
+ http.validateHeaderValue :
+ (name, value) => {
+ if (/[^\t\u0020-\u007E\u0080-\u00FF]/.test(value)) {
+ const error = new TypeError(`Invalid character in header content ["${name}"]`);
+ Object.defineProperty(error, 'code', {value: 'ERR_INVALID_CHAR'});
+ throw error;
+ }
+ };
+
+/**
+ * @typedef {Headers | Record | Iterable | Iterable>} HeadersInit
+ */
+
+/**
+ * This Fetch API interface allows you to perform various actions on HTTP request and response headers.
+ * These actions include retrieving, setting, adding to, and removing.
+ * A Headers object has an associated header list, which is initially empty and consists of zero or more name and value pairs.
+ * You can add to this using methods like append() (see Examples.)
+ * In all methods of this interface, header names are matched by case-insensitive byte sequence.
+ *
+ */
+export default class Headers extends URLSearchParams {
+ /**
+ * Headers class
+ *
+ * @constructor
+ * @param {HeadersInit} [init] - Response headers
+ */
+ constructor(init) {
+ // Validate and normalize init object in [name, value(s)][]
+ /** @type {string[][]} */
+ let result = [];
+ if (init instanceof Headers) {
+ const raw = init.raw();
+ for (const [name, values] of Object.entries(raw)) {
+ result.push(...values.map(value => [name, value]));
+ }
+ } else if (init == null) { // eslint-disable-line no-eq-null, eqeqeq
+ // No op
+ } else if (typeof init === 'object' && !types.isBoxedPrimitive(init)) {
+ const method = init[Symbol.iterator];
+ // eslint-disable-next-line no-eq-null, eqeqeq
+ if (method == null) {
+ // Record
+ result.push(...Object.entries(init));
+ } else {
+ if (typeof method !== 'function') {
+ throw new TypeError('Header pairs must be iterable');
+ }
+
+ // Sequence>
+ // Note: per spec we have to first exhaust the lists then process them
+ result = [...init]
+ .map(pair => {
+ if (
+ typeof pair !== 'object' || types.isBoxedPrimitive(pair)
+ ) {
+ throw new TypeError('Each header pair must be an iterable object');
+ }
+
+ return [...pair];
+ }).map(pair => {
+ if (pair.length !== 2) {
+ throw new TypeError('Each header pair must be a name/value tuple');
+ }
+
+ return [...pair];
+ });
+ }
+ } else {
+ throw new TypeError('Failed to construct \'Headers\': The provided value is not of type \'(sequence> or record)');
+ }
+
+ // Validate and lowercase
+ result =
+ result.length > 0 ?
+ result.map(([name, value]) => {
+ validateHeaderName(name);
+ validateHeaderValue(name, String(value));
+ return [String(name).toLowerCase(), String(value)];
+ }) :
+ undefined;
+
+ super(result);
+
+ // Returning a Proxy that will lowercase key names, validate parameters and sort keys
+ // eslint-disable-next-line no-constructor-return
+ return new Proxy(this, {
+ get(target, p, receiver) {
+ switch (p) {
+ case 'append':
+ case 'set':
+ return (name, value) => {
+ validateHeaderName(name);
+ validateHeaderValue(name, String(value));
+ return URLSearchParams.prototype[p].call(
+ target,
+ String(name).toLowerCase(),
+ String(value)
+ );
+ };
+
+ case 'delete':
+ case 'has':
+ case 'getAll':
+ return name => {
+ validateHeaderName(name);
+ return URLSearchParams.prototype[p].call(
+ target,
+ String(name).toLowerCase()
+ );
+ };
+
+ case 'keys':
+ return () => {
+ target.sort();
+ return new Set(URLSearchParams.prototype.keys.call(target)).keys();
+ };
+
+ default:
+ return Reflect.get(target, p, receiver);
+ }
+ }
+ });
+ /* c8 ignore next */
+ }
+
+ get [Symbol.toStringTag]() {
+ return this.constructor.name;
+ }
+
+ toString() {
+ return Object.prototype.toString.call(this);
+ }
+
+ get(name) {
+ const values = this.getAll(name);
+ if (values.length === 0) {
+ return null;
+ }
+
+ let value = values.join(', ');
+ if (/^content-encoding$/i.test(name)) {
+ value = value.toLowerCase();
+ }
+
+ return value;
+ }
+
+ forEach(callback, thisArg = undefined) {
+ for (const name of this.keys()) {
+ Reflect.apply(callback, thisArg, [this.get(name), name, this]);
+ }
+ }
+
+ * values() {
+ for (const name of this.keys()) {
+ yield this.get(name);
+ }
+ }
+
+ /**
+ * @type {() => IterableIterator<[string, string]>}
+ */
+ * entries() {
+ for (const name of this.keys()) {
+ yield [name, this.get(name)];
+ }
+ }
+
+ [Symbol.iterator]() {
+ return this.entries();
+ }
+
+ /**
+ * Node-fetch non-spec method
+ * returning all headers and their values as array
+ * @returns {Record}
+ */
+ raw() {
+ return [...this.keys()].reduce((result, key) => {
+ result[key] = this.getAll(key);
+ return result;
+ }, {});
+ }
+
+ /**
+ * For better console.log(headers) and also to convert Headers into Node.js Request compatible format
+ */
+ [Symbol.for('nodejs.util.inspect.custom')]() {
+ return [...this.keys()].reduce((result, key) => {
+ const values = this.getAll(key);
+ // Http.request() only supports string as Host header.
+ // This hack makes specifying custom Host header possible.
+ if (key === 'host') {
+ result[key] = values[0];
+ } else {
+ result[key] = values.length > 1 ? values : values[0];
+ }
+
+ return result;
+ }, {});
+ }
+}
+
+/**
+ * Re-shaping object for Web IDL tests
+ * Only need to do it for overridden methods
+ */
+Object.defineProperties(
+ Headers.prototype,
+ ['get', 'entries', 'forEach', 'values'].reduce((result, property) => {
+ result[property] = {enumerable: true};
+ return result;
+ }, {})
+);
+
+/**
+ * Create a Headers object from an http.IncomingMessage.rawHeaders, ignoring those that do
+ * not conform to HTTP grammar productions.
+ * @param {import('http').IncomingMessage['rawHeaders']} headers
+ */
+export function fromRawHeaders(headers = []) {
+ return new Headers(
+ headers
+ // Split into pairs
+ .reduce((result, value, index, array) => {
+ if (index % 2 === 0) {
+ result.push(array.slice(index, index + 2));
+ }
+
+ return result;
+ }, [])
+ .filter(([name, value]) => {
+ try {
+ validateHeaderName(name);
+ validateHeaderValue(name, String(value));
+ return true;
+ } catch {
+ return false;
+ }
+ })
+
+ );
+}
diff --git a/node_modules/node-fetch/src/index.js b/node_modules/node-fetch/src/index.js
new file mode 100644
index 0000000..82efc98
--- /dev/null
+++ b/node_modules/node-fetch/src/index.js
@@ -0,0 +1,414 @@
+/**
+ * Index.js
+ *
+ * a request API compatible with window.fetch
+ *
+ * All spec algorithm step numbers are based on https://fetch.spec.whatwg.org/commit-snapshots/ae716822cb3a61843226cd090eefc6589446c1d2/.
+ */
+
+import http from 'node:http';
+import https from 'node:https';
+import zlib from 'node:zlib';
+import Stream, {PassThrough, pipeline as pump} from 'node:stream';
+import {Buffer} from 'node:buffer';
+
+import dataUriToBuffer from 'data-uri-to-buffer';
+
+import {writeToStream, clone} from './body.js';
+import Response from './response.js';
+import Headers, {fromRawHeaders} from './headers.js';
+import Request, {getNodeRequestOptions} from './request.js';
+import {FetchError} from './errors/fetch-error.js';
+import {AbortError} from './errors/abort-error.js';
+import {isRedirect} from './utils/is-redirect.js';
+import {FormData} from 'formdata-polyfill/esm.min.js';
+import {isDomainOrSubdomain} from './utils/is.js';
+import {parseReferrerPolicyFromHeader} from './utils/referrer.js';
+import {
+ Blob,
+ File,
+ fileFromSync,
+ fileFrom,
+ blobFromSync,
+ blobFrom
+} from 'fetch-blob/from.js';
+
+export {FormData, Headers, Request, Response, FetchError, AbortError, isRedirect};
+export {Blob, File, fileFromSync, fileFrom, blobFromSync, blobFrom};
+
+const supportedSchemas = new Set(['data:', 'http:', 'https:']);
+
+/**
+ * Fetch function
+ *
+ * @param {string | URL | import('./request').default} url - Absolute url or Request instance
+ * @param {*} [options_] - Fetch options
+ * @return {Promise}
+ */
+export default async function fetch(url, options_) {
+ return new Promise((resolve, reject) => {
+ // Build request object
+ const request = new Request(url, options_);
+ const {parsedURL, options} = getNodeRequestOptions(request);
+ if (!supportedSchemas.has(parsedURL.protocol)) {
+ throw new TypeError(`node-fetch cannot load ${url}. URL scheme "${parsedURL.protocol.replace(/:$/, '')}" is not supported.`);
+ }
+
+ if (parsedURL.protocol === 'data:') {
+ const data = dataUriToBuffer(request.url);
+ const response = new Response(data, {headers: {'Content-Type': data.typeFull}});
+ resolve(response);
+ return;
+ }
+
+ // Wrap http.request into fetch
+ const send = (parsedURL.protocol === 'https:' ? https : http).request;
+ const {signal} = request;
+ let response = null;
+
+ const abort = () => {
+ const error = new AbortError('The operation was aborted.');
+ reject(error);
+ if (request.body && request.body instanceof Stream.Readable) {
+ request.body.destroy(error);
+ }
+
+ if (!response || !response.body) {
+ return;
+ }
+
+ response.body.emit('error', error);
+ };
+
+ if (signal && signal.aborted) {
+ abort();
+ return;
+ }
+
+ const abortAndFinalize = () => {
+ abort();
+ finalize();
+ };
+
+ // Send request
+ const request_ = send(parsedURL.toString(), options);
+
+ if (signal) {
+ signal.addEventListener('abort', abortAndFinalize);
+ }
+
+ const finalize = () => {
+ request_.abort();
+ if (signal) {
+ signal.removeEventListener('abort', abortAndFinalize);
+ }
+ };
+
+ request_.on('error', error => {
+ reject(new FetchError(`request to ${request.url} failed, reason: ${error.message}`, 'system', error));
+ finalize();
+ });
+
+ fixResponseChunkedTransferBadEnding(request_, error => {
+ if (response && response.body) {
+ response.body.destroy(error);
+ }
+ });
+
+ /* c8 ignore next 18 */
+ if (process.version < 'v14') {
+ // Before Node.js 14, pipeline() does not fully support async iterators and does not always
+ // properly handle when the socket close/end events are out of order.
+ request_.on('socket', s => {
+ let endedWithEventsCount;
+ s.prependListener('end', () => {
+ endedWithEventsCount = s._eventsCount;
+ });
+ s.prependListener('close', hadError => {
+ // if end happened before close but the socket didn't emit an error, do it now
+ if (response && endedWithEventsCount < s._eventsCount && !hadError) {
+ const error = new Error('Premature close');
+ error.code = 'ERR_STREAM_PREMATURE_CLOSE';
+ response.body.emit('error', error);
+ }
+ });
+ });
+ }
+
+ request_.on('response', response_ => {
+ request_.setTimeout(0);
+ const headers = fromRawHeaders(response_.rawHeaders);
+
+ // HTTP fetch step 5
+ if (isRedirect(response_.statusCode)) {
+ // HTTP fetch step 5.2
+ const location = headers.get('Location');
+
+ // HTTP fetch step 5.3
+ let locationURL = null;
+ try {
+ locationURL = location === null ? null : new URL(location, request.url);
+ } catch {
+ // error here can only be invalid URL in Location: header
+ // do not throw when options.redirect == manual
+ // let the user extract the errorneous redirect URL
+ if (request.redirect !== 'manual') {
+ reject(new FetchError(`uri requested responds with an invalid redirect URL: ${location}`, 'invalid-redirect'));
+ finalize();
+ return;
+ }
+ }
+
+ // HTTP fetch step 5.5
+ switch (request.redirect) {
+ case 'error':
+ reject(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, 'no-redirect'));
+ finalize();
+ return;
+ case 'manual':
+ // Nothing to do
+ break;
+ case 'follow': {
+ // HTTP-redirect fetch step 2
+ if (locationURL === null) {
+ break;
+ }
+
+ // HTTP-redirect fetch step 5
+ if (request.counter >= request.follow) {
+ reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect'));
+ finalize();
+ return;
+ }
+
+ // HTTP-redirect fetch step 6 (counter increment)
+ // Create a new Request object.
+ const requestOptions = {
+ headers: new Headers(request.headers),
+ follow: request.follow,
+ counter: request.counter + 1,
+ agent: request.agent,
+ compress: request.compress,
+ method: request.method,
+ body: clone(request),
+ signal: request.signal,
+ size: request.size,
+ referrer: request.referrer,
+ referrerPolicy: request.referrerPolicy
+ };
+
+ // when forwarding sensitive headers like "Authorization",
+ // "WWW-Authenticate", and "Cookie" to untrusted targets,
+ // headers will be ignored when following a redirect to a domain
+ // that is not a subdomain match or exact match of the initial domain.
+ // For example, a redirect from "foo.com" to either "foo.com" or "sub.foo.com"
+ // will forward the sensitive headers, but a redirect to "bar.com" will not.
+ if (!isDomainOrSubdomain(request.url, locationURL)) {
+ for (const name of ['authorization', 'www-authenticate', 'cookie', 'cookie2']) {
+ requestOptions.headers.delete(name);
+ }
+ }
+
+ // HTTP-redirect fetch step 9
+ if (response_.statusCode !== 303 && request.body && options_.body instanceof Stream.Readable) {
+ reject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect'));
+ finalize();
+ return;
+ }
+
+ // HTTP-redirect fetch step 11
+ if (response_.statusCode === 303 || ((response_.statusCode === 301 || response_.statusCode === 302) && request.method === 'POST')) {
+ requestOptions.method = 'GET';
+ requestOptions.body = undefined;
+ requestOptions.headers.delete('content-length');
+ }
+
+ // HTTP-redirect fetch step 14
+ const responseReferrerPolicy = parseReferrerPolicyFromHeader(headers);
+ if (responseReferrerPolicy) {
+ requestOptions.referrerPolicy = responseReferrerPolicy;
+ }
+
+ // HTTP-redirect fetch step 15
+ resolve(fetch(new Request(locationURL, requestOptions)));
+ finalize();
+ return;
+ }
+
+ default:
+ return reject(new TypeError(`Redirect option '${request.redirect}' is not a valid value of RequestRedirect`));
+ }
+ }
+
+ // Prepare response
+ if (signal) {
+ response_.once('end', () => {
+ signal.removeEventListener('abort', abortAndFinalize);
+ });
+ }
+
+ let body = pump(response_, new PassThrough(), error => {
+ if (error) {
+ reject(error);
+ }
+ });
+ // see https://github.com/nodejs/node/pull/29376
+ /* c8 ignore next 3 */
+ if (process.version < 'v12.10') {
+ response_.on('aborted', abortAndFinalize);
+ }
+
+ const responseOptions = {
+ url: request.url,
+ status: response_.statusCode,
+ statusText: response_.statusMessage,
+ headers,
+ size: request.size,
+ counter: request.counter,
+ highWaterMark: request.highWaterMark
+ };
+
+ // HTTP-network fetch step 12.1.1.3
+ const codings = headers.get('Content-Encoding');
+
+ // HTTP-network fetch step 12.1.1.4: handle content codings
+
+ // in following scenarios we ignore compression support
+ // 1. compression support is disabled
+ // 2. HEAD request
+ // 3. no Content-Encoding header
+ // 4. no content response (204)
+ // 5. content not modified response (304)
+ if (!request.compress || request.method === 'HEAD' || codings === null || response_.statusCode === 204 || response_.statusCode === 304) {
+ response = new Response(body, responseOptions);
+ resolve(response);
+ return;
+ }
+
+ // For Node v6+
+ // Be less strict when decoding compressed responses, since sometimes
+ // servers send slightly invalid responses that are still accepted
+ // by common browsers.
+ // Always using Z_SYNC_FLUSH is what cURL does.
+ const zlibOptions = {
+ flush: zlib.Z_SYNC_FLUSH,
+ finishFlush: zlib.Z_SYNC_FLUSH
+ };
+
+ // For gzip
+ if (codings === 'gzip' || codings === 'x-gzip') {
+ body = pump(body, zlib.createGunzip(zlibOptions), error => {
+ if (error) {
+ reject(error);
+ }
+ });
+ response = new Response(body, responseOptions);
+ resolve(response);
+ return;
+ }
+
+ // For deflate
+ if (codings === 'deflate' || codings === 'x-deflate') {
+ // Handle the infamous raw deflate response from old servers
+ // a hack for old IIS and Apache servers
+ const raw = pump(response_, new PassThrough(), error => {
+ if (error) {
+ reject(error);
+ }
+ });
+ raw.once('data', chunk => {
+ // See http://stackoverflow.com/questions/37519828
+ if ((chunk[0] & 0x0F) === 0x08) {
+ body = pump(body, zlib.createInflate(), error => {
+ if (error) {
+ reject(error);
+ }
+ });
+ } else {
+ body = pump(body, zlib.createInflateRaw(), error => {
+ if (error) {
+ reject(error);
+ }
+ });
+ }
+
+ response = new Response(body, responseOptions);
+ resolve(response);
+ });
+ raw.once('end', () => {
+ // Some old IIS servers return zero-length OK deflate responses, so
+ // 'data' is never emitted. See https://github.com/node-fetch/node-fetch/pull/903
+ if (!response) {
+ response = new Response(body, responseOptions);
+ resolve(response);
+ }
+ });
+ return;
+ }
+
+ // For br
+ if (codings === 'br') {
+ body = pump(body, zlib.createBrotliDecompress(), error => {
+ if (error) {
+ reject(error);
+ }
+ });
+ response = new Response(body, responseOptions);
+ resolve(response);
+ return;
+ }
+
+ // Otherwise, use response as-is
+ response = new Response(body, responseOptions);
+ resolve(response);
+ });
+
+ // eslint-disable-next-line promise/prefer-await-to-then
+ writeToStream(request_, request).catch(reject);
+ });
+}
+
+function fixResponseChunkedTransferBadEnding(request, errorCallback) {
+ const LAST_CHUNK = Buffer.from('0\r\n\r\n');
+
+ let isChunkedTransfer = false;
+ let properLastChunkReceived = false;
+ let previousChunk;
+
+ request.on('response', response => {
+ const {headers} = response;
+ isChunkedTransfer = headers['transfer-encoding'] === 'chunked' && !headers['content-length'];
+ });
+
+ request.on('socket', socket => {
+ const onSocketClose = () => {
+ if (isChunkedTransfer && !properLastChunkReceived) {
+ const error = new Error('Premature close');
+ error.code = 'ERR_STREAM_PREMATURE_CLOSE';
+ errorCallback(error);
+ }
+ };
+
+ const onData = buf => {
+ properLastChunkReceived = Buffer.compare(buf.slice(-5), LAST_CHUNK) === 0;
+
+ // Sometimes final 0-length chunk and end of message code are in separate packets
+ if (!properLastChunkReceived && previousChunk) {
+ properLastChunkReceived = (
+ Buffer.compare(previousChunk.slice(-3), LAST_CHUNK.slice(0, 3)) === 0 &&
+ Buffer.compare(buf.slice(-2), LAST_CHUNK.slice(3)) === 0
+ );
+ }
+
+ previousChunk = buf;
+ };
+
+ socket.prependListener('close', onSocketClose);
+ socket.on('data', onData);
+
+ request.on('close', () => {
+ socket.removeListener('close', onSocketClose);
+ socket.removeListener('data', onData);
+ });
+ });
+}
diff --git a/node_modules/node-fetch/src/request.js b/node_modules/node-fetch/src/request.js
new file mode 100644
index 0000000..38f33df
--- /dev/null
+++ b/node_modules/node-fetch/src/request.js
@@ -0,0 +1,317 @@
+/**
+ * Request.js
+ *
+ * Request class contains server only options
+ *
+ * All spec algorithm step numbers are based on https://fetch.spec.whatwg.org/commit-snapshots/ae716822cb3a61843226cd090eefc6589446c1d2/.
+ */
+
+import {format as formatUrl} from 'node:url';
+import {deprecate} from 'node:util';
+import Headers from './headers.js';
+import Body, {clone, extractContentType, getTotalBytes} from './body.js';
+import {isAbortSignal} from './utils/is.js';
+import {getSearch} from './utils/get-search.js';
+import {
+ validateReferrerPolicy, determineRequestsReferrer, DEFAULT_REFERRER_POLICY
+} from './utils/referrer.js';
+
+const INTERNALS = Symbol('Request internals');
+
+/**
+ * Check if `obj` is an instance of Request.
+ *
+ * @param {*} object
+ * @return {boolean}
+ */
+const isRequest = object => {
+ return (
+ typeof object === 'object' &&
+ typeof object[INTERNALS] === 'object'
+ );
+};
+
+const doBadDataWarn = deprecate(() => {},
+ '.data is not a valid RequestInit property, use .body instead',
+ 'https://github.com/node-fetch/node-fetch/issues/1000 (request)');
+
+/**
+ * Request class
+ *
+ * Ref: https://fetch.spec.whatwg.org/#request-class
+ *
+ * @param Mixed input Url or Request instance
+ * @param Object init Custom options
+ * @return Void
+ */
+export default class Request extends Body {
+ constructor(input, init = {}) {
+ let parsedURL;
+
+ // Normalize input and force URL to be encoded as UTF-8 (https://github.com/node-fetch/node-fetch/issues/245)
+ if (isRequest(input)) {
+ parsedURL = new URL(input.url);
+ } else {
+ parsedURL = new URL(input);
+ input = {};
+ }
+
+ if (parsedURL.username !== '' || parsedURL.password !== '') {
+ throw new TypeError(`${parsedURL} is an url with embedded credentials.`);
+ }
+
+ let method = init.method || input.method || 'GET';
+ if (/^(delete|get|head|options|post|put)$/i.test(method)) {
+ method = method.toUpperCase();
+ }
+
+ if ('data' in init) {
+ doBadDataWarn();
+ }
+
+ // eslint-disable-next-line no-eq-null, eqeqeq
+ if ((init.body != null || (isRequest(input) && input.body !== null)) &&
+ (method === 'GET' || method === 'HEAD')) {
+ throw new TypeError('Request with GET/HEAD method cannot have body');
+ }
+
+ const inputBody = init.body ?
+ init.body :
+ (isRequest(input) && input.body !== null ?
+ clone(input) :
+ null);
+
+ super(inputBody, {
+ size: init.size || input.size || 0
+ });
+
+ const headers = new Headers(init.headers || input.headers || {});
+
+ if (inputBody !== null && !headers.has('Content-Type')) {
+ const contentType = extractContentType(inputBody, this);
+ if (contentType) {
+ headers.set('Content-Type', contentType);
+ }
+ }
+
+ let signal = isRequest(input) ?
+ input.signal :
+ null;
+ if ('signal' in init) {
+ signal = init.signal;
+ }
+
+ // eslint-disable-next-line no-eq-null, eqeqeq
+ if (signal != null && !isAbortSignal(signal)) {
+ throw new TypeError('Expected signal to be an instanceof AbortSignal or EventTarget');
+ }
+
+ // §5.4, Request constructor steps, step 15.1
+ // eslint-disable-next-line no-eq-null, eqeqeq
+ let referrer = init.referrer == null ? input.referrer : init.referrer;
+ if (referrer === '') {
+ // §5.4, Request constructor steps, step 15.2
+ referrer = 'no-referrer';
+ } else if (referrer) {
+ // §5.4, Request constructor steps, step 15.3.1, 15.3.2
+ const parsedReferrer = new URL(referrer);
+ // §5.4, Request constructor steps, step 15.3.3, 15.3.4
+ referrer = /^about:(\/\/)?client$/.test(parsedReferrer) ? 'client' : parsedReferrer;
+ } else {
+ referrer = undefined;
+ }
+
+ this[INTERNALS] = {
+ method,
+ redirect: init.redirect || input.redirect || 'follow',
+ headers,
+ parsedURL,
+ signal,
+ referrer
+ };
+
+ // Node-fetch-only options
+ this.follow = init.follow === undefined ? (input.follow === undefined ? 20 : input.follow) : init.follow;
+ this.compress = init.compress === undefined ? (input.compress === undefined ? true : input.compress) : init.compress;
+ this.counter = init.counter || input.counter || 0;
+ this.agent = init.agent || input.agent;
+ this.highWaterMark = init.highWaterMark || input.highWaterMark || 16384;
+ this.insecureHTTPParser = init.insecureHTTPParser || input.insecureHTTPParser || false;
+
+ // §5.4, Request constructor steps, step 16.
+ // Default is empty string per https://fetch.spec.whatwg.org/#concept-request-referrer-policy
+ this.referrerPolicy = init.referrerPolicy || input.referrerPolicy || '';
+ }
+
+ /** @returns {string} */
+ get method() {
+ return this[INTERNALS].method;
+ }
+
+ /** @returns {string} */
+ get url() {
+ return formatUrl(this[INTERNALS].parsedURL);
+ }
+
+ /** @returns {Headers} */
+ get headers() {
+ return this[INTERNALS].headers;
+ }
+
+ get redirect() {
+ return this[INTERNALS].redirect;
+ }
+
+ /** @returns {AbortSignal} */
+ get signal() {
+ return this[INTERNALS].signal;
+ }
+
+ // https://fetch.spec.whatwg.org/#dom-request-referrer
+ get referrer() {
+ if (this[INTERNALS].referrer === 'no-referrer') {
+ return '';
+ }
+
+ if (this[INTERNALS].referrer === 'client') {
+ return 'about:client';
+ }
+
+ if (this[INTERNALS].referrer) {
+ return this[INTERNALS].referrer.toString();
+ }
+
+ return undefined;
+ }
+
+ get referrerPolicy() {
+ return this[INTERNALS].referrerPolicy;
+ }
+
+ set referrerPolicy(referrerPolicy) {
+ this[INTERNALS].referrerPolicy = validateReferrerPolicy(referrerPolicy);
+ }
+
+ /**
+ * Clone this request
+ *
+ * @return Request
+ */
+ clone() {
+ return new Request(this);
+ }
+
+ get [Symbol.toStringTag]() {
+ return 'Request';
+ }
+}
+
+Object.defineProperties(Request.prototype, {
+ method: {enumerable: true},
+ url: {enumerable: true},
+ headers: {enumerable: true},
+ redirect: {enumerable: true},
+ clone: {enumerable: true},
+ signal: {enumerable: true},
+ referrer: {enumerable: true},
+ referrerPolicy: {enumerable: true}
+});
+
+/**
+ * Convert a Request to Node.js http request options.
+ *
+ * @param {Request} request - A Request instance
+ * @return The options object to be passed to http.request
+ */
+export const getNodeRequestOptions = request => {
+ const {parsedURL} = request[INTERNALS];
+ const headers = new Headers(request[INTERNALS].headers);
+
+ // Fetch step 1.3
+ if (!headers.has('Accept')) {
+ headers.set('Accept', '*/*');
+ }
+
+ // HTTP-network-or-cache fetch steps 2.4-2.7
+ let contentLengthValue = null;
+ if (request.body === null && /^(post|put)$/i.test(request.method)) {
+ contentLengthValue = '0';
+ }
+
+ if (request.body !== null) {
+ const totalBytes = getTotalBytes(request);
+ // Set Content-Length if totalBytes is a number (that is not NaN)
+ if (typeof totalBytes === 'number' && !Number.isNaN(totalBytes)) {
+ contentLengthValue = String(totalBytes);
+ }
+ }
+
+ if (contentLengthValue) {
+ headers.set('Content-Length', contentLengthValue);
+ }
+
+ // 4.1. Main fetch, step 2.6
+ // > If request's referrer policy is the empty string, then set request's referrer policy to the
+ // > default referrer policy.
+ if (request.referrerPolicy === '') {
+ request.referrerPolicy = DEFAULT_REFERRER_POLICY;
+ }
+
+ // 4.1. Main fetch, step 2.7
+ // > If request's referrer is not "no-referrer", set request's referrer to the result of invoking
+ // > determine request's referrer.
+ if (request.referrer && request.referrer !== 'no-referrer') {
+ request[INTERNALS].referrer = determineRequestsReferrer(request);
+ } else {
+ request[INTERNALS].referrer = 'no-referrer';
+ }
+
+ // 4.5. HTTP-network-or-cache fetch, step 6.9
+ // > If httpRequest's referrer is a URL, then append `Referer`/httpRequest's referrer, serialized
+ // > and isomorphic encoded, to httpRequest's header list.
+ if (request[INTERNALS].referrer instanceof URL) {
+ headers.set('Referer', request.referrer);
+ }
+
+ // HTTP-network-or-cache fetch step 2.11
+ if (!headers.has('User-Agent')) {
+ headers.set('User-Agent', 'node-fetch');
+ }
+
+ // HTTP-network-or-cache fetch step 2.15
+ if (request.compress && !headers.has('Accept-Encoding')) {
+ headers.set('Accept-Encoding', 'gzip, deflate, br');
+ }
+
+ let {agent} = request;
+ if (typeof agent === 'function') {
+ agent = agent(parsedURL);
+ }
+
+ if (!headers.has('Connection') && !agent) {
+ headers.set('Connection', 'close');
+ }
+
+ // HTTP-network fetch step 4.2
+ // chunked encoding is handled by Node.js
+
+ const search = getSearch(parsedURL);
+
+ // Pass the full URL directly to request(), but overwrite the following
+ // options:
+ const options = {
+ // Overwrite search to retain trailing ? (issue #776)
+ path: parsedURL.pathname + search,
+ // The following options are not expressed in the URL
+ method: request.method,
+ headers: headers[Symbol.for('nodejs.util.inspect.custom')](),
+ insecureHTTPParser: request.insecureHTTPParser,
+ agent
+ };
+
+ return {
+ /** @type {URL} */
+ parsedURL,
+ options
+ };
+};
diff --git a/node_modules/node-fetch/src/response.js b/node_modules/node-fetch/src/response.js
new file mode 100644
index 0000000..63af267
--- /dev/null
+++ b/node_modules/node-fetch/src/response.js
@@ -0,0 +1,141 @@
+/**
+ * Response.js
+ *
+ * Response class provides content decoding
+ */
+
+import Headers from './headers.js';
+import Body, {clone, extractContentType} from './body.js';
+import {isRedirect} from './utils/is-redirect.js';
+
+const INTERNALS = Symbol('Response internals');
+
+/**
+ * Response class
+ *
+ * Ref: https://fetch.spec.whatwg.org/#response-class
+ *
+ * @param Stream body Readable stream
+ * @param Object opts Response options
+ * @return Void
+ */
+export default class Response extends Body {
+ constructor(body = null, options = {}) {
+ super(body, options);
+
+ // eslint-disable-next-line no-eq-null, eqeqeq, no-negated-condition
+ const status = options.status != null ? options.status : 200;
+
+ const headers = new Headers(options.headers);
+
+ if (body !== null && !headers.has('Content-Type')) {
+ const contentType = extractContentType(body, this);
+ if (contentType) {
+ headers.append('Content-Type', contentType);
+ }
+ }
+
+ this[INTERNALS] = {
+ type: 'default',
+ url: options.url,
+ status,
+ statusText: options.statusText || '',
+ headers,
+ counter: options.counter,
+ highWaterMark: options.highWaterMark
+ };
+ }
+
+ get type() {
+ return this[INTERNALS].type;
+ }
+
+ get url() {
+ return this[INTERNALS].url || '';
+ }
+
+ get status() {
+ return this[INTERNALS].status;
+ }
+
+ /**
+ * Convenience property representing if the request ended normally
+ */
+ get ok() {
+ return this[INTERNALS].status >= 200 && this[INTERNALS].status < 300;
+ }
+
+ get redirected() {
+ return this[INTERNALS].counter > 0;
+ }
+
+ get statusText() {
+ return this[INTERNALS].statusText;
+ }
+
+ get headers() {
+ return this[INTERNALS].headers;
+ }
+
+ get highWaterMark() {
+ return this[INTERNALS].highWaterMark;
+ }
+
+ /**
+ * Clone this response
+ *
+ * @return Response
+ */
+ clone() {
+ return new Response(clone(this, this.highWaterMark), {
+ type: this.type,
+ url: this.url,
+ status: this.status,
+ statusText: this.statusText,
+ headers: this.headers,
+ ok: this.ok,
+ redirected: this.redirected,
+ size: this.size,
+ highWaterMark: this.highWaterMark
+ });
+ }
+
+ /**
+ * @param {string} url The URL that the new response is to originate from.
+ * @param {number} status An optional status code for the response (e.g., 302.)
+ * @returns {Response} A Response object.
+ */
+ static redirect(url, status = 302) {
+ if (!isRedirect(status)) {
+ throw new RangeError('Failed to execute "redirect" on "response": Invalid status code');
+ }
+
+ return new Response(null, {
+ headers: {
+ location: new URL(url).toString()
+ },
+ status
+ });
+ }
+
+ static error() {
+ const response = new Response(null, {status: 0, statusText: ''});
+ response[INTERNALS].type = 'error';
+ return response;
+ }
+
+ get [Symbol.toStringTag]() {
+ return 'Response';
+ }
+}
+
+Object.defineProperties(Response.prototype, {
+ type: {enumerable: true},
+ url: {enumerable: true},
+ status: {enumerable: true},
+ ok: {enumerable: true},
+ redirected: {enumerable: true},
+ statusText: {enumerable: true},
+ headers: {enumerable: true},
+ clone: {enumerable: true}
+});
diff --git a/node_modules/node-fetch/src/utils/get-search.js b/node_modules/node-fetch/src/utils/get-search.js
new file mode 100644
index 0000000..d067e7c
--- /dev/null
+++ b/node_modules/node-fetch/src/utils/get-search.js
@@ -0,0 +1,9 @@
+export const getSearch = parsedURL => {
+ if (parsedURL.search) {
+ return parsedURL.search;
+ }
+
+ const lastOffset = parsedURL.href.length - 1;
+ const hash = parsedURL.hash || (parsedURL.href[lastOffset] === '#' ? '#' : '');
+ return parsedURL.href[lastOffset - hash.length] === '?' ? '?' : '';
+};
diff --git a/node_modules/node-fetch/src/utils/is-redirect.js b/node_modules/node-fetch/src/utils/is-redirect.js
new file mode 100644
index 0000000..d1347f0
--- /dev/null
+++ b/node_modules/node-fetch/src/utils/is-redirect.js
@@ -0,0 +1,11 @@
+const redirectStatus = new Set([301, 302, 303, 307, 308]);
+
+/**
+ * Redirect code matching
+ *
+ * @param {number} code - Status code
+ * @return {boolean}
+ */
+export const isRedirect = code => {
+ return redirectStatus.has(code);
+};
diff --git a/node_modules/node-fetch/src/utils/is.js b/node_modules/node-fetch/src/utils/is.js
new file mode 100644
index 0000000..00eb89b
--- /dev/null
+++ b/node_modules/node-fetch/src/utils/is.js
@@ -0,0 +1,73 @@
+/**
+ * Is.js
+ *
+ * Object type checks.
+ */
+
+const NAME = Symbol.toStringTag;
+
+/**
+ * Check if `obj` is a URLSearchParams object
+ * ref: https://github.com/node-fetch/node-fetch/issues/296#issuecomment-307598143
+ * @param {*} object - Object to check for
+ * @return {boolean}
+ */
+export const isURLSearchParameters = object => {
+ return (
+ typeof object === 'object' &&
+ typeof object.append === 'function' &&
+ typeof object.delete === 'function' &&
+ typeof object.get === 'function' &&
+ typeof object.getAll === 'function' &&
+ typeof object.has === 'function' &&
+ typeof object.set === 'function' &&
+ typeof object.sort === 'function' &&
+ object[NAME] === 'URLSearchParams'
+ );
+};
+
+/**
+ * Check if `object` is a W3C `Blob` object (which `File` inherits from)
+ * @param {*} object - Object to check for
+ * @return {boolean}
+ */
+export const isBlob = object => {
+ return (
+ object &&
+ typeof object === 'object' &&
+ typeof object.arrayBuffer === 'function' &&
+ typeof object.type === 'string' &&
+ typeof object.stream === 'function' &&
+ typeof object.constructor === 'function' &&
+ /^(Blob|File)$/.test(object[NAME])
+ );
+};
+
+/**
+ * Check if `obj` is an instance of AbortSignal.
+ * @param {*} object - Object to check for
+ * @return {boolean}
+ */
+export const isAbortSignal = object => {
+ return (
+ typeof object === 'object' && (
+ object[NAME] === 'AbortSignal' ||
+ object[NAME] === 'EventTarget'
+ )
+ );
+};
+
+/**
+ * isDomainOrSubdomain reports whether sub is a subdomain (or exact match) of
+ * the parent domain.
+ *
+ * Both domains must already be in canonical form.
+ * @param {string|URL} original
+ * @param {string|URL} destination
+ */
+export const isDomainOrSubdomain = (destination, original) => {
+ const orig = new URL(original).hostname;
+ const dest = new URL(destination).hostname;
+
+ return orig === dest || orig.endsWith(`.${dest}`);
+};
diff --git a/node_modules/node-fetch/src/utils/multipart-parser.js b/node_modules/node-fetch/src/utils/multipart-parser.js
new file mode 100644
index 0000000..5ad06f9
--- /dev/null
+++ b/node_modules/node-fetch/src/utils/multipart-parser.js
@@ -0,0 +1,432 @@
+import {File} from 'fetch-blob/from.js';
+import {FormData} from 'formdata-polyfill/esm.min.js';
+
+let s = 0;
+const S = {
+ START_BOUNDARY: s++,
+ HEADER_FIELD_START: s++,
+ HEADER_FIELD: s++,
+ HEADER_VALUE_START: s++,
+ HEADER_VALUE: s++,
+ HEADER_VALUE_ALMOST_DONE: s++,
+ HEADERS_ALMOST_DONE: s++,
+ PART_DATA_START: s++,
+ PART_DATA: s++,
+ END: s++
+};
+
+let f = 1;
+const F = {
+ PART_BOUNDARY: f,
+ LAST_BOUNDARY: f *= 2
+};
+
+const LF = 10;
+const CR = 13;
+const SPACE = 32;
+const HYPHEN = 45;
+const COLON = 58;
+const A = 97;
+const Z = 122;
+
+const lower = c => c | 0x20;
+
+const noop = () => {};
+
+class MultipartParser {
+ /**
+ * @param {string} boundary
+ */
+ constructor(boundary) {
+ this.index = 0;
+ this.flags = 0;
+
+ this.onHeaderEnd = noop;
+ this.onHeaderField = noop;
+ this.onHeadersEnd = noop;
+ this.onHeaderValue = noop;
+ this.onPartBegin = noop;
+ this.onPartData = noop;
+ this.onPartEnd = noop;
+
+ this.boundaryChars = {};
+
+ boundary = '\r\n--' + boundary;
+ const ui8a = new Uint8Array(boundary.length);
+ for (let i = 0; i < boundary.length; i++) {
+ ui8a[i] = boundary.charCodeAt(i);
+ this.boundaryChars[ui8a[i]] = true;
+ }
+
+ this.boundary = ui8a;
+ this.lookbehind = new Uint8Array(this.boundary.length + 8);
+ this.state = S.START_BOUNDARY;
+ }
+
+ /**
+ * @param {Uint8Array} data
+ */
+ write(data) {
+ let i = 0;
+ const length_ = data.length;
+ let previousIndex = this.index;
+ let {lookbehind, boundary, boundaryChars, index, state, flags} = this;
+ const boundaryLength = this.boundary.length;
+ const boundaryEnd = boundaryLength - 1;
+ const bufferLength = data.length;
+ let c;
+ let cl;
+
+ const mark = name => {
+ this[name + 'Mark'] = i;
+ };
+
+ const clear = name => {
+ delete this[name + 'Mark'];
+ };
+
+ const callback = (callbackSymbol, start, end, ui8a) => {
+ if (start === undefined || start !== end) {
+ this[callbackSymbol](ui8a && ui8a.subarray(start, end));
+ }
+ };
+
+ const dataCallback = (name, clear) => {
+ const markSymbol = name + 'Mark';
+ if (!(markSymbol in this)) {
+ return;
+ }
+
+ if (clear) {
+ callback(name, this[markSymbol], i, data);
+ delete this[markSymbol];
+ } else {
+ callback(name, this[markSymbol], data.length, data);
+ this[markSymbol] = 0;
+ }
+ };
+
+ for (i = 0; i < length_; i++) {
+ c = data[i];
+
+ switch (state) {
+ case S.START_BOUNDARY:
+ if (index === boundary.length - 2) {
+ if (c === HYPHEN) {
+ flags |= F.LAST_BOUNDARY;
+ } else if (c !== CR) {
+ return;
+ }
+
+ index++;
+ break;
+ } else if (index - 1 === boundary.length - 2) {
+ if (flags & F.LAST_BOUNDARY && c === HYPHEN) {
+ state = S.END;
+ flags = 0;
+ } else if (!(flags & F.LAST_BOUNDARY) && c === LF) {
+ index = 0;
+ callback('onPartBegin');
+ state = S.HEADER_FIELD_START;
+ } else {
+ return;
+ }
+
+ break;
+ }
+
+ if (c !== boundary[index + 2]) {
+ index = -2;
+ }
+
+ if (c === boundary[index + 2]) {
+ index++;
+ }
+
+ break;
+ case S.HEADER_FIELD_START:
+ state = S.HEADER_FIELD;
+ mark('onHeaderField');
+ index = 0;
+ // falls through
+ case S.HEADER_FIELD:
+ if (c === CR) {
+ clear('onHeaderField');
+ state = S.HEADERS_ALMOST_DONE;
+ break;
+ }
+
+ index++;
+ if (c === HYPHEN) {
+ break;
+ }
+
+ if (c === COLON) {
+ if (index === 1) {
+ // empty header field
+ return;
+ }
+
+ dataCallback('onHeaderField', true);
+ state = S.HEADER_VALUE_START;
+ break;
+ }
+
+ cl = lower(c);
+ if (cl < A || cl > Z) {
+ return;
+ }
+
+ break;
+ case S.HEADER_VALUE_START:
+ if (c === SPACE) {
+ break;
+ }
+
+ mark('onHeaderValue');
+ state = S.HEADER_VALUE;
+ // falls through
+ case S.HEADER_VALUE:
+ if (c === CR) {
+ dataCallback('onHeaderValue', true);
+ callback('onHeaderEnd');
+ state = S.HEADER_VALUE_ALMOST_DONE;
+ }
+
+ break;
+ case S.HEADER_VALUE_ALMOST_DONE:
+ if (c !== LF) {
+ return;
+ }
+
+ state = S.HEADER_FIELD_START;
+ break;
+ case S.HEADERS_ALMOST_DONE:
+ if (c !== LF) {
+ return;
+ }
+
+ callback('onHeadersEnd');
+ state = S.PART_DATA_START;
+ break;
+ case S.PART_DATA_START:
+ state = S.PART_DATA;
+ mark('onPartData');
+ // falls through
+ case S.PART_DATA:
+ previousIndex = index;
+
+ if (index === 0) {
+ // boyer-moore derrived algorithm to safely skip non-boundary data
+ i += boundaryEnd;
+ while (i < bufferLength && !(data[i] in boundaryChars)) {
+ i += boundaryLength;
+ }
+
+ i -= boundaryEnd;
+ c = data[i];
+ }
+
+ if (index < boundary.length) {
+ if (boundary[index] === c) {
+ if (index === 0) {
+ dataCallback('onPartData', true);
+ }
+
+ index++;
+ } else {
+ index = 0;
+ }
+ } else if (index === boundary.length) {
+ index++;
+ if (c === CR) {
+ // CR = part boundary
+ flags |= F.PART_BOUNDARY;
+ } else if (c === HYPHEN) {
+ // HYPHEN = end boundary
+ flags |= F.LAST_BOUNDARY;
+ } else {
+ index = 0;
+ }
+ } else if (index - 1 === boundary.length) {
+ if (flags & F.PART_BOUNDARY) {
+ index = 0;
+ if (c === LF) {
+ // unset the PART_BOUNDARY flag
+ flags &= ~F.PART_BOUNDARY;
+ callback('onPartEnd');
+ callback('onPartBegin');
+ state = S.HEADER_FIELD_START;
+ break;
+ }
+ } else if (flags & F.LAST_BOUNDARY) {
+ if (c === HYPHEN) {
+ callback('onPartEnd');
+ state = S.END;
+ flags = 0;
+ } else {
+ index = 0;
+ }
+ } else {
+ index = 0;
+ }
+ }
+
+ if (index > 0) {
+ // when matching a possible boundary, keep a lookbehind reference
+ // in case it turns out to be a false lead
+ lookbehind[index - 1] = c;
+ } else if (previousIndex > 0) {
+ // if our boundary turned out to be rubbish, the captured lookbehind
+ // belongs to partData
+ const _lookbehind = new Uint8Array(lookbehind.buffer, lookbehind.byteOffset, lookbehind.byteLength);
+ callback('onPartData', 0, previousIndex, _lookbehind);
+ previousIndex = 0;
+ mark('onPartData');
+
+ // reconsider the current character even so it interrupted the sequence
+ // it could be the beginning of a new sequence
+ i--;
+ }
+
+ break;
+ case S.END:
+ break;
+ default:
+ throw new Error(`Unexpected state entered: ${state}`);
+ }
+ }
+
+ dataCallback('onHeaderField');
+ dataCallback('onHeaderValue');
+ dataCallback('onPartData');
+
+ // Update properties for the next call
+ this.index = index;
+ this.state = state;
+ this.flags = flags;
+ }
+
+ end() {
+ if ((this.state === S.HEADER_FIELD_START && this.index === 0) ||
+ (this.state === S.PART_DATA && this.index === this.boundary.length)) {
+ this.onPartEnd();
+ } else if (this.state !== S.END) {
+ throw new Error('MultipartParser.end(): stream ended unexpectedly');
+ }
+ }
+}
+
+function _fileName(headerValue) {
+ // matches either a quoted-string or a token (RFC 2616 section 19.5.1)
+ const m = headerValue.match(/\bfilename=("(.*?)"|([^()<>@,;:\\"/[\]?={}\s\t]+))($|;\s)/i);
+ if (!m) {
+ return;
+ }
+
+ const match = m[2] || m[3] || '';
+ let filename = match.slice(match.lastIndexOf('\\') + 1);
+ filename = filename.replace(/%22/g, '"');
+ filename = filename.replace(/(\d{4});/g, (m, code) => {
+ return String.fromCharCode(code);
+ });
+ return filename;
+}
+
+export async function toFormData(Body, ct) {
+ if (!/multipart/i.test(ct)) {
+ throw new TypeError('Failed to fetch');
+ }
+
+ const m = ct.match(/boundary=(?:"([^"]+)"|([^;]+))/i);
+
+ if (!m) {
+ throw new TypeError('no or bad content-type header, no multipart boundary');
+ }
+
+ const parser = new MultipartParser(m[1] || m[2]);
+
+ let headerField;
+ let headerValue;
+ let entryValue;
+ let entryName;
+ let contentType;
+ let filename;
+ const entryChunks = [];
+ const formData = new FormData();
+
+ const onPartData = ui8a => {
+ entryValue += decoder.decode(ui8a, {stream: true});
+ };
+
+ const appendToFile = ui8a => {
+ entryChunks.push(ui8a);
+ };
+
+ const appendFileToFormData = () => {
+ const file = new File(entryChunks, filename, {type: contentType});
+ formData.append(entryName, file);
+ };
+
+ const appendEntryToFormData = () => {
+ formData.append(entryName, entryValue);
+ };
+
+ const decoder = new TextDecoder('utf-8');
+ decoder.decode();
+
+ parser.onPartBegin = function () {
+ parser.onPartData = onPartData;
+ parser.onPartEnd = appendEntryToFormData;
+
+ headerField = '';
+ headerValue = '';
+ entryValue = '';
+ entryName = '';
+ contentType = '';
+ filename = null;
+ entryChunks.length = 0;
+ };
+
+ parser.onHeaderField = function (ui8a) {
+ headerField += decoder.decode(ui8a, {stream: true});
+ };
+
+ parser.onHeaderValue = function (ui8a) {
+ headerValue += decoder.decode(ui8a, {stream: true});
+ };
+
+ parser.onHeaderEnd = function () {
+ headerValue += decoder.decode();
+ headerField = headerField.toLowerCase();
+
+ if (headerField === 'content-disposition') {
+ // matches either a quoted-string or a token (RFC 2616 section 19.5.1)
+ const m = headerValue.match(/\bname=("([^"]*)"|([^()<>@,;:\\"/[\]?={}\s\t]+))/i);
+
+ if (m) {
+ entryName = m[2] || m[3] || '';
+ }
+
+ filename = _fileName(headerValue);
+
+ if (filename) {
+ parser.onPartData = appendToFile;
+ parser.onPartEnd = appendFileToFormData;
+ }
+ } else if (headerField === 'content-type') {
+ contentType = headerValue;
+ }
+
+ headerValue = '';
+ headerField = '';
+ };
+
+ for await (const chunk of Body) {
+ parser.write(chunk);
+ }
+
+ parser.end();
+
+ return formData;
+}
diff --git a/node_modules/node-fetch/src/utils/referrer.js b/node_modules/node-fetch/src/utils/referrer.js
new file mode 100644
index 0000000..c8c6686
--- /dev/null
+++ b/node_modules/node-fetch/src/utils/referrer.js
@@ -0,0 +1,340 @@
+import {isIP} from 'node:net';
+
+/**
+ * @external URL
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/URL|URL}
+ */
+
+/**
+ * @module utils/referrer
+ * @private
+ */
+
+/**
+ * @see {@link https://w3c.github.io/webappsec-referrer-policy/#strip-url|Referrer Policy §8.4. Strip url for use as a referrer}
+ * @param {string} URL
+ * @param {boolean} [originOnly=false]
+ */
+export function stripURLForUseAsAReferrer(url, originOnly = false) {
+ // 1. If url is null, return no referrer.
+ if (url == null) { // eslint-disable-line no-eq-null, eqeqeq
+ return 'no-referrer';
+ }
+
+ url = new URL(url);
+
+ // 2. If url's scheme is a local scheme, then return no referrer.
+ if (/^(about|blob|data):$/.test(url.protocol)) {
+ return 'no-referrer';
+ }
+
+ // 3. Set url's username to the empty string.
+ url.username = '';
+
+ // 4. Set url's password to null.
+ // Note: `null` appears to be a mistake as this actually results in the password being `"null"`.
+ url.password = '';
+
+ // 5. Set url's fragment to null.
+ // Note: `null` appears to be a mistake as this actually results in the fragment being `"#null"`.
+ url.hash = '';
+
+ // 6. If the origin-only flag is true, then:
+ if (originOnly) {
+ // 6.1. Set url's path to null.
+ // Note: `null` appears to be a mistake as this actually results in the path being `"/null"`.
+ url.pathname = '';
+
+ // 6.2. Set url's query to null.
+ // Note: `null` appears to be a mistake as this actually results in the query being `"?null"`.
+ url.search = '';
+ }
+
+ // 7. Return url.
+ return url;
+}
+
+/**
+ * @see {@link https://w3c.github.io/webappsec-referrer-policy/#enumdef-referrerpolicy|enum ReferrerPolicy}
+ */
+export const ReferrerPolicy = new Set([
+ '',
+ 'no-referrer',
+ 'no-referrer-when-downgrade',
+ 'same-origin',
+ 'origin',
+ 'strict-origin',
+ 'origin-when-cross-origin',
+ 'strict-origin-when-cross-origin',
+ 'unsafe-url'
+]);
+
+/**
+ * @see {@link https://w3c.github.io/webappsec-referrer-policy/#default-referrer-policy|default referrer policy}
+ */
+export const DEFAULT_REFERRER_POLICY = 'strict-origin-when-cross-origin';
+
+/**
+ * @see {@link https://w3c.github.io/webappsec-referrer-policy/#referrer-policies|Referrer Policy §3. Referrer Policies}
+ * @param {string} referrerPolicy
+ * @returns {string} referrerPolicy
+ */
+export function validateReferrerPolicy(referrerPolicy) {
+ if (!ReferrerPolicy.has(referrerPolicy)) {
+ throw new TypeError(`Invalid referrerPolicy: ${referrerPolicy}`);
+ }
+
+ return referrerPolicy;
+}
+
+/**
+ * @see {@link https://w3c.github.io/webappsec-secure-contexts/#is-origin-trustworthy|Referrer Policy §3.2. Is origin potentially trustworthy?}
+ * @param {external:URL} url
+ * @returns `true`: "Potentially Trustworthy", `false`: "Not Trustworthy"
+ */
+export function isOriginPotentiallyTrustworthy(url) {
+ // 1. If origin is an opaque origin, return "Not Trustworthy".
+ // Not applicable
+
+ // 2. Assert: origin is a tuple origin.
+ // Not for implementations
+
+ // 3. If origin's scheme is either "https" or "wss", return "Potentially Trustworthy".
+ if (/^(http|ws)s:$/.test(url.protocol)) {
+ return true;
+ }
+
+ // 4. If origin's host component matches one of the CIDR notations 127.0.0.0/8 or ::1/128 [RFC4632], return "Potentially Trustworthy".
+ const hostIp = url.host.replace(/(^\[)|(]$)/g, '');
+ const hostIPVersion = isIP(hostIp);
+
+ if (hostIPVersion === 4 && /^127\./.test(hostIp)) {
+ return true;
+ }
+
+ if (hostIPVersion === 6 && /^(((0+:){7})|(::(0+:){0,6}))0*1$/.test(hostIp)) {
+ return true;
+ }
+
+ // 5. If origin's host component is "localhost" or falls within ".localhost", and the user agent conforms to the name resolution rules in [let-localhost-be-localhost], return "Potentially Trustworthy".
+ // We are returning FALSE here because we cannot ensure conformance to
+ // let-localhost-be-loalhost (https://tools.ietf.org/html/draft-west-let-localhost-be-localhost)
+ if (/^(.+\.)*localhost$/.test(url.host)) {
+ return false;
+ }
+
+ // 6. If origin's scheme component is file, return "Potentially Trustworthy".
+ if (url.protocol === 'file:') {
+ return true;
+ }
+
+ // 7. If origin's scheme component is one which the user agent considers to be authenticated, return "Potentially Trustworthy".
+ // Not supported
+
+ // 8. If origin has been configured as a trustworthy origin, return "Potentially Trustworthy".
+ // Not supported
+
+ // 9. Return "Not Trustworthy".
+ return false;
+}
+
+/**
+ * @see {@link https://w3c.github.io/webappsec-secure-contexts/#is-url-trustworthy|Referrer Policy §3.3. Is url potentially trustworthy?}
+ * @param {external:URL} url
+ * @returns `true`: "Potentially Trustworthy", `false`: "Not Trustworthy"
+ */
+export function isUrlPotentiallyTrustworthy(url) {
+ // 1. If url is "about:blank" or "about:srcdoc", return "Potentially Trustworthy".
+ if (/^about:(blank|srcdoc)$/.test(url)) {
+ return true;
+ }
+
+ // 2. If url's scheme is "data", return "Potentially Trustworthy".
+ if (url.protocol === 'data:') {
+ return true;
+ }
+
+ // Note: The origin of blob: and filesystem: URLs is the origin of the context in which they were
+ // created. Therefore, blobs created in a trustworthy origin will themselves be potentially
+ // trustworthy.
+ if (/^(blob|filesystem):$/.test(url.protocol)) {
+ return true;
+ }
+
+ // 3. Return the result of executing §3.2 Is origin potentially trustworthy? on url's origin.
+ return isOriginPotentiallyTrustworthy(url);
+}
+
+/**
+ * Modifies the referrerURL to enforce any extra security policy considerations.
+ * @see {@link https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer|Referrer Policy §8.3. Determine request's Referrer}, step 7
+ * @callback module:utils/referrer~referrerURLCallback
+ * @param {external:URL} referrerURL
+ * @returns {external:URL} modified referrerURL
+ */
+
+/**
+ * Modifies the referrerOrigin to enforce any extra security policy considerations.
+ * @see {@link https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer|Referrer Policy §8.3. Determine request's Referrer}, step 7
+ * @callback module:utils/referrer~referrerOriginCallback
+ * @param {external:URL} referrerOrigin
+ * @returns {external:URL} modified referrerOrigin
+ */
+
+/**
+ * @see {@link https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer|Referrer Policy §8.3. Determine request's Referrer}
+ * @param {Request} request
+ * @param {object} o
+ * @param {module:utils/referrer~referrerURLCallback} o.referrerURLCallback
+ * @param {module:utils/referrer~referrerOriginCallback} o.referrerOriginCallback
+ * @returns {external:URL} Request's referrer
+ */
+export function determineRequestsReferrer(request, {referrerURLCallback, referrerOriginCallback} = {}) {
+ // There are 2 notes in the specification about invalid pre-conditions. We return null, here, for
+ // these cases:
+ // > Note: If request's referrer is "no-referrer", Fetch will not call into this algorithm.
+ // > Note: If request's referrer policy is the empty string, Fetch will not call into this
+ // > algorithm.
+ if (request.referrer === 'no-referrer' || request.referrerPolicy === '') {
+ return null;
+ }
+
+ // 1. Let policy be request's associated referrer policy.
+ const policy = request.referrerPolicy;
+
+ // 2. Let environment be request's client.
+ // not applicable to node.js
+
+ // 3. Switch on request's referrer:
+ if (request.referrer === 'about:client') {
+ return 'no-referrer';
+ }
+
+ // "a URL": Let referrerSource be request's referrer.
+ const referrerSource = request.referrer;
+
+ // 4. Let request's referrerURL be the result of stripping referrerSource for use as a referrer.
+ let referrerURL = stripURLForUseAsAReferrer(referrerSource);
+
+ // 5. Let referrerOrigin be the result of stripping referrerSource for use as a referrer, with the
+ // origin-only flag set to true.
+ let referrerOrigin = stripURLForUseAsAReferrer(referrerSource, true);
+
+ // 6. If the result of serializing referrerURL is a string whose length is greater than 4096, set
+ // referrerURL to referrerOrigin.
+ if (referrerURL.toString().length > 4096) {
+ referrerURL = referrerOrigin;
+ }
+
+ // 7. The user agent MAY alter referrerURL or referrerOrigin at this point to enforce arbitrary
+ // policy considerations in the interests of minimizing data leakage. For example, the user
+ // agent could strip the URL down to an origin, modify its host, replace it with an empty
+ // string, etc.
+ if (referrerURLCallback) {
+ referrerURL = referrerURLCallback(referrerURL);
+ }
+
+ if (referrerOriginCallback) {
+ referrerOrigin = referrerOriginCallback(referrerOrigin);
+ }
+
+ // 8.Execute the statements corresponding to the value of policy:
+ const currentURL = new URL(request.url);
+
+ switch (policy) {
+ case 'no-referrer':
+ return 'no-referrer';
+
+ case 'origin':
+ return referrerOrigin;
+
+ case 'unsafe-url':
+ return referrerURL;
+
+ case 'strict-origin':
+ // 1. If referrerURL is a potentially trustworthy URL and request's current URL is not a
+ // potentially trustworthy URL, then return no referrer.
+ if (isUrlPotentiallyTrustworthy(referrerURL) && !isUrlPotentiallyTrustworthy(currentURL)) {
+ return 'no-referrer';
+ }
+
+ // 2. Return referrerOrigin.
+ return referrerOrigin.toString();
+
+ case 'strict-origin-when-cross-origin':
+ // 1. If the origin of referrerURL and the origin of request's current URL are the same, then
+ // return referrerURL.
+ if (referrerURL.origin === currentURL.origin) {
+ return referrerURL;
+ }
+
+ // 2. If referrerURL is a potentially trustworthy URL and request's current URL is not a
+ // potentially trustworthy URL, then return no referrer.
+ if (isUrlPotentiallyTrustworthy(referrerURL) && !isUrlPotentiallyTrustworthy(currentURL)) {
+ return 'no-referrer';
+ }
+
+ // 3. Return referrerOrigin.
+ return referrerOrigin;
+
+ case 'same-origin':
+ // 1. If the origin of referrerURL and the origin of request's current URL are the same, then
+ // return referrerURL.
+ if (referrerURL.origin === currentURL.origin) {
+ return referrerURL;
+ }
+
+ // 2. Return no referrer.
+ return 'no-referrer';
+
+ case 'origin-when-cross-origin':
+ // 1. If the origin of referrerURL and the origin of request's current URL are the same, then
+ // return referrerURL.
+ if (referrerURL.origin === currentURL.origin) {
+ return referrerURL;
+ }
+
+ // Return referrerOrigin.
+ return referrerOrigin;
+
+ case 'no-referrer-when-downgrade':
+ // 1. If referrerURL is a potentially trustworthy URL and request's current URL is not a
+ // potentially trustworthy URL, then return no referrer.
+ if (isUrlPotentiallyTrustworthy(referrerURL) && !isUrlPotentiallyTrustworthy(currentURL)) {
+ return 'no-referrer';
+ }
+
+ // 2. Return referrerURL.
+ return referrerURL;
+
+ default:
+ throw new TypeError(`Invalid referrerPolicy: ${policy}`);
+ }
+}
+
+/**
+ * @see {@link https://w3c.github.io/webappsec-referrer-policy/#parse-referrer-policy-from-header|Referrer Policy §8.1. Parse a referrer policy from a Referrer-Policy header}
+ * @param {Headers} headers Response headers
+ * @returns {string} policy
+ */
+export function parseReferrerPolicyFromHeader(headers) {
+ // 1. Let policy-tokens be the result of extracting header list values given `Referrer-Policy`
+ // and response’s header list.
+ const policyTokens = (headers.get('referrer-policy') || '').split(/[,\s]+/);
+
+ // 2. Let policy be the empty string.
+ let policy = '';
+
+ // 3. For each token in policy-tokens, if token is a referrer policy and token is not the empty
+ // string, then set policy to token.
+ // Note: This algorithm loops over multiple policy values to allow deployment of new policy
+ // values with fallbacks for older user agents, as described in § 11.1 Unknown Policy Values.
+ for (const token of policyTokens) {
+ if (token && ReferrerPolicy.has(token)) {
+ policy = token;
+ }
+ }
+
+ // 4. Return policy.
+ return policy;
+}
diff --git a/node_modules/undici/README.md b/node_modules/undici/README.md
deleted file mode 100644
index 432eb26..0000000
--- a/node_modules/undici/README.md
+++ /dev/null
@@ -1,402 +0,0 @@
-# undici
-
-[](https://github.com/nodejs/undici/actions/workflows/nodejs.yml) [](http://standardjs.com/) [](https://badge.fury.io/js/undici) [](https://codecov.io/gh/nodejs/undici)
-
-An HTTP/1.1 client, written from scratch for Node.js.
-
-> Undici means eleven in Italian. 1.1 -> 11 -> Eleven -> Undici.
-It is also a Stranger Things reference.
-
-Have a question about using Undici? Open a [Q&A Discussion](https://github.com/nodejs/undici/discussions/new) or join our official OpenJS [Slack](https://openjs-foundation.slack.com/archives/C01QF9Q31QD) channel.
-
-## Install
-
-```
-npm i undici
-```
-
-## Benchmarks
-
-The benchmark is a simple `hello world` [example](benchmarks/benchmark.js) using a
-number of unix sockets (connections) with a pipelining depth of 10 running on Node 16.
-The benchmarks below have the [simd](https://github.com/WebAssembly/simd) feature enabled.
-
-### Connections 1
-
-| Tests | Samples | Result | Tolerance | Difference with slowest |
-|---------------------|---------|---------------|-----------|-------------------------|
-| http - no keepalive | 15 | 4.63 req/sec | ± 2.77 % | - |
-| http - keepalive | 10 | 4.81 req/sec | ± 2.16 % | + 3.94 % |
-| undici - stream | 25 | 62.22 req/sec | ± 2.67 % | + 1244.58 % |
-| undici - dispatch | 15 | 64.33 req/sec | ± 2.47 % | + 1290.24 % |
-| undici - request | 15 | 66.08 req/sec | ± 2.48 % | + 1327.88 % |
-| undici - pipeline | 10 | 66.13 req/sec | ± 1.39 % | + 1329.08 % |
-
-### Connections 50
-
-| Tests | Samples | Result | Tolerance | Difference with slowest |
-|---------------------|---------|------------------|-----------|-------------------------|
-| http - no keepalive | 50 | 3546.49 req/sec | ± 2.90 % | - |
-| http - keepalive | 15 | 5692.67 req/sec | ± 2.48 % | + 60.52 % |
-| undici - pipeline | 25 | 8478.71 req/sec | ± 2.62 % | + 139.07 % |
-| undici - request | 20 | 9766.66 req/sec | ± 2.79 % | + 175.39 % |
-| undici - stream | 15 | 10109.74 req/sec | ± 2.94 % | + 185.06 % |
-| undici - dispatch | 25 | 10949.73 req/sec | ± 2.54 % | + 208.75 % |
-
-## Quick Start
-
-```js
-import { request } from 'undici'
-
-const {
- statusCode,
- headers,
- trailers,
- body
-} = await request('http://localhost:3000/foo')
-
-console.log('response received', statusCode)
-console.log('headers', headers)
-
-for await (const data of body) {
- console.log('data', data)
-}
-
-console.log('trailers', trailers)
-```
-
-## Body Mixins
-
-The `body` mixins are the most common way to format the request/response body. Mixins include:
-
-- [`.formData()`](https://fetch.spec.whatwg.org/#dom-body-formdata)
-- [`.json()`](https://fetch.spec.whatwg.org/#dom-body-json)
-- [`.text()`](https://fetch.spec.whatwg.org/#dom-body-text)
-
-Example usage:
-
-```js
-import { request } from 'undici'
-
-const {
- statusCode,
- headers,
- trailers,
- body
-} = await request('http://localhost:3000/foo')
-
-console.log('response received', statusCode)
-console.log('headers', headers)
-console.log('data', await body.json())
-console.log('trailers', trailers)
-```
-
-_Note: Once a mixin has been called then the body cannot be reused, thus calling additional mixins on `.body`, e.g. `.body.json(); .body.text()` will result in an error `TypeError: unusable` being thrown and returned through the `Promise` rejection._
-
-Should you need to access the `body` in plain-text after using a mixin, the best practice is to use the `.text()` mixin first and then manually parse the text to the desired format.
-
-For more information about their behavior, please reference the body mixin from the [Fetch Standard](https://fetch.spec.whatwg.org/#body-mixin).
-
-## Common API Methods
-
-This section documents our most commonly used API methods. Additional APIs are documented in their own files within the [docs](./docs/) folder and are accessible via the navigation list on the left side of the docs site.
-
-### `undici.request([url, options]): Promise`
-
-Arguments:
-
-* **url** `string | URL | UrlObject`
-* **options** [`RequestOptions`](./docs/api/Dispatcher.md#parameter-requestoptions)
- * **dispatcher** `Dispatcher` - Default: [getGlobalDispatcher](#undicigetglobaldispatcher)
- * **method** `String` - Default: `PUT` if `options.body`, otherwise `GET`
- * **maxRedirections** `Integer` - Default: `0`
-
-Returns a promise with the result of the `Dispatcher.request` method.
-
-Calls `options.dispatcher.request(options)`.
-
-See [Dispatcher.request](./docs/api/Dispatcher.md#dispatcherrequestoptions-callback) for more details.
-
-### `undici.stream([url, options, ]factory): Promise`
-
-Arguments:
-
-* **url** `string | URL | UrlObject`
-* **options** [`StreamOptions`](./docs/api/Dispatcher.md#parameter-streamoptions)
- * **dispatcher** `Dispatcher` - Default: [getGlobalDispatcher](#undicigetglobaldispatcher)
- * **method** `String` - Default: `PUT` if `options.body`, otherwise `GET`
- * **maxRedirections** `Integer` - Default: `0`
-* **factory** `Dispatcher.stream.factory`
-
-Returns a promise with the result of the `Dispatcher.stream` method.
-
-Calls `options.dispatcher.stream(options, factory)`.
-
-See [Dispatcher.stream](docs/api/Dispatcher.md#dispatcherstreamoptions-factory-callback) for more details.
-
-### `undici.pipeline([url, options, ]handler): Duplex`
-
-Arguments:
-
-* **url** `string | URL | UrlObject`
-* **options** [`PipelineOptions`](docs/api/Dispatcher.md#parameter-pipelineoptions)
- * **dispatcher** `Dispatcher` - Default: [getGlobalDispatcher](#undicigetglobaldispatcher)
- * **method** `String` - Default: `PUT` if `options.body`, otherwise `GET`
- * **maxRedirections** `Integer` - Default: `0`
-* **handler** `Dispatcher.pipeline.handler`
-
-Returns: `stream.Duplex`
-
-Calls `options.dispatch.pipeline(options, handler)`.
-
-See [Dispatcher.pipeline](docs/api/Dispatcher.md#dispatcherpipelineoptions-handler) for more details.
-
-### `undici.connect([url, options]): Promise`
-
-Starts two-way communications with the requested resource using [HTTP CONNECT](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/CONNECT).
-
-Arguments:
-
-* **url** `string | URL | UrlObject`
-* **options** [`ConnectOptions`](docs/api/Dispatcher.md#parameter-connectoptions)
- * **dispatcher** `Dispatcher` - Default: [getGlobalDispatcher](#undicigetglobaldispatcher)
- * **maxRedirections** `Integer` - Default: `0`
-* **callback** `(err: Error | null, data: ConnectData | null) => void` (optional)
-
-Returns a promise with the result of the `Dispatcher.connect` method.
-
-Calls `options.dispatch.connect(options)`.
-
-See [Dispatcher.connect](docs/api/Dispatcher.md#dispatcherconnectoptions-callback) for more details.
-
-### `undici.fetch(input[, init]): Promise`
-
-Implements [fetch](https://fetch.spec.whatwg.org/#fetch-method).
-
-* https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch
-* https://fetch.spec.whatwg.org/#fetch-method
-
-Only supported on Node 16.5+.
-
-This is [experimental](https://nodejs.org/api/documentation.html#documentation_stability_index) and is not yet fully compliant with the Fetch Standard.
-We plan to ship breaking changes to this feature until it is out of experimental.
-Help us improve the test coverage by following instructions at [nodejs/undici/#951](https://github.com/nodejs/undici/issues/951).
-
-Basic usage example:
-
-```js
-import { fetch } from 'undici';
-
-
-const res = await fetch('https://example.com')
-const json = await res.json()
-console.log(json);
-```
-
-You can pass an optional dispatcher to `fetch` as:
-
-```js
-import { fetch, Agent } from 'undici'
-
-const res = await fetch('https://example.com', {
- // Mocks are also supported
- dispatcher: new Agent({
- keepAliveTimeout: 10,
- keepAliveMaxTimeout: 10
- })
-})
-const json = await res.json()
-console.log(json)
-```
-
-#### `request.body`
-
-A body can be of the following types:
-
-- ArrayBuffer
-- ArrayBufferView
-- AsyncIterables
-- Blob
-- Iterables
-- String
-- URLSearchParams
-- FormData
-
-In this implementation of fetch, ```request.body``` now accepts ```Async Iterables```. It is not present in the [Fetch Standard.](https://fetch.spec.whatwg.org)
-
-```js
-import { fetch } from "undici";
-
-const data = {
- async *[Symbol.asyncIterator]() {
- yield "hello";
- yield "world";
- },
-};
-
-await fetch("https://example.com", { body: data, method: 'POST' });
-```
-
-#### `response.body`
-
-Nodejs has two kinds of streams: [web streams](https://nodejs.org/dist/latest-v16.x/docs/api/webstreams.html), which follow the API of the WHATWG web standard found in browsers, and an older Node-specific [streams API](https://nodejs.org/api/stream.html). `response.body` returns a readable web stream. If you would prefer to work with a Node stream you can convert a web stream using `.fromWeb()`.
-
-```js
-import { fetch } from 'undici';
-import { Readable } from 'node:stream';
-
-const response = await fetch('https://example.com')
-const readableWebStream = response.body;
-const readableNodeStream = Readable.fromWeb(readableWebStream);
-```
-
-#### Specification Compliance
-
-This section documents parts of the [Fetch Standard](https://fetch.spec.whatwg.org) that Undici does
-not support or does not fully implement.
-
-##### Garbage Collection
-
-* https://fetch.spec.whatwg.org/#garbage-collection
-
-The [Fetch Standard](https://fetch.spec.whatwg.org) allows users to skip consuming the response body by relying on
-[garbage collection](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management#garbage_collection) to release connection resources. Undici does not do the same. Therefore, it is important to always either consume or cancel the response body.
-
-Garbage collection in Node is less aggressive and deterministic
-(due to the lack of clear idle periods that browsers have through the rendering refresh rate)
-which means that leaving the release of connection resources to the garbage collector can lead
-to excessive connection usage, reduced performance (due to less connection re-use), and even
-stalls or deadlocks when running out of connections.
-
-```js
-// Do
-const headers = await fetch(url)
- .then(async res => {
- for await (const chunk of res.body) {
- // force consumption of body
- }
- return res.headers
- })
-
-// Do not
-const headers = await fetch(url)
- .then(res => res.headers)
-```
-
-However, if you want to get only headers, it might be better to use `HEAD` request method. Usage of this method will obviate the need for consumption or cancelling of the response body. See [MDN - HTTP - HTTP request methods - HEAD](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/HEAD) for more details.
-
-```js
-const headers = await fetch(url, { method: 'HEAD' })
- .then(res => res.headers)
-```
-
-##### Forbidden and Safelisted Header Names
-
-* https://fetch.spec.whatwg.org/#cors-safelisted-response-header-name
-* https://fetch.spec.whatwg.org/#forbidden-header-name
-* https://fetch.spec.whatwg.org/#forbidden-response-header-name
-* https://github.com/wintercg/fetch/issues/6
-
-The [Fetch Standard](https://fetch.spec.whatwg.org) requires implementations to exclude certain headers from requests and responses. In browser environments, some headers are forbidden so the user agent remains in full control over them. In Undici, these constraints are removed to give more control to the user.
-
-### `undici.upgrade([url, options]): Promise`
-
-Upgrade to a different protocol. See [MDN - HTTP - Protocol upgrade mechanism](https://developer.mozilla.org/en-US/docs/Web/HTTP/Protocol_upgrade_mechanism) for more details.
-
-Arguments:
-
-* **url** `string | URL | UrlObject`
-* **options** [`UpgradeOptions`](docs/api/Dispatcher.md#parameter-upgradeoptions)
- * **dispatcher** `Dispatcher` - Default: [getGlobalDispatcher](#undicigetglobaldispatcher)
- * **maxRedirections** `Integer` - Default: `0`
-* **callback** `(error: Error | null, data: UpgradeData) => void` (optional)
-
-Returns a promise with the result of the `Dispatcher.upgrade` method.
-
-Calls `options.dispatcher.upgrade(options)`.
-
-See [Dispatcher.upgrade](docs/api/Dispatcher.md#dispatcherupgradeoptions-callback) for more details.
-
-### `undici.setGlobalDispatcher(dispatcher)`
-
-* dispatcher `Dispatcher`
-
-Sets the global dispatcher used by Common API Methods.
-
-### `undici.getGlobalDispatcher()`
-
-Gets the global dispatcher used by Common API Methods.
-
-Returns: `Dispatcher`
-
-### `UrlObject`
-
-* **port** `string | number` (optional)
-* **path** `string` (optional)
-* **pathname** `string` (optional)
-* **hostname** `string` (optional)
-* **origin** `string` (optional)
-* **protocol** `string` (optional)
-* **search** `string` (optional)
-
-## Specification Compliance
-
-This section documents parts of the HTTP/1.1 specification that Undici does
-not support or does not fully implement.
-
-### Expect
-
-Undici does not support the `Expect` request header field. The request
-body is always immediately sent and the `100 Continue` response will be
-ignored.
-
-Refs: https://tools.ietf.org/html/rfc7231#section-5.1.1
-
-### Pipelining
-
-Undici will only use pipelining if configured with a `pipelining` factor
-greater than `1`.
-
-Undici always assumes that connections are persistent and will immediately
-pipeline requests, without checking whether the connection is persistent.
-Hence, automatic fallback to HTTP/1.0 or HTTP/1.1 without pipelining is
-not supported.
-
-Undici will immediately pipeline when retrying requests after a failed
-connection. However, Undici will not retry the first remaining requests in
-the prior pipeline and instead error the corresponding callback/promise/stream.
-
-Undici will abort all running requests in the pipeline when any of them are
-aborted.
-
-* Refs: https://tools.ietf.org/html/rfc2616#section-8.1.2.2
-* Refs: https://tools.ietf.org/html/rfc7230#section-6.3.2
-
-### Manual Redirect
-
-Since it is not possible to manually follow an HTTP redirect on the server-side,
-Undici returns the actual response instead of an `opaqueredirect` filtered one
-when invoked with a `manual` redirect. This aligns `fetch()` with the other
-implementations in Deno and Cloudflare Workers.
-
-Refs: https://fetch.spec.whatwg.org/#atomic-http-redirect-handling
-
-## Collaborators
-
-* [__Daniele Belardi__](https://github.com/dnlup),
-* [__Ethan Arrowood__](https://github.com/ethan-arrowood),
-* [__Matteo Collina__](https://github.com/mcollina),
-* [__Matthew Aitken__](https://github.com/KhafraDev),
-* [__Robert Nagy__](https://github.com/ronag),
-* [__Szymon Marczak__](https://github.com/szmarczak),
-* [__Tomas Della Vedova__](https://github.com/delvedor),
-
-### Releasers
-
-* [__Ethan Arrowood__](https://github.com/ethan-arrowood),
-* [__Matteo Collina__](https://github.com/mcollina),
-* [__Robert Nagy__](https://github.com/ronag),
-
-## License
-
-MIT
diff --git a/node_modules/undici/docs/api/Agent.md b/node_modules/undici/docs/api/Agent.md
deleted file mode 100644
index 854dc6a..0000000
--- a/node_modules/undici/docs/api/Agent.md
+++ /dev/null
@@ -1,79 +0,0 @@
-# Agent
-
-Extends: `undici.Dispatcher`
-
-Agent allow dispatching requests against multiple different origins.
-
-Requests are not guaranteed to be dispatched in order of invocation.
-
-## `new undici.Agent([options])`
-
-Arguments:
-
-* **options** `AgentOptions` (optional)
-
-Returns: `Agent`
-
-### Parameter: `AgentOptions`
-
-Extends: [`ClientOptions`](Pool.md#parameter-pooloptions)
-
-* **factory** `(origin: URL, opts: Object) => Dispatcher` - Default: `(origin, opts) => new Pool(origin, opts)`
-* **maxRedirections** `Integer` - Default: `0`. The number of HTTP redirection to follow unless otherwise specified in `DispatchOptions`.
-
-## Instance Properties
-
-### `Agent.closed`
-
-Implements [Client.closed](Client.md#clientclosed)
-
-### `Agent.destroyed`
-
-Implements [Client.destroyed](Client.md#clientdestroyed)
-
-## Instance Methods
-
-### `Agent.close([callback])`
-
-Implements [`Dispatcher.close([callback])`](Dispatcher.md#dispatcherclosecallback-promise).
-
-### `Agent.destroy([error, callback])`
-
-Implements [`Dispatcher.destroy([error, callback])`](Dispatcher.md#dispatcherdestroyerror-callback-promise).
-
-### `Agent.dispatch(options, handler: AgentDispatchOptions)`
-
-Implements [`Dispatcher.dispatch(options, handler)`](Dispatcher.md#dispatcherdispatchoptions-handler).
-
-#### Parameter: `AgentDispatchOptions`
-
-Extends: [`DispatchOptions`](Dispatcher.md#parameter-dispatchoptions)
-
-* **origin** `string | URL`
-* **maxRedirections** `Integer`.
-
-Implements [`Dispatcher.destroy([error, callback])`](Dispatcher.md#dispatcherdestroyerror-callback-promise).
-
-### `Agent.connect(options[, callback])`
-
-See [`Dispatcher.connect(options[, callback])`](Dispatcher.md#dispatcherconnectoptions-callback).
-
-### `Agent.dispatch(options, handler)`
-
-Implements [`Dispatcher.dispatch(options, handler)`](Dispatcher.md#dispatcherdispatchoptions-handler).
-
-### `Agent.pipeline(options, handler)`
-
-See [`Dispatcher.pipeline(options, handler)`](Dispatcher.md#dispatcherpipelineoptions-handler).
-
-### `Agent.request(options[, callback])`
-
-See [`Dispatcher.request(options [, callback])`](Dispatcher.md#dispatcherrequestoptions-callback).
-
-### `Agent.stream(options, factory[, callback])`
-
-See [`Dispatcher.stream(options, factory[, callback])`](Dispatcher.md#dispatcherstreamoptions-factory-callback).
-
-### `Agent.upgrade(options[, callback])`
-
-See [`Dispatcher.upgrade(options[, callback])`](Dispatcher.md#dispatcherupgradeoptions-callback).
diff --git a/node_modules/undici/docs/api/BalancedPool.md b/node_modules/undici/docs/api/BalancedPool.md
deleted file mode 100644
index 290c734..0000000
--- a/node_modules/undici/docs/api/BalancedPool.md
+++ /dev/null
@@ -1,99 +0,0 @@
-# Class: BalancedPool
-
-Extends: `undici.Dispatcher`
-
-A pool of [Pool](Pool.md) instances connected to multiple upstreams.
-
-Requests are not guaranteed to be dispatched in order of invocation.
-
-## `new BalancedPool(upstreams [, options])`
-
-Arguments:
-
-* **upstreams** `URL | string | string[]` - It should only include the **protocol, hostname, and port**.
-* **options** `BalancedPoolOptions` (optional)
-
-### Parameter: `BalancedPoolOptions`
-
-Extends: [`PoolOptions`](Pool.md#parameter-pooloptions)
-
-* **factory** `(origin: URL, opts: Object) => Dispatcher` - Default: `(origin, opts) => new Pool(origin, opts)`
-
-The `PoolOptions` are passed to each of the `Pool` instances being created.
-## Instance Properties
-
-### `BalancedPool.upstreams`
-
-Returns an array of upstreams that were previously added.
-
-### `BalancedPool.closed`
-
-Implements [Client.closed](Client.md#clientclosed)
-
-### `BalancedPool.destroyed`
-
-Implements [Client.destroyed](Client.md#clientdestroyed)
-
-### `Pool.stats`
-
-Returns [`PoolStats`](PoolStats.md) instance for this pool.
-
-## Instance Methods
-
-### `BalancedPool.addUpstream(upstream)`
-
-Add an upstream.
-
-Arguments:
-
-* **upstream** `string` - It should only include the **protocol, hostname, and port**.
-
-### `BalancedPool.removeUpstream(upstream)`
-
-Removes an upstream that was previously addded.
-
-### `BalancedPool.close([callback])`
-
-Implements [`Dispatcher.close([callback])`](Dispatcher.md#dispatcherclosecallback-promise).
-
-### `BalancedPool.destroy([error, callback])`
-
-Implements [`Dispatcher.destroy([error, callback])`](Dispatcher.md#dispatcherdestroyerror-callback-promise).
-
-### `BalancedPool.connect(options[, callback])`
-
-See [`Dispatcher.connect(options[, callback])`](Dispatcher.md#dispatcherconnectoptions-callback).
-
-### `BalancedPool.dispatch(options, handlers)`
-
-Implements [`Dispatcher.dispatch(options, handlers)`](Dispatcher.md#dispatcherdispatchoptions-handler).
-
-### `BalancedPool.pipeline(options, handler)`
-
-See [`Dispatcher.pipeline(options, handler)`](Dispatcher.md#dispatcherpipelineoptions-handler).
-
-### `BalancedPool.request(options[, callback])`
-
-See [`Dispatcher.request(options [, callback])`](Dispatcher.md#dispatcherrequestoptions-callback).
-
-### `BalancedPool.stream(options, factory[, callback])`
-
-See [`Dispatcher.stream(options, factory[, callback])`](Dispatcher.md#dispatcherstreamoptions-factory-callback).
-
-### `BalancedPool.upgrade(options[, callback])`
-
-See [`Dispatcher.upgrade(options[, callback])`](Dispatcher.md#dispatcherupgradeoptions-callback).
-
-## Instance Events
-
-### Event: `'connect'`
-
-See [Dispatcher Event: `'connect'`](Dispatcher.md#event-connect).
-
-### Event: `'disconnect'`
-
-See [Dispatcher Event: `'disconnect'`](Dispatcher.md#event-disconnect).
-
-### Event: `'drain'`
-
-See [Dispatcher Event: `'drain'`](Dispatcher.md#event-drain).
diff --git a/node_modules/undici/docs/api/Client.md b/node_modules/undici/docs/api/Client.md
deleted file mode 100644
index cfc4c39..0000000
--- a/node_modules/undici/docs/api/Client.md
+++ /dev/null
@@ -1,263 +0,0 @@
-# Class: Client
-
-Extends: `undici.Dispatcher`
-
-A basic HTTP/1.1 client, mapped on top a single TCP/TLS connection. Pipelining is disabled by default.
-
-Requests are not guaranteed to be dispatched in order of invocation.
-
-## `new Client(url[, options])`
-
-Arguments:
-
-* **url** `URL | string` - Should only include the **protocol, hostname, and port**.
-* **options** `ClientOptions` (optional)
-
-Returns: `Client`
-
-### Parameter: `ClientOptions`
-
-* **bodyTimeout** `number | null` (optional) - Default: `30e3` - The timeout after which a request will time out, in milliseconds. Monitors time between receiving body data. Use `0` to disable it entirely. Defaults to 30 seconds.
-* **headersTimeout** `number | null` (optional) - Default: `30e3` - The amount of time the parser will wait to receive the complete HTTP headers. Defaults to 30 seconds.
-* **keepAliveMaxTimeout** `number | null` (optional) - Default: `600e3` - The maximum allowed `keepAliveTimeout` when overridden by *keep-alive* hints from the server. Defaults to 10 minutes.
-* **keepAliveTimeout** `number | null` (optional) - Default: `4e3` - The timeout after which a socket without active requests will time out. Monitors time between activity on a connected socket. This value may be overridden by *keep-alive* hints from the server. See [MDN: HTTP - Headers - Keep-Alive directives](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Keep-Alive#directives) for more details. Defaults to 4 seconds.
-* **keepAliveTimeoutThreshold** `number | null` (optional) - Default: `1e3` - A number subtracted from server *keep-alive* hints when overriding `keepAliveTimeout` to account for timing inaccuracies caused by e.g. transport latency. Defaults to 1 second.
-* **maxHeaderSize** `number | null` (optional) - Default: `16384` - The maximum length of request headers in bytes. Defaults to 16KiB.
-* **pipelining** `number | null` (optional) - Default: `1` - The amount of concurrent requests to be sent over the single TCP/TLS connection according to [RFC7230](https://tools.ietf.org/html/rfc7230#section-6.3.2). Carefully consider your workload and environment before enabling concurrent requests as pipelining may reduce performance if used incorrectly. Pipelining is sensitive to network stack settings as well as head of line blocking caused by e.g. long running requests. Set to `0` to disable keep-alive connections.
-* **connect** `ConnectOptions | Function | null` (optional) - Default: `null`.
-* **strictContentLength** `Boolean` (optional) - Default: `true` - Whether to treat request content length mismatches as errors. If true, an error is thrown when the request content-length header doesn't match the length of the request body.
-
-#### Parameter: `ConnectOptions`
-
-Every Tls option, see [here](https://nodejs.org/api/tls.html#tls_tls_connect_options_callback).
-Furthermore, the following options can be passed:
-
-* **socketPath** `string | null` (optional) - Default: `null` - An IPC endpoint, either Unix domain socket or Windows named pipe.
-* **maxCachedSessions** `number | null` (optional) - Default: `100` - Maximum number of TLS cached sessions. Use 0 to disable TLS session caching. Default: 100.
-* **timeout** `number | null` (optional) - Default `10e3`
-* **servername** `string | null` (optional)
-
-### Example - Basic Client instantiation
-
-This will instantiate the undici Client, but it will not connect to the origin until something is queued. Consider using `client.connect` to prematurely connect to the origin, or just call `client.request`.
-
-```js
-'use strict'
-import { Client } from 'undici'
-
-const client = new Client('http://localhost:3000')
-```
-
-### Example - Custom connector
-
-This will allow you to perform some additional check on the socket that will be used for the next request.
-
-```js
-'use strict'
-import { Client, buildConnector } from 'undici'
-
-const connector = buildConnector({ rejectUnauthorized: false })
-const client = new Client('https://localhost:3000', {
- connect (opts, cb) {
- connector(opts, (err, socket) => {
- if (err) {
- cb(err)
- } else if (/* assertion */) {
- socket.destroy()
- cb(new Error('kaboom'))
- } else {
- cb(null, socket)
- }
- })
- }
-})
-```
-
-## Instance Methods
-
-### `Client.close([callback])`
-
-Implements [`Dispatcher.close([callback])`](Dispatcher.md#dispatcherclosecallback-promise).
-
-### `Client.destroy([error, callback])`
-
-Implements [`Dispatcher.destroy([error, callback])`](Dispatcher.md#dispatcherdestroyerror-callback-promise).
-
-Waits until socket is closed before invoking the callback (or returning a promise if no callback is provided).
-
-### `Client.connect(options[, callback])`
-
-See [`Dispatcher.connect(options[, callback])`](Dispatcher.md#dispatcherconnectoptions-callback).
-
-### `Client.dispatch(options, handlers)`
-
-Implements [`Dispatcher.dispatch(options, handlers)`](Dispatcher.md#dispatcherdispatchoptions-handler).
-
-### `Client.pipeline(options, handler)`
-
-See [`Dispatcher.pipeline(options, handler)`](Dispatcher.md#dispatcherpipelineoptions-handler).
-
-### `Client.request(options[, callback])`
-
-See [`Dispatcher.request(options [, callback])`](Dispatcher.md#dispatcherrequestoptions-callback).
-
-### `Client.stream(options, factory[, callback])`
-
-See [`Dispatcher.stream(options, factory[, callback])`](Dispatcher.md#dispatcherstreamoptions-factory-callback).
-
-### `Client.upgrade(options[, callback])`
-
-See [`Dispatcher.upgrade(options[, callback])`](Dispatcher.md#dispatcherupgradeoptions-callback).
-
-## Instance Properties
-
-### `Client.closed`
-
-* `boolean`
-
-`true` after `client.close()` has been called.
-
-### `Client.destroyed`
-
-* `boolean`
-
-`true` after `client.destroyed()` has been called or `client.close()` has been called and the client shutdown has completed.
-
-### `Client.pipelining`
-
-* `number`
-
-Property to get and set the pipelining factor.
-
-## Instance Events
-
-### Event: `'connect'`
-
-See [Dispatcher Event: `'connect'`](Dispatcher.md#event-connect).
-
-Parameters:
-
-* **origin** `URL`
-* **targets** `Array`
-
-Emitted when a socket has been created and connected. The client will connect once `client.size > 0`.
-
-#### Example - Client connect event
-
-```js
-import { createServer } from 'http'
-import { Client } from 'undici'
-import { once } from 'events'
-
-const server = createServer((request, response) => {
- response.end('Hello, World!')
-}).listen()
-
-await once(server, 'listening')
-
-const client = new Client(`http://localhost:${server.address().port}`)
-
-client.on('connect', (origin) => {
- console.log(`Connected to ${origin}`) // should print before the request body statement
-})
-
-try {
- const { body } = await client.request({
- path: '/',
- method: 'GET'
- })
- body.setEncoding('utf-8')
- body.on('data', console.log)
- client.close()
- server.close()
-} catch (error) {
- console.error(error)
- client.close()
- server.close()
-}
-```
-
-### Event: `'disconnect'`
-
-See [Dispatcher Event: `'disconnect'`](Dispatcher.md#event-disconnect).
-
-Parameters:
-
-* **origin** `URL`
-* **targets** `Array`
-* **error** `Error`
-
-Emitted when socket has disconnected. The error argument of the event is the error which caused the socket to disconnect. The client will reconnect if or once `client.size > 0`.
-
-#### Example - Client disconnect event
-
-```js
-import { createServer } from 'http'
-import { Client } from 'undici'
-import { once } from 'events'
-
-const server = createServer((request, response) => {
- response.destroy()
-}).listen()
-
-await once(server, 'listening')
-
-const client = new Client(`http://localhost:${server.address().port}`)
-
-client.on('disconnect', (origin) => {
- console.log(`Disconnected from ${origin}`)
-})
-
-try {
- await client.request({
- path: '/',
- method: 'GET'
- })
-} catch (error) {
- console.error(error.message)
- client.close()
- server.close()
-}
-```
-
-### Event: `'drain'`
-
-Emitted when pipeline is no longer busy.
-
-See [Dispatcher Event: `'drain'`](Dispatcher.md#event-drain).
-
-#### Example - Client drain event
-
-```js
-import { createServer } from 'http'
-import { Client } from 'undici'
-import { once } from 'events'
-
-const server = createServer((request, response) => {
- response.end('Hello, World!')
-}).listen()
-
-await once(server, 'listening')
-
-const client = new Client(`http://localhost:${server.address().port}`)
-
-client.on('drain', () => {
- console.log('drain event')
- client.close()
- server.close()
-})
-
-const requests = [
- client.request({ path: '/', method: 'GET' }),
- client.request({ path: '/', method: 'GET' }),
- client.request({ path: '/', method: 'GET' })
-]
-
-await Promise.all(requests)
-
-console.log('requests completed')
-```
-
-### Event: `'error'`
-
-Invoked for users errors such as throwing in the `onError` handler.
diff --git a/node_modules/undici/docs/api/Connector.md b/node_modules/undici/docs/api/Connector.md
deleted file mode 100644
index fe446b4..0000000
--- a/node_modules/undici/docs/api/Connector.md
+++ /dev/null
@@ -1,113 +0,0 @@
-# Connector
-
-Undici creates the underlying socket via the connector builder.
-Normally, this happens automatically and you don't need to care about this,
-but if you need to perform some additional check over the currently used socket,
-this is the right place.
-
-If you want to create a custom connector, you must import the `buildConnector` utility.
-
-#### Parameter: `buildConnector.BuildOptions`
-
-Every Tls option, see [here](https://nodejs.org/api/tls.html#tls_tls_connect_options_callback).
-Furthermore, the following options can be passed:
-
-* **socketPath** `string | null` (optional) - Default: `null` - An IPC endpoint, either Unix domain socket or Windows named pipe.
-* **maxCachedSessions** `number | null` (optional) - Default: `100` - Maximum number of TLS cached sessions. Use 0 to disable TLS session caching. Default: 100.
-* **timeout** `number | null` (optional) - Default `10e3`
-* **servername** `string | null` (optional)
-
-Once you call `buildConnector`, it will return a connector function, which takes the following parameters.
-
-#### Parameter: `connector.Options`
-
-* **hostname** `string` (required)
-* **host** `string` (optional)
-* **protocol** `string` (required)
-* **port** `number` (required)
-* **servername** `string` (optional)
-
-### Basic example
-
-```js
-'use strict'
-
-import { Client, buildConnector } from 'undici'
-
-const connector = buildConnector({ rejectUnauthorized: false })
-const client = new Client('https://localhost:3000', {
- connect (opts, cb) {
- connector(opts, (err, socket) => {
- if (err) {
- cb(err)
- } else if (/* assertion */) {
- socket.destroy()
- cb(new Error('kaboom'))
- } else {
- cb(null, socket)
- }
- })
- }
-})
-```
-
-### Example: validate the CA fingerprint
-
-```js
-'use strict'
-
-import { Client, buildConnector } from 'undici'
-
-const caFingerprint = 'FO:OB:AR'
-const connector = buildConnector({ rejectUnauthorized: false })
-const client = new Client('https://localhost:3000', {
- connect (opts, cb) {
- connector(opts, (err, socket) => {
- if (err) {
- cb(err)
- } else if (getIssuerCertificate(socket).fingerprint256 !== caFingerprint) {
- socket.destroy()
- cb(new Error('Fingerprint does not match or malformed certificate'))
- } else {
- cb(null, socket)
- }
- })
- }
-})
-
-client.request({
- path: '/',
- method: 'GET'
-}, (err, data) => {
- if (err) throw err
-
- const bufs = []
- data.body.on('data', (buf) => {
- bufs.push(buf)
- })
- data.body.on('end', () => {
- console.log(Buffer.concat(bufs).toString('utf8'))
- client.close()
- })
-})
-
-function getIssuerCertificate (socket) {
- let certificate = socket.getPeerCertificate(true)
- while (certificate && Object.keys(certificate).length > 0) {
- // invalid certificate
- if (certificate.issuerCertificate == null) {
- return null
- }
-
- // We have reached the root certificate.
- // In case of self-signed certificates, `issuerCertificate` may be a circular reference.
- if (certificate.fingerprint256 === certificate.issuerCertificate.fingerprint256) {
- break
- }
-
- // continue the loop
- certificate = certificate.issuerCertificate
- }
- return certificate
-}
-```
diff --git a/node_modules/undici/docs/api/DiagnosticsChannel.md b/node_modules/undici/docs/api/DiagnosticsChannel.md
deleted file mode 100644
index 09a7f9a..0000000
--- a/node_modules/undici/docs/api/DiagnosticsChannel.md
+++ /dev/null
@@ -1,137 +0,0 @@
-# Diagnostics Channel Support
-
-Stability: Experimental.
-
-Undici supports the [`diagnostics_channel`](https://nodejs.org/api/diagnostics_channel.html) (currently available only on Node.js v16+).
-It is the preferred way to instrument Undici and retrieve internal information.
-
-The channels available are the following.
-
-## `undici:request:create`
-
-This message is published when a new outgoing request is created.
-
-```js
-import diagnosticsChannel from 'diagnostics_channel'
-
-diagnosticsChannel.channel('undici:request:create').subscribe(({ request }) => {
- console.log('origin', request.origin)
- console.log('completed', request.completed)
- console.log('method', request.method)
- console.log('path', request.path)
- console.log('headers') // raw text, e.g: 'bar: bar\r\n'
- request.addHeader('hello', 'world')
- console.log('headers', request.headers) // e.g. 'bar: bar\r\nhello: world\r\n'
-})
-```
-
-Note: a request is only loosely completed to a given socket.
-
-
-## `undici:request:bodySent`
-
-```js
-import diagnosticsChannel from 'diagnostics_channel'
-
-diagnosticsChannel.channel('undici:request:bodySent').subscribe(({ request }) => {
- // request is the same object undici:request:create
-})
-```
-
-## `undici:request:headers`
-
-This message is published after the response headers have been received, i.e. the response has been completed.
-
-```js
-import diagnosticsChannel from 'diagnostics_channel'
-
-diagnosticsChannel.channel('undici:request:headers').subscribe(({ request, response }) => {
- // request is the same object undici:request:create
- console.log('statusCode', response.statusCode)
- console.log(response.statusText)
- // response.headers are buffers.
- console.log(response.headers.map((x) => x.toString()))
-})
-```
-
-## `undici:request:trailers`
-
-This message is published after the response body and trailers have been received, i.e. the response has been completed.
-
-```js
-import diagnosticsChannel from 'diagnostics_channel'
-
-diagnosticsChannel.channel('undici:request:trailers').subscribe(({ request, trailers }) => {
- // request is the same object undici:request:create
- console.log('completed', request.completed)
- // trailers are buffers.
- console.log(trailers.map((x) => x.toString()))
-})
-```
-
-## `undici:request:error`
-
-This message is published if the request is going to error, but it has not errored yet.
-
-```js
-import diagnosticsChannel from 'diagnostics_channel'
-
-diagnosticsChannel.channel('undici:request:error').subscribe(({ request, error }) => {
- // request is the same object undici:request:create
-})
-```
-
-## `undici:client:sendHeaders`
-
-This message is published right before the first byte of the request is written to the socket.
-
-*Note*: It will publish the exact headers that will be sent to the server in raw format.
-
-```js
-import diagnosticsChannel from 'diagnostics_channel'
-
-diagnosticsChannel.channel('undici:client:sendHeaders').subscribe(({ request, headers, socket }) => {
- // request is the same object undici:request:create
- console.log(`Full headers list ${headers.split('\r\n')}`);
-})
-```
-
-## `undici:client:beforeConnect`
-
-This message is published before creating a new connection for **any** request.
-You can not assume that this event is related to any specific request.
-
-```js
-import diagnosticsChannel from 'diagnostics_channel'
-
-diagnosticsChannel.channel('undici:client:beforeConnect').subscribe(({ connectParams, connector }) => {
- // const { host, hostname, protocol, port, servername } = connectParams
- // connector is a function that creates the socket
-})
-```
-
-## `undici:client:connected`
-
-This message is published after a connection is established.
-
-```js
-import diagnosticsChannel from 'diagnostics_channel'
-
-diagnosticsChannel.channel('undici:client:connected').subscribe(({ socket, connectParams, connector }) => {
- // const { host, hostname, protocol, port, servername } = connectParams
- // connector is a function that creates the socket
-})
-```
-
-## `undici:client:connectError`
-
-This message is published if it did not succeed to create new connection
-
-```js
-import diagnosticsChannel from 'diagnostics_channel'
-
-diagnosticsChannel.channel('undici:client:connectError').subscribe(({ error, socket, connectParams, connector }) => {
- // const { host, hostname, protocol, port, servername } = connectParams
- // connector is a function that creates the socket
- console.log(`Connect failed with ${error.message}`)
-})
diff --git a/node_modules/undici/docs/api/Dispatcher.md b/node_modules/undici/docs/api/Dispatcher.md
deleted file mode 100644
index 32ccb57..0000000
--- a/node_modules/undici/docs/api/Dispatcher.md
+++ /dev/null
@@ -1,885 +0,0 @@
-# Dispatcher
-
-Extends: `events.EventEmitter`
-
-Dispatcher is the core API used to dispatch requests.
-
-Requests are not guaranteed to be dispatched in order of invocation.
-
-## Instance Methods
-
-### `Dispatcher.close([callback]): Promise`
-
-Closes the dispatcher and gracefully waits for enqueued requests to complete before resolving.
-
-Arguments:
-
-* **callback** `(error: Error | null, data: null) => void` (optional)
-
-Returns: `void | Promise` - Only returns a `Promise` if no `callback` argument was passed
-
-```js
-dispatcher.close() // -> Promise
-dispatcher.close(() => {}) // -> void
-```
-
-#### Example - Request resolves before Client closes
-
-```js
-import { createServer } from 'http'
-import { Client } from 'undici'
-import { once } from 'events'
-
-const server = createServer((request, response) => {
- response.end('undici')
-}).listen()
-
-await once(server, 'listening')
-
-const client = new Client(`http://localhost:${server.address().port}`)
-
-try {
- const { body } = await client.request({
- path: '/',
- method: 'GET'
- })
- body.setEncoding('utf8')
- body.on('data', console.log)
-} catch (error) {}
-
-await client.close()
-
-console.log('Client closed')
-server.close()
-```
-
-### `Dispatcher.connect(options[, callback])`
-
-Starts two-way communications with the requested resource using [HTTP CONNECT](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/CONNECT).
-
-Arguments:
-
-* **options** `ConnectOptions`
-* **callback** `(err: Error | null, data: ConnectData | null) => void` (optional)
-
-Returns: `void | Promise` - Only returns a `Promise` if no `callback` argument was passed
-
-#### Parameter: `ConnectOptions`
-
-* **path** `string`
-* **headers** `UndiciHeaders` (optional) - Default: `null`
-* **signal** `AbortSignal | events.EventEmitter | null` (optional) - Default: `null`
-* **opaque** `unknown` (optional) - This argument parameter is passed through to `ConnectData`
-
-#### Parameter: `ConnectData`
-
-* **statusCode** `number`
-* **headers** `http.IncomingHttpHeaders`
-* **socket** `stream.Duplex`
-* **opaque** `unknown`
-
-#### Example - Connect request with echo
-
-```js
-import { createServer } from 'http'
-import { Client } from 'undici'
-import { once } from 'events'
-
-const server = createServer((request, response) => {
- throw Error('should never get here')
-}).listen()
-
-server.on('connect', (req, socket, head) => {
- socket.write('HTTP/1.1 200 Connection established\r\n\r\n')
-
- let data = head.toString()
- socket.on('data', (buf) => {
- data += buf.toString()
- })
-
- socket.on('end', () => {
- socket.end(data)
- })
-})
-
-await once(server, 'listening')
-
-const client = new Client(`http://localhost:${server.address().port}`)
-
-try {
- const { socket } = await client.connect({
- path: '/'
- })
- const wanted = 'Body'
- let data = ''
- socket.on('data', d => { data += d })
- socket.on('end', () => {
- console.log(`Data received: ${data.toString()} | Data wanted: ${wanted}`)
- client.close()
- server.close()
- })
- socket.write(wanted)
- socket.end()
-} catch (error) { }
-```
-
-### `Dispatcher.destroy([error, callback]): Promise`
-
-Destroy the dispatcher abruptly with the given error. All the pending and running requests will be asynchronously aborted and error. Since this operation is asynchronously dispatched there might still be some progress on dispatched requests.
-
-Both arguments are optional; the method can be called in four different ways:
-
-Arguments:
-
-* **error** `Error | null` (optional)
-* **callback** `(error: Error | null, data: null) => void` (optional)
-
-Returns: `void | Promise` - Only returns a `Promise` if no `callback` argument was passed
-
-```js
-dispatcher.destroy() // -> Promise
-dispatcher.destroy(new Error()) // -> Promise
-dispatcher.destroy(() => {}) // -> void
-dispatcher.destroy(new Error(), () => {}) // -> void
-```
-
-#### Example - Request is aborted when Client is destroyed
-
-```js
-import { createServer } from 'http'
-import { Client } from 'undici'
-import { once } from 'events'
-
-const server = createServer((request, response) => {
- response.end()
-}).listen()
-
-await once(server, 'listening')
-
-const client = new Client(`http://localhost:${server.address().port}`)
-
-try {
- const request = client.request({
- path: '/',
- method: 'GET'
- })
- client.destroy()
- .then(() => {
- console.log('Client destroyed')
- server.close()
- })
- await request
-} catch (error) {
- console.error(error)
-}
-```
-
-### `Dispatcher.dispatch(options, handler)`
-
-This is the low level API which all the preceding APIs are implemented on top of.
-This API is expected to evolve through semver-major versions and is less stable than the preceding higher level APIs.
-It is primarily intended for library developers who implement higher level APIs on top of this.
-
-Arguments:
-
-* **options** `DispatchOptions`
-* **handler** `DispatchHandler`
-
-Returns: `Boolean` - `false` if dispatcher is busy and further dispatch calls won't make any progress until the `'drain'` event has been emitted.
-
-#### Parameter: `DispatchOptions`
-
-* **origin** `string | URL`
-* **path** `string`
-* **method** `string`
-* **body** `string | Buffer | Uint8Array | stream.Readable | Iterable | AsyncIterable | null` (optional) - Default: `null`
-* **headers** `UndiciHeaders | string[]` (optional) - Default: `null`.
-* **query** `Record | null` (optional) - Default: `null` - Query string params to be embedded in the request URL. Note that both keys and values of query are encoded using `encodeURIComponent`. If for some reason you need to send them unencoded, embed query params into path directly instead.
-* **idempotent** `boolean` (optional) - Default: `true` if `method` is `'HEAD'` or `'GET'` - Whether the requests can be safely retried or not. If `false` the request won't be sent until all preceding requests in the pipeline has completed.
-* **blocking** `boolean` (optional) - Default: `false` - Whether the response is expected to take a long time and would end up blocking the pipeline. When this is set to `true` further pipelining will be avoided on the same connection until headers have been received.
-* **upgrade** `string | null` (optional) - Default: `null` - Upgrade the request. Should be used to specify the kind of upgrade i.e. `'Websocket'`.
-* **bodyTimeout** `number | null` (optional) - The timeout after which a request will time out, in milliseconds. Monitors time between receiving body data. Use `0` to disable it entirely. Defaults to 30 seconds.
-* **headersTimeout** `number | null` (optional) - The amount of time the parser will wait to receive the complete HTTP headers. Defaults to 30 seconds.
-* **throwOnError** `boolean` (optional) - Default: `false` - Whether Undici should throw an error upon receiving a 4xx or 5xx response from the server.
-
-#### Parameter: `DispatchHandler`
-
-* **onConnect** `(abort: () => void, context: object) => void` - Invoked before request is dispatched on socket. May be invoked multiple times when a request is retried when the request at the head of the pipeline fails.
-* **onError** `(error: Error) => void` - Invoked when an error has occurred. May not throw.
-* **onUpgrade** `(statusCode: number, headers: Buffer[], socket: Duplex) => void` (optional) - Invoked when request is upgraded. Required if `DispatchOptions.upgrade` is defined or `DispatchOptions.method === 'CONNECT'`.
-* **onHeaders** `(statusCode: number, headers: Buffer[], resume: () => void, statusText: string) => boolean` - Invoked when statusCode and headers have been received. May be invoked multiple times due to 1xx informational headers. Not required for `upgrade` requests.
-* **onData** `(chunk: Buffer) => boolean` - Invoked when response payload data is received. Not required for `upgrade` requests.
-* **onComplete** `(trailers: Buffer[]) => void` - Invoked when response payload and trailers have been received and the request has completed. Not required for `upgrade` requests.
-* **onBodySent** `(chunk: string | Buffer | Uint8Array) => void` - Invoked when a body chunk is sent to the server. Not required. For a stream or iterable body this will be invoked for every chunk. For other body types, it will be invoked once after the body is sent.
-
-#### Example 1 - Dispatch GET request
-
-```js
-import { createServer } from 'http'
-import { Client } from 'undici'
-import { once } from 'events'
-
-const server = createServer((request, response) => {
- response.end('Hello, World!')
-}).listen()
-
-await once(server, 'listening')
-
-const client = new Client(`http://localhost:${server.address().port}`)
-
-const data = []
-
-client.dispatch({
- path: '/',
- method: 'GET',
- headers: {
- 'x-foo': 'bar'
- }
-}, {
- onConnect: () => {
- console.log('Connected!')
- },
- onError: (error) => {
- console.error(error)
- },
- onHeaders: (statusCode, headers) => {
- console.log(`onHeaders | statusCode: ${statusCode} | headers: ${headers}`)
- },
- onData: (chunk) => {
- console.log('onData: chunk received')
- data.push(chunk)
- },
- onComplete: (trailers) => {
- console.log(`onComplete | trailers: ${trailers}`)
- const res = Buffer.concat(data).toString('utf8')
- console.log(`Data: ${res}`)
- client.close()
- server.close()
- }
-})
-```
-
-#### Example 2 - Dispatch Upgrade Request
-
-```js
-import { createServer } from 'http'
-import { Client } from 'undici'
-import { once } from 'events'
-
-const server = createServer((request, response) => {
- response.end()
-}).listen()
-
-await once(server, 'listening')
-
-server.on('upgrade', (request, socket, head) => {
- console.log('Node.js Server - upgrade event')
- socket.write('HTTP/1.1 101 Web Socket Protocol Handshake\r\n')
- socket.write('Upgrade: WebSocket\r\n')
- socket.write('Connection: Upgrade\r\n')
- socket.write('\r\n')
- socket.end()
-})
-
-const client = new Client(`http://localhost:${server.address().port}`)
-
-client.dispatch({
- path: '/',
- method: 'GET',
- upgrade: 'websocket'
-}, {
- onConnect: () => {
- console.log('Undici Client - onConnect')
- },
- onError: (error) => {
- console.log('onError') // shouldn't print
- },
- onUpgrade: (statusCode, headers, socket) => {
- console.log('Undici Client - onUpgrade')
- console.log(`onUpgrade Headers: ${headers}`)
- socket.on('data', buffer => {
- console.log(buffer.toString('utf8'))
- })
- socket.on('end', () => {
- client.close()
- server.close()
- })
- socket.end()
- }
-})
-```
-
-#### Example 3 - Dispatch POST request
-
-```js
-import { createServer } from 'http'
-import { Client } from 'undici'
-import { once } from 'events'
-
-const server = createServer((request, response) => {
- request.on('data', (data) => {
- console.log(`Request Data: ${data.toString('utf8')}`)
- const body = JSON.parse(data)
- body.message = 'World'
- response.end(JSON.stringify(body))
- })
-}).listen()
-
-await once(server, 'listening')
-
-const client = new Client(`http://localhost:${server.address().port}`)
-
-const data = []
-
-client.dispatch({
- path: '/',
- method: 'POST',
- headers: {
- 'content-type': 'application/json'
- },
- body: JSON.stringify({ message: 'Hello' })
-}, {
- onConnect: () => {
- console.log('Connected!')
- },
- onError: (error) => {
- console.error(error)
- },
- onHeaders: (statusCode, headers) => {
- console.log(`onHeaders | statusCode: ${statusCode} | headers: ${headers}`)
- },
- onData: (chunk) => {
- console.log('onData: chunk received')
- data.push(chunk)
- },
- onComplete: (trailers) => {
- console.log(`onComplete | trailers: ${trailers}`)
- const res = Buffer.concat(data).toString('utf8')
- console.log(`Response Data: ${res}`)
- client.close()
- server.close()
- }
-})
-```
-
-### `Dispatcher.pipeline(options, handler)`
-
-For easy use with [stream.pipeline](https://nodejs.org/api/stream.html#stream_stream_pipeline_source_transforms_destination_callback). The `handler` argument should return a `Readable` from which the result will be read. Usually it should just return the `body` argument unless some kind of transformation needs to be performed based on e.g. `headers` or `statusCode`. The `handler` should validate the response and save any required state. If there is an error, it should be thrown. The function returns a `Duplex` which writes to the request and reads from the response.
-
-Arguments:
-
-* **options** `PipelineOptions`
-* **handler** `(data: PipelineHandlerData) => stream.Readable`
-
-Returns: `stream.Duplex`
-
-#### Parameter: PipelineOptions
-
-Extends: [`RequestOptions`](#parameter-requestoptions)
-
-* **objectMode** `boolean` (optional) - Default: `false` - Set to `true` if the `handler` will return an object stream.
-
-#### Parameter: PipelineHandlerData
-
-* **statusCode** `number`
-* **headers** `IncomingHttpHeaders`
-* **opaque** `unknown`
-* **body** `stream.Readable`
-* **context** `object`
-* **onInfo** `({statusCode: number, headers: Record}) => void | null` (optional) - Default: `null` - Callback collecting all the info headers (HTTP 100-199) received.
-
-#### Example 1 - Pipeline Echo
-
-```js
-import { Readable, Writable, PassThrough, pipeline } from 'stream'
-import { createServer } from 'http'
-import { Client } from 'undici'
-import { once } from 'events'
-
-const server = createServer((request, response) => {
- request.pipe(response)
-}).listen()
-
-await once(server, 'listening')
-
-const client = new Client(`http://localhost:${server.address().port}`)
-
-let res = ''
-
-pipeline(
- new Readable({
- read () {
- this.push(Buffer.from('undici'))
- this.push(null)
- }
- }),
- client.pipeline({
- path: '/',
- method: 'GET'
- }, ({ statusCode, headers, body }) => {
- console.log(`response received ${statusCode}`)
- console.log('headers', headers)
- return pipeline(body, new PassThrough(), () => {})
- }),
- new Writable({
- write (chunk, _, callback) {
- res += chunk.toString()
- callback()
- },
- final (callback) {
- console.log(`Response pipelined to writable: ${res}`)
- callback()
- }
- }),
- error => {
- if (error) {
- console.error(error)
- }
-
- client.close()
- server.close()
- }
-)
-```
-
-### `Dispatcher.request(options[, callback])`
-
-Performs a HTTP request.
-
-Non-idempotent requests will not be pipelined in order
-to avoid indirect failures.
-
-Idempotent requests will be automatically retried if
-they fail due to indirect failure from the request
-at the head of the pipeline. This does not apply to
-idempotent requests with a stream request body.
-
-All response bodies must always be fully consumed or destroyed.
-
-Arguments:
-
-* **options** `RequestOptions`
-* **callback** `(error: Error | null, data: ResponseData) => void` (optional)
-
-Returns: `void | Promise` - Only returns a `Promise` if no `callback` argument was passed.
-
-#### Parameter: `RequestOptions`
-
-Extends: [`DispatchOptions`](#parameter-dispatchoptions)
-
-* **opaque** `unknown` (optional) - Default: `null` - Used for passing through context to `ResponseData`.
-* **signal** `AbortSignal | events.EventEmitter | null` (optional) - Default: `null`.
-* **onInfo** `({statusCode: number, headers: Record}) => void | null` (optional) - Default: `null` - Callback collecting all the info headers (HTTP 100-199) received.
-
-The `RequestOptions.method` property should not be value `'CONNECT'`.
-
-#### Parameter: `ResponseData`
-
-* **statusCode** `number`
-* **headers** `http.IncomingHttpHeaders` - Note that all header keys are lower-cased, e. g. `content-type`.
-* **body** `stream.Readable` which also implements [the body mixin from the Fetch Standard](https://fetch.spec.whatwg.org/#body-mixin).
-* **trailers** `Record` - This object starts out
- as empty and will be mutated to contain trailers after `body` has emitted `'end'`.
-* **opaque** `unknown`
-* **context** `object`
-
-`body` contains the following additional [body mixin](https://fetch.spec.whatwg.org/#body-mixin) methods and properties:
-
-- `text()`
-- `json()`
-- `arrayBuffer()`
-- `body`
-- `bodyUsed`
-
-`body` can not be consumed twice. For example, calling `text()` after `json()` throws `TypeError`.
-
-`body` contains the following additional extensions:
-
-- `dump({ limit: Integer })`, dump the response by reading up to `limit` bytes without killing the socket (optional) - Default: 262144.
-
-Note that body will still be a `Readable` even if it is empty, but attempting to deserialize it with `json()` will result in an exception. Recommended way to ensure there is a body to deserialize is to check if status code is not 204, and `content-type` header starts with `application/json`.
-
-#### Example 1 - Basic GET Request
-
-```js
-import { createServer } from 'http'
-import { Client } from 'undici'
-import { once } from 'events'
-
-const server = createServer((request, response) => {
- response.end('Hello, World!')
-}).listen()
-
-await once(server, 'listening')
-
-const client = new Client(`http://localhost:${server.address().port}`)
-
-try {
- const { body, headers, statusCode, trailers } = await client.request({
- path: '/',
- method: 'GET'
- })
- console.log(`response received ${statusCode}`)
- console.log('headers', headers)
- body.setEncoding('utf8')
- body.on('data', console.log)
- body.on('end', () => {
- console.log('trailers', trailers)
- })
-
- client.close()
- server.close()
-} catch (error) {
- console.error(error)
-}
-```
-
-#### Example 2 - Aborting a request
-
-> Node.js v15+ is required to run this example
-
-```js
-import { createServer } from 'http'
-import { Client } from 'undici'
-import { once } from 'events'
-
-const server = createServer((request, response) => {
- response.end('Hello, World!')
-}).listen()
-
-await once(server, 'listening')
-
-const client = new Client(`http://localhost:${server.address().port}`)
-const abortController = new AbortController()
-
-try {
- client.request({
- path: '/',
- method: 'GET',
- signal: abortController.signal
- })
-} catch (error) {
- console.error(error) // should print an RequestAbortedError
- client.close()
- server.close()
-}
-
-abortController.abort()
-```
-
-Alternatively, any `EventEmitter` that emits an `'abort'` event may be used as an abort controller:
-
-```js
-import { createServer } from 'http'
-import { Client } from 'undici'
-import EventEmitter, { once } from 'events'
-
-const server = createServer((request, response) => {
- response.end('Hello, World!')
-}).listen()
-
-await once(server, 'listening')
-
-const client = new Client(`http://localhost:${server.address().port}`)
-const ee = new EventEmitter()
-
-try {
- client.request({
- path: '/',
- method: 'GET',
- signal: ee
- })
-} catch (error) {
- console.error(error) // should print an RequestAbortedError
- client.close()
- server.close()
-}
-
-ee.emit('abort')
-```
-
-Destroying the request or response body will have the same effect.
-
-```js
-import { createServer } from 'http'
-import { Client } from 'undici'
-import { once } from 'events'
-
-const server = createServer((request, response) => {
- response.end('Hello, World!')
-}).listen()
-
-await once(server, 'listening')
-
-const client = new Client(`http://localhost:${server.address().port}`)
-
-try {
- const { body } = await client.request({
- path: '/',
- method: 'GET'
- })
- body.destroy()
-} catch (error) {
- console.error(error) // should print an RequestAbortedError
- client.close()
- server.close()
-}
-```
-
-### `Dispatcher.stream(options, factory[, callback])`
-
-A faster version of `Dispatcher.request`. This method expects the second argument `factory` to return a [`stream.Writable`](https://nodejs.org/api/stream.html#stream_class_stream_writable) stream which the response will be written to. This improves performance by avoiding creating an intermediate [`stream.Readable`](https://nodejs.org/api/stream.html#stream_readable_streams) stream when the user expects to directly pipe the response body to a [`stream.Writable`](https://nodejs.org/api/stream.html#stream_class_stream_writable) stream.
-
-As demonstrated in [Example 1 - Basic GET stream request](#example-1-basic-get-stream-request), it is recommended to use the `option.opaque` property to avoid creating a closure for the `factory` method. This pattern works well with Node.js Web Frameworks such as [Fastify](https://fastify.io). See [Example 2 - Stream to Fastify Response](#example-2-stream-to-fastify-response) for more details.
-
-Arguments:
-
-* **options** `RequestOptions`
-* **factory** `(data: StreamFactoryData) => stream.Writable`
-* **callback** `(error: Error | null, data: StreamData) => void` (optional)
-
-Returns: `void | Promise` - Only returns a `Promise` if no `callback` argument was passed
-
-#### Parameter: `StreamFactoryData`
-
-* **statusCode** `number`
-* **headers** `http.IncomingHttpHeaders`
-* **opaque** `unknown`
-* **onInfo** `({statusCode: number, headers: Record}) => void | null` (optional) - Default: `null` - Callback collecting all the info headers (HTTP 100-199) received.
-
-#### Parameter: `StreamData`
-
-* **opaque** `unknown`
-* **trailers** `Record`
-* **context** `object`
-
-#### Example 1 - Basic GET stream request
-
-```js
-import { createServer } from 'http'
-import { Client } from 'undici'
-import { once } from 'events'
-import { Writable } from 'stream'
-
-const server = createServer((request, response) => {
- response.end('Hello, World!')
-}).listen()
-
-await once(server, 'listening')
-
-const client = new Client(`http://localhost:${server.address().port}`)
-
-const bufs = []
-
-try {
- await client.stream({
- path: '/',
- method: 'GET',
- opaque: { bufs }
- }, ({ statusCode, headers, opaque: { bufs } }) => {
- console.log(`response received ${statusCode}`)
- console.log('headers', headers)
- return new Writable({
- write (chunk, encoding, callback) {
- bufs.push(chunk)
- callback()
- }
- })
- })
-
- console.log(Buffer.concat(bufs).toString('utf-8'))
-
- client.close()
- server.close()
-} catch (error) {
- console.error(error)
-}
-```
-
-#### Example 2 - Stream to Fastify Response
-
-In this example, a (fake) request is made to the fastify server using `fastify.inject()`. This request then executes the fastify route handler which makes a subsequent request to the raw Node.js http server using `undici.dispatcher.stream()`. The fastify response is passed to the `opaque` option so that undici can tap into the underlying writable stream using `response.raw`. This methodology demonstrates how one could use undici and fastify together to create fast-as-possible requests from one backend server to another.
-
-```js
-import { createServer } from 'http'
-import { Client } from 'undici'
-import { once } from 'events'
-import fastify from 'fastify'
-
-const nodeServer = createServer((request, response) => {
- response.end('Hello, World! From Node.js HTTP Server')
-}).listen()
-
-await once(nodeServer, 'listening')
-
-console.log('Node Server listening')
-
-const nodeServerUndiciClient = new Client(`http://localhost:${nodeServer.address().port}`)
-
-const fastifyServer = fastify()
-
-fastifyServer.route({
- url: '/',
- method: 'GET',
- handler: (request, response) => {
- nodeServerUndiciClient.stream({
- path: '/',
- method: 'GET',
- opaque: response
- }, ({ opaque }) => opaque.raw)
- }
-})
-
-await fastifyServer.listen()
-
-console.log('Fastify Server listening')
-
-const fastifyServerUndiciClient = new Client(`http://localhost:${fastifyServer.server.address().port}`)
-
-try {
- const { statusCode, body } = await fastifyServerUndiciClient.request({
- path: '/',
- method: 'GET'
- })
-
- console.log(`response received ${statusCode}`)
- body.setEncoding('utf8')
- body.on('data', console.log)
-
- nodeServerUndiciClient.close()
- fastifyServerUndiciClient.close()
- fastifyServer.close()
- nodeServer.close()
-} catch (error) { }
-```
-
-### `Dispatcher.upgrade(options[, callback])`
-
-Upgrade to a different protocol. Visit [MDN - HTTP - Protocol upgrade mechanism](https://developer.mozilla.org/en-US/docs/Web/HTTP/Protocol_upgrade_mechanism) for more details.
-
-Arguments:
-
-* **options** `UpgradeOptions`
-
-* **callback** `(error: Error | null, data: UpgradeData) => void` (optional)
-
-Returns: `void | Promise` - Only returns a `Promise` if no `callback` argument was passed
-
-#### Parameter: `UpgradeOptions`
-
-* **path** `string`
-* **method** `string` (optional) - Default: `'GET'`
-* **headers** `UndiciHeaders` (optional) - Default: `null`
-* **protocol** `string` (optional) - Default: `'Websocket'` - A string of comma separated protocols, in descending preference order.
-* **signal** `AbortSignal | EventEmitter | null` (optional) - Default: `null`
-
-#### Parameter: `UpgradeData`
-
-* **headers** `http.IncomingHeaders`
-* **socket** `stream.Duplex`
-* **opaque** `unknown`
-
-#### Example 1 - Basic Upgrade Request
-
-```js
-import { createServer } from 'http'
-import { Client } from 'undici'
-import { once } from 'events'
-
-const server = createServer((request, response) => {
- response.statusCode = 101
- response.setHeader('connection', 'upgrade')
- response.setHeader('upgrade', request.headers.upgrade)
- response.end()
-}).listen()
-
-await once(server, 'listening')
-
-const client = new Client(`http://localhost:${server.address().port}`)
-
-try {
- const { headers, socket } = await client.upgrade({
- path: '/',
- })
- socket.on('end', () => {
- console.log(`upgrade: ${headers.upgrade}`) // upgrade: Websocket
- client.close()
- server.close()
- })
- socket.end()
-} catch (error) {
- console.error(error)
- client.close()
- server.close()
-}
-```
-
-## Instance Events
-
-### Event: `'connect'`
-
-Parameters:
-
-* **origin** `URL`
-* **targets** `Array`
-
-### Event: `'disconnect'`
-
-Parameters:
-
-* **origin** `URL`
-* **targets** `Array`
-* **error** `Error`
-
-### Event: `'connectionError'`
-
-Parameters:
-
-* **origin** `URL`
-* **targets** `Array`
-* **error** `Error`
-
-Emitted when dispatcher fails to connect to
-origin.
-
-### Event: `'drain'`
-
-Parameters:
-
-* **origin** `URL`
-
-Emitted when dispatcher is no longer busy.
-
-## Parameter: `UndiciHeaders`
-
-* `http.IncomingHttpHeaders | string[] | null`
-
-Header arguments such as `options.headers` in [`Client.dispatch`](Client.md#clientdispatchoptions-handlers) can be specified in two forms; either as an object specified by the `http.IncomingHttpHeaders` type, or an array of strings. An array representation of a header list must have an even length or an `InvalidArgumentError` will be thrown.
-
-Keys are lowercase and values are not modified.
-
-Response headers will derive a `host` from the `url` of the [Client](Client.md#class-client) instance if no `host` header was previously specified.
-
-### Example 1 - Object
-
-```js
-{
- 'content-length': '123',
- 'content-type': 'text/plain',
- connection: 'keep-alive',
- host: 'mysite.com',
- accept: '*/*'
-}
-```
-
-### Example 2 - Array
-
-```js
-[
- 'content-length', '123',
- 'content-type', 'text/plain',
- 'connection', 'keep-alive',
- 'host', 'mysite.com',
- 'accept', '*/*'
-]
-```
diff --git a/node_modules/undici/docs/api/Errors.md b/node_modules/undici/docs/api/Errors.md
deleted file mode 100644
index 6287ddc..0000000
--- a/node_modules/undici/docs/api/Errors.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# Errors
-
-Undici exposes a variety of error objects that you can use to enhance your error handling.
-You can find all the error objects inside the `errors` key.
-
-```js
-import { errors } from 'undici'
-```
-
-| Error | Error Codes | Description |
-| ------------------------------------ | ------------------------------------- | -------------------------------------------------- |
-| `InvalidArgumentError` | `UND_ERR_INVALID_ARG` | passed an invalid argument. |
-| `InvalidReturnValueError` | `UND_ERR_INVALID_RETURN_VALUE` | returned an invalid value. |
-| `RequestAbortedError` | `UND_ERR_ABORTED` | the request has been aborted by the user |
-| `ClientDestroyedError` | `UND_ERR_DESTROYED` | trying to use a destroyed client. |
-| `ClientClosedError` | `UND_ERR_CLOSED` | trying to use a closed client. |
-| `SocketError` | `UND_ERR_SOCKET` | there is an error with the socket. |
-| `NotSupportedError` | `UND_ERR_NOT_SUPPORTED` | encountered unsupported functionality. |
-| `RequestContentLengthMismatchError` | `UND_ERR_REQ_CONTENT_LENGTH_MISMATCH` | request body does not match content-length header |
-| `ResponseContentLengthMismatchError` | `UND_ERR_RES_CONTENT_LENGTH_MISMATCH` | response body does not match content-length header |
-| `InformationalError` | `UND_ERR_INFO` | expected error with reason |
-
-### `SocketError`
-
-The `SocketError` has a `.socket` property which holds socket metadata:
-
-```ts
-interface SocketInfo {
- localAddress?: string
- localPort?: number
- remoteAddress?: string
- remotePort?: number
- remoteFamily?: string
- timeout?: number
- bytesWritten?: number
- bytesRead?: number
-}
-```
-
-Be aware that in some cases the `.socket` property can be `null`.
diff --git a/node_modules/undici/docs/api/MockAgent.md b/node_modules/undici/docs/api/MockAgent.md
deleted file mode 100644
index 04cfcb0..0000000
--- a/node_modules/undici/docs/api/MockAgent.md
+++ /dev/null
@@ -1,523 +0,0 @@
-# Class: MockAgent
-
-Extends: `undici.Dispatcher`
-
-A mocked Agent class that implements the Agent API. It allows one to intercept HTTP requests made through undici and return mocked responses instead.
-
-## `new MockAgent([options])`
-
-Arguments:
-
-* **options** `MockAgentOptions` (optional) - It extends the `Agent` options.
-
-Returns: `MockAgent`
-
-### Parameter: `MockAgentOptions`
-
-Extends: [`AgentOptions`](Agent.md#parameter-agentoptions)
-
-* **agent** `Agent` (optional) - Default: `new Agent([options])` - a custom agent encapsulated by the MockAgent.
-
-### Example - Basic MockAgent instantiation
-
-This will instantiate the MockAgent. It will not do anything until registered as the agent to use with requests and mock interceptions are added.
-
-```js
-import { MockAgent } from 'undici'
-
-const mockAgent = new MockAgent()
-```
-
-### Example - Basic MockAgent instantiation with custom agent
-
-```js
-import { Agent, MockAgent } from 'undici'
-
-const agent = new Agent()
-
-const mockAgent = new MockAgent({ agent })
-```
-
-## Instance Methods
-
-### `MockAgent.get(origin)`
-
-This method creates and retrieves MockPool or MockClient instances which can then be used to intercept HTTP requests. If the number of connections on the mock agent is set to 1, a MockClient instance is returned. Otherwise a MockPool instance is returned.
-
-For subsequent `MockAgent.get` calls on the same origin, the same mock instance will be returned.
-
-Arguments:
-
-* **origin** `string | RegExp | (value) => boolean` - a matcher for the pool origin to be retrieved from the MockAgent.
-
-| Matcher type | Condition to pass |
-|:------------:| -------------------------- |
-| `string` | Exact match against string |
-| `RegExp` | Regex must pass |
-| `Function` | Function must return true |
-
-Returns: `MockClient | MockPool`.
-
-| `MockAgentOptions` | Mock instance returned |
-| -------------------- | ---------------------- |
-| `connections === 1` | `MockClient` |
-| `connections` > `1` | `MockPool` |
-
-#### Example - Basic Mocked Request
-
-```js
-import { MockAgent, setGlobalDispatcher, request } from 'undici'
-
-const mockAgent = new MockAgent()
-setGlobalDispatcher(mockAgent)
-
-const mockPool = mockAgent.get('http://localhost:3000')
-mockPool.intercept({ path: '/foo' }).reply(200, 'foo')
-
-const { statusCode, body } = await request('http://localhost:3000/foo')
-
-console.log('response received', statusCode) // response received 200
-
-for await (const data of body) {
- console.log('data', data.toString('utf8')) // data foo
-}
-```
-
-#### Example - Basic Mocked Request with local mock agent dispatcher
-
-```js
-import { MockAgent, request } from 'undici'
-
-const mockAgent = new MockAgent()
-
-const mockPool = mockAgent.get('http://localhost:3000')
-mockPool.intercept({ path: '/foo' }).reply(200, 'foo')
-
-const {
- statusCode,
- body
-} = await request('http://localhost:3000/foo', { dispatcher: mockAgent })
-
-console.log('response received', statusCode) // response received 200
-
-for await (const data of body) {
- console.log('data', data.toString('utf8')) // data foo
-}
-```
-
-#### Example - Basic Mocked Request with local mock pool dispatcher
-
-```js
-import { MockAgent, request } from 'undici'
-
-const mockAgent = new MockAgent()
-
-const mockPool = mockAgent.get('http://localhost:3000')
-mockPool.intercept({ path: '/foo' }).reply(200, 'foo')
-
-const {
- statusCode,
- body
-} = await request('http://localhost:3000/foo', { dispatcher: mockPool })
-
-console.log('response received', statusCode) // response received 200
-
-for await (const data of body) {
- console.log('data', data.toString('utf8')) // data foo
-}
-```
-
-#### Example - Basic Mocked Request with local mock client dispatcher
-
-```js
-import { MockAgent, request } from 'undici'
-
-const mockAgent = new MockAgent({ connections: 1 })
-
-const mockClient = mockAgent.get('http://localhost:3000')
-mockClient.intercept({ path: '/foo' }).reply(200, 'foo')
-
-const {
- statusCode,
- body
-} = await request('http://localhost:3000/foo', { dispatcher: mockClient })
-
-console.log('response received', statusCode) // response received 200
-
-for await (const data of body) {
- console.log('data', data.toString('utf8')) // data foo
-}
-```
-
-#### Example - Basic Mocked requests with multiple intercepts
-
-```js
-import { MockAgent, setGlobalDispatcher, request } from 'undici'
-
-const mockAgent = new MockAgent()
-setGlobalDispatcher(mockAgent)
-
-const mockPool = mockAgent.get('http://localhost:3000')
-mockPool.intercept({ path: '/foo' }).reply(200, 'foo')
-mockPool.intercept({ path: '/hello'}).reply(200, 'hello')
-
-const result1 = await request('http://localhost:3000/foo')
-
-console.log('response received', result1.statusCode) // response received 200
-
-for await (const data of result1.body) {
- console.log('data', data.toString('utf8')) // data foo
-}
-
-const result2 = await request('http://localhost:3000/hello')
-
-console.log('response received', result2.statusCode) // response received 200
-
-for await (const data of result2.body) {
- console.log('data', data.toString('utf8')) // data hello
-}
-```
-
-#### Example - Mocked request with query body, headers and trailers
-
-```js
-import { MockAgent, setGlobalDispatcher, request } from 'undici'
-
-const mockAgent = new MockAgent()
-setGlobalDispatcher(mockAgent)
-
-const mockPool = mockAgent.get('http://localhost:3000')
-
-mockPool.intercept({
- path: '/foo?hello=there&see=ya',
- method: 'POST',
- body: 'form1=data1&form2=data2'
-}).reply(200, { foo: 'bar' }, {
- headers: { 'content-type': 'application/json' },
- trailers: { 'Content-MD5': 'test' }
-})
-
-const {
- statusCode,
- headers,
- trailers,
- body
-} = await request('http://localhost:3000/foo?hello=there&see=ya', {
- method: 'POST',
- body: 'form1=data1&form2=data2'
-})
-
-console.log('response received', statusCode) // response received 200
-console.log('headers', headers) // { 'content-type': 'application/json' }
-
-for await (const data of body) {
- console.log('data', data.toString('utf8')) // '{"foo":"bar"}'
-}
-
-console.log('trailers', trailers) // { 'content-md5': 'test' }
-```
-
-#### Example - Mocked request with origin regex
-
-```js
-import { MockAgent, setGlobalDispatcher, request } from 'undici'
-
-const mockAgent = new MockAgent()
-setGlobalDispatcher(mockAgent)
-
-const mockPool = mockAgent.get(new RegExp('http://localhost:3000'))
-mockPool.intercept({ path: '/foo' }).reply(200, 'foo')
-
-const {
- statusCode,
- body
-} = await request('http://localhost:3000/foo')
-
-console.log('response received', statusCode) // response received 200
-
-for await (const data of body) {
- console.log('data', data.toString('utf8')) // data foo
-}
-```
-
-#### Example - Mocked request with origin function
-
-```js
-import { MockAgent, setGlobalDispatcher, request } from 'undici'
-
-const mockAgent = new MockAgent()
-setGlobalDispatcher(mockAgent)
-
-const mockPool = mockAgent.get((origin) => origin === 'http://localhost:3000')
-mockPool.intercept({ path: '/foo' }).reply(200, 'foo')
-
-const {
- statusCode,
- body
-} = await request('http://localhost:3000/foo')
-
-console.log('response received', statusCode) // response received 200
-
-for await (const data of body) {
- console.log('data', data.toString('utf8')) // data foo
-}
-```
-
-### `MockAgent.close()`
-
-Closes the mock agent and waits for registered mock pools and clients to also close before resolving.
-
-Returns: `Promise`
-
-#### Example - clean up after tests are complete
-
-```js
-import { MockAgent, setGlobalDispatcher } from 'undici'
-
-const mockAgent = new MockAgent()
-setGlobalDispatcher(mockAgent)
-
-await mockAgent.close()
-```
-
-### `MockAgent.dispatch(options, handlers)`
-
-Implements [`Agent.dispatch(options, handlers)`](Agent.md#parameter-agentdispatchoptions).
-
-### `MockAgent.request(options[, callback])`
-
-See [`Dispatcher.request(options [, callback])`](Dispatcher.md#dispatcherrequestoptions-callback).
-
-#### Example - MockAgent request
-
-```js
-import { MockAgent } from 'undici'
-
-const mockAgent = new MockAgent()
-
-const mockPool = mockAgent.get('http://localhost:3000')
-mockPool.intercept({ path: '/foo' }).reply(200, 'foo')
-
-const {
- statusCode,
- body
-} = await mockAgent.request({
- origin: 'http://localhost:3000',
- path: '/foo',
- method: 'GET'
-})
-
-console.log('response received', statusCode) // response received 200
-
-for await (const data of body) {
- console.log('data', data.toString('utf8')) // data foo
-}
-```
-
-### `MockAgent.deactivate()`
-
-This method disables mocking in MockAgent.
-
-Returns: `void`
-
-#### Example - Deactivate Mocking
-
-```js
-import { MockAgent, setGlobalDispatcher } from 'undici'
-
-const mockAgent = new MockAgent()
-setGlobalDispatcher(mockAgent)
-
-mockAgent.deactivate()
-```
-
-### `MockAgent.activate()`
-
-This method enables mocking in a MockAgent instance. When instantiated, a MockAgent is automatically activated. Therefore, this method is only effective after `MockAgent.deactivate` has been called.
-
-Returns: `void`
-
-#### Example - Activate Mocking
-
-```js
-import { MockAgent, setGlobalDispatcher } from 'undici'
-
-const mockAgent = new MockAgent()
-setGlobalDispatcher(mockAgent)
-
-mockAgent.deactivate()
-// No mocking will occur
-
-// Later
-mockAgent.activate()
-```
-
-### `MockAgent.enableNetConnect([host])`
-
-When requests are not matched in a MockAgent intercept, a real HTTP request is attempted. We can control this further through the use of `enableNetConnect`. This is achieved by defining host matchers so only matching requests will be attempted.
-
-When using a string, it should only include the **hostname and optionally, the port**. In addition, calling this method multiple times with a string will allow all HTTP requests that match these values.
-
-Arguments:
-
-* **host** `string | RegExp | (value) => boolean` - (optional)
-
-Returns: `void`
-
-#### Example - Allow all non-matching urls to be dispatched in a real HTTP request
-
-```js
-import { MockAgent, setGlobalDispatcher, request } from 'undici'
-
-const mockAgent = new MockAgent()
-setGlobalDispatcher(mockAgent)
-
-mockAgent.enableNetConnect()
-
-await request('http://example.com')
-// A real request is made
-```
-
-#### Example - Allow requests matching a host string to make real requests
-
-```js
-import { MockAgent, setGlobalDispatcher, request } from 'undici'
-
-const mockAgent = new MockAgent()
-setGlobalDispatcher(mockAgent)
-
-mockAgent.enableNetConnect('example-1.com')
-mockAgent.enableNetConnect('example-2.com:8080')
-
-await request('http://example-1.com')
-// A real request is made
-
-await request('http://example-2.com:8080')
-// A real request is made
-
-await request('http://example-3.com')
-// Will throw
-```
-
-#### Example - Allow requests matching a host regex to make real requests
-
-```js
-import { MockAgent, setGlobalDispatcher, request } from 'undici'
-
-const mockAgent = new MockAgent()
-setGlobalDispatcher(mockAgent)
-
-mockAgent.enableNetConnect(new RegExp('example.com'))
-
-await request('http://example.com')
-// A real request is made
-```
-
-#### Example - Allow requests matching a host function to make real requests
-
-```js
-import { MockAgent, setGlobalDispatcher, request } from 'undici'
-
-const mockAgent = new MockAgent()
-setGlobalDispatcher(mockAgent)
-
-mockAgent.enableNetConnect((value) => value === 'example.com')
-
-await request('http://example.com')
-// A real request is made
-```
-
-### `MockAgent.disableNetConnect()`
-
-This method causes all requests to throw when requests are not matched in a MockAgent intercept.
-
-Returns: `void`
-
-#### Example - Disable all non-matching requests by throwing an error for each
-
-```js
-import { MockAgent, request } from 'undici'
-
-const mockAgent = new MockAgent()
-
-mockAgent.disableNetConnect()
-
-await request('http://example.com')
-// Will throw
-```
-
-### `MockAgent.pendingInterceptors()`
-
-This method returns any pending interceptors registered on a mock agent. A pending interceptor meets one of the following criteria:
-
-- Is registered with neither `.times()` nor `.persist()`, and has not been invoked;
-- Is persistent (i.e., registered with `.persist()`) and has not been invoked;
-- Is registered with `.times()` and has not been invoked `` of times.
-
-Returns: `PendingInterceptor[]` (where `PendingInterceptor` is a `MockDispatch` with an additional `origin: string`)
-
-#### Example - List all pending inteceptors
-
-```js
-const agent = new MockAgent()
-agent.disableNetConnect()
-
-agent
- .get('https://example.com')
- .intercept({ method: 'GET', path: '/' })
- .reply(200, '')
-
-const pendingInterceptors = agent.pendingInterceptors()
-// Returns [
-// {
-// timesInvoked: 0,
-// times: 1,
-// persist: false,
-// consumed: false,
-// pending: true,
-// path: '/',
-// method: 'GET',
-// body: undefined,
-// headers: undefined,
-// data: {
-// error: null,
-// statusCode: 200,
-// data: '',
-// headers: {},
-// trailers: {}
-// },
-// origin: 'https://example.com'
-// }
-// ]
-```
-
-### `MockAgent.assertNoPendingInterceptors([options])`
-
-This method throws if the mock agent has any pending interceptors. A pending interceptor meets one of the following criteria:
-
-- Is registered with neither `.times()` nor `.persist()`, and has not been invoked;
-- Is persistent (i.e., registered with `.persist()`) and has not been invoked;
-- Is registered with `.times()` and has not been invoked `` of times.
-
-#### Example - Check that there are no pending interceptors
-
-```js
-const agent = new MockAgent()
-agent.disableNetConnect()
-
-agent
- .get('https://example.com')
- .intercept({ method: 'GET', path: '/' })
- .reply(200, '')
-
-agent.assertNoPendingInterceptors()
-// Throws an UndiciError with the following message:
-//
-// 1 interceptor is pending:
-//
-// ┌─────────┬────────┬───────────────────────┬──────┬─────────────┬────────────┬─────────────┬───────────┐
-// │ (index) │ Method │ Origin │ Path │ Status code │ Persistent │ Invocations │ Remaining │
-// ├─────────┼────────┼───────────────────────┼──────┼─────────────┼────────────┼─────────────┼───────────┤
-// │ 0 │ 'GET' │ 'https://example.com' │ '/' │ 200 │ '❌' │ 0 │ 1 │
-// └─────────┴────────┴───────────────────────┴──────┴─────────────┴────────────┴─────────────┴───────────┘
-```
diff --git a/node_modules/undici/docs/api/MockClient.md b/node_modules/undici/docs/api/MockClient.md
deleted file mode 100644
index ac54691..0000000
--- a/node_modules/undici/docs/api/MockClient.md
+++ /dev/null
@@ -1,77 +0,0 @@
-# Class: MockClient
-
-Extends: `undici.Client`
-
-A mock client class that implements the same api as [MockPool](MockPool.md).
-
-## `new MockClient(origin, [options])`
-
-Arguments:
-
-* **origin** `string` - It should only include the **protocol, hostname, and port**.
-* **options** `MockClientOptions` - It extends the `Client` options.
-
-Returns: `MockClient`
-
-### Parameter: `MockClientOptions`
-
-Extends: `ClientOptions`
-
-* **agent** `Agent` - the agent to associate this MockClient with.
-
-### Example - Basic MockClient instantiation
-
-We can use MockAgent to instantiate a MockClient ready to be used to intercept specified requests. It will not do anything until registered as the agent to use and any mock request are registered.
-
-```js
-import { MockAgent } from 'undici'
-
-// Connections must be set to 1 to return a MockClient instance
-const mockAgent = new MockAgent({ connections: 1 })
-
-const mockClient = mockAgent.get('http://localhost:3000')
-```
-
-## Instance Methods
-
-### `MockClient.intercept(options)`
-
-Implements: [`MockPool.intercept(options)`](MockPool.md#mockpoolinterceptoptions)
-
-### `MockClient.close()`
-
-Implements: [`MockPool.close()`](MockPool.md#mockpoolclose)
-
-### `MockClient.dispatch(options, handlers)`
-
-Implements [`Dispatcher.dispatch(options, handlers)`](Dispatcher.md#dispatcherdispatchoptions-handler).
-
-### `MockClient.request(options[, callback])`
-
-See [`Dispatcher.request(options [, callback])`](Dispatcher.md#dispatcherrequestoptions-callback).
-
-#### Example - MockClient request
-
-```js
-import { MockAgent } from 'undici'
-
-const mockAgent = new MockAgent({ connections: 1 })
-
-const mockClient = mockAgent.get('http://localhost:3000')
-mockClient.intercept({ path: '/foo' }).reply(200, 'foo')
-
-const {
- statusCode,
- body
-} = await mockClient.request({
- origin: 'http://localhost:3000',
- path: '/foo',
- method: 'GET'
-})
-
-console.log('response received', statusCode) // response received 200
-
-for await (const data of body) {
- console.log('data', data.toString('utf8')) // data foo
-}
-```
diff --git a/node_modules/undici/docs/api/MockErrors.md b/node_modules/undici/docs/api/MockErrors.md
deleted file mode 100644
index c1aa3db..0000000
--- a/node_modules/undici/docs/api/MockErrors.md
+++ /dev/null
@@ -1,12 +0,0 @@
-# MockErrors
-
-Undici exposes a variety of mock error objects that you can use to enhance your mock error handling.
-You can find all the mock error objects inside the `mockErrors` key.
-
-```js
-import { mockErrors } from 'undici'
-```
-
-| Mock Error | Mock Error Codes | Description |
-| --------------------- | ------------------------------- | ---------------------------------------------------------- |
-| `MockNotMatchedError` | `UND_MOCK_ERR_MOCK_NOT_MATCHED` | The request does not match any registered mock dispatches. |
diff --git a/node_modules/undici/docs/api/MockPool.md b/node_modules/undici/docs/api/MockPool.md
deleted file mode 100644
index 87fde1d..0000000
--- a/node_modules/undici/docs/api/MockPool.md
+++ /dev/null
@@ -1,511 +0,0 @@
-# Class: MockPool
-
-Extends: `undici.Pool`
-
-A mock Pool class that implements the Pool API and is used by MockAgent to intercept real requests and return mocked responses.
-
-## `new MockPool(origin, [options])`
-
-Arguments:
-
-* **origin** `string` - It should only include the **protocol, hostname, and port**.
-* **options** `MockPoolOptions` - It extends the `Pool` options.
-
-Returns: `MockPool`
-
-### Parameter: `MockPoolOptions`
-
-Extends: `PoolOptions`
-
-* **agent** `Agent` - the agent to associate this MockPool with.
-
-### Example - Basic MockPool instantiation
-
-We can use MockAgent to instantiate a MockPool ready to be used to intercept specified requests. It will not do anything until registered as the agent to use and any mock request are registered.
-
-```js
-import { MockAgent } from 'undici'
-
-const mockAgent = new MockAgent()
-
-const mockPool = mockAgent.get('http://localhost:3000')
-```
-
-## Instance Methods
-
-### `MockPool.intercept(options)`
-
-This method defines the interception rules for matching against requests for a MockPool or MockPool. We can intercept multiple times on a single instance.
-
-When defining interception rules, all the rules must pass for a request to be intercepted. If a request is not intercepted, a real request will be attempted.
-
-| Matcher type | Condition to pass |
-|:------------:| -------------------------- |
-| `string` | Exact match against string |
-| `RegExp` | Regex must pass |
-| `Function` | Function must return true |
-
-Arguments:
-
-* **options** `MockPoolInterceptOptions` - Interception options.
-
-Returns: `MockInterceptor` corresponding to the input options.
-
-### Parameter: `MockPoolInterceptOptions`
-
-* **path** `string | RegExp | (path: string) => boolean` - a matcher for the HTTP request path.
-* **method** `string | RegExp | (method: string) => boolean` - a matcher for the HTTP request method.
-* **body** `string | RegExp | (body: string) => boolean` - (optional) - a matcher for the HTTP request body.
-* **headers** `Record boolean`> - (optional) - a matcher for the HTTP request headers. To be intercepted, a request must match all defined headers. Extra headers not defined here may (or may not) be included in the request and do not affect the interception in any way.
-* **query** `Record | null` - (optional) - a matcher for the HTTP request query string params.
-
-### Return: `MockInterceptor`
-
-We can define the behaviour of an intercepted request with the following options.
-
-* **reply** `(statusCode: number, replyData: string | Buffer | object | MockInterceptor.MockResponseDataHandler, responseOptions?: MockResponseOptions) => MockScope` - define a reply for a matching request. You can define this as a callback to read incoming request data. Default for `responseOptions` is `{}`.
-* **replyWithError** `(error: Error) => MockScope` - define an error for a matching request to throw.
-* **defaultReplyHeaders** `(headers: Record) => MockInterceptor` - define default headers to be included in subsequent replies. These are in addition to headers on a specific reply.
-* **defaultReplyTrailers** `(trailers: Record) => MockInterceptor` - define default trailers to be included in subsequent replies. These are in addition to trailers on a specific reply.
-* **replyContentLength** `() => MockInterceptor` - define automatically calculated `content-length` headers to be included in subsequent replies.
-
-The reply data of an intercepted request may either be a string, buffer, or JavaScript object. Objects are converted to JSON while strings and buffers are sent as-is.
-
-By default, `reply` and `replyWithError` define the behaviour for the first matching request only. Subsequent requests will not be affected (this can be changed using the returned `MockScope`).
-
-### Parameter: `MockResponseOptions`
-
-* **headers** `Record` - headers to be included on the mocked reply.
-* **trailers** `Record` - trailers to be included on the mocked reply.
-
-### Return: `MockScope`
-
-A `MockScope` is associated with a single `MockInterceptor`. With this, we can configure the default behaviour of a intercepted reply.
-
-* **delay** `(waitInMs: number) => MockScope` - delay the associated reply by a set amount in ms.
-* **persist** `() => MockScope` - any matching request will always reply with the defined response indefinitely.
-* **times** `(repeatTimes: number) => MockScope` - any matching request will reply with the defined response a fixed amount of times. This is overridden by **persist**.
-
-#### Example - Basic Mocked Request
-
-```js
-import { MockAgent, setGlobalDispatcher, request } from 'undici'
-
-const mockAgent = new MockAgent()
-setGlobalDispatcher(mockAgent)
-
-// MockPool
-const mockPool = mockAgent.get('http://localhost:3000')
-mockPool.intercept({ path: '/foo' }).reply(200, 'foo')
-
-const {
- statusCode,
- body
-} = await request('http://localhost:3000/foo')
-
-console.log('response received', statusCode) // response received 200
-
-for await (const data of body) {
- console.log('data', data.toString('utf8')) // data foo
-}
-```
-
-#### Example - Mocked request using reply data callbacks
-
-```js
-import { MockAgent, setGlobalDispatcher, request } from 'undici'
-
-const mockAgent = new MockAgent()
-setGlobalDispatcher(mockAgent)
-
-const mockPool = mockAgent.get('http://localhost:3000')
-
-mockPool.intercept({
- path: '/echo',
- method: 'GET',
- headers: {
- 'User-Agent': 'undici',
- Host: 'example.com'
- }
-}).reply(200, ({ headers }) => ({ message: headers.get('message') }))
-
-const { statusCode, body, headers } = await request('http://localhost:3000', {
- headers: {
- message: 'hello world!'
- }
-})
-
-console.log('response received', statusCode) // response received 200
-console.log('headers', headers) // { 'content-type': 'application/json' }
-
-for await (const data of body) {
- console.log('data', data.toString('utf8')) // { "message":"hello world!" }
-}
-```
-
-#### Example - Mocked request using reply options callback
-
-```js
-import { MockAgent, setGlobalDispatcher, request } from 'undici'
-
-const mockAgent = new MockAgent()
-setGlobalDispatcher(mockAgent)
-
-const mockPool = mockAgent.get('http://localhost:3000')
-
-mockPool.intercept({
- path: '/echo',
- method: 'GET',
- headers: {
- 'User-Agent': 'undici',
- Host: 'example.com'
- }
-}).reply(({ headers }) => ({ statusCode: 200, data: { message: headers.get('message') }})))
-
-const { statusCode, body, headers } = await request('http://localhost:3000', {
- headers: {
- message: 'hello world!'
- }
-})
-
-console.log('response received', statusCode) // response received 200
-console.log('headers', headers) // { 'content-type': 'application/json' }
-
-for await (const data of body) {
- console.log('data', data.toString('utf8')) // { "message":"hello world!" }
-}
-```
-
-#### Example - Basic Mocked requests with multiple intercepts
-
-```js
-import { MockAgent, setGlobalDispatcher, request } from 'undici'
-
-const mockAgent = new MockAgent()
-setGlobalDispatcher(mockAgent)
-
-const mockPool = mockAgent.get('http://localhost:3000')
-
-mockPool.intercept({
- path: '/foo',
- method: 'GET'
-}).reply(200, 'foo')
-
-mockPool.intercept({
- path: '/hello',
- method: 'GET',
-}).reply(200, 'hello')
-
-const result1 = await request('http://localhost:3000/foo')
-
-console.log('response received', result1.statusCode) // response received 200
-
-for await (const data of result1.body) {
- console.log('data', data.toString('utf8')) // data foo
-}
-
-const result2 = await request('http://localhost:3000/hello')
-
-console.log('response received', result2.statusCode) // response received 200
-
-for await (const data of result2.body) {
- console.log('data', data.toString('utf8')) // data hello
-}
-```
-
-#### Example - Mocked request with query body, request headers and response headers and trailers
-
-```js
-import { MockAgent, setGlobalDispatcher, request } from 'undici'
-
-const mockAgent = new MockAgent()
-setGlobalDispatcher(mockAgent)
-
-const mockPool = mockAgent.get('http://localhost:3000')
-
-mockPool.intercept({
- path: '/foo?hello=there&see=ya',
- method: 'POST',
- body: 'form1=data1&form2=data2',
- headers: {
- 'User-Agent': 'undici',
- Host: 'example.com'
- }
-}).reply(200, { foo: 'bar' }, {
- headers: { 'content-type': 'application/json' },
- trailers: { 'Content-MD5': 'test' }
-})
-
-const {
- statusCode,
- headers,
- trailers,
- body
-} = await request('http://localhost:3000/foo?hello=there&see=ya', {
- method: 'POST',
- body: 'form1=data1&form2=data2',
- headers: {
- foo: 'bar',
- 'User-Agent': 'undici',
- Host: 'example.com'
- }
- })
-
-console.log('response received', statusCode) // response received 200
-console.log('headers', headers) // { 'content-type': 'application/json' }
-
-for await (const data of body) {
- console.log('data', data.toString('utf8')) // '{"foo":"bar"}'
-}
-
-console.log('trailers', trailers) // { 'content-md5': 'test' }
-```
-
-#### Example - Mocked request using different matchers
-
-```js
-import { MockAgent, setGlobalDispatcher, request } from 'undici'
-
-const mockAgent = new MockAgent()
-setGlobalDispatcher(mockAgent)
-
-const mockPool = mockAgent.get('http://localhost:3000')
-
-mockPool.intercept({
- path: '/foo',
- method: /^GET$/,
- body: (value) => value === 'form=data',
- headers: {
- 'User-Agent': 'undici',
- Host: /^example.com$/
- }
-}).reply(200, 'foo')
-
-const {
- statusCode,
- body
-} = await request('http://localhost:3000/foo', {
- method: 'GET',
- body: 'form=data',
- headers: {
- foo: 'bar',
- 'User-Agent': 'undici',
- Host: 'example.com'
- }
-})
-
-console.log('response received', statusCode) // response received 200
-
-for await (const data of body) {
- console.log('data', data.toString('utf8')) // data foo
-}
-```
-
-#### Example - Mocked request with reply with a defined error
-
-```js
-import { MockAgent, setGlobalDispatcher, request } from 'undici'
-
-const mockAgent = new MockAgent()
-setGlobalDispatcher(mockAgent)
-
-const mockPool = mockAgent.get('http://localhost:3000')
-
-mockPool.intercept({
- path: '/foo',
- method: 'GET'
-}).replyWithError(new Error('kaboom'))
-
-try {
- await request('http://localhost:3000/foo', {
- method: 'GET'
- })
-} catch (error) {
- console.error(error) // Error: kaboom
-}
-```
-
-#### Example - Mocked request with defaultReplyHeaders
-
-```js
-import { MockAgent, setGlobalDispatcher, request } from 'undici'
-
-const mockAgent = new MockAgent()
-setGlobalDispatcher(mockAgent)
-
-const mockPool = mockAgent.get('http://localhost:3000')
-
-mockPool.intercept({
- path: '/foo',
- method: 'GET'
-}).defaultReplyHeaders({ foo: 'bar' })
- .reply(200, 'foo')
-
-const { headers } = await request('http://localhost:3000/foo')
-
-console.log('headers', headers) // headers { foo: 'bar' }
-```
-
-#### Example - Mocked request with defaultReplyTrailers
-
-```js
-import { MockAgent, setGlobalDispatcher, request } from 'undici'
-
-const mockAgent = new MockAgent()
-setGlobalDispatcher(mockAgent)
-
-const mockPool = mockAgent.get('http://localhost:3000')
-
-mockPool.intercept({
- path: '/foo',
- method: 'GET'
-}).defaultReplyTrailers({ foo: 'bar' })
- .reply(200, 'foo')
-
-const { trailers } = await request('http://localhost:3000/foo')
-
-console.log('trailers', trailers) // trailers { foo: 'bar' }
-```
-
-#### Example - Mocked request with automatic content-length calculation
-
-```js
-import { MockAgent, setGlobalDispatcher, request } from 'undici'
-
-const mockAgent = new MockAgent()
-setGlobalDispatcher(mockAgent)
-
-const mockPool = mockAgent.get('http://localhost:3000')
-
-mockPool.intercept({
- path: '/foo',
- method: 'GET'
-}).replyContentLength().reply(200, 'foo')
-
-const { headers } = await request('http://localhost:3000/foo')
-
-console.log('headers', headers) // headers { 'content-length': '3' }
-```
-
-#### Example - Mocked request with automatic content-length calculation on an object
-
-```js
-import { MockAgent, setGlobalDispatcher, request } from 'undici'
-
-const mockAgent = new MockAgent()
-setGlobalDispatcher(mockAgent)
-
-const mockPool = mockAgent.get('http://localhost:3000')
-
-mockPool.intercept({
- path: '/foo',
- method: 'GET'
-}).replyContentLength().reply(200, { foo: 'bar' })
-
-const { headers } = await request('http://localhost:3000/foo')
-
-console.log('headers', headers) // headers { 'content-length': '13' }
-```
-
-#### Example - Mocked request with persist enabled
-
-```js
-import { MockAgent, setGlobalDispatcher, request } from 'undici'
-
-const mockAgent = new MockAgent()
-setGlobalDispatcher(mockAgent)
-
-const mockPool = mockAgent.get('http://localhost:3000')
-
-mockPool.intercept({
- path: '/foo',
- method: 'GET'
-}).reply(200, 'foo').persist()
-
-const result1 = await request('http://localhost:3000/foo')
-// Will match and return mocked data
-
-const result2 = await request('http://localhost:3000/foo')
-// Will match and return mocked data
-
-// Etc
-```
-
-#### Example - Mocked request with times enabled
-
-```js
-import { MockAgent, setGlobalDispatcher, request } from 'undici'
-
-const mockAgent = new MockAgent()
-setGlobalDispatcher(mockAgent)
-
-const mockPool = mockAgent.get('http://localhost:3000')
-
-mockPool.intercept({
- path: '/foo',
- method: 'GET'
-}).reply(200, 'foo').times(2)
-
-const result1 = await request('http://localhost:3000/foo')
-// Will match and return mocked data
-
-const result2 = await request('http://localhost:3000/foo')
-// Will match and return mocked data
-
-const result3 = await request('http://localhost:3000/foo')
-// Will not match and make attempt a real request
-```
-
-### `MockPool.close()`
-
-Closes the mock pool and de-registers from associated MockAgent.
-
-Returns: `Promise`
-
-#### Example - clean up after tests are complete
-
-```js
-import { MockAgent } from 'undici'
-
-const mockAgent = new MockAgent()
-const mockPool = mockAgent.get('http://localhost:3000')
-
-await mockPool.close()
-```
-
-### `MockPool.dispatch(options, handlers)`
-
-Implements [`Dispatcher.dispatch(options, handlers)`](Dispatcher.md#dispatcherdispatchoptions-handler).
-
-### `MockPool.request(options[, callback])`
-
-See [`Dispatcher.request(options [, callback])`](Dispatcher.md#dispatcherrequestoptions-callback).
-
-#### Example - MockPool request
-
-```js
-import { MockAgent } from 'undici'
-
-const mockAgent = new MockAgent()
-
-const mockPool = mockAgent.get('http://localhost:3000')
-mockPool.intercept({
- path: '/foo',
- method: 'GET',
-}).reply(200, 'foo')
-
-const {
- statusCode,
- body
-} = await mockPool.request({
- origin: 'http://localhost:3000',
- path: '/foo',
- method: 'GET'
-})
-
-console.log('response received', statusCode) // response received 200
-
-for await (const data of body) {
- console.log('data', data.toString('utf8')) // data foo
-}
-```
diff --git a/node_modules/undici/docs/api/Pool.md b/node_modules/undici/docs/api/Pool.md
deleted file mode 100644
index 6b08294..0000000
--- a/node_modules/undici/docs/api/Pool.md
+++ /dev/null
@@ -1,83 +0,0 @@
-# Class: Pool
-
-Extends: `undici.Dispatcher`
-
-A pool of [Client](Client.md) instances connected to the same upstream target.
-
-Requests are not guaranteed to be dispatched in order of invocation.
-
-## `new Pool(url[, options])`
-
-Arguments:
-
-* **url** `URL | string` - It should only include the **protocol, hostname, and port**.
-* **options** `PoolOptions` (optional)
-
-### Parameter: `PoolOptions`
-
-Extends: [`ClientOptions`](Client.md#parameter-clientoptions)
-
-* **factory** `(origin: URL, opts: Object) => Dispatcher` - Default: `(origin, opts) => new Client(origin, opts)`
-* **connections** `number | null` (optional) - Default: `null` - The number of `Client` instances to create. When set to `null`, the `Pool` instance will create an unlimited amount of `Client` instances.
-
-## Instance Properties
-
-### `Pool.closed`
-
-Implements [Client.closed](Client.md#clientclosed)
-
-### `Pool.destroyed`
-
-Implements [Client.destroyed](Client.md#clientdestroyed)
-
-### `Pool.stats`
-
-Returns [`PoolStats`](PoolStats.md) instance for this pool.
-
-## Instance Methods
-
-### `Pool.close([callback])`
-
-Implements [`Dispatcher.close([callback])`](Dispatcher.md#dispatcherclosecallback-promise).
-
-### `Pool.destroy([error, callback])`
-
-Implements [`Dispatcher.destroy([error, callback])`](Dispatcher.md#dispatcherdestroyerror-callback-promise).
-
-### `Pool.connect(options[, callback])`
-
-See [`Dispatcher.connect(options[, callback])`](Dispatcher.md#dispatcherconnectoptions-callback).
-
-### `Pool.dispatch(options, handler)`
-
-Implements [`Dispatcher.dispatch(options, handler)`](Dispatcher.md#dispatcherdispatchoptions-handler).
-
-### `Pool.pipeline(options, handler)`
-
-See [`Dispatcher.pipeline(options, handler)`](Dispatcher.md#dispatcherpipelineoptions-handler).
-
-### `Pool.request(options[, callback])`
-
-See [`Dispatcher.request(options [, callback])`](Dispatcher.md#dispatcherrequestoptions-callback).
-
-### `Pool.stream(options, factory[, callback])`
-
-See [`Dispatcher.stream(options, factory[, callback])`](Dispatcher.md#dispatcherstreamoptions-factory-callback).
-
-### `Pool.upgrade(options[, callback])`
-
-See [`Dispatcher.upgrade(options[, callback])`](Dispatcher.md#dispatcherupgradeoptions-callback).
-
-## Instance Events
-
-### Event: `'connect'`
-
-See [Dispatcher Event: `'connect'`](Dispatcher.md#event-connect).
-
-### Event: `'disconnect'`
-
-See [Dispatcher Event: `'disconnect'`](Dispatcher.md#event-disconnect).
-
-### Event: `'drain'`
-
-See [Dispatcher Event: `'drain'`](Dispatcher.md#event-drain).
diff --git a/node_modules/undici/docs/api/PoolStats.md b/node_modules/undici/docs/api/PoolStats.md
deleted file mode 100644
index 16b6dc2..0000000
--- a/node_modules/undici/docs/api/PoolStats.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# Class: PoolStats
-
-Aggregate stats for a [Pool](Pool.md) or [BalancedPool](BalancedPool.md).
-
-## `new PoolStats(pool)`
-
-Arguments:
-
-* **pool** `Pool` - Pool or BalancedPool from which to return stats.
-
-## Instance Properties
-
-### `PoolStats.connected`
-
-Number of open socket connections in this pool.
-
-### `PoolStats.free`
-
-Number of open socket connections in this pool that do not have an active request.
-
-### `PoolStats.pending`
-
-Number of pending requests across all clients in this pool.
-
-### `PoolStats.queued`
-
-Number of queued requests across all clients in this pool.
-
-### `PoolStats.running`
-
-Number of currently active requests across all clients in this pool.
-
-### `PoolStats.size`
-
-Number of active, pending, or queued requests across all clients in this pool.
diff --git a/node_modules/undici/docs/api/ProxyAgent.md b/node_modules/undici/docs/api/ProxyAgent.md
deleted file mode 100644
index cbd2dad..0000000
--- a/node_modules/undici/docs/api/ProxyAgent.md
+++ /dev/null
@@ -1,100 +0,0 @@
-# Class: ProxyAgent
-
-Extends: `undici.Dispatcher`
-
-A Proxy Agent class that implements the Agent API. It allows the connection through proxy in a simple way.
-
-## `new ProxyAgent([options])`
-
-Arguments:
-
-* **options** `ProxyAgentOptions` (required) - It extends the `Agent` options.
-
-Returns: `ProxyAgent`
-
-### Parameter: `ProxyAgentOptions`
-
-Extends: [`AgentOptions`](Agent.md#parameter-agentoptions)
-
-* **uri** `string` (required) - It can be passed either by a string or a object containing `uri` as string.
-
-Examples:
-
-```js
-import { ProxyAgent } from 'undici'
-
-const proxyAgent = new ProxyAgent('my.proxy.server')
-// or
-const proxyAgent = new ProxyAgent({ uri: 'my.proxy.server' })
-```
-
-#### Example - Basic ProxyAgent instantiation
-
-This will instantiate the ProxyAgent. It will not do anything until registered as the agent to use with requests.
-
-```js
-import { ProxyAgent } from 'undici'
-
-const proxyAgent = new ProxyAgent('my.proxy.server')
-```
-
-#### Example - Basic Proxy Request with global agent dispatcher
-
-```js
-import { setGlobalDispatcher, request, ProxyAgent } from 'undici'
-
-const proxyAgent = new ProxyAgent('my.proxy.server')
-setGlobalDispatcher(proxyAgent)
-
-const { statusCode, body } = await request('http://localhost:3000/foo')
-
-console.log('response received', statusCode) // response received 200
-
-for await (const data of body) {
- console.log('data', data.toString('utf8')) // data foo
-}
-```
-
-#### Example - Basic Proxy Request with local agent dispatcher
-
-```js
-import { ProxyAgent, request } from 'undici'
-
-const proxyAgent = new ProxyAgent('my.proxy.server')
-
-const {
- statusCode,
- body
-} = await request('http://localhost:3000/foo', { dispatcher: proxyAgent })
-
-console.log('response received', statusCode) // response received 200
-
-for await (const data of body) {
- console.log('data', data.toString('utf8')) // data foo
-}
-```
-
-### `ProxyAgent.close()`
-
-Closes the proxy agent and waits for registered pools and clients to also close before resolving.
-
-Returns: `Promise`
-
-#### Example - clean up after tests are complete
-
-```js
-import { ProxyAgent, setGlobalDispatcher } from 'undici'
-
-const proxyAgent = new ProxyAgent('my.proxy.server')
-setGlobalDispatcher(proxyAgent)
-
-await proxyAgent.close()
-```
-
-### `ProxyAgent.dispatch(options, handlers)`
-
-Implements [`Agent.dispatch(options, handlers)`](Agent.md#parameter-agentdispatchoptions).
-
-### `ProxyAgent.request(options[, callback])`
-
-See [`Dispatcher.request(options [, callback])`](Dispatcher.md#dispatcherrequestoptions-callback).
diff --git a/node_modules/undici/docs/api/api-lifecycle.md b/node_modules/undici/docs/api/api-lifecycle.md
deleted file mode 100644
index d158126..0000000
--- a/node_modules/undici/docs/api/api-lifecycle.md
+++ /dev/null
@@ -1,62 +0,0 @@
-# Client Lifecycle
-
-An Undici [Client](Client.md) can be best described as a state machine. The following list is a summary of the various state transitions the `Client` will go through in its lifecycle. This document also contains detailed breakdowns of each state.
-
-> This diagram is not a perfect representation of the undici Client. Since the Client class is not actually implemented as a state-machine, actual execution may deviate slightly from what is described below. Consider this as a general resource for understanding the inner workings of the Undici client rather than some kind of formal specification.
-
-## State Transition Overview
-
-* A `Client` begins in the **idle** state with no socket connection and no requests in queue.
- * The *connect* event transitions the `Client` to the **pending** state where requests can be queued prior to processing.
- * The *close* and *destroy* events transition the `Client` to the **destroyed** state. Since there are no requests in the queue, the *close* event immediately transitions to the **destroyed** state.
-* The **pending** state indicates the underlying socket connection has been successfully established and requests are queueing.
- * The *process* event transitions the `Client` to the **processing** state where requests are processed.
- * If requests are queued, the *close* event transitions to the **processing** state; otherwise, it transitions to the **destroyed** state.
- * The *destroy* event transitions to the **destroyed** state.
-* The **processing** state initializes to the **processing.running** state.
- * If the current request requires draining, the *needDrain* event transitions the `Client` into the **processing.busy** state which will return to the **processing.running** state with the *drainComplete* event.
- * After all queued requests are completed, the *keepalive* event transitions the `Client` back to the **pending** state. If no requests are queued during the timeout, the **close** event transitions the `Client` to the **destroyed** state.
- * If the *close* event is fired while the `Client` still has queued requests, the `Client` transitions to the **process.closing** state where it will complete all existing requests before firing the *done* event.
- * The *done* event gracefully transitions the `Client` to the **destroyed** state.
- * At any point in time, the *destroy* event will transition the `Client` from the **processing** state to the **destroyed** state, destroying any queued requests.
-* The **destroyed** state is a final state and the `Client` is no longer functional.
-
-
-
-> The diagram was generated using Mermaid.js Live Editor. Modify the state diagram [here](https://mermaid-js.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoic3RhdGVEaWFncmFtLXYyXG4gICAgWypdIC0tPiBpZGxlXG4gICAgaWRsZSAtLT4gcGVuZGluZyA6IGNvbm5lY3RcbiAgICBpZGxlIC0tPiBkZXN0cm95ZWQgOiBkZXN0cm95L2Nsb3NlXG4gICAgXG4gICAgcGVuZGluZyAtLT4gaWRsZSA6IHRpbWVvdXRcbiAgICBwZW5kaW5nIC0tPiBkZXN0cm95ZWQgOiBkZXN0cm95XG5cbiAgICBzdGF0ZSBjbG9zZV9mb3JrIDw8Zm9yaz4-XG4gICAgcGVuZGluZyAtLT4gY2xvc2VfZm9yayA6IGNsb3NlXG4gICAgY2xvc2VfZm9yayAtLT4gcHJvY2Vzc2luZ1xuICAgIGNsb3NlX2ZvcmsgLS0-IGRlc3Ryb3llZFxuXG4gICAgcGVuZGluZyAtLT4gcHJvY2Vzc2luZyA6IHByb2Nlc3NcblxuICAgIHByb2Nlc3NpbmcgLS0-IHBlbmRpbmcgOiBrZWVwYWxpdmVcbiAgICBwcm9jZXNzaW5nIC0tPiBkZXN0cm95ZWQgOiBkb25lXG4gICAgcHJvY2Vzc2luZyAtLT4gZGVzdHJveWVkIDogZGVzdHJveVxuXG4gICAgc3RhdGUgcHJvY2Vzc2luZyB7XG4gICAgICAgIHJ1bm5pbmcgLS0-IGJ1c3kgOiBuZWVkRHJhaW5cbiAgICAgICAgYnVzeSAtLT4gcnVubmluZyA6IGRyYWluQ29tcGxldGVcbiAgICAgICAgcnVubmluZyAtLT4gWypdIDoga2VlcGFsaXZlXG4gICAgICAgIHJ1bm5pbmcgLS0-IGNsb3NpbmcgOiBjbG9zZVxuICAgICAgICBjbG9zaW5nIC0tPiBbKl0gOiBkb25lXG4gICAgICAgIFsqXSAtLT4gcnVubmluZ1xuICAgIH1cbiAgICAiLCJtZXJtYWlkIjp7InRoZW1lIjoiYmFzZSJ9LCJ1cGRhdGVFZGl0b3IiOmZhbHNlfQ)
-
-## State details
-
-### idle
-
-The **idle** state is the initial state of a `Client` instance. While an `origin` is required for instantiating a `Client` instance, the underlying socket connection will not be established until a request is queued using [`Client.dispatch()`](Client.md#clientdispatchoptions-handlers). By calling `Client.dispatch()` directly or using one of the multiple implementations ([`Client.connect()`](Client.md#clientconnectoptions-callback), [`Client.pipeline()`](Client.md#clientpipelineoptions-handler), [`Client.request()`](Client.md#clientrequestoptions-callback), [`Client.stream()`](Client.md#clientstreamoptions-factory-callback), and [`Client.upgrade()`](Client.md#clientupgradeoptions-callback)), the `Client` instance will transition from **idle** to [**pending**](#pending) and then most likely directly to [**processing**](#processing).
-
-Calling [`Client.close()`](Client.md#clientclosecallback) or [`Client.destroy()`](Client.md#clientdestroyerror-callback) transitions directly to the [**destroyed**](#destroyed) state since the `Client` instance will have no queued requests in this state.
-
-### pending
-
-The **pending** state signifies a non-processing `Client`. Upon entering this state, the `Client` establishes a socket connection and emits the [`'connect'`](Client.md#event-connect) event signalling a connection was successfully established with the `origin` provided during `Client` instantiation. The internal queue is initially empty, and requests can start queueing.
-
-Calling [`Client.close()`](Client.md#clientclosecallback) with queued requests, transitions the `Client` to the [**processing**](#processing) state. Without queued requests, it transitions to the [**destroyed**](#destroyed) state.
-
-Calling [`Client.destroy()`](Client.md#clientdestroyerror-callback) transitions directly to the [**destroyed**](#destroyed) state regardless of existing requests.
-
-### processing
-
-The **processing** state is a state machine within itself. It initializes to the [**processing.running**](#running) state. The [`Client.dispatch()`](Client.md#clientdispatchoptions-handlers), [`Client.close()`](Client.md#clientclosecallback), and [`Client.destroy()`](Client.md#clientdestroyerror-callback) can be called at any time while the `Client` is in this state. `Client.dispatch()` will add more requests to the queue while existing requests continue to be processed. `Client.close()` will transition to the [**processing.closing**](#closing) state. And `Client.destroy()` will transition to [**destroyed**](#destroyed).
-
-#### running
-
-In the **processing.running** sub-state, queued requests are being processed in a FIFO order. If a request body requires draining, the *needDrain* event transitions to the [**processing.busy**](#busy) sub-state. The *close* event transitions the Client to the [**process.closing**](#closing) sub-state. If all queued requests are processed and neither [`Client.close()`](Client.md#clientclosecallback) nor [`Client.destroy()`](Client.md#clientdestroyerror-callback) are called, then the [**processing**](#processing) machine will trigger a *keepalive* event transitioning the `Client` back to the [**pending**](#pending) state. During this time, the `Client` is waiting for the socket connection to timeout, and once it does, it triggers the *timeout* event and transitions to the [**idle**](#idle) state.
-
-#### busy
-
-This sub-state is only entered when a request body is an instance of [Stream](https://nodejs.org/api/stream.html) and requires draining. The `Client` cannot process additional requests while in this state and must wait until the currently processing request body is completely drained before transitioning back to [**processing.running**](#running).
-
-#### closing
-
-This sub-state is only entered when a `Client` instance has queued requests and the [`Client.close()`](Client.md#clientclosecallback) method is called. In this state, the `Client` instance continues to process requests as usual, with the one exception that no additional requests can be queued. Once all of the queued requests are processed, the `Client` will trigger the *done* event gracefully entering the [**destroyed**](#destroyed) state without an error.
-
-### destroyed
-
-The **destroyed** state is a final state for the `Client` instance. Once in this state, a `Client` is nonfunctional. Calling any other `Client` methods will result in an `ClientDestroyedError`.
diff --git a/node_modules/undici/docs/assets/lifecycle-diagram.png b/node_modules/undici/docs/assets/lifecycle-diagram.png
deleted file mode 100644
index 01d1c32..0000000
Binary files a/node_modules/undici/docs/assets/lifecycle-diagram.png and /dev/null differ
diff --git a/node_modules/undici/docs/best-practices/client-certificate.md b/node_modules/undici/docs/best-practices/client-certificate.md
deleted file mode 100644
index 4fc84ec..0000000
--- a/node_modules/undici/docs/best-practices/client-certificate.md
+++ /dev/null
@@ -1,64 +0,0 @@
-# Client certificate
-
-Client certificate authentication can be configured with the `Client`, the required options are passed along through the `connect` option.
-
-The client certificates must be signed by a trusted CA. The Node.js default is to trust the well-known CAs curated by Mozilla.
-
-Setting the server option `requestCert: true` tells the server to request the client certificate.
-
-The server option `rejectUnauthorized: false` allows us to handle any invalid certificate errors in client code. The `authorized` property on the socket of the incoming request will show if the client certificate was valid. The `authorizationError` property will give the reason if the certificate was not valid.
-
-### Client Certificate Authentication
-
-```js
-const { readFileSync } = require('fs')
-const { join } = require('path')
-const { createServer } = require('https')
-const { Client } = require('undici')
-
-const serverOptions = {
- ca: [
- readFileSync(join(__dirname, 'client-ca-crt.pem'), 'utf8')
- ],
- key: readFileSync(join(__dirname, 'server-key.pem'), 'utf8'),
- cert: readFileSync(join(__dirname, 'server-crt.pem'), 'utf8'),
- requestCert: true,
- rejectUnauthorized: false
-}
-
-const server = createServer(serverOptions, (req, res) => {
- // true if client cert is valid
- if(req.client.authorized === true) {
- console.log('valid')
- } else {
- console.error(req.client.authorizationError)
- }
- res.end()
-})
-
-server.listen(0, function () {
- const tls = {
- ca: [
- readFileSync(join(__dirname, 'server-ca-crt.pem'), 'utf8')
- ],
- key: readFileSync(join(__dirname, 'client-key.pem'), 'utf8'),
- cert: readFileSync(join(__dirname, 'client-crt.pem'), 'utf8'),
- rejectUnauthorized: false,
- servername: 'agent1'
- }
- const client = new Client(`https://localhost:${server.address().port}`, {
- connect: tls
- })
-
- client.request({
- path: '/',
- method: 'GET'
- }, (err, { body }) => {
- body.on('data', (buf) => {})
- body.on('end', () => {
- client.close()
- server.close()
- })
- })
-})
-```
diff --git a/node_modules/undici/docs/best-practices/mocking-request.md b/node_modules/undici/docs/best-practices/mocking-request.md
deleted file mode 100644
index b98a450..0000000
--- a/node_modules/undici/docs/best-practices/mocking-request.md
+++ /dev/null
@@ -1,136 +0,0 @@
-# Mocking Request
-
-Undici have its own mocking [utility](../api/MockAgent.md). It allow us to intercept undici HTTP request and return mocked value instead. It can be useful for testing purposes.
-
-Example:
-
-```js
-// bank.mjs
-import { request } from 'undici'
-
-export async function bankTransfer(recepient, amount) {
- const { body } = await request('http://localhost:3000/bank-transfer',
- {
- method: 'POST',
- headers: {
- 'X-TOKEN-SECRET': 'SuperSecretToken',
- },
- body: JSON.stringify({
- recepient,
- amount
- })
- }
- )
- return await body.json()
-}
-```
-
-And this is what the test file looks like:
-
-```js
-// index.test.mjs
-import { strict as assert } from 'assert'
-import { MockAgent, setGlobalDispatcher, } from 'undici'
-import { bankTransfer } from './bank.mjs'
-
-const mockAgent = new MockAgent();
-
-setGlobalDispatcher(mockAgent);
-
-// Provide the base url to the request
-const mockPool = mockAgent.get('http://localhost:3000');
-
-// intercept the request
-mockPool.intercept({
- path: '/bank-transfer',
- method: 'POST',
- headers: {
- 'X-TOKEN-SECRET': 'SuperSecretToken',
- },
- body: JSON.stringify({
- recepient: '1234567890',
- amount: '100'
- })
-}).reply(200, {
- message: 'transaction processed'
-})
-
-const success = await bankTransfer('1234567890', '100')
-
-assert.deepEqual(success, { message: 'transaction processed' })
-
-// if you dont want to check whether the body or the headers contain the same value
-// just remove it from interceptor
-mockPool.intercept({
- path: '/bank-transfer',
- method: 'POST',
-}).reply(400, {
- message: 'bank account not found'
-})
-
-const badRequest = await bankTransfer('1234567890', '100')
-
-assert.deepEqual(badRequest, { message: 'bank account not found' })
-```
-
-Explore other MockAgent functionality [here](../api/MockAgent.md)
-
-## Debug Mock Value
-
-When the interceptor we wrote are not the same undici will automatically call real HTTP request. To debug our mock value use `mockAgent.disableNetConnect()`
-
-```js
-const mockAgent = new MockAgent();
-
-setGlobalDispatcher(mockAgent);
-mockAgent.disableNetConnect()
-
-// Provide the base url to the request
-const mockPool = mockAgent.get('http://localhost:3000');
-
-mockPool.intercept({
- path: '/bank-tanfer',
- method: 'POST',
-}).reply(200, {
- message: 'transaction processed'
-})
-
-const badRequest = await bankTransfer('1234567890', '100')
-// Will throw an error
-// MockNotMatchedError: Mock dispatch not matched for path '/bank-transfer':
-// subsequent request to origin http://localhost:3000 was not allowed (net.connect disabled)
-```
-
-## Reply with data based on request
-
-If the mocked response needs to be dynamically derived from the request parameters, you can provide a function instead of an object to `reply`
-
-```js
-mockPool.intercept({
- path: '/bank-transfer',
- method: 'POST',
- headers: {
- 'X-TOKEN-SECRET': 'SuperSecretToken',
- },
- body: JSON.stringify({
- recepient: '1234567890',
- amount: '100'
- })
-}).reply(200, (opts) => {
- // do something with opts
-
- return { message: 'transaction processed' }
-})
-```
-
-in this case opts will be
-
-```
-{
- method: 'POST',
- headers: { 'X-TOKEN-SECRET': 'SuperSecretToken' },
- body: '{"recepient":"1234567890","amount":"100"}',
- origin: 'http://localhost:3000',
- path: '/bank-transfer'
-}
-```
diff --git a/node_modules/undici/docs/best-practices/proxy.md b/node_modules/undici/docs/best-practices/proxy.md
deleted file mode 100644
index 256e8f9..0000000
--- a/node_modules/undici/docs/best-practices/proxy.md
+++ /dev/null
@@ -1,126 +0,0 @@
-# Connecting through a proxy
-
-Connecting through a proxy is possible by:
-
-- Using [AgentProxy](../api/ProxyAgent.md).
-- Configuring `Client` or `Pool` constructor.
-
-The proxy url should be passed to the `Client` or `Pool` constructor, while the upstream server url
-should be added to every request call in the `path`.
-For instance, if you need to send a request to the `/hello` route of your upstream server,
-the `path` should be `path: 'http://upstream.server:port/hello?foo=bar'`.
-
-If you proxy requires basic authentication, you can send it via the `proxy-authorization` header.
-
-### Connect without authentication
-
-```js
-import { Client } from 'undici'
-import { createServer } from 'http'
-import proxy from 'proxy'
-
-const server = await buildServer()
-const proxy = await buildProxy()
-
-const serverUrl = `http://localhost:${server.address().port}`
-const proxyUrl = `http://localhost:${proxy.address().port}`
-
-server.on('request', (req, res) => {
- console.log(req.url) // '/hello?foo=bar'
- res.setHeader('content-type', 'application/json')
- res.end(JSON.stringify({ hello: 'world' }))
-})
-
-const client = new Client(proxyUrl)
-
-const response = await client.request({
- method: 'GET',
- path: serverUrl + '/hello?foo=bar'
-})
-
-response.body.setEncoding('utf8')
-let data = ''
-for await (const chunk of response.body) {
- data += chunk
-}
-console.log(response.statusCode) // 200
-console.log(JSON.parse(data)) // { hello: 'world' }
-
-server.close()
-proxy.close()
-client.close()
-
-function buildServer () {
- return new Promise((resolve, reject) => {
- const server = createServer()
- server.listen(0, () => resolve(server))
- })
-}
-
-function buildProxy () {
- return new Promise((resolve, reject) => {
- const server = proxy(createServer())
- server.listen(0, () => resolve(server))
- })
-}
-```
-
-### Connect with authentication
-
-```js
-import { Client } from 'undici'
-import { createServer } from 'http'
-import proxy from 'proxy'
-
-const server = await buildServer()
-const proxy = await buildProxy()
-
-const serverUrl = `http://localhost:${server.address().port}`
-const proxyUrl = `http://localhost:${proxy.address().port}`
-
-proxy.authenticate = function (req, fn) {
- fn(null, req.headers['proxy-authorization'] === `Basic ${Buffer.from('user:pass').toString('base64')}`)
-}
-
-server.on('request', (req, res) => {
- console.log(req.url) // '/hello?foo=bar'
- res.setHeader('content-type', 'application/json')
- res.end(JSON.stringify({ hello: 'world' }))
-})
-
-const client = new Client(proxyUrl)
-
-const response = await client.request({
- method: 'GET',
- path: serverUrl + '/hello?foo=bar',
- headers: {
- 'proxy-authorization': `Basic ${Buffer.from('user:pass').toString('base64')}`
- }
-})
-
-response.body.setEncoding('utf8')
-let data = ''
-for await (const chunk of response.body) {
- data += chunk
-}
-console.log(response.statusCode) // 200
-console.log(JSON.parse(data)) // { hello: 'world' }
-
-server.close()
-proxy.close()
-client.close()
-
-function buildServer () {
- return new Promise((resolve, reject) => {
- const server = createServer()
- server.listen(0, () => resolve(server))
- })
-}
-
-function buildProxy () {
- return new Promise((resolve, reject) => {
- const server = proxy(createServer())
- server.listen(0, () => resolve(server))
- })
-}
-```
diff --git a/node_modules/undici/docs/best-practices/writing-tests.md b/node_modules/undici/docs/best-practices/writing-tests.md
deleted file mode 100644
index 57549de..0000000
--- a/node_modules/undici/docs/best-practices/writing-tests.md
+++ /dev/null
@@ -1,20 +0,0 @@
-# Writing tests
-
-Undici is tuned for a production use case and its default will keep
-a socket open for a few seconds after an HTTP request is completed to
-remove the overhead of opening up a new socket. These settings that makes
-Undici shine in production are not a good fit for using Undici in automated
-tests, as it will result in longer execution times.
-
-The following are good defaults that will keep the socket open for only 10ms:
-
-```js
-import { request, setGlobalDispatcher, Agent } from 'undici'
-
-const agent = new Agent({
- keepAliveTimeout: 10, // milliseconds
- keepAliveMaxTimeout: 10 // milliseconds
-})
-
-setGlobalDispatcher(agent)
-```
diff --git a/node_modules/undici/index-fetch.js b/node_modules/undici/index-fetch.js
deleted file mode 100644
index 2ee12fc..0000000
--- a/node_modules/undici/index-fetch.js
+++ /dev/null
@@ -1,13 +0,0 @@
-'use strict'
-
-const { getGlobalDispatcher } = require('./lib/global')
-const fetchImpl = require('./lib/fetch')
-
-module.exports.fetch = async function fetch (resource) {
- const dispatcher = (arguments[1] && arguments[1].dispatcher) || getGlobalDispatcher()
- return fetchImpl.apply(dispatcher, arguments)
-}
-module.exports.FormData = require('./lib/fetch/formdata').FormData
-module.exports.Headers = require('./lib/fetch/headers').Headers
-module.exports.Response = require('./lib/fetch/response').Response
-module.exports.Request = require('./lib/fetch/request').Request
diff --git a/node_modules/undici/index.d.ts b/node_modules/undici/index.d.ts
deleted file mode 100644
index e4aa8f6..0000000
--- a/node_modules/undici/index.d.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import Dispatcher = require('./types/dispatcher')
-import { setGlobalDispatcher, getGlobalDispatcher } from './types/global-dispatcher'
-import Pool = require('./types/pool')
-import BalancedPool = require('./types/balanced-pool')
-import Client = require('./types/client')
-import buildConnector = require('./types/connector')
-import errors = require('./types/errors')
-import Agent = require('./types/agent')
-import MockClient = require('./types/mock-client')
-import MockPool = require('./types/mock-pool')
-import MockAgent = require('./types/mock-agent')
-import mockErrors = require('./types/mock-errors')
-import ProxyAgent = require('./types/proxy-agent')
-import { request, pipeline, stream, connect, upgrade } from './types/api'
-
-export * from './types/fetch'
-export * from './types/file'
-export * from './types/formdata'
-export * from './types/diagnostics-channel'
-export { Interceptable } from './types/mock-interceptor'
-
-export { Dispatcher, BalancedPool, Pool, Client, buildConnector, errors, Agent, request, stream, pipeline, connect, upgrade, setGlobalDispatcher, getGlobalDispatcher, MockClient, MockPool, MockAgent, mockErrors, ProxyAgent }
-export default Undici
-
-declare function Undici(url: string, opts: Pool.Options): Pool
-
-declare namespace Undici {
- var Dispatcher: typeof import('./types/dispatcher')
- var Pool: typeof import('./types/pool');
- var BalancedPool: typeof import('./types/balanced-pool');
- var Client: typeof import('./types/client');
- var buildConnector: typeof import('./types/connector');
- var errors: typeof import('./types/errors');
- var Agent: typeof import('./types/agent');
- var setGlobalDispatcher: typeof import('./types/global-dispatcher').setGlobalDispatcher;
- var getGlobalDispatcher: typeof import('./types/global-dispatcher').getGlobalDispatcher;
- var request: typeof import('./types/api').request;
- var stream: typeof import('./types/api').stream;
- var pipeline: typeof import('./types/api').pipeline;
- var connect: typeof import('./types/api').connect;
- var upgrade: typeof import('./types/api').upgrade;
- var MockClient: typeof import('./types/mock-client');
- var MockPool: typeof import('./types/mock-pool');
- var MockAgent: typeof import('./types/mock-agent');
- var mockErrors: typeof import('./types/mock-errors');
- var fetch: typeof import('./types/fetch').fetch;
-}
diff --git a/node_modules/undici/index.js b/node_modules/undici/index.js
deleted file mode 100644
index 2248619..0000000
--- a/node_modules/undici/index.js
+++ /dev/null
@@ -1,108 +0,0 @@
-'use strict'
-
-const Client = require('./lib/client')
-const Dispatcher = require('./lib/dispatcher')
-const errors = require('./lib/core/errors')
-const Pool = require('./lib/pool')
-const BalancedPool = require('./lib/balanced-pool')
-const Agent = require('./lib/agent')
-const util = require('./lib/core/util')
-const { InvalidArgumentError } = errors
-const api = require('./lib/api')
-const buildConnector = require('./lib/core/connect')
-const MockClient = require('./lib/mock/mock-client')
-const MockAgent = require('./lib/mock/mock-agent')
-const MockPool = require('./lib/mock/mock-pool')
-const mockErrors = require('./lib/mock/mock-errors')
-const ProxyAgent = require('./lib/proxy-agent')
-const { getGlobalDispatcher, setGlobalDispatcher } = require('./lib/global')
-
-const nodeVersion = process.versions.node.split('.')
-const nodeMajor = Number(nodeVersion[0])
-const nodeMinor = Number(nodeVersion[1])
-
-Object.assign(Dispatcher.prototype, api)
-
-module.exports.Dispatcher = Dispatcher
-module.exports.Client = Client
-module.exports.Pool = Pool
-module.exports.BalancedPool = BalancedPool
-module.exports.Agent = Agent
-module.exports.ProxyAgent = ProxyAgent
-
-module.exports.buildConnector = buildConnector
-module.exports.errors = errors
-
-function makeDispatcher (fn) {
- return (url, opts, handler) => {
- if (typeof opts === 'function') {
- handler = opts
- opts = null
- }
-
- if (!url || (typeof url !== 'string' && typeof url !== 'object' && !(url instanceof URL))) {
- throw new InvalidArgumentError('invalid url')
- }
-
- if (opts != null && typeof opts !== 'object') {
- throw new InvalidArgumentError('invalid opts')
- }
-
- if (opts && opts.path != null) {
- if (typeof opts.path !== 'string') {
- throw new InvalidArgumentError('invalid opts.path')
- }
-
- url = new URL(opts.path, util.parseOrigin(url))
- } else {
- if (!opts) {
- opts = typeof url === 'object' ? url : {}
- }
-
- url = util.parseURL(url)
- }
-
- const { agent, dispatcher = getGlobalDispatcher() } = opts
-
- if (agent) {
- throw new InvalidArgumentError('unsupported opts.agent. Did you mean opts.client?')
- }
-
- return fn.call(dispatcher, {
- ...opts,
- origin: url.origin,
- path: url.search ? `${url.pathname}${url.search}` : url.pathname,
- method: opts.method || (opts.body ? 'PUT' : 'GET')
- }, handler)
- }
-}
-
-module.exports.setGlobalDispatcher = setGlobalDispatcher
-module.exports.getGlobalDispatcher = getGlobalDispatcher
-
-if (nodeMajor > 16 || (nodeMajor === 16 && nodeMinor >= 5)) {
- let fetchImpl = null
- module.exports.fetch = async function fetch (resource) {
- if (!fetchImpl) {
- fetchImpl = require('./lib/fetch')
- }
- const dispatcher = (arguments[1] && arguments[1].dispatcher) || getGlobalDispatcher()
- return fetchImpl.apply(dispatcher, arguments)
- }
- module.exports.Headers = require('./lib/fetch/headers').Headers
- module.exports.Response = require('./lib/fetch/response').Response
- module.exports.Request = require('./lib/fetch/request').Request
- module.exports.FormData = require('./lib/fetch/formdata').FormData
- module.exports.File = require('./lib/fetch/file').File
-}
-
-module.exports.request = makeDispatcher(api.request)
-module.exports.stream = makeDispatcher(api.stream)
-module.exports.pipeline = makeDispatcher(api.pipeline)
-module.exports.connect = makeDispatcher(api.connect)
-module.exports.upgrade = makeDispatcher(api.upgrade)
-
-module.exports.MockClient = MockClient
-module.exports.MockPool = MockPool
-module.exports.MockAgent = MockAgent
-module.exports.mockErrors = mockErrors
diff --git a/node_modules/undici/lib/agent.js b/node_modules/undici/lib/agent.js
deleted file mode 100644
index 47aa236..0000000
--- a/node_modules/undici/lib/agent.js
+++ /dev/null
@@ -1,147 +0,0 @@
-'use strict'
-
-const { InvalidArgumentError } = require('./core/errors')
-const { kClients, kRunning, kClose, kDestroy, kDispatch } = require('./core/symbols')
-const DispatcherBase = require('./dispatcher-base')
-const Pool = require('./pool')
-const Client = require('./client')
-const util = require('./core/util')
-const RedirectHandler = require('./handler/redirect')
-const { WeakRef, FinalizationRegistry } = require('./compat/dispatcher-weakref')()
-
-const kOnConnect = Symbol('onConnect')
-const kOnDisconnect = Symbol('onDisconnect')
-const kOnConnectionError = Symbol('onConnectionError')
-const kMaxRedirections = Symbol('maxRedirections')
-const kOnDrain = Symbol('onDrain')
-const kFactory = Symbol('factory')
-const kFinalizer = Symbol('finalizer')
-const kOptions = Symbol('options')
-
-function defaultFactory (origin, opts) {
- return opts && opts.connections === 1
- ? new Client(origin, opts)
- : new Pool(origin, opts)
-}
-
-class Agent extends DispatcherBase {
- constructor ({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) {
- super()
-
- if (typeof factory !== 'function') {
- throw new InvalidArgumentError('factory must be a function.')
- }
-
- if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') {
- throw new InvalidArgumentError('connect must be a function or an object')
- }
-
- if (!Number.isInteger(maxRedirections) || maxRedirections < 0) {
- throw new InvalidArgumentError('maxRedirections must be a positive number')
- }
-
- if (connect && typeof connect !== 'function') {
- connect = { ...connect }
- }
-
- this[kOptions] = { ...util.deepClone(options), connect }
- this[kMaxRedirections] = maxRedirections
- this[kFactory] = factory
- this[kClients] = new Map()
- this[kFinalizer] = new FinalizationRegistry(/* istanbul ignore next: gc is undeterministic */ key => {
- const ref = this[kClients].get(key)
- if (ref !== undefined && ref.deref() === undefined) {
- this[kClients].delete(key)
- }
- })
-
- const agent = this
-
- this[kOnDrain] = (origin, targets) => {
- agent.emit('drain', origin, [agent, ...targets])
- }
-
- this[kOnConnect] = (origin, targets) => {
- agent.emit('connect', origin, [agent, ...targets])
- }
-
- this[kOnDisconnect] = (origin, targets, err) => {
- agent.emit('disconnect', origin, [agent, ...targets], err)
- }
-
- this[kOnConnectionError] = (origin, targets, err) => {
- agent.emit('connectionError', origin, [agent, ...targets], err)
- }
- }
-
- get [kRunning] () {
- let ret = 0
- for (const ref of this[kClients].values()) {
- const client = ref.deref()
- /* istanbul ignore next: gc is undeterministic */
- if (client) {
- ret += client[kRunning]
- }
- }
- return ret
- }
-
- [kDispatch] (opts, handler) {
- let key
- if (opts.origin && (typeof opts.origin === 'string' || opts.origin instanceof URL)) {
- key = String(opts.origin)
- } else {
- throw new InvalidArgumentError('opts.origin must be a non-empty string or URL.')
- }
-
- const ref = this[kClients].get(key)
-
- let dispatcher = ref ? ref.deref() : null
- if (!dispatcher) {
- dispatcher = this[kFactory](opts.origin, this[kOptions])
- .on('drain', this[kOnDrain])
- .on('connect', this[kOnConnect])
- .on('disconnect', this[kOnDisconnect])
- .on('connectionError', this[kOnConnectionError])
-
- this[kClients].set(key, new WeakRef(dispatcher))
- this[kFinalizer].register(dispatcher, key)
- }
-
- const { maxRedirections = this[kMaxRedirections] } = opts
- if (maxRedirections != null && maxRedirections !== 0) {
- opts = { ...opts, maxRedirections: 0 } // Stop sub dispatcher from also redirecting.
- handler = new RedirectHandler(this, maxRedirections, opts, handler)
- }
-
- return dispatcher.dispatch(opts, handler)
- }
-
- async [kClose] () {
- const closePromises = []
- for (const ref of this[kClients].values()) {
- const client = ref.deref()
- /* istanbul ignore else: gc is undeterministic */
- if (client) {
- closePromises.push(client.close())
- }
- }
-
- await Promise.all(closePromises)
- }
-
- async [kDestroy] (err) {
- const destroyPromises = []
- for (const ref of this[kClients].values()) {
- const client = ref.deref()
- /* istanbul ignore else: gc is undeterministic */
- if (client) {
- destroyPromises.push(client.destroy(err))
- }
- }
-
- await Promise.all(destroyPromises)
- }
-}
-
-module.exports = Agent
diff --git a/node_modules/undici/lib/api/abort-signal.js b/node_modules/undici/lib/api/abort-signal.js
deleted file mode 100644
index 895629a..0000000
--- a/node_modules/undici/lib/api/abort-signal.js
+++ /dev/null
@@ -1,57 +0,0 @@
-const { RequestAbortedError } = require('../core/errors')
-
-const kListener = Symbol('kListener')
-const kSignal = Symbol('kSignal')
-
-function abort (self) {
- if (self.abort) {
- self.abort()
- } else {
- self.onError(new RequestAbortedError())
- }
-}
-
-function addSignal (self, signal) {
- self[kSignal] = null
- self[kListener] = null
-
- if (!signal) {
- return
- }
-
- if (signal.aborted) {
- abort(self)
- return
- }
-
- self[kSignal] = signal
- self[kListener] = () => {
- abort(self)
- }
-
- if ('addEventListener' in self[kSignal]) {
- self[kSignal].addEventListener('abort', self[kListener])
- } else {
- self[kSignal].addListener('abort', self[kListener])
- }
-}
-
-function removeSignal (self) {
- if (!self[kSignal]) {
- return
- }
-
- if ('removeEventListener' in self[kSignal]) {
- self[kSignal].removeEventListener('abort', self[kListener])
- } else {
- self[kSignal].removeListener('abort', self[kListener])
- }
-
- self[kSignal] = null
- self[kListener] = null
-}
-
-module.exports = {
- addSignal,
- removeSignal
-}
diff --git a/node_modules/undici/lib/api/api-connect.js b/node_modules/undici/lib/api/api-connect.js
deleted file mode 100644
index 0503b1a..0000000
--- a/node_modules/undici/lib/api/api-connect.js
+++ /dev/null
@@ -1,98 +0,0 @@
-'use strict'
-
-const { InvalidArgumentError, RequestAbortedError, SocketError } = require('../core/errors')
-const { AsyncResource } = require('async_hooks')
-const util = require('../core/util')
-const { addSignal, removeSignal } = require('./abort-signal')
-
-class ConnectHandler extends AsyncResource {
- constructor (opts, callback) {
- if (!opts || typeof opts !== 'object') {
- throw new InvalidArgumentError('invalid opts')
- }
-
- if (typeof callback !== 'function') {
- throw new InvalidArgumentError('invalid callback')
- }
-
- const { signal, opaque, responseHeaders } = opts
-
- if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') {
- throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget')
- }
-
- super('UNDICI_CONNECT')
-
- this.opaque = opaque || null
- this.responseHeaders = responseHeaders || null
- this.callback = callback
- this.abort = null
-
- addSignal(this, signal)
- }
-
- onConnect (abort, context) {
- if (!this.callback) {
- throw new RequestAbortedError()
- }
-
- this.abort = abort
- this.context = context
- }
-
- onHeaders () {
- throw new SocketError('bad connect', null)
- }
-
- onUpgrade (statusCode, rawHeaders, socket) {
- const { callback, opaque, context } = this
-
- removeSignal(this)
-
- this.callback = null
- const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders)
- this.runInAsyncScope(callback, null, null, {
- statusCode,
- headers,
- socket,
- opaque,
- context
- })
- }
-
- onError (err) {
- const { callback, opaque } = this
-
- removeSignal(this)
-
- if (callback) {
- this.callback = null
- queueMicrotask(() => {
- this.runInAsyncScope(callback, null, err, { opaque })
- })
- }
- }
-}
-
-function connect (opts, callback) {
- if (callback === undefined) {
- return new Promise((resolve, reject) => {
- connect.call(this, opts, (err, data) => {
- return err ? reject(err) : resolve(data)
- })
- })
- }
-
- try {
- const connectHandler = new ConnectHandler(opts, callback)
- this.dispatch({ ...opts, method: 'CONNECT' }, connectHandler)
- } catch (err) {
- if (typeof callback !== 'function') {
- throw err
- }
- const opaque = opts && opts.opaque
- queueMicrotask(() => callback(err, { opaque }))
- }
-}
-
-module.exports = connect
diff --git a/node_modules/undici/lib/api/api-pipeline.js b/node_modules/undici/lib/api/api-pipeline.js
deleted file mode 100644
index af4a180..0000000
--- a/node_modules/undici/lib/api/api-pipeline.js
+++ /dev/null
@@ -1,249 +0,0 @@
-'use strict'
-
-const {
- Readable,
- Duplex,
- PassThrough
-} = require('stream')
-const {
- InvalidArgumentError,
- InvalidReturnValueError,
- RequestAbortedError
-} = require('../core/errors')
-const util = require('../core/util')
-const { AsyncResource } = require('async_hooks')
-const { addSignal, removeSignal } = require('./abort-signal')
-const assert = require('assert')
-
-const kResume = Symbol('resume')
-
-class PipelineRequest extends Readable {
- constructor () {
- super({ autoDestroy: true })
-
- this[kResume] = null
- }
-
- _read () {
- const { [kResume]: resume } = this
-
- if (resume) {
- this[kResume] = null
- resume()
- }
- }
-
- _destroy (err, callback) {
- this._read()
-
- callback(err)
- }
-}
-
-class PipelineResponse extends Readable {
- constructor (resume) {
- super({ autoDestroy: true })
- this[kResume] = resume
- }
-
- _read () {
- this[kResume]()
- }
-
- _destroy (err, callback) {
- if (!err && !this._readableState.endEmitted) {
- err = new RequestAbortedError()
- }
-
- callback(err)
- }
-}
-
-class PipelineHandler extends AsyncResource {
- constructor (opts, handler) {
- if (!opts || typeof opts !== 'object') {
- throw new InvalidArgumentError('invalid opts')
- }
-
- if (typeof handler !== 'function') {
- throw new InvalidArgumentError('invalid handler')
- }
-
- const { signal, method, opaque, onInfo, responseHeaders } = opts
-
- if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') {
- throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget')
- }
-
- if (method === 'CONNECT') {
- throw new InvalidArgumentError('invalid method')
- }
-
- if (onInfo && typeof onInfo !== 'function') {
- throw new InvalidArgumentError('invalid onInfo callback')
- }
-
- super('UNDICI_PIPELINE')
-
- this.opaque = opaque || null
- this.responseHeaders = responseHeaders || null
- this.handler = handler
- this.abort = null
- this.context = null
- this.onInfo = onInfo || null
-
- this.req = new PipelineRequest().on('error', util.nop)
-
- this.ret = new Duplex({
- readableObjectMode: opts.objectMode,
- autoDestroy: true,
- read: () => {
- const { body } = this
-
- if (body && body.resume) {
- body.resume()
- }
- },
- write: (chunk, encoding, callback) => {
- const { req } = this
-
- if (req.push(chunk, encoding) || req._readableState.destroyed) {
- callback()
- } else {
- req[kResume] = callback
- }
- },
- destroy: (err, callback) => {
- const { body, req, res, ret, abort } = this
-
- if (!err && !ret._readableState.endEmitted) {
- err = new RequestAbortedError()
- }
-
- if (abort && err) {
- abort()
- }
-
- util.destroy(body, err)
- util.destroy(req, err)
- util.destroy(res, err)
-
- removeSignal(this)
-
- callback(err)
- }
- }).on('prefinish', () => {
- const { req } = this
-
- // Node < 15 does not call _final in same tick.
- req.push(null)
- })
-
- this.res = null
-
- addSignal(this, signal)
- }
-
- onConnect (abort, context) {
- const { ret, res } = this
-
- assert(!res, 'pipeline cannot be retried')
-
- if (ret.destroyed) {
- throw new RequestAbortedError()
- }
-
- this.abort = abort
- this.context = context
- }
-
- onHeaders (statusCode, rawHeaders, resume) {
- const { opaque, handler, context } = this
-
- if (statusCode < 200) {
- if (this.onInfo) {
- const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders)
- this.onInfo({ statusCode, headers })
- }
- return
- }
-
- this.res = new PipelineResponse(resume)
-
- let body
- try {
- this.handler = null
- const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders)
- body = this.runInAsyncScope(handler, null, {
- statusCode,
- headers,
- opaque,
- body: this.res,
- context
- })
- } catch (err) {
- this.res.on('error', util.nop)
- throw err
- }
-
- if (!body || typeof body.on !== 'function') {
- throw new InvalidReturnValueError('expected Readable')
- }
-
- body
- .on('data', (chunk) => {
- const { ret, body } = this
-
- if (!ret.push(chunk) && body.pause) {
- body.pause()
- }
- })
- .on('error', (err) => {
- const { ret } = this
-
- util.destroy(ret, err)
- })
- .on('end', () => {
- const { ret } = this
-
- ret.push(null)
- })
- .on('close', () => {
- const { ret } = this
-
- if (!ret._readableState.ended) {
- util.destroy(ret, new RequestAbortedError())
- }
- })
-
- this.body = body
- }
-
- onData (chunk) {
- const { res } = this
- return res.push(chunk)
- }
-
- onComplete (trailers) {
- const { res } = this
- res.push(null)
- }
-
- onError (err) {
- const { ret } = this
- this.handler = null
- util.destroy(ret, err)
- }
-}
-
-function pipeline (opts, handler) {
- try {
- const pipelineHandler = new PipelineHandler(opts, handler)
- this.dispatch({ ...opts, body: pipelineHandler.req }, pipelineHandler)
- return pipelineHandler.ret
- } catch (err) {
- return new PassThrough().destroy(err)
- }
-}
-
-module.exports = pipeline
diff --git a/node_modules/undici/lib/api/api-request.js b/node_modules/undici/lib/api/api-request.js
deleted file mode 100644
index b467487..0000000
--- a/node_modules/undici/lib/api/api-request.js
+++ /dev/null
@@ -1,203 +0,0 @@
-'use strict'
-
-const Readable = require('./readable')
-const {
- InvalidArgumentError,
- RequestAbortedError,
- ResponseStatusCodeError
-} = require('../core/errors')
-const util = require('../core/util')
-const { AsyncResource } = require('async_hooks')
-const { addSignal, removeSignal } = require('./abort-signal')
-
-class RequestHandler extends AsyncResource {
- constructor (opts, callback) {
- if (!opts || typeof opts !== 'object') {
- throw new InvalidArgumentError('invalid opts')
- }
-
- const { signal, method, opaque, body, onInfo, responseHeaders, throwOnError } = opts
-
- try {
- if (typeof callback !== 'function') {
- throw new InvalidArgumentError('invalid callback')
- }
-
- if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') {
- throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget')
- }
-
- if (method === 'CONNECT') {
- throw new InvalidArgumentError('invalid method')
- }
-
- if (onInfo && typeof onInfo !== 'function') {
- throw new InvalidArgumentError('invalid onInfo callback')
- }
-
- super('UNDICI_REQUEST')
- } catch (err) {
- if (util.isStream(body)) {
- util.destroy(body.on('error', util.nop), err)
- }
- throw err
- }
-
- this.responseHeaders = responseHeaders || null
- this.opaque = opaque || null
- this.callback = callback
- this.res = null
- this.abort = null
- this.body = body
- this.trailers = {}
- this.context = null
- this.onInfo = onInfo || null
- this.throwOnError = throwOnError
-
- if (util.isStream(body)) {
- body.on('error', (err) => {
- this.onError(err)
- })
- }
-
- addSignal(this, signal)
- }
-
- onConnect (abort, context) {
- if (!this.callback) {
- throw new RequestAbortedError()
- }
-
- this.abort = abort
- this.context = context
- }
-
- onHeaders (statusCode, rawHeaders, resume, statusMessage) {
- const { callback, opaque, abort, context } = this
-
- if (statusCode < 200) {
- if (this.onInfo) {
- const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders)
- this.onInfo({ statusCode, headers })
- }
- return
- }
-
- const parsedHeaders = util.parseHeaders(rawHeaders)
- const contentType = parsedHeaders['content-type']
- const body = new Readable(resume, abort, contentType)
-
- this.callback = null
- this.res = body
- const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders)
-
- if (callback !== null) {
- if (this.throwOnError && statusCode >= 400) {
- this.runInAsyncScope(getResolveErrorBodyCallback, null,
- { callback, body, contentType, statusCode, statusMessage, headers }
- )
- return
- }
-
- this.runInAsyncScope(callback, null, null, {
- statusCode,
- headers,
- trailers: this.trailers,
- opaque,
- body,
- context
- })
- }
- }
-
- onData (chunk) {
- const { res } = this
- return res.push(chunk)
- }
-
- onComplete (trailers) {
- const { res } = this
-
- removeSignal(this)
-
- util.parseHeaders(trailers, this.trailers)
-
- res.push(null)
- }
-
- onError (err) {
- const { res, callback, body, opaque } = this
-
- removeSignal(this)
-
- if (callback) {
- // TODO: Does this need queueMicrotask?
- this.callback = null
- queueMicrotask(() => {
- this.runInAsyncScope(callback, null, err, { opaque })
- })
- }
-
- if (res) {
- this.res = null
- // Ensure all queued handlers are invoked before destroying res.
- queueMicrotask(() => {
- util.destroy(res, err)
- })
- }
-
- if (body) {
- this.body = null
- util.destroy(body, err)
- }
- }
-}
-
-async function getResolveErrorBodyCallback ({ callback, body, contentType, statusCode, statusMessage, headers }) {
- if (statusCode === 204 || !contentType) {
- body.dump()
- process.nextTick(callback, new ResponseStatusCodeError(`Response status code ${statusCode}${statusMessage ? `: ${statusMessage}` : ''}`, statusCode, headers))
- return
- }
-
- try {
- if (contentType.startsWith('application/json')) {
- const payload = await body.json()
- process.nextTick(callback, new ResponseStatusCodeError(`Response status code ${statusCode}${statusMessage ? `: ${statusMessage}` : ''}`, statusCode, headers, payload))
- return
- }
-
- if (contentType.startsWith('text/')) {
- const payload = await body.text()
- process.nextTick(callback, new ResponseStatusCodeError(`Response status code ${statusCode}${statusMessage ? `: ${statusMessage}` : ''}`, statusCode, headers, payload))
- return
- }
- } catch (err) {
- // Process in a fallback if error
- }
-
- body.dump()
- process.nextTick(callback, new ResponseStatusCodeError(`Response status code ${statusCode}${statusMessage ? `: ${statusMessage}` : ''}`, statusCode, headers))
-}
-
-function request (opts, callback) {
- if (callback === undefined) {
- return new Promise((resolve, reject) => {
- request.call(this, opts, (err, data) => {
- return err ? reject(err) : resolve(data)
- })
- })
- }
-
- try {
- this.dispatch(opts, new RequestHandler(opts, callback))
- } catch (err) {
- if (typeof callback !== 'function') {
- throw err
- }
- const opaque = opts && opts.opaque
- queueMicrotask(() => callback(err, { opaque }))
- }
-}
-
-module.exports = request
diff --git a/node_modules/undici/lib/api/api-stream.js b/node_modules/undici/lib/api/api-stream.js
deleted file mode 100644
index 020fd08..0000000
--- a/node_modules/undici/lib/api/api-stream.js
+++ /dev/null
@@ -1,195 +0,0 @@
-'use strict'
-
-const { finished } = require('stream')
-const {
- InvalidArgumentError,
- InvalidReturnValueError,
- RequestAbortedError
-} = require('../core/errors')
-const util = require('../core/util')
-const { AsyncResource } = require('async_hooks')
-const { addSignal, removeSignal } = require('./abort-signal')
-
-class StreamHandler extends AsyncResource {
- constructor (opts, factory, callback) {
- if (!opts || typeof opts !== 'object') {
- throw new InvalidArgumentError('invalid opts')
- }
-
- const { signal, method, opaque, body, onInfo, responseHeaders } = opts
-
- try {
- if (typeof callback !== 'function') {
- throw new InvalidArgumentError('invalid callback')
- }
-
- if (typeof factory !== 'function') {
- throw new InvalidArgumentError('invalid factory')
- }
-
- if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') {
- throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget')
- }
-
- if (method === 'CONNECT') {
- throw new InvalidArgumentError('invalid method')
- }
-
- if (onInfo && typeof onInfo !== 'function') {
- throw new InvalidArgumentError('invalid onInfo callback')
- }
-
- super('UNDICI_STREAM')
- } catch (err) {
- if (util.isStream(body)) {
- util.destroy(body.on('error', util.nop), err)
- }
- throw err
- }
-
- this.responseHeaders = responseHeaders || null
- this.opaque = opaque || null
- this.factory = factory
- this.callback = callback
- this.res = null
- this.abort = null
- this.context = null
- this.trailers = null
- this.body = body
- this.onInfo = onInfo || null
-
- if (util.isStream(body)) {
- body.on('error', (err) => {
- this.onError(err)
- })
- }
-
- addSignal(this, signal)
- }
-
- onConnect (abort, context) {
- if (!this.callback) {
- throw new RequestAbortedError()
- }
-
- this.abort = abort
- this.context = context
- }
-
- onHeaders (statusCode, rawHeaders, resume) {
- const { factory, opaque, context } = this
-
- if (statusCode < 200) {
- if (this.onInfo) {
- const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders)
- this.onInfo({ statusCode, headers })
- }
- return
- }
-
- this.factory = null
- const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders)
- const res = this.runInAsyncScope(factory, null, {
- statusCode,
- headers,
- opaque,
- context
- })
-
- if (
- !res ||
- typeof res.write !== 'function' ||
- typeof res.end !== 'function' ||
- typeof res.on !== 'function'
- ) {
- throw new InvalidReturnValueError('expected Writable')
- }
-
- res.on('drain', resume)
- // TODO: Avoid finished. It registers an unecessary amount of listeners.
- finished(res, { readable: false }, (err) => {
- const { callback, res, opaque, trailers, abort } = this
-
- this.res = null
- if (err || !res.readable) {
- util.destroy(res, err)
- }
-
- this.callback = null
- this.runInAsyncScope(callback, null, err || null, { opaque, trailers })
-
- if (err) {
- abort()
- }
- })
-
- this.res = res
-
- const needDrain = res.writableNeedDrain !== undefined
- ? res.writableNeedDrain
- : res._writableState && res._writableState.needDrain
-
- return needDrain !== true
- }
-
- onData (chunk) {
- const { res } = this
-
- return res.write(chunk)
- }
-
- onComplete (trailers) {
- const { res } = this
-
- removeSignal(this)
-
- this.trailers = util.parseHeaders(trailers)
-
- res.end()
- }
-
- onError (err) {
- const { res, callback, opaque, body } = this
-
- removeSignal(this)
-
- this.factory = null
-
- if (res) {
- this.res = null
- util.destroy(res, err)
- } else if (callback) {
- this.callback = null
- queueMicrotask(() => {
- this.runInAsyncScope(callback, null, err, { opaque })
- })
- }
-
- if (body) {
- this.body = null
- util.destroy(body, err)
- }
- }
-}
-
-function stream (opts, factory, callback) {
- if (callback === undefined) {
- return new Promise((resolve, reject) => {
- stream.call(this, opts, factory, (err, data) => {
- return err ? reject(err) : resolve(data)
- })
- })
- }
-
- try {
- this.dispatch(opts, new StreamHandler(opts, factory, callback))
- } catch (err) {
- if (typeof callback !== 'function') {
- throw err
- }
- const opaque = opts && opts.opaque
- queueMicrotask(() => callback(err, { opaque }))
- }
-}
-
-module.exports = stream
diff --git a/node_modules/undici/lib/api/api-upgrade.js b/node_modules/undici/lib/api/api-upgrade.js
deleted file mode 100644
index ef783e8..0000000
--- a/node_modules/undici/lib/api/api-upgrade.js
+++ /dev/null
@@ -1,105 +0,0 @@
-'use strict'
-
-const { InvalidArgumentError, RequestAbortedError, SocketError } = require('../core/errors')
-const { AsyncResource } = require('async_hooks')
-const util = require('../core/util')
-const { addSignal, removeSignal } = require('./abort-signal')
-const assert = require('assert')
-
-class UpgradeHandler extends AsyncResource {
- constructor (opts, callback) {
- if (!opts || typeof opts !== 'object') {
- throw new InvalidArgumentError('invalid opts')
- }
-
- if (typeof callback !== 'function') {
- throw new InvalidArgumentError('invalid callback')
- }
-
- const { signal, opaque, responseHeaders } = opts
-
- if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') {
- throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget')
- }
-
- super('UNDICI_UPGRADE')
-
- this.responseHeaders = responseHeaders || null
- this.opaque = opaque || null
- this.callback = callback
- this.abort = null
- this.context = null
-
- addSignal(this, signal)
- }
-
- onConnect (abort, context) {
- if (!this.callback) {
- throw new RequestAbortedError()
- }
-
- this.abort = abort
- this.context = null
- }
-
- onHeaders () {
- throw new SocketError('bad upgrade', null)
- }
-
- onUpgrade (statusCode, rawHeaders, socket) {
- const { callback, opaque, context } = this
-
- assert.strictEqual(statusCode, 101)
-
- removeSignal(this)
-
- this.callback = null
- const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders)
- this.runInAsyncScope(callback, null, null, {
- headers,
- socket,
- opaque,
- context
- })
- }
-
- onError (err) {
- const { callback, opaque } = this
-
- removeSignal(this)
-
- if (callback) {
- this.callback = null
- queueMicrotask(() => {
- this.runInAsyncScope(callback, null, err, { opaque })
- })
- }
- }
-}
-
-function upgrade (opts, callback) {
- if (callback === undefined) {
- return new Promise((resolve, reject) => {
- upgrade.call(this, opts, (err, data) => {
- return err ? reject(err) : resolve(data)
- })
- })
- }
-
- try {
- const upgradeHandler = new UpgradeHandler(opts, callback)
- this.dispatch({
- ...opts,
- method: opts.method || 'GET',
- upgrade: opts.protocol || 'Websocket'
- }, upgradeHandler)
- } catch (err) {
- if (typeof callback !== 'function') {
- throw err
- }
- const opaque = opts && opts.opaque
- queueMicrotask(() => callback(err, { opaque }))
- }
-}
-
-module.exports = upgrade
diff --git a/node_modules/undici/lib/api/index.js b/node_modules/undici/lib/api/index.js
deleted file mode 100644
index 8983a5e..0000000
--- a/node_modules/undici/lib/api/index.js
+++ /dev/null
@@ -1,7 +0,0 @@
-'use strict'
-
-module.exports.request = require('./api-request')
-module.exports.stream = require('./api-stream')
-module.exports.pipeline = require('./api-pipeline')
-module.exports.upgrade = require('./api-upgrade')
-module.exports.connect = require('./api-connect')
diff --git a/node_modules/undici/lib/api/readable.js b/node_modules/undici/lib/api/readable.js
deleted file mode 100644
index 4184a86..0000000
--- a/node_modules/undici/lib/api/readable.js
+++ /dev/null
@@ -1,283 +0,0 @@
-// Ported from https://github.com/nodejs/undici/pull/907
-
-'use strict'
-
-const assert = require('assert')
-const { Readable } = require('stream')
-const { RequestAbortedError, NotSupportedError } = require('../core/errors')
-const util = require('../core/util')
-const { ReadableStreamFrom, toUSVString } = require('../core/util')
-
-let Blob
-
-const kConsume = Symbol('kConsume')
-const kReading = Symbol('kReading')
-const kBody = Symbol('kBody')
-const kAbort = Symbol('abort')
-const kContentType = Symbol('kContentType')
-
-module.exports = class BodyReadable extends Readable {
- constructor (resume, abort, contentType = '') {
- super({
- autoDestroy: true,
- read: resume,
- highWaterMark: 64 * 1024 // Same as nodejs fs streams.
- })
-
- this._readableState.dataEmitted = false
-
- this[kAbort] = abort
- this[kConsume] = null
- this[kBody] = null
- this[kContentType] = contentType
-
- // Is stream being consumed through Readable API?
- // This is an optimization so that we avoid checking
- // for 'data' and 'readable' listeners in the hot path
- // inside push().
- this[kReading] = false
- }
-
- destroy (err) {
- if (this.destroyed) {
- // Node < 16
- return this
- }
-
- if (!err && !this._readableState.endEmitted) {
- err = new RequestAbortedError()
- }
-
- if (err) {
- this[kAbort]()
- }
-
- return super.destroy(err)
- }
-
- emit (ev, ...args) {
- if (ev === 'data') {
- // Node < 16.7
- this._readableState.dataEmitted = true
- } else if (ev === 'error') {
- // Node < 16
- this._readableState.errorEmitted = true
- }
- return super.emit(ev, ...args)
- }
-
- on (ev, ...args) {
- if (ev === 'data' || ev === 'readable') {
- this[kReading] = true
- }
- return super.on(ev, ...args)
- }
-
- addListener (ev, ...args) {
- return this.on(ev, ...args)
- }
-
- off (ev, ...args) {
- const ret = super.off(ev, ...args)
- if (ev === 'data' || ev === 'readable') {
- this[kReading] = (
- this.listenerCount('data') > 0 ||
- this.listenerCount('readable') > 0
- )
- }
- return ret
- }
-
- removeListener (ev, ...args) {
- return this.off(ev, ...args)
- }
-
- push (chunk) {
- if (this[kConsume] && chunk !== null) {
- consumePush(this[kConsume], chunk)
- return this[kReading] ? super.push(chunk) : true
- }
- return super.push(chunk)
- }
-
- // https://fetch.spec.whatwg.org/#dom-body-text
- async text () {
- return consume(this, 'text')
- }
-
- // https://fetch.spec.whatwg.org/#dom-body-json
- async json () {
- return consume(this, 'json')
- }
-
- // https://fetch.spec.whatwg.org/#dom-body-blob
- async blob () {
- return consume(this, 'blob')
- }
-
- // https://fetch.spec.whatwg.org/#dom-body-arraybuffer
- async arrayBuffer () {
- return consume(this, 'arrayBuffer')
- }
-
- // https://fetch.spec.whatwg.org/#dom-body-formdata
- async formData () {
- // TODO: Implement.
- throw new NotSupportedError()
- }
-
- // https://fetch.spec.whatwg.org/#dom-body-bodyused
- get bodyUsed () {
- return util.isDisturbed(this)
- }
-
- // https://fetch.spec.whatwg.org/#dom-body-body
- get body () {
- if (!this[kBody]) {
- this[kBody] = ReadableStreamFrom(this)
- if (this[kConsume]) {
- // TODO: Is this the best way to force a lock?
- this[kBody].getReader() // Ensure stream is locked.
- assert(this[kBody].locked)
- }
- }
- return this[kBody]
- }
-
- async dump (opts) {
- let limit = opts && Number.isFinite(opts.limit) ? opts.limit : 262144
- try {
- for await (const chunk of this) {
- limit -= Buffer.byteLength(chunk)
- if (limit < 0) {
- return
- }
- }
- } catch {
- // Do nothing...
- }
- }
-}
-
-// https://streams.spec.whatwg.org/#readablestream-locked
-function isLocked (self) {
- // Consume is an implicit lock.
- return (self[kBody] && self[kBody].locked === true) || self[kConsume]
-}
-
-// https://fetch.spec.whatwg.org/#body-unusable
-function isUnusable (self) {
- return util.isDisturbed(self) || isLocked(self)
-}
-
-async function consume (stream, type) {
- if (isUnusable(stream)) {
- throw new TypeError('unusable')
- }
-
- assert(!stream[kConsume])
-
- return new Promise((resolve, reject) => {
- stream[kConsume] = {
- type,
- stream,
- resolve,
- reject,
- length: 0,
- body: []
- }
-
- stream
- .on('error', function (err) {
- consumeFinish(this[kConsume], err)
- })
- .on('close', function () {
- if (this[kConsume].body !== null) {
- consumeFinish(this[kConsume], new RequestAbortedError())
- }
- })
-
- process.nextTick(consumeStart, stream[kConsume])
- })
-}
-
-function consumeStart (consume) {
- if (consume.body === null) {
- return
- }
-
- const { _readableState: state } = consume.stream
-
- for (const chunk of state.buffer) {
- consumePush(consume, chunk)
- }
-
- if (state.endEmitted) {
- consumeEnd(this[kConsume])
- } else {
- consume.stream.on('end', function () {
- consumeEnd(this[kConsume])
- })
- }
-
- consume.stream.resume()
-
- while (consume.stream.read() != null) {
- // Loop
- }
-}
-
-function consumeEnd (consume) {
- const { type, body, resolve, stream, length } = consume
-
- try {
- if (type === 'text') {
- resolve(toUSVString(Buffer.concat(body)))
- } else if (type === 'json') {
- resolve(JSON.parse(Buffer.concat(body)))
- } else if (type === 'arrayBuffer') {
- const dst = new Uint8Array(length)
-
- let pos = 0
- for (const buf of body) {
- dst.set(buf, pos)
- pos += buf.byteLength
- }
-
- resolve(dst)
- } else if (type === 'blob') {
- if (!Blob) {
- Blob = require('buffer').Blob
- }
- resolve(new Blob(body, { type: stream[kContentType] }))
- }
-
- consumeFinish(consume)
- } catch (err) {
- stream.destroy(err)
- }
-}
-
-function consumePush (consume, chunk) {
- consume.length += chunk.length
- consume.body.push(chunk)
-}
-
-function consumeFinish (consume, err) {
- if (consume.body === null) {
- return
- }
-
- if (err) {
- consume.reject(err)
- } else {
- consume.resolve()
- }
-
- consume.type = null
- consume.stream = null
- consume.resolve = null
- consume.reject = null
- consume.length = 0
- consume.body = null
-}
diff --git a/node_modules/undici/lib/balanced-pool.js b/node_modules/undici/lib/balanced-pool.js
deleted file mode 100644
index bb5788a..0000000
--- a/node_modules/undici/lib/balanced-pool.js
+++ /dev/null
@@ -1,110 +0,0 @@
-'use strict'
-
-const {
- BalancedPoolMissingUpstreamError,
- InvalidArgumentError
-} = require('./core/errors')
-const {
- PoolBase,
- kClients,
- kNeedDrain,
- kAddClient,
- kRemoveClient,
- kGetDispatcher
-} = require('./pool-base')
-const Pool = require('./pool')
-const { kUrl } = require('./core/symbols')
-const { parseOrigin } = require('./core/util')
-const kFactory = Symbol('factory')
-
-const kOptions = Symbol('options')
-
-function defaultFactory (origin, opts) {
- return new Pool(origin, opts)
-}
-
-class BalancedPool extends PoolBase {
- constructor (upstreams = [], { factory = defaultFactory, ...opts } = {}) {
- super()
-
- this[kOptions] = opts
-
- if (!Array.isArray(upstreams)) {
- upstreams = [upstreams]
- }
-
- if (typeof factory !== 'function') {
- throw new InvalidArgumentError('factory must be a function.')
- }
-
- this[kFactory] = factory
-
- for (const upstream of upstreams) {
- this.addUpstream(upstream)
- }
- }
-
- addUpstream (upstream) {
- const upstreamOrigin = parseOrigin(upstream).origin
-
- if (this[kClients].find((pool) => (
- pool[kUrl].origin === upstreamOrigin &&
- pool.closed !== true &&
- pool.destroyed !== true
- ))) {
- return this
- }
-
- this[kAddClient](this[kFactory](upstreamOrigin, Object.assign({}, this[kOptions])))
-
- return this
- }
-
- removeUpstream (upstream) {
- const upstreamOrigin = parseOrigin(upstream).origin
-
- const pool = this[kClients].find((pool) => (
- pool[kUrl].origin === upstreamOrigin &&
- pool.closed !== true &&
- pool.destroyed !== true
- ))
-
- if (pool) {
- this[kRemoveClient](pool)
- }
-
- return this
- }
-
- get upstreams () {
- return this[kClients]
- .filter(dispatcher => dispatcher.closed !== true && dispatcher.destroyed !== true)
- .map((p) => p[kUrl].origin)
- }
-
- [kGetDispatcher] () {
- // We validate that pools is greater than 0,
- // otherwise we would have to wait until an upstream
- // is added, which might never happen.
- if (this[kClients].length === 0) {
- throw new BalancedPoolMissingUpstreamError()
- }
-
- const dispatcher = this[kClients].find(dispatcher => (
- !dispatcher[kNeedDrain] &&
- dispatcher.closed !== true &&
- dispatcher.destroyed !== true
- ))
-
- if (!dispatcher) {
- return
- }
-
- this[kClients].splice(this[kClients].indexOf(dispatcher), 1)
- this[kClients].push(dispatcher)
-
- return dispatcher
- }
-}
-
-module.exports = BalancedPool
diff --git a/node_modules/undici/lib/client.js b/node_modules/undici/lib/client.js
deleted file mode 100644
index fb0b985..0000000
--- a/node_modules/undici/lib/client.js
+++ /dev/null
@@ -1,1716 +0,0 @@
-'use strict'
-
-/* global WebAssembly */
-
-const assert = require('assert')
-const net = require('net')
-const util = require('./core/util')
-const Request = require('./core/request')
-const DispatcherBase = require('./dispatcher-base')
-const RedirectHandler = require('./handler/redirect')
-const {
- RequestContentLengthMismatchError,
- ResponseContentLengthMismatchError,
- InvalidArgumentError,
- RequestAbortedError,
- HeadersTimeoutError,
- HeadersOverflowError,
- SocketError,
- InformationalError,
- BodyTimeoutError,
- HTTPParserError
-} = require('./core/errors')
-const buildConnector = require('./core/connect')
-const {
- kUrl,
- kReset,
- kServerName,
- kClient,
- kBusy,
- kParser,
- kConnect,
- kBlocking,
- kResuming,
- kRunning,
- kPending,
- kSize,
- kWriting,
- kQueue,
- kConnected,
- kConnecting,
- kNeedDrain,
- kNoRef,
- kKeepAliveDefaultTimeout,
- kHostHeader,
- kPendingIdx,
- kRunningIdx,
- kError,
- kPipelining,
- kSocket,
- kKeepAliveTimeoutValue,
- kMaxHeadersSize,
- kKeepAliveMaxTimeout,
- kKeepAliveTimeoutThreshold,
- kHeadersTimeout,
- kBodyTimeout,
- kStrictContentLength,
- kConnector,
- kMaxRedirections,
- kMaxRequests,
- kCounter,
- kClose,
- kDestroy,
- kDispatch
-} = require('./core/symbols')
-
-const kClosedResolve = Symbol('kClosedResolve')
-
-const channels = {}
-
-try {
- const diagnosticsChannel = require('diagnostics_channel')
- channels.sendHeaders = diagnosticsChannel.channel('undici:client:sendHeaders')
- channels.beforeConnect = diagnosticsChannel.channel('undici:client:beforeConnect')
- channels.connectError = diagnosticsChannel.channel('undici:client:connectError')
- channels.connected = diagnosticsChannel.channel('undici:client:connected')
-} catch {
- channels.sendHeaders = { hasSubscribers: false }
- channels.beforeConnect = { hasSubscribers: false }
- channels.connectError = { hasSubscribers: false }
- channels.connected = { hasSubscribers: false }
-}
-
-class Client extends DispatcherBase {
- constructor (url, {
- maxHeaderSize,
- headersTimeout,
- socketTimeout,
- requestTimeout,
- connectTimeout,
- bodyTimeout,
- idleTimeout,
- keepAlive,
- keepAliveTimeout,
- maxKeepAliveTimeout,
- keepAliveMaxTimeout,
- keepAliveTimeoutThreshold,
- socketPath,
- pipelining,
- tls,
- strictContentLength,
- maxCachedSessions,
- maxRedirections,
- connect,
- maxRequestsPerClient
- } = {}) {
- super()
-
- if (keepAlive !== undefined) {
- throw new InvalidArgumentError('unsupported keepAlive, use pipelining=0 instead')
- }
-
- if (socketTimeout !== undefined) {
- throw new InvalidArgumentError('unsupported socketTimeout, use headersTimeout & bodyTimeout instead')
- }
-
- if (requestTimeout !== undefined) {
- throw new InvalidArgumentError('unsupported requestTimeout, use headersTimeout & bodyTimeout instead')
- }
-
- if (idleTimeout !== undefined) {
- throw new InvalidArgumentError('unsupported idleTimeout, use keepAliveTimeout instead')
- }
-
- if (maxKeepAliveTimeout !== undefined) {
- throw new InvalidArgumentError('unsupported maxKeepAliveTimeout, use keepAliveMaxTimeout instead')
- }
-
- if (maxHeaderSize != null && !Number.isFinite(maxHeaderSize)) {
- throw new InvalidArgumentError('invalid maxHeaderSize')
- }
-
- if (socketPath != null && typeof socketPath !== 'string') {
- throw new InvalidArgumentError('invalid socketPath')
- }
-
- if (connectTimeout != null && (!Number.isFinite(connectTimeout) || connectTimeout < 0)) {
- throw new InvalidArgumentError('invalid connectTimeout')
- }
-
- if (keepAliveTimeout != null && (!Number.isFinite(keepAliveTimeout) || keepAliveTimeout <= 0)) {
- throw new InvalidArgumentError('invalid keepAliveTimeout')
- }
-
- if (keepAliveMaxTimeout != null && (!Number.isFinite(keepAliveMaxTimeout) || keepAliveMaxTimeout <= 0)) {
- throw new InvalidArgumentError('invalid keepAliveMaxTimeout')
- }
-
- if (keepAliveTimeoutThreshold != null && !Number.isFinite(keepAliveTimeoutThreshold)) {
- throw new InvalidArgumentError('invalid keepAliveTimeoutThreshold')
- }
-
- if (headersTimeout != null && (!Number.isInteger(headersTimeout) || headersTimeout < 0)) {
- throw new InvalidArgumentError('headersTimeout must be a positive integer or zero')
- }
-
- if (bodyTimeout != null && (!Number.isInteger(bodyTimeout) || bodyTimeout < 0)) {
- throw new InvalidArgumentError('bodyTimeout must be a positive integer or zero')
- }
-
- if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') {
- throw new InvalidArgumentError('connect must be a function or an object')
- }
-
- if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) {
- throw new InvalidArgumentError('maxRedirections must be a positive number')
- }
-
- if (maxRequestsPerClient != null && (!Number.isInteger(maxRequestsPerClient) || maxRequestsPerClient < 0)) {
- throw new InvalidArgumentError('maxRequestsPerClient must be a positive number')
- }
-
- if (typeof connect !== 'function') {
- connect = buildConnector({
- ...tls,
- maxCachedSessions,
- socketPath,
- timeout: connectTimeout,
- ...connect
- })
- }
-
- this[kUrl] = util.parseOrigin(url)
- this[kConnector] = connect
- this[kSocket] = null
- this[kPipelining] = pipelining != null ? pipelining : 1
- this[kMaxHeadersSize] = maxHeaderSize || 16384
- this[kKeepAliveDefaultTimeout] = keepAliveTimeout == null ? 4e3 : keepAliveTimeout
- this[kKeepAliveMaxTimeout] = keepAliveMaxTimeout == null ? 600e3 : keepAliveMaxTimeout
- this[kKeepAliveTimeoutThreshold] = keepAliveTimeoutThreshold == null ? 1e3 : keepAliveTimeoutThreshold
- this[kKeepAliveTimeoutValue] = this[kKeepAliveDefaultTimeout]
- this[kServerName] = null
- this[kResuming] = 0 // 0, idle, 1, scheduled, 2 resuming
- this[kNeedDrain] = 0 // 0, idle, 1, scheduled, 2 resuming
- this[kHostHeader] = `host: ${this[kUrl].hostname}${this[kUrl].port ? `:${this[kUrl].port}` : ''}\r\n`
- this[kBodyTimeout] = bodyTimeout != null ? bodyTimeout : 30e3
- this[kHeadersTimeout] = headersTimeout != null ? headersTimeout : 30e3
- this[kStrictContentLength] = strictContentLength == null ? true : strictContentLength
- this[kMaxRedirections] = maxRedirections
- this[kMaxRequests] = maxRequestsPerClient
- this[kClosedResolve] = null
-
- // kQueue is built up of 3 sections separated by
- // the kRunningIdx and kPendingIdx indices.
- // | complete | running | pending |
- // ^ kRunningIdx ^ kPendingIdx ^ kQueue.length
- // kRunningIdx points to the first running element.
- // kPendingIdx points to the first pending element.
- // This implements a fast queue with an amortized
- // time of O(1).
-
- this[kQueue] = []
- this[kRunningIdx] = 0
- this[kPendingIdx] = 0
- }
-
- get pipelining () {
- return this[kPipelining]
- }
-
- set pipelining (value) {
- this[kPipelining] = value
- resume(this, true)
- }
-
- get [kPending] () {
- return this[kQueue].length - this[kPendingIdx]
- }
-
- get [kRunning] () {
- return this[kPendingIdx] - this[kRunningIdx]
- }
-
- get [kSize] () {
- return this[kQueue].length - this[kRunningIdx]
- }
-
- get [kConnected] () {
- return !!this[kSocket] && !this[kConnecting] && !this[kSocket].destroyed
- }
-
- get [kBusy] () {
- const socket = this[kSocket]
- return (
- (socket && (socket[kReset] || socket[kWriting] || socket[kBlocking])) ||
- (this[kSize] >= (this[kPipelining] || 1)) ||
- this[kPending] > 0
- )
- }
-
- /* istanbul ignore: only used for test */
- [kConnect] (cb) {
- connect(this)
- this.once('connect', cb)
- }
-
- [kDispatch] (opts, handler) {
- const { maxRedirections = this[kMaxRedirections] } = opts
- if (maxRedirections) {
- handler = new RedirectHandler(this, maxRedirections, opts, handler)
- }
-
- const origin = opts.origin || this[kUrl].origin
-
- const request = new Request(origin, opts, handler)
-
- this[kQueue].push(request)
- if (this[kResuming]) {
- // Do nothing.
- } else if (util.bodyLength(request.body) == null && util.isIterable(request.body)) {
- // Wait a tick in case stream/iterator is ended in the same tick.
- this[kResuming] = 1
- process.nextTick(resume, this)
- } else {
- resume(this, true)
- }
-
- if (this[kResuming] && this[kNeedDrain] !== 2 && this[kBusy]) {
- this[kNeedDrain] = 2
- }
-
- return this[kNeedDrain] < 2
- }
-
- async [kClose] () {
- return new Promise((resolve) => {
- if (!this[kSize]) {
- this.destroy(resolve)
- } else {
- this[kClosedResolve] = resolve
- }
- })
- }
-
- async [kDestroy] (err) {
- return new Promise((resolve) => {
- const requests = this[kQueue].splice(this[kPendingIdx])
- for (let i = 0; i < requests.length; i++) {
- const request = requests[i]
- errorRequest(this, request, err)
- }
-
- const callback = () => {
- if (this[kClosedResolve]) {
- this[kClosedResolve]()
- this[kClosedResolve] = null
- }
- resolve()
- }
-
- if (!this[kSocket]) {
- queueMicrotask(callback)
- } else {
- util.destroy(this[kSocket].on('close', callback), err)
- }
-
- resume(this)
- })
- }
-}
-
-const constants = require('./llhttp/constants')
-const EMPTY_BUF = Buffer.alloc(0)
-
-async function lazyllhttp () {
- const llhttpWasmData = process.env.JEST_WORKER_ID ? require('./llhttp/llhttp.wasm.js') : undefined
-
- let mod
- try {
- mod = await WebAssembly.compile(Buffer.from(require('./llhttp/llhttp_simd.wasm.js'), 'base64'))
- } catch (e) {
- /* istanbul ignore next */
-
- // We could check if the error was caused by the simd option not
- // being enabled, but the occurring of this other error
- // * https://github.com/emscripten-core/emscripten/issues/11495
- // got me to remove that check to avoid breaking Node 12.
- mod = await WebAssembly.compile(Buffer.from(llhttpWasmData || require('./llhttp/llhttp.wasm.js'), 'base64'))
- }
-
- return await WebAssembly.instantiate(mod, {
- env: {
- /* eslint-disable camelcase */
-
- wasm_on_url: (p, at, len) => {
- /* istanbul ignore next */
- return 0
- },
- wasm_on_status: (p, at, len) => {
- assert.strictEqual(currentParser.ptr, p)
- const start = at - currentBufferPtr
- const end = start + len
- return currentParser.onStatus(currentBufferRef.slice(start, end)) || 0
- },
- wasm_on_message_begin: (p) => {
- assert.strictEqual(currentParser.ptr, p)
- return currentParser.onMessageBegin() || 0
- },
- wasm_on_header_field: (p, at, len) => {
- assert.strictEqual(currentParser.ptr, p)
- const start = at - currentBufferPtr
- const end = start + len
- return currentParser.onHeaderField(currentBufferRef.slice(start, end)) || 0
- },
- wasm_on_header_value: (p, at, len) => {
- assert.strictEqual(currentParser.ptr, p)
- const start = at - currentBufferPtr
- const end = start + len
- return currentParser.onHeaderValue(currentBufferRef.slice(start, end)) || 0
- },
- wasm_on_headers_complete: (p, statusCode, upgrade, shouldKeepAlive) => {
- assert.strictEqual(currentParser.ptr, p)
- return currentParser.onHeadersComplete(statusCode, Boolean(upgrade), Boolean(shouldKeepAlive)) || 0
- },
- wasm_on_body: (p, at, len) => {
- assert.strictEqual(currentParser.ptr, p)
- const start = at - currentBufferPtr
- const end = start + len
- return currentParser.onBody(currentBufferRef.slice(start, end)) || 0
- },
- wasm_on_message_complete: (p) => {
- assert.strictEqual(currentParser.ptr, p)
- return currentParser.onMessageComplete() || 0
- }
-
- /* eslint-enable camelcase */
- }
- })
-}
-
-let llhttpInstance = null
-let llhttpPromise = lazyllhttp()
- .catch(() => {
- })
-
-let currentParser = null
-let currentBufferRef = null
-let currentBufferSize = 0
-let currentBufferPtr = null
-
-const TIMEOUT_HEADERS = 1
-const TIMEOUT_BODY = 2
-const TIMEOUT_IDLE = 3
-
-class Parser {
- constructor (client, socket, { exports }) {
- assert(Number.isFinite(client[kMaxHeadersSize]) && client[kMaxHeadersSize] > 0)
-
- this.llhttp = exports
- this.ptr = this.llhttp.llhttp_alloc(constants.TYPE.RESPONSE)
- this.client = client
- this.socket = socket
- this.timeout = null
- this.timeoutValue = null
- this.timeoutType = null
- this.statusCode = null
- this.statusText = ''
- this.upgrade = false
- this.headers = []
- this.headersSize = 0
- this.headersMaxSize = client[kMaxHeadersSize]
- this.shouldKeepAlive = false
- this.paused = false
- this.resume = this.resume.bind(this)
-
- this.bytesRead = 0
-
- this.keepAlive = ''
- this.contentLength = ''
- }
-
- setTimeout (value, type) {
- this.timeoutType = type
- if (value !== this.timeoutValue) {
- clearTimeout(this.timeout)
- if (value) {
- this.timeout = setTimeout(onParserTimeout, value, this)
- // istanbul ignore else: only for jest
- if (this.timeout.unref) {
- this.timeout.unref()
- }
- } else {
- this.timeout = null
- }
- this.timeoutValue = value
- } else if (this.timeout) {
- // istanbul ignore else: only for jest
- if (this.timeout.refresh) {
- this.timeout.refresh()
- }
- }
- }
-
- resume () {
- if (this.socket.destroyed || !this.paused) {
- return
- }
-
- assert(this.ptr != null)
- assert(currentParser == null)
-
- this.llhttp.llhttp_resume(this.ptr)
-
- assert(this.timeoutType === TIMEOUT_BODY)
- if (this.timeout) {
- // istanbul ignore else: only for jest
- if (this.timeout.refresh) {
- this.timeout.refresh()
- }
- }
-
- this.paused = false
- this.execute(this.socket.read() || EMPTY_BUF) // Flush parser.
- this.readMore()
- }
-
- readMore () {
- while (!this.paused && this.ptr) {
- const chunk = this.socket.read()
- if (chunk === null) {
- break
- }
- this.execute(chunk)
- }
- }
-
- execute (data) {
- assert(this.ptr != null)
- assert(currentParser == null)
- assert(!this.paused)
-
- const { socket, llhttp } = this
-
- if (data.length > currentBufferSize) {
- if (currentBufferPtr) {
- llhttp.free(currentBufferPtr)
- }
- currentBufferSize = Math.ceil(data.length / 4096) * 4096
- currentBufferPtr = llhttp.malloc(currentBufferSize)
- }
-
- new Uint8Array(llhttp.memory.buffer, currentBufferPtr, currentBufferSize).set(data)
-
- // Call `execute` on the wasm parser.
- // We pass the `llhttp_parser` pointer address, the pointer address of buffer view data,
- // and finally the length of bytes to parse.
- // The return value is an error code or `constants.ERROR.OK`.
- try {
- let ret
-
- try {
- currentBufferRef = data
- currentParser = this
- ret = llhttp.llhttp_execute(this.ptr, currentBufferPtr, data.length)
- /* eslint-disable-next-line no-useless-catch */
- } catch (err) {
- /* istanbul ignore next: difficult to make a test case for */
- throw err
- } finally {
- currentParser = null
- currentBufferRef = null
- }
-
- const offset = llhttp.llhttp_get_error_pos(this.ptr) - currentBufferPtr
-
- if (ret === constants.ERROR.PAUSED_UPGRADE) {
- this.onUpgrade(data.slice(offset))
- } else if (ret === constants.ERROR.PAUSED) {
- this.paused = true
- socket.unshift(data.slice(offset))
- } else if (ret !== constants.ERROR.OK) {
- const ptr = llhttp.llhttp_get_error_reason(this.ptr)
- let message = ''
- /* istanbul ignore else: difficult to make a test case for */
- if (ptr) {
- const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0)
- message = Buffer.from(llhttp.memory.buffer, ptr, len).toString()
- }
- throw new HTTPParserError(message, constants.ERROR[ret], data.slice(offset))
- }
- } catch (err) {
- util.destroy(socket, err)
- }
- }
-
- finish () {
- try {
- try {
- currentParser = this
- } finally {
- currentParser = null
- }
- } catch (err) {
- /* istanbul ignore next: difficult to make a test case for */
- util.destroy(this.socket, err)
- }
- }
-
- destroy () {
- assert(this.ptr != null)
- assert(currentParser == null)
-
- this.llhttp.llhttp_free(this.ptr)
- this.ptr = null
-
- clearTimeout(this.timeout)
- this.timeout = null
- this.timeoutValue = null
- this.timeoutType = null
-
- this.paused = false
- }
-
- onStatus (buf) {
- this.statusText = buf.toString()
- }
-
- onMessageBegin () {
- const { socket, client } = this
-
- /* istanbul ignore next: difficult to make a test case for */
- if (socket.destroyed) {
- return -1
- }
-
- const request = client[kQueue][client[kRunningIdx]]
- if (!request) {
- return -1
- }
- }
-
- onHeaderField (buf) {
- const len = this.headers.length
-
- if ((len & 1) === 0) {
- this.headers.push(buf)
- } else {
- this.headers[len - 1] = Buffer.concat([this.headers[len - 1], buf])
- }
-
- this.trackHeader(buf.length)
- }
-
- onHeaderValue (buf) {
- let len = this.headers.length
-
- if ((len & 1) === 1) {
- this.headers.push(buf)
- len += 1
- } else {
- this.headers[len - 1] = Buffer.concat([this.headers[len - 1], buf])
- }
-
- const key = this.headers[len - 2]
- if (key.length === 10 && key.toString().toLowerCase() === 'keep-alive') {
- this.keepAlive += buf.toString()
- } else if (key.length === 14 && key.toString().toLowerCase() === 'content-length') {
- this.contentLength += buf.toString()
- }
-
- this.trackHeader(buf.length)
- }
-
- trackHeader (len) {
- this.headersSize += len
- if (this.headersSize >= this.headersMaxSize) {
- util.destroy(this.socket, new HeadersOverflowError())
- }
- }
-
- onUpgrade (head) {
- const { upgrade, client, socket, headers, statusCode } = this
-
- assert(upgrade)
-
- const request = client[kQueue][client[kRunningIdx]]
- assert(request)
-
- assert(!socket.destroyed)
- assert(socket === client[kSocket])
- assert(!this.paused)
- assert(request.upgrade || request.method === 'CONNECT')
-
- this.statusCode = null
- this.statusText = ''
- this.shouldKeepAlive = null
-
- assert(this.headers.length % 2 === 0)
- this.headers = []
- this.headersSize = 0
-
- socket.unshift(head)
-
- socket[kParser].destroy()
- socket[kParser] = null
-
- socket[kClient] = null
- socket[kError] = null
- socket
- .removeListener('error', onSocketError)
- .removeListener('readable', onSocketReadable)
- .removeListener('end', onSocketEnd)
- .removeListener('close', onSocketClose)
-
- client[kSocket] = null
- client[kQueue][client[kRunningIdx]++] = null
- client.emit('disconnect', client[kUrl], [client], new InformationalError('upgrade'))
-
- try {
- request.onUpgrade(statusCode, headers, socket)
- } catch (err) {
- util.destroy(socket, err)
- }
-
- resume(client)
- }
-
- onHeadersComplete (statusCode, upgrade, shouldKeepAlive) {
- const { client, socket, headers, statusText } = this
-
- /* istanbul ignore next: difficult to make a test case for */
- if (socket.destroyed) {
- return -1
- }
-
- const request = client[kQueue][client[kRunningIdx]]
-
- /* istanbul ignore next: difficult to make a test case for */
- if (!request) {
- return -1
- }
-
- assert(!this.upgrade)
- assert(this.statusCode < 200)
-
- if (statusCode === 100) {
- util.destroy(socket, new SocketError('bad response', util.getSocketInfo(socket)))
- return -1
- }
-
- /* this can only happen if server is misbehaving */
- if (upgrade && !request.upgrade) {
- util.destroy(socket, new SocketError('bad upgrade', util.getSocketInfo(socket)))
- return -1
- }
-
- assert.strictEqual(this.timeoutType, TIMEOUT_HEADERS)
-
- this.statusCode = statusCode
- this.shouldKeepAlive = shouldKeepAlive
-
- if (this.statusCode >= 200) {
- const bodyTimeout = request.bodyTimeout != null
- ? request.bodyTimeout
- : client[kBodyTimeout]
- this.setTimeout(bodyTimeout, TIMEOUT_BODY)
- } else if (this.timeout) {
- // istanbul ignore else: only for jest
- if (this.timeout.refresh) {
- this.timeout.refresh()
- }
- }
-
- if (request.method === 'CONNECT') {
- assert(client[kRunning] === 1)
- this.upgrade = true
- return 2
- }
-
- if (upgrade) {
- assert(client[kRunning] === 1)
- this.upgrade = true
- return 2
- }
-
- assert(this.headers.length % 2 === 0)
- this.headers = []
- this.headersSize = 0
-
- if (shouldKeepAlive && client[kPipelining]) {
- const keepAliveTimeout = this.keepAlive ? util.parseKeepAliveTimeout(this.keepAlive) : null
-
- if (keepAliveTimeout != null) {
- const timeout = Math.min(
- keepAliveTimeout - client[kKeepAliveTimeoutThreshold],
- client[kKeepAliveMaxTimeout]
- )
- if (timeout <= 0) {
- socket[kReset] = true
- } else {
- client[kKeepAliveTimeoutValue] = timeout
- }
- } else {
- client[kKeepAliveTimeoutValue] = client[kKeepAliveDefaultTimeout]
- }
- } else {
- // Stop more requests from being dispatched.
- socket[kReset] = true
- }
-
- let pause
- try {
- pause = request.onHeaders(statusCode, headers, this.resume, statusText) === false
- } catch (err) {
- util.destroy(socket, err)
- return -1
- }
-
- if (request.method === 'HEAD') {
- assert(socket[kReset])
- return 1
- }
-
- if (statusCode < 200) {
- return 1
- }
-
- if (socket[kBlocking]) {
- socket[kBlocking] = false
- resume(client)
- }
-
- return pause ? constants.ERROR.PAUSED : 0
- }
-
- onBody (buf) {
- const { client, socket, statusCode } = this
-
- if (socket.destroyed) {
- return -1
- }
-
- const request = client[kQueue][client[kRunningIdx]]
- assert(request)
-
- assert.strictEqual(this.timeoutType, TIMEOUT_BODY)
- if (this.timeout) {
- // istanbul ignore else: only for jest
- if (this.timeout.refresh) {
- this.timeout.refresh()
- }
- }
-
- assert(statusCode >= 200)
-
- this.bytesRead += buf.length
-
- try {
- if (request.onData(buf) === false) {
- return constants.ERROR.PAUSED
- }
- } catch (err) {
- util.destroy(socket, err)
- return -1
- }
- }
-
- onMessageComplete () {
- const { client, socket, statusCode, upgrade, headers, contentLength, bytesRead, shouldKeepAlive } = this
-
- if (socket.destroyed && (!statusCode || shouldKeepAlive)) {
- return -1
- }
-
- if (upgrade) {
- return
- }
-
- const request = client[kQueue][client[kRunningIdx]]
- assert(request)
-
- assert(statusCode >= 100)
-
- this.statusCode = null
- this.statusText = ''
- this.bytesRead = 0
- this.contentLength = ''
- this.keepAlive = ''
-
- assert(this.headers.length % 2 === 0)
- this.headers = []
- this.headersSize = 0
-
- if (statusCode < 200) {
- return
- }
-
- /* istanbul ignore next: should be handled by llhttp? */
- if (request.method !== 'HEAD' && contentLength && bytesRead !== parseInt(contentLength, 10)) {
- util.destroy(socket, new ResponseContentLengthMismatchError())
- return -1
- }
-
- try {
- request.onComplete(headers)
- } catch (err) {
- errorRequest(client, request, err)
- }
-
- client[kQueue][client[kRunningIdx]++] = null
-
- if (socket[kWriting]) {
- assert.strictEqual(client[kRunning], 0)
- // Response completed before request.
- util.destroy(socket, new InformationalError('reset'))
- return constants.ERROR.PAUSED
- } else if (!shouldKeepAlive) {
- util.destroy(socket, new InformationalError('reset'))
- return constants.ERROR.PAUSED
- } else if (socket[kReset] && client[kRunning] === 0) {
- // Destroy socket once all requests have completed.
- // The request at the tail of the pipeline is the one
- // that requested reset and no further requests should
- // have been queued since then.
- util.destroy(socket, new InformationalError('reset'))
- return constants.ERROR.PAUSED
- } else if (client[kPipelining] === 1) {
- // We must wait a full event loop cycle to reuse this socket to make sure
- // that non-spec compliant servers are not closing the connection even if they
- // said they won't.
- setImmediate(resume, client)
- } else {
- resume(client)
- }
- }
-}
-
-function onParserTimeout (parser) {
- const { socket, timeoutType, client } = parser
-
- /* istanbul ignore else */
- if (timeoutType === TIMEOUT_HEADERS) {
- assert(!parser.paused, 'cannot be paused while waiting for headers')
- util.destroy(socket, new HeadersTimeoutError())
- } else if (timeoutType === TIMEOUT_BODY) {
- if (!parser.paused) {
- util.destroy(socket, new BodyTimeoutError())
- }
- } else if (timeoutType === TIMEOUT_IDLE) {
- assert(client[kRunning] === 0 && client[kKeepAliveTimeoutValue])
- util.destroy(socket, new InformationalError('socket idle timeout'))
- }
-}
-
-function onSocketReadable () {
- const { [kParser]: parser } = this
- parser.readMore()
-}
-
-function onSocketError (err) {
- const { [kParser]: parser } = this
-
- assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID')
-
- // On Mac OS, we get an ECONNRESET even if there is a full body to be forwarded
- // to the user.
- if (err.code === 'ECONNRESET' && parser.statusCode && !parser.shouldKeepAlive) {
- // We treat all incoming data so for as a valid response.
- parser.finish()
- return
- }
-
- this[kError] = err
-
- onError(this[kClient], err)
-}
-
-function onError (client, err) {
- if (
- client[kRunning] === 0 &&
- err.code !== 'UND_ERR_INFO' &&
- err.code !== 'UND_ERR_SOCKET'
- ) {
- // Error is not caused by running request and not a recoverable
- // socket error.
-
- assert(client[kPendingIdx] === client[kRunningIdx])
-
- const requests = client[kQueue].splice(client[kRunningIdx])
- for (let i = 0; i < requests.length; i++) {
- const request = requests[i]
- errorRequest(client, request, err)
- }
- assert(client[kSize] === 0)
- }
-}
-
-function onSocketEnd () {
- const { [kParser]: parser } = this
-
- if (parser.statusCode && !parser.shouldKeepAlive) {
- // We treat all incoming data so far as a valid response.
- parser.finish()
- return
- }
-
- util.destroy(this, new SocketError('other side closed', util.getSocketInfo(this)))
-}
-
-function onSocketClose () {
- const { [kClient]: client } = this
-
- this[kParser].destroy()
- this[kParser] = null
-
- const err = this[kError] || new SocketError('closed', util.getSocketInfo(this))
-
- client[kSocket] = null
-
- if (client.destroyed) {
- assert(client[kPending] === 0)
-
- // Fail entire queue.
- const requests = client[kQueue].splice(client[kRunningIdx])
- for (let i = 0; i < requests.length; i++) {
- const request = requests[i]
- errorRequest(client, request, err)
- }
- } else if (client[kRunning] > 0 && err.code !== 'UND_ERR_INFO') {
- // Fail head of pipeline.
- const request = client[kQueue][client[kRunningIdx]]
- client[kQueue][client[kRunningIdx]++] = null
-
- errorRequest(client, request, err)
- }
-
- client[kPendingIdx] = client[kRunningIdx]
-
- assert(client[kRunning] === 0)
-
- client.emit('disconnect', client[kUrl], [client], err)
-
- resume(client)
-}
-
-async function connect (client) {
- assert(!client[kConnecting])
- assert(!client[kSocket])
-
- let { host, hostname, protocol, port } = client[kUrl]
-
- // Resolve ipv6
- if (hostname[0] === '[') {
- const idx = hostname.indexOf(']')
-
- assert(idx !== -1)
- const ip = hostname.substr(1, idx - 1)
-
- assert(net.isIP(ip))
- hostname = ip
- }
-
- client[kConnecting] = true
-
- if (channels.beforeConnect.hasSubscribers) {
- channels.beforeConnect.publish({
- connectParams: {
- host,
- hostname,
- protocol,
- port,
- servername: client[kServerName]
- },
- connector: client[kConnector]
- })
- }
-
- try {
- const socket = await new Promise((resolve, reject) => {
- client[kConnector]({
- host,
- hostname,
- protocol,
- port,
- servername: client[kServerName]
- }, (err, socket) => {
- if (err) {
- reject(err)
- } else {
- resolve(socket)
- }
- })
- })
-
- if (!llhttpInstance) {
- llhttpInstance = await llhttpPromise
- llhttpPromise = null
- }
-
- client[kConnecting] = false
-
- assert(socket)
-
- client[kSocket] = socket
-
- socket[kNoRef] = false
- socket[kWriting] = false
- socket[kReset] = false
- socket[kBlocking] = false
- socket[kError] = null
- socket[kParser] = new Parser(client, socket, llhttpInstance)
- socket[kClient] = client
- socket[kCounter] = 0
- socket[kMaxRequests] = client[kMaxRequests]
- socket
- .on('error', onSocketError)
- .on('readable', onSocketReadable)
- .on('end', onSocketEnd)
- .on('close', onSocketClose)
-
- if (channels.connected.hasSubscribers) {
- channels.connected.publish({
- connectParams: {
- host,
- hostname,
- protocol,
- port,
- servername: client[kServerName]
- },
- connector: client[kConnector],
- socket
- })
- }
- client.emit('connect', client[kUrl], [client])
- } catch (err) {
- client[kConnecting] = false
-
- if (channels.connectError.hasSubscribers) {
- channels.connectError.publish({
- connectParams: {
- host,
- hostname,
- protocol,
- port,
- servername: client[kServerName]
- },
- connector: client[kConnector],
- error: err
- })
- }
-
- if (err.code === 'ERR_TLS_CERT_ALTNAME_INVALID') {
- assert(client[kRunning] === 0)
- while (client[kPending] > 0 && client[kQueue][client[kPendingIdx]].servername === client[kServerName]) {
- const request = client[kQueue][client[kPendingIdx]++]
- errorRequest(client, request, err)
- }
- } else {
- onError(client, err)
- }
-
- client.emit('connectionError', client[kUrl], [client], err)
- }
-
- resume(client)
-}
-
-function emitDrain (client) {
- client[kNeedDrain] = 0
- client.emit('drain', client[kUrl], [client])
-}
-
-function resume (client, sync) {
- if (client[kResuming] === 2) {
- return
- }
-
- client[kResuming] = 2
-
- _resume(client, sync)
- client[kResuming] = 0
-
- if (client[kRunningIdx] > 256) {
- client[kQueue].splice(0, client[kRunningIdx])
- client[kPendingIdx] -= client[kRunningIdx]
- client[kRunningIdx] = 0
- }
-}
-
-function _resume (client, sync) {
- while (true) {
- if (client.destroyed) {
- assert(client[kPending] === 0)
- return
- }
-
- if (client.closed && !client[kSize]) {
- client.destroy()
- return
- }
-
- const socket = client[kSocket]
-
- if (socket) {
- if (client[kSize] === 0) {
- if (!socket[kNoRef] && socket.unref) {
- socket.unref()
- socket[kNoRef] = true
- }
- } else if (socket[kNoRef] && socket.ref) {
- socket.ref()
- socket[kNoRef] = false
- }
-
- if (client[kSize] === 0) {
- if (socket[kParser].timeoutType !== TIMEOUT_IDLE) {
- socket[kParser].setTimeout(client[kKeepAliveTimeoutValue], TIMEOUT_IDLE)
- }
- } else if (client[kRunning] > 0 && socket[kParser].statusCode < 200) {
- if (socket[kParser].timeoutType !== TIMEOUT_HEADERS) {
- const request = client[kQueue][client[kRunningIdx]]
- const headersTimeout = request.headersTimeout != null
- ? request.headersTimeout
- : client[kHeadersTimeout]
- socket[kParser].setTimeout(headersTimeout, TIMEOUT_HEADERS)
- }
- }
- }
-
- if (client[kBusy]) {
- client[kNeedDrain] = 2
- } else if (client[kNeedDrain] === 2) {
- if (sync) {
- client[kNeedDrain] = 1
- process.nextTick(emitDrain, client)
- } else {
- emitDrain(client)
- }
- continue
- }
-
- if (client[kPending] === 0) {
- return
- }
-
- if (client[kRunning] >= (client[kPipelining] || 1)) {
- return
- }
-
- const request = client[kQueue][client[kPendingIdx]]
-
- if (client[kUrl].protocol === 'https:' && client[kServerName] !== request.servername) {
- if (client[kRunning] > 0) {
- return
- }
-
- client[kServerName] = request.servername
-
- if (socket && socket.servername !== request.servername) {
- util.destroy(socket, new InformationalError('servername changed'))
- return
- }
- }
-
- if (client[kConnecting]) {
- return
- }
-
- if (!socket) {
- connect(client)
- continue
- }
-
- if (socket.destroyed || socket[kWriting] || socket[kReset] || socket[kBlocking]) {
- return
- }
-
- if (client[kRunning] > 0 && !request.idempotent) {
- // Non-idempotent request cannot be retried.
- // Ensure that no other requests are inflight and
- // could cause failure.
- return
- }
-
- if (client[kRunning] > 0 && (request.upgrade || request.method === 'CONNECT')) {
- // Don't dispatch an upgrade until all preceding requests have completed.
- // A misbehaving server might upgrade the connection before all pipelined
- // request has completed.
- return
- }
-
- if (util.isStream(request.body) && util.bodyLength(request.body) === 0) {
- request.body
- .on('data', /* istanbul ignore next */ function () {
- /* istanbul ignore next */
- assert(false)
- })
- .on('error', function (err) {
- errorRequest(client, request, err)
- })
- .on('end', function () {
- util.destroy(this)
- })
-
- request.body = null
- }
-
- if (client[kRunning] > 0 &&
- (util.isStream(request.body) || util.isAsyncIterable(request.body))) {
- // Request with stream or iterator body can error while other requests
- // are inflight and indirectly error those as well.
- // Ensure this doesn't happen by waiting for inflight
- // to complete before dispatching.
-
- // Request with stream or iterator body cannot be retried.
- // Ensure that no other requests are inflight and
- // could cause failure.
- return
- }
-
- if (!request.aborted && write(client, request)) {
- client[kPendingIdx]++
- } else {
- client[kQueue].splice(client[kPendingIdx], 1)
- }
- }
-}
-
-function write (client, request) {
- const { body, method, path, host, upgrade, headers, blocking } = request
-
- // https://tools.ietf.org/html/rfc7231#section-4.3.1
- // https://tools.ietf.org/html/rfc7231#section-4.3.2
- // https://tools.ietf.org/html/rfc7231#section-4.3.5
-
- // Sending a payload body on a request that does not
- // expect it can cause undefined behavior on some
- // servers and corrupt connection state. Do not
- // re-use the connection for further requests.
-
- const expectsPayload = (
- method === 'PUT' ||
- method === 'POST' ||
- method === 'PATCH'
- )
-
- if (body && typeof body.read === 'function') {
- // Try to read EOF in order to get length.
- body.read(0)
- }
-
- let contentLength = util.bodyLength(body)
-
- if (contentLength === null) {
- contentLength = request.contentLength
- }
-
- if (contentLength === 0 && !expectsPayload) {
- // https://tools.ietf.org/html/rfc7230#section-3.3.2
- // A user agent SHOULD NOT send a Content-Length header field when
- // the request message does not contain a payload body and the method
- // semantics do not anticipate such a body.
-
- contentLength = null
- }
-
- if (request.contentLength !== null && request.contentLength !== contentLength) {
- if (client[kStrictContentLength]) {
- errorRequest(client, request, new RequestContentLengthMismatchError())
- return false
- }
-
- process.emitWarning(new RequestContentLengthMismatchError())
- }
-
- const socket = client[kSocket]
-
- try {
- request.onConnect((err) => {
- if (request.aborted || request.completed) {
- return
- }
-
- errorRequest(client, request, err || new RequestAbortedError())
-
- util.destroy(socket, new InformationalError('aborted'))
- })
- } catch (err) {
- errorRequest(client, request, err)
- }
-
- if (request.aborted) {
- return false
- }
-
- if (method === 'HEAD') {
- // https://github.com/mcollina/undici/issues/258
-
- // Close after a HEAD request to interop with misbehaving servers
- // that may send a body in the response.
-
- socket[kReset] = true
- }
-
- if (upgrade || method === 'CONNECT') {
- // On CONNECT or upgrade, block pipeline from dispatching further
- // requests on this connection.
-
- socket[kReset] = true
- }
-
- if (client[kMaxRequests] && socket[kCounter]++ >= client[kMaxRequests]) {
- socket[kReset] = true
- }
-
- if (blocking) {
- socket[kBlocking] = true
- }
-
- let header = `${method} ${path} HTTP/1.1\r\n`
-
- if (typeof host === 'string') {
- header += `host: ${host}\r\n`
- } else {
- header += client[kHostHeader]
- }
-
- if (upgrade) {
- header += `connection: upgrade\r\nupgrade: ${upgrade}\r\n`
- } else if (client[kPipelining]) {
- header += 'connection: keep-alive\r\n'
- } else {
- header += 'connection: close\r\n'
- }
-
- if (headers) {
- header += headers
- }
-
- if (channels.sendHeaders.hasSubscribers) {
- channels.sendHeaders.publish({ request, headers: header, socket })
- }
-
- /* istanbul ignore else: assertion */
- if (!body) {
- if (contentLength === 0) {
- socket.write(`${header}content-length: 0\r\n\r\n`, 'ascii')
- } else {
- assert(contentLength === null, 'no body must not have content length')
- socket.write(`${header}\r\n`, 'ascii')
- }
- request.onRequestSent()
- } else if (util.isBuffer(body)) {
- assert(contentLength === body.byteLength, 'buffer body must have content length')
-
- socket.cork()
- socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'ascii')
- socket.write(body)
- socket.uncork()
- request.onBodySent(body)
- request.onRequestSent()
- if (!expectsPayload) {
- socket[kReset] = true
- }
- } else if (util.isBlobLike(body)) {
- if (typeof body.stream === 'function') {
- writeIterable({ body: body.stream(), client, request, socket, contentLength, header, expectsPayload })
- } else {
- writeBlob({ body, client, request, socket, contentLength, header, expectsPayload })
- }
- } else if (util.isStream(body)) {
- writeStream({ body, client, request, socket, contentLength, header, expectsPayload })
- } else if (util.isIterable(body)) {
- writeIterable({ body, client, request, socket, contentLength, header, expectsPayload })
- } else {
- assert(false)
- }
-
- return true
-}
-
-function writeStream ({ body, client, request, socket, contentLength, header, expectsPayload }) {
- assert(contentLength !== 0 || client[kRunning] === 0, 'stream body cannot be pipelined')
-
- let finished = false
-
- const writer = new AsyncWriter({ socket, request, contentLength, client, expectsPayload, header })
-
- const onData = function (chunk) {
- try {
- assert(!finished)
-
- if (!writer.write(chunk) && this.pause) {
- this.pause()
- }
- } catch (err) {
- util.destroy(this, err)
- }
- }
- const onDrain = function () {
- assert(!finished)
-
- if (body.resume) {
- body.resume()
- }
- }
- const onAbort = function () {
- onFinished(new RequestAbortedError())
- }
- const onFinished = function (err) {
- if (finished) {
- return
- }
-
- finished = true
-
- assert(socket.destroyed || (socket[kWriting] && client[kRunning] <= 1))
-
- socket
- .off('drain', onDrain)
- .off('error', onFinished)
-
- body
- .removeListener('data', onData)
- .removeListener('end', onFinished)
- .removeListener('error', onFinished)
- .removeListener('close', onAbort)
-
- if (!err) {
- try {
- writer.end()
- } catch (er) {
- err = er
- }
- }
-
- writer.destroy(err)
-
- if (err && (err.code !== 'UND_ERR_INFO' || err.message !== 'reset')) {
- util.destroy(body, err)
- } else {
- util.destroy(body)
- }
- }
-
- body
- .on('data', onData)
- .on('end', onFinished)
- .on('error', onFinished)
- .on('close', onAbort)
-
- if (body.resume) {
- body.resume()
- }
-
- socket
- .on('drain', onDrain)
- .on('error', onFinished)
-}
-
-async function writeBlob ({ body, client, request, socket, contentLength, header, expectsPayload }) {
- assert(contentLength === body.size, 'blob body must have content length')
-
- try {
- if (contentLength != null && contentLength !== body.size) {
- throw new RequestContentLengthMismatchError()
- }
-
- const buffer = Buffer.from(await body.arrayBuffer())
-
- socket.cork()
- socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'ascii')
- socket.write(buffer)
- socket.uncork()
-
- request.onBodySent(buffer)
- request.onRequestSent()
-
- if (!expectsPayload) {
- socket[kReset] = true
- }
-
- resume(client)
- } catch (err) {
- util.destroy(socket, err)
- }
-}
-
-async function writeIterable ({ body, client, request, socket, contentLength, header, expectsPayload }) {
- assert(contentLength !== 0 || client[kRunning] === 0, 'iterator body cannot be pipelined')
-
- let callback = null
- function onDrain () {
- if (callback) {
- const cb = callback
- callback = null
- cb()
- }
- }
-
- const waitForDrain = () => new Promise((resolve, reject) => {
- assert(callback === null)
-
- if (socket[kError]) {
- reject(socket[kError])
- } else {
- callback = resolve
- }
- })
-
- socket
- .on('close', onDrain)
- .on('drain', onDrain)
-
- const writer = new AsyncWriter({ socket, request, contentLength, client, expectsPayload, header })
- try {
- // It's up to the user to somehow abort the async iterable.
- for await (const chunk of body) {
- if (socket[kError]) {
- throw socket[kError]
- }
-
- if (!writer.write(chunk)) {
- await waitForDrain()
- }
- }
-
- writer.end()
- } catch (err) {
- writer.destroy(err)
- } finally {
- socket
- .off('close', onDrain)
- .off('drain', onDrain)
- }
-}
-
-class AsyncWriter {
- constructor ({ socket, request, contentLength, client, expectsPayload, header }) {
- this.socket = socket
- this.request = request
- this.contentLength = contentLength
- this.client = client
- this.bytesWritten = 0
- this.expectsPayload = expectsPayload
- this.header = header
-
- socket[kWriting] = true
- }
-
- write (chunk) {
- const { socket, request, contentLength, client, bytesWritten, expectsPayload, header } = this
-
- if (socket[kError]) {
- throw socket[kError]
- }
-
- if (socket.destroyed) {
- return false
- }
-
- const len = Buffer.byteLength(chunk)
- if (!len) {
- return true
- }
-
- // We should defer writing chunks.
- if (contentLength !== null && bytesWritten + len > contentLength) {
- if (client[kStrictContentLength]) {
- throw new RequestContentLengthMismatchError()
- }
-
- process.emitWarning(new RequestContentLengthMismatchError())
- }
-
- if (bytesWritten === 0) {
- if (!expectsPayload) {
- socket[kReset] = true
- }
-
- if (contentLength === null) {
- socket.write(`${header}transfer-encoding: chunked\r\n`, 'ascii')
- } else {
- socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'ascii')
- }
- }
-
- if (contentLength === null) {
- socket.write(`\r\n${len.toString(16)}\r\n`, 'ascii')
- }
-
- this.bytesWritten += len
-
- const ret = socket.write(chunk)
- request.onBodySent(chunk)
- return ret
- }
-
- end () {
- const { socket, contentLength, client, bytesWritten, expectsPayload, header, request } = this
- request.onRequestSent()
-
- socket[kWriting] = false
-
- if (socket[kError]) {
- throw socket[kError]
- }
-
- if (socket.destroyed) {
- return
- }
-
- if (bytesWritten === 0) {
- if (expectsPayload) {
- // https://tools.ietf.org/html/rfc7230#section-3.3.2
- // A user agent SHOULD send a Content-Length in a request message when
- // no Transfer-Encoding is sent and the request method defines a meaning
- // for an enclosed payload body.
-
- socket.write(`${header}content-length: 0\r\n\r\n`, 'ascii')
- } else {
- socket.write(`${header}\r\n`, 'ascii')
- }
- } else if (contentLength === null) {
- socket.write('\r\n0\r\n\r\n', 'ascii')
- }
-
- if (contentLength !== null && bytesWritten !== contentLength) {
- if (client[kStrictContentLength]) {
- throw new RequestContentLengthMismatchError()
- } else {
- process.emitWarning(new RequestContentLengthMismatchError())
- }
- }
-
- if (socket[kParser].timeout && socket[kParser].timeoutType === TIMEOUT_HEADERS) {
- // istanbul ignore else: only for jest
- if (socket[kParser].timeout.refresh) {
- socket[kParser].timeout.refresh()
- }
- }
-
- resume(client)
- }
-
- destroy (err) {
- const { socket, client } = this
-
- socket[kWriting] = false
-
- if (err) {
- assert(client[kRunning] <= 1, 'pipeline should only contain this request')
- util.destroy(socket, err)
- }
- }
-}
-
-function errorRequest (client, request, err) {
- try {
- request.onError(err)
- assert(request.aborted)
- } catch (err) {
- client.emit('error', err)
- }
-}
-
-module.exports = Client
diff --git a/node_modules/undici/lib/compat/dispatcher-weakref.js b/node_modules/undici/lib/compat/dispatcher-weakref.js
deleted file mode 100644
index dbca858..0000000
--- a/node_modules/undici/lib/compat/dispatcher-weakref.js
+++ /dev/null
@@ -1,38 +0,0 @@
-'use strict'
-
-/* istanbul ignore file: only for Node 12 */
-
-const { kConnected, kSize } = require('../core/symbols')
-
-class CompatWeakRef {
- constructor (value) {
- this.value = value
- }
-
- deref () {
- return this.value[kConnected] === 0 && this.value[kSize] === 0
- ? undefined
- : this.value
- }
-}
-
-class CompatFinalizer {
- constructor (finalizer) {
- this.finalizer = finalizer
- }
-
- register (dispatcher, key) {
- dispatcher.on('disconnect', () => {
- if (dispatcher[kConnected] === 0 && dispatcher[kSize] === 0) {
- this.finalizer(key)
- }
- })
- }
-}
-
-module.exports = function () {
- return {
- WeakRef: global.WeakRef || CompatWeakRef,
- FinalizationRegistry: global.FinalizationRegistry || CompatFinalizer
- }
-}
diff --git a/node_modules/undici/lib/core/connect.js b/node_modules/undici/lib/core/connect.js
deleted file mode 100644
index 57667a1..0000000
--- a/node_modules/undici/lib/core/connect.js
+++ /dev/null
@@ -1,111 +0,0 @@
-'use strict'
-
-const net = require('net')
-const assert = require('assert')
-const util = require('./util')
-const { InvalidArgumentError, ConnectTimeoutError } = require('./errors')
-let tls // include tls conditionally since it is not always available
-
-// TODO: session re-use does not wait for the first
-// connection to resolve the session and might therefore
-// resolve the same servername multiple times even when
-// re-use is enabled.
-
-function buildConnector ({ maxCachedSessions, socketPath, timeout, ...opts }) {
- if (maxCachedSessions != null && (!Number.isInteger(maxCachedSessions) || maxCachedSessions < 0)) {
- throw new InvalidArgumentError('maxCachedSessions must be a positive integer or zero')
- }
-
- const options = { path: socketPath, ...opts }
- const sessionCache = new Map()
- timeout = timeout == null ? 10e3 : timeout
- maxCachedSessions = maxCachedSessions == null ? 100 : maxCachedSessions
-
- return function connect ({ hostname, host, protocol, port, servername, httpSocket }, callback) {
- let socket
- if (protocol === 'https:') {
- if (!tls) {
- tls = require('tls')
- }
- servername = servername || options.servername || util.getServerName(host) || null
-
- const sessionKey = servername || hostname
- const session = sessionCache.get(sessionKey) || null
-
- assert(sessionKey)
-
- socket = tls.connect({
- highWaterMark: 16384, // TLS in node can't have bigger HWM anyway...
- ...options,
- servername,
- session,
- socket: httpSocket, // upgrade socket connection
- port: port || 443,
- host: hostname
- })
-
- socket
- .on('session', function (session) {
- // cache is disabled
- if (maxCachedSessions === 0) {
- return
- }
-
- if (sessionCache.size >= maxCachedSessions) {
- // remove the oldest session
- const { value: oldestKey } = sessionCache.keys().next()
- sessionCache.delete(oldestKey)
- }
-
- sessionCache.set(sessionKey, session)
- })
- .on('error', function (err) {
- if (sessionKey && err.code !== 'UND_ERR_INFO') {
- // TODO (fix): Only delete for session related errors.
- sessionCache.delete(sessionKey)
- }
- })
- } else {
- assert(!httpSocket, 'httpSocket can only be sent on TLS update')
- socket = net.connect({
- highWaterMark: 64 * 1024, // Same as nodejs fs streams.
- ...options,
- port: port || 80,
- host: hostname
- })
- }
-
- const timeoutId = timeout
- ? setTimeout(onConnectTimeout, timeout, socket)
- : null
-
- socket
- .setNoDelay(true)
- .once(protocol === 'https:' ? 'secureConnect' : 'connect', function () {
- clearTimeout(timeoutId)
-
- if (callback) {
- const cb = callback
- callback = null
- cb(null, this)
- }
- })
- .on('error', function (err) {
- clearTimeout(timeoutId)
-
- if (callback) {
- const cb = callback
- callback = null
- cb(err)
- }
- })
-
- return socket
- }
-}
-
-function onConnectTimeout (socket) {
- util.destroy(socket, new ConnectTimeoutError())
-}
-
-module.exports = buildConnector
diff --git a/node_modules/undici/lib/core/errors.js b/node_modules/undici/lib/core/errors.js
deleted file mode 100644
index 1f87dbf..0000000
--- a/node_modules/undici/lib/core/errors.js
+++ /dev/null
@@ -1,205 +0,0 @@
-'use strict'
-
-class UndiciError extends Error {
- constructor (message) {
- super(message)
- this.name = 'UndiciError'
- this.code = 'UND_ERR'
- }
-}
-
-class ConnectTimeoutError extends UndiciError {
- constructor (message) {
- super(message)
- Error.captureStackTrace(this, ConnectTimeoutError)
- this.name = 'ConnectTimeoutError'
- this.message = message || 'Connect Timeout Error'
- this.code = 'UND_ERR_CONNECT_TIMEOUT'
- }
-}
-
-class HeadersTimeoutError extends UndiciError {
- constructor (message) {
- super(message)
- Error.captureStackTrace(this, HeadersTimeoutError)
- this.name = 'HeadersTimeoutError'
- this.message = message || 'Headers Timeout Error'
- this.code = 'UND_ERR_HEADERS_TIMEOUT'
- }
-}
-
-class HeadersOverflowError extends UndiciError {
- constructor (message) {
- super(message)
- Error.captureStackTrace(this, HeadersOverflowError)
- this.name = 'HeadersOverflowError'
- this.message = message || 'Headers Overflow Error'
- this.code = 'UND_ERR_HEADERS_OVERFLOW'
- }
-}
-
-class BodyTimeoutError extends UndiciError {
- constructor (message) {
- super(message)
- Error.captureStackTrace(this, BodyTimeoutError)
- this.name = 'BodyTimeoutError'
- this.message = message || 'Body Timeout Error'
- this.code = 'UND_ERR_BODY_TIMEOUT'
- }
-}
-
-class ResponseStatusCodeError extends UndiciError {
- constructor (message, statusCode, headers, body) {
- super(message)
- Error.captureStackTrace(this, ResponseStatusCodeError)
- this.name = 'ResponseStatusCodeError'
- this.message = message || 'Response Status Code Error'
- this.code = 'UND_ERR_RESPONSE_STATUS_CODE'
- this.body = body
- this.status = statusCode
- this.statusCode = statusCode
- this.headers = headers
- }
-}
-
-class InvalidArgumentError extends UndiciError {
- constructor (message) {
- super(message)
- Error.captureStackTrace(this, InvalidArgumentError)
- this.name = 'InvalidArgumentError'
- this.message = message || 'Invalid Argument Error'
- this.code = 'UND_ERR_INVALID_ARG'
- }
-}
-
-class InvalidReturnValueError extends UndiciError {
- constructor (message) {
- super(message)
- Error.captureStackTrace(this, InvalidReturnValueError)
- this.name = 'InvalidReturnValueError'
- this.message = message || 'Invalid Return Value Error'
- this.code = 'UND_ERR_INVALID_RETURN_VALUE'
- }
-}
-
-class RequestAbortedError extends UndiciError {
- constructor (message) {
- super(message)
- Error.captureStackTrace(this, RequestAbortedError)
- this.name = 'AbortError'
- this.message = message || 'Request aborted'
- this.code = 'UND_ERR_ABORTED'
- }
-}
-
-class InformationalError extends UndiciError {
- constructor (message) {
- super(message)
- Error.captureStackTrace(this, InformationalError)
- this.name = 'InformationalError'
- this.message = message || 'Request information'
- this.code = 'UND_ERR_INFO'
- }
-}
-
-class RequestContentLengthMismatchError extends UndiciError {
- constructor (message) {
- super(message)
- Error.captureStackTrace(this, RequestContentLengthMismatchError)
- this.name = 'RequestContentLengthMismatchError'
- this.message = message || 'Request body length does not match content-length header'
- this.code = 'UND_ERR_REQ_CONTENT_LENGTH_MISMATCH'
- }
-}
-
-class ResponseContentLengthMismatchError extends UndiciError {
- constructor (message) {
- super(message)
- Error.captureStackTrace(this, ResponseContentLengthMismatchError)
- this.name = 'ResponseContentLengthMismatchError'
- this.message = message || 'Response body length does not match content-length header'
- this.code = 'UND_ERR_RES_CONTENT_LENGTH_MISMATCH'
- }
-}
-
-class ClientDestroyedError extends UndiciError {
- constructor (message) {
- super(message)
- Error.captureStackTrace(this, ClientDestroyedError)
- this.name = 'ClientDestroyedError'
- this.message = message || 'The client is destroyed'
- this.code = 'UND_ERR_DESTROYED'
- }
-}
-
-class ClientClosedError extends UndiciError {
- constructor (message) {
- super(message)
- Error.captureStackTrace(this, ClientClosedError)
- this.name = 'ClientClosedError'
- this.message = message || 'The client is closed'
- this.code = 'UND_ERR_CLOSED'
- }
-}
-
-class SocketError extends UndiciError {
- constructor (message, socket) {
- super(message)
- Error.captureStackTrace(this, SocketError)
- this.name = 'SocketError'
- this.message = message || 'Socket error'
- this.code = 'UND_ERR_SOCKET'
- this.socket = socket
- }
-}
-
-class NotSupportedError extends UndiciError {
- constructor (message) {
- super(message)
- Error.captureStackTrace(this, NotSupportedError)
- this.name = 'NotSupportedError'
- this.message = message || 'Not supported error'
- this.code = 'UND_ERR_NOT_SUPPORTED'
- }
-}
-
-class BalancedPoolMissingUpstreamError extends UndiciError {
- constructor (message) {
- super(message)
- Error.captureStackTrace(this, NotSupportedError)
- this.name = 'MissingUpstreamError'
- this.message = message || 'No upstream has been added to the BalancedPool'
- this.code = 'UND_ERR_BPL_MISSING_UPSTREAM'
- }
-}
-
-class HTTPParserError extends Error {
- constructor (message, code, data) {
- super(message)
- Error.captureStackTrace(this, HTTPParserError)
- this.name = 'HTTPParserError'
- this.code = code ? `HPE_${code}` : undefined
- this.data = data ? data.toString() : undefined
- }
-}
-
-module.exports = {
- HTTPParserError,
- UndiciError,
- HeadersTimeoutError,
- HeadersOverflowError,
- BodyTimeoutError,
- RequestContentLengthMismatchError,
- ConnectTimeoutError,
- ResponseStatusCodeError,
- InvalidArgumentError,
- InvalidReturnValueError,
- RequestAbortedError,
- ClientDestroyedError,
- ClientClosedError,
- InformationalError,
- SocketError,
- NotSupportedError,
- ResponseContentLengthMismatchError,
- BalancedPoolMissingUpstreamError
-}
diff --git a/node_modules/undici/lib/core/request.js b/node_modules/undici/lib/core/request.js
deleted file mode 100644
index 1969f84..0000000
--- a/node_modules/undici/lib/core/request.js
+++ /dev/null
@@ -1,309 +0,0 @@
-'use strict'
-
-const {
- InvalidArgumentError,
- NotSupportedError
-} = require('./errors')
-const assert = require('assert')
-const util = require('./util')
-
-const kHandler = Symbol('handler')
-
-const channels = {}
-
-let extractBody
-
-const nodeVersion = process.versions.node.split('.')
-const nodeMajor = Number(nodeVersion[0])
-const nodeMinor = Number(nodeVersion[1])
-
-try {
- const diagnosticsChannel = require('diagnostics_channel')
- channels.create = diagnosticsChannel.channel('undici:request:create')
- channels.bodySent = diagnosticsChannel.channel('undici:request:bodySent')
- channels.headers = diagnosticsChannel.channel('undici:request:headers')
- channels.trailers = diagnosticsChannel.channel('undici:request:trailers')
- channels.error = diagnosticsChannel.channel('undici:request:error')
-} catch {
- channels.create = { hasSubscribers: false }
- channels.bodySent = { hasSubscribers: false }
- channels.headers = { hasSubscribers: false }
- channels.trailers = { hasSubscribers: false }
- channels.error = { hasSubscribers: false }
-}
-
-class Request {
- constructor (origin, {
- path,
- method,
- body,
- headers,
- query,
- idempotent,
- blocking,
- upgrade,
- headersTimeout,
- bodyTimeout,
- throwOnError
- }, handler) {
- if (typeof path !== 'string') {
- throw new InvalidArgumentError('path must be a string')
- } else if (
- path[0] !== '/' &&
- !(path.startsWith('http://') || path.startsWith('https://')) &&
- method !== 'CONNECT'
- ) {
- throw new InvalidArgumentError('path must be an absolute URL or start with a slash')
- }
-
- if (typeof method !== 'string') {
- throw new InvalidArgumentError('method must be a string')
- }
-
- if (upgrade && typeof upgrade !== 'string') {
- throw new InvalidArgumentError('upgrade must be a string')
- }
-
- if (headersTimeout != null && (!Number.isFinite(headersTimeout) || headersTimeout < 0)) {
- throw new InvalidArgumentError('invalid headersTimeout')
- }
-
- if (bodyTimeout != null && (!Number.isFinite(bodyTimeout) || bodyTimeout < 0)) {
- throw new InvalidArgumentError('invalid bodyTimeout')
- }
-
- this.headersTimeout = headersTimeout
-
- this.bodyTimeout = bodyTimeout
-
- this.throwOnError = throwOnError === true
-
- this.method = method
-
- if (body == null) {
- this.body = null
- } else if (util.isStream(body)) {
- this.body = body
- } else if (util.isBuffer(body)) {
- this.body = body.byteLength ? body : null
- } else if (ArrayBuffer.isView(body)) {
- this.body = body.buffer.byteLength ? Buffer.from(body.buffer, body.byteOffset, body.byteLength) : null
- } else if (body instanceof ArrayBuffer) {
- this.body = body.byteLength ? Buffer.from(body) : null
- } else if (typeof body === 'string') {
- this.body = body.length ? Buffer.from(body) : null
- } else if (util.isFormDataLike(body) || util.isIterable(body) || util.isBlobLike(body)) {
- this.body = body
- } else {
- throw new InvalidArgumentError('body must be a string, a Buffer, a Readable stream, an iterable, or an async iterable')
- }
-
- this.completed = false
-
- this.aborted = false
-
- this.upgrade = upgrade || null
-
- this.path = query ? util.buildURL(path, query) : path
-
- this.origin = origin
-
- this.idempotent = idempotent == null
- ? method === 'HEAD' || method === 'GET'
- : idempotent
-
- this.blocking = blocking == null ? false : blocking
-
- this.host = null
-
- this.contentLength = null
-
- this.contentType = null
-
- this.headers = ''
-
- if (Array.isArray(headers)) {
- if (headers.length % 2 !== 0) {
- throw new InvalidArgumentError('headers array must be even')
- }
- for (let i = 0; i < headers.length; i += 2) {
- processHeader(this, headers[i], headers[i + 1])
- }
- } else if (headers && typeof headers === 'object') {
- const keys = Object.keys(headers)
- for (let i = 0; i < keys.length; i++) {
- const key = keys[i]
- processHeader(this, key, headers[key])
- }
- } else if (headers != null) {
- throw new InvalidArgumentError('headers must be an object or an array')
- }
-
- if (util.isFormDataLike(this.body)) {
- if (nodeMajor < 16 || (nodeMajor === 16 && nodeMinor < 5)) {
- throw new InvalidArgumentError('Form-Data bodies are only supported in node v16.5 and newer.')
- }
-
- if (!extractBody) {
- extractBody = require('../fetch/body.js').extractBody
- }
-
- const [bodyStream, contentType] = extractBody(body)
- if (this.contentType == null) {
- this.contentType = contentType
- this.headers += `content-type: ${contentType}\r\n`
- }
- this.body = bodyStream.stream
- } else if (util.isBlobLike(body) && this.contentType == null && body.type) {
- this.contentType = body.type
- this.headers += `content-type: ${body.type}\r\n`
- }
-
- util.validateHandler(handler, method, upgrade)
-
- this.servername = util.getServerName(this.host)
-
- this[kHandler] = handler
-
- if (channels.create.hasSubscribers) {
- channels.create.publish({ request: this })
- }
- }
-
- onBodySent (chunk) {
- if (this[kHandler].onBodySent) {
- try {
- this[kHandler].onBodySent(chunk)
- } catch (err) {
- this.onError(err)
- }
- }
- }
-
- onRequestSent () {
- if (channels.bodySent.hasSubscribers) {
- channels.bodySent.publish({ request: this })
- }
- }
-
- onConnect (abort) {
- assert(!this.aborted)
- assert(!this.completed)
-
- return this[kHandler].onConnect(abort)
- }
-
- onHeaders (statusCode, headers, resume, statusText) {
- assert(!this.aborted)
- assert(!this.completed)
-
- if (channels.headers.hasSubscribers) {
- channels.headers.publish({ request: this, response: { statusCode, headers, statusText } })
- }
-
- return this[kHandler].onHeaders(statusCode, headers, resume, statusText)
- }
-
- onData (chunk) {
- assert(!this.aborted)
- assert(!this.completed)
-
- return this[kHandler].onData(chunk)
- }
-
- onUpgrade (statusCode, headers, socket) {
- assert(!this.aborted)
- assert(!this.completed)
-
- return this[kHandler].onUpgrade(statusCode, headers, socket)
- }
-
- onComplete (trailers) {
- assert(!this.aborted)
-
- this.completed = true
- if (channels.trailers.hasSubscribers) {
- channels.trailers.publish({ request: this, trailers })
- }
- return this[kHandler].onComplete(trailers)
- }
-
- onError (error) {
- if (channels.error.hasSubscribers) {
- channels.error.publish({ request: this, error })
- }
-
- if (this.aborted) {
- return
- }
- this.aborted = true
- return this[kHandler].onError(error)
- }
-
- addHeader (key, value) {
- processHeader(this, key, value)
- return this
- }
-}
-
-function processHeader (request, key, val) {
- if (val && typeof val === 'object') {
- throw new InvalidArgumentError(`invalid ${key} header`)
- } else if (val === undefined) {
- return
- }
-
- if (
- request.host === null &&
- key.length === 4 &&
- key.toLowerCase() === 'host'
- ) {
- // Consumed by Client
- request.host = val
- } else if (
- request.contentLength === null &&
- key.length === 14 &&
- key.toLowerCase() === 'content-length'
- ) {
- request.contentLength = parseInt(val, 10)
- if (!Number.isFinite(request.contentLength)) {
- throw new InvalidArgumentError('invalid content-length header')
- }
- } else if (
- request.contentType === null &&
- key.length === 12 &&
- key.toLowerCase() === 'content-type'
- ) {
- request.contentType = val
- request.headers += `${key}: ${val}\r\n`
- } else if (
- key.length === 17 &&
- key.toLowerCase() === 'transfer-encoding'
- ) {
- throw new InvalidArgumentError('invalid transfer-encoding header')
- } else if (
- key.length === 10 &&
- key.toLowerCase() === 'connection'
- ) {
- throw new InvalidArgumentError('invalid connection header')
- } else if (
- key.length === 10 &&
- key.toLowerCase() === 'keep-alive'
- ) {
- throw new InvalidArgumentError('invalid keep-alive header')
- } else if (
- key.length === 7 &&
- key.toLowerCase() === 'upgrade'
- ) {
- throw new InvalidArgumentError('invalid upgrade header')
- } else if (
- key.length === 6 &&
- key.toLowerCase() === 'expect'
- ) {
- throw new NotSupportedError('expect header not supported')
- } else {
- request.headers += `${key}: ${val}\r\n`
- }
-}
-
-module.exports = Request
diff --git a/node_modules/undici/lib/core/symbols.js b/node_modules/undici/lib/core/symbols.js
deleted file mode 100644
index 3010882..0000000
--- a/node_modules/undici/lib/core/symbols.js
+++ /dev/null
@@ -1,52 +0,0 @@
-module.exports = {
- kClose: Symbol('close'),
- kDestroy: Symbol('destroy'),
- kDispatch: Symbol('dispatch'),
- kUrl: Symbol('url'),
- kWriting: Symbol('writing'),
- kResuming: Symbol('resuming'),
- kQueue: Symbol('queue'),
- kConnect: Symbol('connect'),
- kConnecting: Symbol('connecting'),
- kHeadersList: Symbol('headers list'),
- kKeepAliveDefaultTimeout: Symbol('default keep alive timeout'),
- kKeepAliveMaxTimeout: Symbol('max keep alive timeout'),
- kKeepAliveTimeoutThreshold: Symbol('keep alive timeout threshold'),
- kKeepAliveTimeoutValue: Symbol('keep alive timeout'),
- kKeepAlive: Symbol('keep alive'),
- kHeadersTimeout: Symbol('headers timeout'),
- kBodyTimeout: Symbol('body timeout'),
- kServerName: Symbol('server name'),
- kHost: Symbol('host'),
- kNoRef: Symbol('no ref'),
- kBodyUsed: Symbol('used'),
- kRunning: Symbol('running'),
- kBlocking: Symbol('blocking'),
- kPending: Symbol('pending'),
- kSize: Symbol('size'),
- kBusy: Symbol('busy'),
- kQueued: Symbol('queued'),
- kFree: Symbol('free'),
- kConnected: Symbol('connected'),
- kClosed: Symbol('closed'),
- kNeedDrain: Symbol('need drain'),
- kReset: Symbol('reset'),
- kDestroyed: Symbol('destroyed'),
- kMaxHeadersSize: Symbol('max headers size'),
- kRunningIdx: Symbol('running index'),
- kPendingIdx: Symbol('pending index'),
- kError: Symbol('error'),
- kClients: Symbol('clients'),
- kClient: Symbol('client'),
- kParser: Symbol('parser'),
- kOnDestroyed: Symbol('destroy callbacks'),
- kPipelining: Symbol('pipelinig'),
- kSocket: Symbol('socket'),
- kHostHeader: Symbol('host header'),
- kConnector: Symbol('connector'),
- kStrictContentLength: Symbol('strict content length'),
- kMaxRedirections: Symbol('maxRedirections'),
- kMaxRequests: Symbol('maxRequestsPerClient'),
- kProxy: Symbol('proxy agent options'),
- kCounter: Symbol('socket request counter')
-}
diff --git a/node_modules/undici/lib/core/util.js b/node_modules/undici/lib/core/util.js
deleted file mode 100644
index 635ef2e..0000000
--- a/node_modules/undici/lib/core/util.js
+++ /dev/null
@@ -1,407 +0,0 @@
-'use strict'
-
-const assert = require('assert')
-const { kDestroyed, kBodyUsed } = require('./symbols')
-const { IncomingMessage } = require('http')
-const stream = require('stream')
-const net = require('net')
-const { InvalidArgumentError } = require('./errors')
-const { Blob } = require('buffer')
-const nodeUtil = require('util')
-
-function nop () {}
-
-function isStream (obj) {
- return obj && typeof obj.pipe === 'function'
-}
-
-// based on https://github.com/node-fetch/fetch-blob/blob/8ab587d34080de94140b54f07168451e7d0b655e/index.js#L229-L241 (MIT License)
-function isBlobLike (object) {
- return (Blob && object instanceof Blob) || (
- object &&
- typeof object === 'object' &&
- (typeof object.stream === 'function' ||
- typeof object.arrayBuffer === 'function') &&
- /^(Blob|File)$/.test(object[Symbol.toStringTag])
- )
-}
-
-function isObject (val) {
- return val !== null && typeof val === 'object'
-}
-
-// this escapes all non-uri friendly characters
-function encode (val) {
- return encodeURIComponent(val)
-}
-
-// based on https://github.com/axios/axios/blob/63e559fa609c40a0a460ae5d5a18c3470ffc6c9e/lib/helpers/buildURL.js (MIT license)
-function buildURL (url, queryParams) {
- if (url.includes('?') || url.includes('#')) {
- throw new Error('Query params cannot be passed when url already contains "?" or "#".')
- }
- if (!isObject(queryParams)) {
- throw new Error('Query params must be an object')
- }
-
- const parts = []
- for (let [key, val] of Object.entries(queryParams)) {
- if (val === null || typeof val === 'undefined') {
- continue
- }
-
- if (!Array.isArray(val)) {
- val = [val]
- }
-
- for (const v of val) {
- if (isObject(v)) {
- throw new Error('Passing object as a query param is not supported, please serialize to string up-front')
- }
- parts.push(encode(key) + '=' + encode(v))
- }
- }
-
- const serializedParams = parts.join('&')
-
- if (serializedParams) {
- url += '?' + serializedParams
- }
-
- return url
-}
-
-function parseURL (url) {
- if (typeof url === 'string') {
- url = new URL(url)
- }
-
- if (!url || typeof url !== 'object') {
- throw new InvalidArgumentError('invalid url')
- }
-
- if (url.port != null && url.port !== '' && !Number.isFinite(parseInt(url.port))) {
- throw new InvalidArgumentError('invalid port')
- }
-
- if (url.path != null && typeof url.path !== 'string') {
- throw new InvalidArgumentError('invalid path')
- }
-
- if (url.pathname != null && typeof url.pathname !== 'string') {
- throw new InvalidArgumentError('invalid pathname')
- }
-
- if (url.hostname != null && typeof url.hostname !== 'string') {
- throw new InvalidArgumentError('invalid hostname')
- }
-
- if (url.origin != null && typeof url.origin !== 'string') {
- throw new InvalidArgumentError('invalid origin')
- }
-
- if (!/^https?:/.test(url.origin || url.protocol)) {
- throw new InvalidArgumentError('invalid protocol')
- }
-
- if (!(url instanceof URL)) {
- const port = url.port != null
- ? url.port
- : (url.protocol === 'https:' ? 443 : 80)
- const origin = url.origin != null
- ? url.origin
- : `${url.protocol}//${url.hostname}:${port}`
- const path = url.path != null
- ? url.path
- : `${url.pathname || ''}${url.search || ''}`
-
- url = new URL(path, origin)
- }
-
- return url
-}
-
-function parseOrigin (url) {
- url = parseURL(url)
-
- if (url.pathname !== '/' || url.search || url.hash) {
- throw new InvalidArgumentError('invalid url')
- }
-
- return url
-}
-
-function getHostname (host) {
- if (host[0] === '[') {
- const idx = host.indexOf(']')
-
- assert(idx !== -1)
- return host.substr(1, idx - 1)
- }
-
- const idx = host.indexOf(':')
- if (idx === -1) return host
-
- return host.substr(0, idx)
-}
-
-// IP addresses are not valid server names per RFC6066
-// > Currently, the only server names supported are DNS hostnames
-function getServerName (host) {
- if (!host) {
- return null
- }
-
- assert.strictEqual(typeof host, 'string')
-
- const servername = getHostname(host)
- if (net.isIP(servername)) {
- return ''
- }
-
- return servername
-}
-
-function deepClone (obj) {
- return JSON.parse(JSON.stringify(obj))
-}
-
-function isAsyncIterable (obj) {
- return !!(obj != null && typeof obj[Symbol.asyncIterator] === 'function')
-}
-
-function isIterable (obj) {
- return !!(obj != null && (typeof obj[Symbol.iterator] === 'function' || typeof obj[Symbol.asyncIterator] === 'function'))
-}
-
-function bodyLength (body) {
- if (body == null) {
- return 0
- } else if (isStream(body)) {
- const state = body._readableState
- return state && state.ended === true && Number.isFinite(state.length)
- ? state.length
- : null
- } else if (isBlobLike(body)) {
- return body.size != null ? body.size : null
- } else if (isBuffer(body)) {
- return body.byteLength
- }
-
- return null
-}
-
-function isDestroyed (stream) {
- return !stream || !!(stream.destroyed || stream[kDestroyed])
-}
-
-function isReadableAborted (stream) {
- const state = stream && stream._readableState
- return isDestroyed(stream) && state && !state.endEmitted
-}
-
-function destroy (stream, err) {
- if (!isStream(stream) || isDestroyed(stream)) {
- return
- }
-
- if (typeof stream.destroy === 'function') {
- if (Object.getPrototypeOf(stream).constructor === IncomingMessage) {
- // See: https://github.com/nodejs/node/pull/38505/files
- stream.socket = null
- }
- stream.destroy(err)
- } else if (err) {
- process.nextTick((stream, err) => {
- stream.emit('error', err)
- }, stream, err)
- }
-
- if (stream.destroyed !== true) {
- stream[kDestroyed] = true
- }
-}
-
-const KEEPALIVE_TIMEOUT_EXPR = /timeout=(\d+)/
-function parseKeepAliveTimeout (val) {
- const m = val.toString().match(KEEPALIVE_TIMEOUT_EXPR)
- return m ? parseInt(m[1], 10) * 1000 : null
-}
-
-function parseHeaders (headers, obj = {}) {
- for (let i = 0; i < headers.length; i += 2) {
- const key = headers[i].toString().toLowerCase()
- let val = obj[key]
- if (!val) {
- obj[key] = headers[i + 1].toString()
- } else {
- if (!Array.isArray(val)) {
- val = [val]
- obj[key] = val
- }
- val.push(headers[i + 1].toString())
- }
- }
- return obj
-}
-
-function parseRawHeaders (headers) {
- return headers.map(header => header.toString())
-}
-
-function isBuffer (buffer) {
- // See, https://github.com/mcollina/undici/pull/319
- return buffer instanceof Uint8Array || Buffer.isBuffer(buffer)
-}
-
-function validateHandler (handler, method, upgrade) {
- if (!handler || typeof handler !== 'object') {
- throw new InvalidArgumentError('handler must be an object')
- }
-
- if (typeof handler.onConnect !== 'function') {
- throw new InvalidArgumentError('invalid onConnect method')
- }
-
- if (typeof handler.onError !== 'function') {
- throw new InvalidArgumentError('invalid onError method')
- }
-
- if (typeof handler.onBodySent !== 'function' && handler.onBodySent !== undefined) {
- throw new InvalidArgumentError('invalid onBodySent method')
- }
-
- if (upgrade || method === 'CONNECT') {
- if (typeof handler.onUpgrade !== 'function') {
- throw new InvalidArgumentError('invalid onUpgrade method')
- }
- } else {
- if (typeof handler.onHeaders !== 'function') {
- throw new InvalidArgumentError('invalid onHeaders method')
- }
-
- if (typeof handler.onData !== 'function') {
- throw new InvalidArgumentError('invalid onData method')
- }
-
- if (typeof handler.onComplete !== 'function') {
- throw new InvalidArgumentError('invalid onComplete method')
- }
- }
-}
-
-// A body is disturbed if it has been read from and it cannot
-// be re-used without losing state or data.
-function isDisturbed (body) {
- return !!(body && (
- stream.isDisturbed
- ? stream.isDisturbed(body) || body[kBodyUsed] // TODO (fix): Why is body[kBodyUsed] needed?
- : body[kBodyUsed] ||
- body.readableDidRead ||
- (body._readableState && body._readableState.dataEmitted) ||
- isReadableAborted(body)
- ))
-}
-
-function isErrored (body) {
- return !!(body && (
- stream.isErrored
- ? stream.isErrored(body)
- : /state: 'errored'/.test(nodeUtil.inspect(body)
- )))
-}
-
-function isReadable (body) {
- return !!(body && (
- stream.isReadable
- ? stream.isReadable(body)
- : /state: 'readable'/.test(nodeUtil.inspect(body)
- )))
-}
-
-function getSocketInfo (socket) {
- return {
- localAddress: socket.localAddress,
- localPort: socket.localPort,
- remoteAddress: socket.remoteAddress,
- remotePort: socket.remotePort,
- remoteFamily: socket.remoteFamily,
- timeout: socket.timeout,
- bytesWritten: socket.bytesWritten,
- bytesRead: socket.bytesRead
- }
-}
-
-let ReadableStream
-function ReadableStreamFrom (iterable) {
- if (!ReadableStream) {
- ReadableStream = require('stream/web').ReadableStream
- }
-
- if (ReadableStream.from) {
- // https://github.com/whatwg/streams/pull/1083
- return ReadableStream.from(iterable)
- }
-
- let iterator
- return new ReadableStream(
- {
- async start () {
- iterator = iterable[Symbol.asyncIterator]()
- },
- async pull (controller) {
- const { done, value } = await iterator.next()
- if (done) {
- queueMicrotask(() => {
- controller.close()
- })
- } else {
- const buf = Buffer.isBuffer(value) ? value : Buffer.from(value)
- controller.enqueue(new Uint8Array(buf))
- }
- return controller.desiredSize > 0
- },
- async cancel (reason) {
- await iterator.return()
- }
- },
- 0
- )
-}
-
-function isFormDataLike (chunk) {
- return chunk && chunk.constructor && chunk.constructor.name === 'FormData'
-}
-
-const kEnumerableProperty = Object.create(null)
-kEnumerableProperty.enumerable = true
-
-module.exports = {
- kEnumerableProperty,
- nop,
- isDisturbed,
- isErrored,
- isReadable,
- toUSVString: nodeUtil.toUSVString || ((val) => `${val}`),
- isReadableAborted,
- isBlobLike,
- parseOrigin,
- parseURL,
- getServerName,
- isStream,
- isIterable,
- isAsyncIterable,
- isDestroyed,
- parseRawHeaders,
- parseHeaders,
- parseKeepAliveTimeout,
- destroy,
- bodyLength,
- deepClone,
- ReadableStreamFrom,
- isBuffer,
- validateHandler,
- getSocketInfo,
- isFormDataLike,
- buildURL
-}
diff --git a/node_modules/undici/lib/dispatcher-base.js b/node_modules/undici/lib/dispatcher-base.js
deleted file mode 100644
index 2c12ba8..0000000
--- a/node_modules/undici/lib/dispatcher-base.js
+++ /dev/null
@@ -1,159 +0,0 @@
-'use strict'
-
-const Dispatcher = require('./dispatcher')
-const {
- ClientDestroyedError,
- ClientClosedError,
- InvalidArgumentError
-} = require('./core/errors')
-const { kDestroy, kClose, kDispatch } = require('./core/symbols')
-
-const kDestroyed = Symbol('destroyed')
-const kClosed = Symbol('closed')
-const kOnDestroyed = Symbol('onDestroyed')
-const kOnClosed = Symbol('onClosed')
-
-class DispatcherBase extends Dispatcher {
- constructor () {
- super()
-
- this[kDestroyed] = false
- this[kOnDestroyed] = []
- this[kClosed] = false
- this[kOnClosed] = []
- }
-
- get destroyed () {
- return this[kDestroyed]
- }
-
- get closed () {
- return this[kClosed]
- }
-
- close (callback) {
- if (callback === undefined) {
- return new Promise((resolve, reject) => {
- this.close((err, data) => {
- return err ? reject(err) : resolve(data)
- })
- })
- }
-
- if (typeof callback !== 'function') {
- throw new InvalidArgumentError('invalid callback')
- }
-
- if (this[kDestroyed]) {
- queueMicrotask(() => callback(new ClientDestroyedError(), null))
- return
- }
-
- if (this[kClosed]) {
- if (this[kOnClosed]) {
- this[kOnClosed].push(callback)
- } else {
- queueMicrotask(() => callback(null, null))
- }
- return
- }
-
- this[kClosed] = true
- this[kOnClosed].push(callback)
-
- const onClosed = () => {
- const callbacks = this[kOnClosed]
- this[kOnClosed] = null
- for (let i = 0; i < callbacks.length; i++) {
- callbacks[i](null, null)
- }
- }
-
- // Should not error.
- this[kClose]()
- .then(() => this.destroy())
- .then(() => {
- queueMicrotask(onClosed)
- })
- }
-
- destroy (err, callback) {
- if (typeof err === 'function') {
- callback = err
- err = null
- }
-
- if (callback === undefined) {
- return new Promise((resolve, reject) => {
- this.destroy(err, (err, data) => {
- return err ? /* istanbul ignore next: should never error */ reject(err) : resolve(data)
- })
- })
- }
-
- if (typeof callback !== 'function') {
- throw new InvalidArgumentError('invalid callback')
- }
-
- if (this[kDestroyed]) {
- if (this[kOnDestroyed]) {
- this[kOnDestroyed].push(callback)
- } else {
- queueMicrotask(() => callback(null, null))
- }
- return
- }
-
- if (!err) {
- err = new ClientDestroyedError()
- }
-
- this[kDestroyed] = true
- this[kOnDestroyed].push(callback)
-
- const onDestroyed = () => {
- const callbacks = this[kOnDestroyed]
- this[kOnDestroyed] = null
- for (let i = 0; i < callbacks.length; i++) {
- callbacks[i](null, null)
- }
- }
-
- // Should not error.
- this[kDestroy](err).then(() => {
- queueMicrotask(onDestroyed)
- })
- }
-
- dispatch (opts, handler) {
- if (!handler || typeof handler !== 'object') {
- throw new InvalidArgumentError('handler must be an object')
- }
-
- try {
- if (!opts || typeof opts !== 'object') {
- throw new InvalidArgumentError('opts must be an object.')
- }
-
- if (this[kDestroyed]) {
- throw new ClientDestroyedError()
- }
-
- if (this[kClosed]) {
- throw new ClientClosedError()
- }
-
- return this[kDispatch](opts, handler)
- } catch (err) {
- if (typeof handler.onError !== 'function') {
- throw new InvalidArgumentError('invalid onError method')
- }
-
- handler.onError(err)
-
- return false
- }
- }
-}
-
-module.exports = DispatcherBase
diff --git a/node_modules/undici/lib/dispatcher.js b/node_modules/undici/lib/dispatcher.js
deleted file mode 100644
index 9b809d8..0000000
--- a/node_modules/undici/lib/dispatcher.js
+++ /dev/null
@@ -1,19 +0,0 @@
-'use strict'
-
-const EventEmitter = require('events')
-
-class Dispatcher extends EventEmitter {
- dispatch () {
- throw new Error('not implemented')
- }
-
- close () {
- throw new Error('not implemented')
- }
-
- destroy () {
- throw new Error('not implemented')
- }
-}
-
-module.exports = Dispatcher
diff --git a/node_modules/undici/lib/fetch/body.js b/node_modules/undici/lib/fetch/body.js
deleted file mode 100644
index 2228376..0000000
--- a/node_modules/undici/lib/fetch/body.js
+++ /dev/null
@@ -1,402 +0,0 @@
-'use strict'
-
-const util = require('../core/util')
-const { ReadableStreamFrom, toUSVString, isBlobLike } = require('./util')
-const { FormData } = require('./formdata')
-const { kState } = require('./symbols')
-const { webidl } = require('./webidl')
-const { Blob } = require('buffer')
-const { kBodyUsed } = require('../core/symbols')
-const assert = require('assert')
-const { NotSupportedError } = require('../core/errors')
-const { isErrored } = require('../core/util')
-const { isUint8Array, isArrayBuffer } = require('util/types')
-
-let ReadableStream
-
-async function * blobGen (blob) {
- if (blob.stream) {
- yield * blob.stream()
- } else {
- // istanbul ignore next: node < 16.7
- yield await blob.arrayBuffer()
- }
-}
-
-// https://fetch.spec.whatwg.org/#concept-bodyinit-extract
-function extractBody (object, keepalive = false) {
- if (!ReadableStream) {
- ReadableStream = require('stream/web').ReadableStream
- }
-
- // 1. Let stream be object if object is a ReadableStream object.
- // Otherwise, let stream be a new ReadableStream, and set up stream.
- let stream = null
-
- // 2. Let action be null.
- let action = null
-
- // 3. Let source be null.
- let source = null
-
- // 4. Let length be null.
- let length = null
-
- // 5. Let Content-Type be null.
- let contentType = null
-
- // 6. Switch on object:
- if (object == null) {
- // Note: The IDL processor cannot handle this situation. See
- // https://crbug.com/335871.
- } else if (object instanceof URLSearchParams) {
- // URLSearchParams
-
- // spec says to run application/x-www-form-urlencoded on body.list
- // this is implemented in Node.js as apart of an URLSearchParams instance toString method
- // See: https://github.com/nodejs/node/blob/e46c680bf2b211bbd52cf959ca17ee98c7f657f5/lib/internal/url.js#L490
- // and https://github.com/nodejs/node/blob/e46c680bf2b211bbd52cf959ca17ee98c7f657f5/lib/internal/url.js#L1100
-
- // Set source to the result of running the application/x-www-form-urlencoded serializer with object’s list.
- source = object.toString()
-
- // Set Content-Type to `application/x-www-form-urlencoded;charset=UTF-8`.
- contentType = 'application/x-www-form-urlencoded;charset=UTF-8'
- } else if (isArrayBuffer(object) || ArrayBuffer.isView(object)) {
- // BufferSource
-
- if (object instanceof DataView) {
- // TODO: Blob doesn't seem to work with DataView?
- object = object.buffer
- }
-
- // Set source to a copy of the bytes held by object.
- source = new Uint8Array(object)
- } else if (util.isFormDataLike(object)) {
- const boundary = '----formdata-undici-' + Math.random()
- const prefix = `--${boundary}\r\nContent-Disposition: form-data`
-
- /*! formdata-polyfill. MIT License. Jimmy Wärting */
- const escape = (str) =>
- str.replace(/\n/g, '%0A').replace(/\r/g, '%0D').replace(/"/g, '%22')
- const normalizeLinefeeds = (value) => value.replace(/\r?\n|\r/g, '\r\n')
-
- // Set action to this step: run the multipart/form-data
- // encoding algorithm, with object’s entry list and UTF-8.
- action = async function * (object) {
- const enc = new TextEncoder()
-
- for (const [name, value] of object) {
- if (typeof value === 'string') {
- yield enc.encode(
- prefix +
- `; name="${escape(normalizeLinefeeds(name))}"` +
- `\r\n\r\n${normalizeLinefeeds(value)}\r\n`
- )
- } else {
- yield enc.encode(
- prefix +
- `; name="${escape(normalizeLinefeeds(name))}"` +
- (value.name ? `; filename="${escape(value.name)}"` : '') +
- '\r\n' +
- `Content-Type: ${
- value.type || 'application/octet-stream'
- }\r\n\r\n`
- )
-
- yield * blobGen(value)
-
- yield enc.encode('\r\n')
- }
- }
-
- yield enc.encode(`--${boundary}--`)
- }
-
- // Set source to object.
- source = object
-
- // Set length to unclear, see html/6424 for improving this.
- // TODO
-
- // Set Content-Type to `multipart/form-data; boundary=`,
- // followed by the multipart/form-data boundary string generated
- // by the multipart/form-data encoding algorithm.
- contentType = 'multipart/form-data; boundary=' + boundary
- } else if (isBlobLike(object)) {
- // Blob
-
- // Set action to this step: read object.
- action = blobGen
-
- // Set source to object.
- source = object
-
- // Set length to object’s size.
- length = object.size
-
- // If object’s type attribute is not the empty byte sequence, set
- // Content-Type to its value.
- if (object.type) {
- contentType = object.type
- }
- } else if (typeof object[Symbol.asyncIterator] === 'function') {
- // If keepalive is true, then throw a TypeError.
- if (keepalive) {
- throw new TypeError('keepalive')
- }
-
- // If object is disturbed or locked, then throw a TypeError.
- if (util.isDisturbed(object) || object.locked) {
- throw new TypeError(
- 'Response body object should not be disturbed or locked'
- )
- }
-
- stream =
- object instanceof ReadableStream ? object : ReadableStreamFrom(object)
- } else {
- // TODO: byte sequence?
- // TODO: scalar value string?
- // TODO: else?
- source = toUSVString(object)
- contentType = 'text/plain;charset=UTF-8'
- }
-
- // 7. If source is a byte sequence, then set action to a
- // step that returns source and length to source’s length.
- // TODO: What is a "byte sequence?"
- if (typeof source === 'string' || util.isBuffer(source)) {
- length = Buffer.byteLength(source)
- }
-
- // 8. If action is non-null, then run these steps in in parallel:
- if (action != null) {
- // Run action.
- let iterator
- stream = new ReadableStream({
- async start () {
- iterator = action(object)[Symbol.asyncIterator]()
- },
- async pull (controller) {
- const { value, done } = await iterator.next()
- if (done) {
- // When running action is done, close stream.
- queueMicrotask(() => {
- controller.close()
- })
- } else {
- // Whenever one or more bytes are available and stream is not errored,
- // enqueue a Uint8Array wrapping an ArrayBuffer containing the available
- // bytes into stream.
- if (!isErrored(stream)) {
- controller.enqueue(new Uint8Array(value))
- }
- }
- return controller.desiredSize > 0
- },
- async cancel (reason) {
- await iterator.return()
- }
- })
- } else if (!stream) {
- // TODO: Spec doesn't say anything about this?
- stream = new ReadableStream({
- async pull (controller) {
- controller.enqueue(
- typeof source === 'string' ? new TextEncoder().encode(source) : source
- )
- queueMicrotask(() => {
- controller.close()
- })
- }
- })
- }
-
- // 9. Let body be a body whose stream is stream, source is source,
- // and length is length.
- const body = { stream, source, length }
-
- // 10. Return body and Content-Type.
- return [body, contentType]
-}
-
-// https://fetch.spec.whatwg.org/#bodyinit-safely-extract
-function safelyExtractBody (object, keepalive = false) {
- if (!ReadableStream) {
- // istanbul ignore next
- ReadableStream = require('stream/web').ReadableStream
- }
-
- // To safely extract a body and a `Content-Type` value from
- // a byte sequence or BodyInit object object, run these steps:
-
- // 1. If object is a ReadableStream object, then:
- if (object instanceof ReadableStream) {
- // Assert: object is neither disturbed nor locked.
- // istanbul ignore next
- assert(!util.isDisturbed(object), 'disturbed')
- // istanbul ignore next
- assert(!object.locked, 'locked')
- }
-
- // 2. Return the results of extracting object.
- return extractBody(object, keepalive)
-}
-
-function cloneBody (body) {
- // To clone a body body, run these steps:
-
- // https://fetch.spec.whatwg.org/#concept-body-clone
-
- // 1. Let « out1, out2 » be the result of teeing body’s stream.
- const [out1, out2] = body.stream.tee()
-
- // 2. Set body’s stream to out1.
- body.stream = out1
-
- // 3. Return a body whose stream is out2 and other members are copied from body.
- return {
- stream: out2,
- length: body.length,
- source: body.source
- }
-}
-
-function bodyMixinMethods (instance) {
- const methods = {
- async blob () {
- if (!(this instanceof instance)) {
- throw new TypeError('Illegal invocation')
- }
-
- const chunks = []
-
- if (this[kState].body) {
- if (isUint8Array(this[kState].body)) {
- chunks.push(this[kState].body)
- } else {
- const stream = this[kState].body.stream
-
- if (util.isDisturbed(stream)) {
- throw new TypeError('disturbed')
- }
-
- if (stream.locked) {
- throw new TypeError('locked')
- }
-
- // Compat.
- stream[kBodyUsed] = true
-
- for await (const chunk of stream) {
- chunks.push(chunk)
- }
- }
- }
-
- return new Blob(chunks, { type: this.headers.get('Content-Type') || '' })
- },
-
- async arrayBuffer () {
- if (!(this instanceof instance)) {
- throw new TypeError('Illegal invocation')
- }
-
- const blob = await this.blob()
- return await blob.arrayBuffer()
- },
-
- async text () {
- if (!(this instanceof instance)) {
- throw new TypeError('Illegal invocation')
- }
-
- const blob = await this.blob()
- return toUSVString(await blob.text())
- },
-
- async json () {
- if (!(this instanceof instance)) {
- throw new TypeError('Illegal invocation')
- }
-
- return JSON.parse(await this.text())
- },
-
- async formData () {
- if (!(this instanceof instance)) {
- throw new TypeError('Illegal invocation')
- }
-
- const contentType = this.headers.get('Content-Type')
-
- // If mimeType’s essence is "multipart/form-data", then:
- if (/multipart\/form-data/.test(contentType)) {
- throw new NotSupportedError('multipart/form-data not supported')
- } else if (/application\/x-www-form-urlencoded/.test(contentType)) {
- // Otherwise, if mimeType’s essence is "application/x-www-form-urlencoded", then:
-
- // 1. Let entries be the result of parsing bytes.
- let entries
- try {
- entries = new URLSearchParams(await this.text())
- } catch (err) {
- // istanbul ignore next: Unclear when new URLSearchParams can fail on a string.
- // 2. If entries is failure, then throw a TypeError.
- throw Object.assign(new TypeError(), { cause: err })
- }
-
- // 3. Return a new FormData object whose entries are entries.
- const formData = new FormData()
- for (const [name, value] of entries) {
- formData.append(name, value)
- }
- return formData
- } else {
- // Otherwise, throw a TypeError.
- webidl.errors.exception({
- header: `${instance.name}.formData`,
- value: 'Could not parse content as FormData.'
- })
- }
- }
- }
-
- return methods
-}
-
-const properties = {
- body: {
- enumerable: true,
- get () {
- if (!this || !this[kState]) {
- throw new TypeError('Illegal invocation')
- }
-
- return this[kState].body ? this[kState].body.stream : null
- }
- },
- bodyUsed: {
- enumerable: true,
- get () {
- if (!this || !this[kState]) {
- throw new TypeError('Illegal invocation')
- }
-
- return !!this[kState].body && util.isDisturbed(this[kState].body.stream)
- }
- }
-}
-
-function mixinBody (prototype) {
- Object.assign(prototype.prototype, bodyMixinMethods(prototype))
- Object.defineProperties(prototype.prototype, properties)
-}
-
-module.exports = {
- extractBody,
- safelyExtractBody,
- cloneBody,
- mixinBody
-}
diff --git a/node_modules/undici/lib/fetch/constants.js b/node_modules/undici/lib/fetch/constants.js
deleted file mode 100644
index 6d201e0..0000000
--- a/node_modules/undici/lib/fetch/constants.js
+++ /dev/null
@@ -1,88 +0,0 @@
-'use strict'
-
-const corsSafeListedMethods = ['GET', 'HEAD', 'POST']
-
-const nullBodyStatus = [101, 204, 205, 304]
-
-const redirectStatus = [301, 302, 303, 307, 308]
-
-const referrerPolicy = [
- '',
- 'no-referrer',
- 'no-referrer-when-downgrade',
- 'same-origin',
- 'origin',
- 'strict-origin',
- 'origin-when-cross-origin',
- 'strict-origin-when-cross-origin',
- 'unsafe-url'
-]
-
-const requestRedirect = ['follow', 'manual', 'error']
-
-const safeMethods = ['GET', 'HEAD', 'OPTIONS', 'TRACE']
-
-const requestMode = ['navigate', 'same-origin', 'no-cors', 'cors']
-
-const requestCredentials = ['omit', 'same-origin', 'include']
-
-const requestCache = [
- 'default',
- 'no-store',
- 'reload',
- 'no-cache',
- 'force-cache',
- 'only-if-cached'
-]
-
-const requestBodyHeader = [
- 'content-encoding',
- 'content-language',
- 'content-location',
- 'content-type'
-]
-
-// http://fetch.spec.whatwg.org/#forbidden-method
-const forbiddenMethods = ['CONNECT', 'TRACE', 'TRACK']
-
-const subresource = [
- 'audio',
- 'audioworklet',
- 'font',
- 'image',
- 'manifest',
- 'paintworklet',
- 'script',
- 'style',
- 'track',
- 'video',
- 'xslt',
- ''
-]
-
-/** @type {globalThis['DOMException']} */
-const DOMException = globalThis.DOMException ?? (() => {
- // DOMException was only made a global in Node v17.0.0,
- // but fetch supports >= v16.5.
- try {
- atob('~')
- } catch (err) {
- return Object.getPrototypeOf(err).constructor
- }
-})()
-
-module.exports = {
- DOMException,
- subresource,
- forbiddenMethods,
- requestBodyHeader,
- referrerPolicy,
- requestRedirect,
- requestMode,
- requestCredentials,
- requestCache,
- redirectStatus,
- corsSafeListedMethods,
- nullBodyStatus,
- safeMethods
-}
diff --git a/node_modules/undici/lib/fetch/dataURL.js b/node_modules/undici/lib/fetch/dataURL.js
deleted file mode 100644
index 5eb0a51..0000000
--- a/node_modules/undici/lib/fetch/dataURL.js
+++ /dev/null
@@ -1,557 +0,0 @@
-const assert = require('assert')
-const { atob } = require('buffer')
-
-const encoder = new TextEncoder()
-
-// https://fetch.spec.whatwg.org/#data-url-processor
-/** @param {URL} dataURL */
-function dataURLProcessor (dataURL) {
- // 1. Assert: dataURL’s scheme is "data".
- assert(dataURL.protocol === 'data:')
-
- // 2. Let input be the result of running the URL
- // serializer on dataURL with exclude fragment
- // set to true.
- let input = URLSerializer(dataURL, true)
-
- // 3. Remove the leading "data:" string from input.
- input = input.slice(5)
-
- // 4. Let position point at the start of input.
- const position = { position: 0 }
-
- // 5. Let mimeType be the result of collecting a
- // sequence of code points that are not equal
- // to U+002C (,), given position.
- let mimeType = collectASequenceOfCodePoints(
- (char) => char !== ',',
- input,
- position
- )
-
- // 6. Strip leading and trailing ASCII whitespace
- // from mimeType.
- // Note: This will only remove U+0020 SPACE code
- // points, if any.
- // Undici implementation note: we need to store the
- // length because if the mimetype has spaces removed,
- // the wrong amount will be sliced from the input in
- // step #9
- const mimeTypeLength = mimeType.length
- mimeType = mimeType.replace(/^(\u0020)+|(\u0020)+$/g, '')
-
- // 7. If position is past the end of input, then
- // return failure
- if (position.position >= input.length) {
- return 'failure'
- }
-
- // 8. Advance position by 1.
- position.position++
-
- // 9. Let encodedBody be the remainder of input.
- const encodedBody = input.slice(mimeTypeLength + 1)
-
- // 10. Let body be the percent-decoding of encodedBody.
- /** @type {Uint8Array|string} */
- let body = stringPercentDecode(encodedBody)
-
- // 11. If mimeType ends with U+003B (;), followed by
- // zero or more U+0020 SPACE, followed by an ASCII
- // case-insensitive match for "base64", then:
- if (/;(\u0020){0,}base64$/i.test(mimeType)) {
- // 1. Let stringBody be the isomorphic decode of body.
- const stringBody = decodeURIComponent(new TextDecoder('utf-8').decode(body))
- // 2. Set body to the forgiving-base64 decode of
- // stringBody.
- body = forgivingBase64(stringBody)
-
- // 3. If body is failure, then return failure.
- if (body === 'failure') {
- return 'failure'
- }
-
- // 4. Remove the last 6 code points from mimeType.
- mimeType = mimeType.slice(0, -6)
-
- // 5. Remove trailing U+0020 SPACE code points from mimeType,
- // if any.
- mimeType = mimeType.replace(/(\u0020)+$/, '')
-
- // 6. Remove the last U+003B (;) code point from mimeType.
- mimeType = mimeType.slice(0, -1)
- }
-
- // 12. If mimeType starts with U+003B (;), then prepend
- // "text/plain" to mimeType.
- if (mimeType.startsWith(';')) {
- mimeType = 'text/plain' + mimeType
- }
-
- // 13. Let mimeTypeRecord be the result of parsing
- // mimeType.
- let mimeTypeRecord = parseMIMEType(mimeType)
-
- // 14. If mimeTypeRecord is failure, then set
- // mimeTypeRecord to text/plain;charset=US-ASCII.
- if (mimeTypeRecord === 'failure') {
- mimeTypeRecord = parseMIMEType('text/plain;charset=US-ASCII')
- }
-
- // 15. Return a new data: URL struct whose MIME
- // type is mimeTypeRecord and body is body.
- // https://fetch.spec.whatwg.org/#data-url-struct
- return { mimeType: mimeTypeRecord, body }
-}
-
-// https://url.spec.whatwg.org/#concept-url-serializer
-/**
- * @param {URL} url
- * @param {boolean} excludeFragment
- */
-function URLSerializer (url, excludeFragment = false) {
- // 1. Let output be url’s scheme and U+003A (:) concatenated.
- let output = url.protocol
-
- // 2. If url’s host is non-null:
- if (url.host.length > 0) {
- // 1. Append "//" to output.
- output += '//'
-
- // 2. If url includes credentials, then:
- if (url.username.length > 0 || url.password.length > 0) {
- // 1. Append url’s username to output.
- output += url.username
-
- // 2. If url’s password is not the empty string, then append U+003A (:),
- // followed by url’s password, to output.
- if (url.password.length > 0) {
- output += ':' + url.password
- }
-
- // 3. Append U+0040 (@) to output.
- output += '@'
- }
-
- // 3. Append url’s host, serialized, to output.
- output += decodeURIComponent(url.host)
-
- // 4. If url’s port is non-null, append U+003A (:) followed by url’s port,
- // serialized, to output.
- if (url.port.length > 0) {
- output += ':' + url.port
- }
- }
-
- // 3. If url’s host is null, url does not have an opaque path,
- // url’s path’s size is greater than 1, and url’s path[0]
- // is the empty string, then append U+002F (/) followed by
- // U+002E (.) to output.
- // Note: This prevents web+demo:/.//not-a-host/ or web+demo:/path/..//not-a-host/,
- // when parsed and then serialized, from ending up as web+demo://not-a-host/
- // (they end up as web+demo:/.//not-a-host/).
- // Undici implementation note: url's path[0] can never be an
- // empty string, so we have to slightly alter what the spec says.
- if (
- url.host.length === 0 &&
- url.pathname.length > 1 &&
- url.href.slice(url.protocol.length + 1)[0] === '.'
- ) {
- output += '/.'
- }
-
- // 4. Append the result of URL path serializing url to output.
- output += url.pathname
-
- // 5. If url’s query is non-null, append U+003F (?),
- // followed by url’s query, to output.
- if (url.search.length > 0) {
- output += url.search
- }
-
- // 6. If exclude fragment is false and url’s fragment is non-null,
- // then append U+0023 (#), followed by url’s fragment, to output.
- if (excludeFragment === false && url.hash.length > 0) {
- output += url.hash
- }
-
- // 7. Return output.
- return output
-}
-
-// https://infra.spec.whatwg.org/#collect-a-sequence-of-code-points
-/**
- * @param {(char: string) => boolean} condition
- * @param {string} input
- * @param {{ position: number }} position
- */
-function collectASequenceOfCodePoints (condition, input, position) {
- // 1. Let result be the empty string.
- let result = ''
-
- // 2. While position doesn’t point past the end of input and the
- // code point at position within input meets the condition condition:
- while (position.position < input.length && condition(input[position.position])) {
- // 1. Append that code point to the end of result.
- result += input[position.position]
-
- // 2. Advance position by 1.
- position.position++
- }
-
- // 3. Return result.
- return result
-}
-
-// https://url.spec.whatwg.org/#string-percent-decode
-/** @param {string} input */
-function stringPercentDecode (input) {
- // 1. Let bytes be the UTF-8 encoding of input.
- const bytes = encoder.encode(input)
-
- // 2. Return the percent-decoding of bytes.
- return percentDecode(bytes)
-}
-
-// https://url.spec.whatwg.org/#percent-decode
-/** @param {Uint8Array} input */
-function percentDecode (input) {
- // 1. Let output be an empty byte sequence.
- /** @type {number[]} */
- const output = []
-
- // 2. For each byte byte in input:
- for (let i = 0; i < input.length; i++) {
- const byte = input[i]
-
- // 1. If byte is not 0x25 (%), then append byte to output.
- if (byte !== 0x25) {
- output.push(byte)
-
- // 2. Otherwise, if byte is 0x25 (%) and the next two bytes
- // after byte in input are not in the ranges
- // 0x30 (0) to 0x39 (9), 0x41 (A) to 0x46 (F),
- // and 0x61 (a) to 0x66 (f), all inclusive, append byte
- // to output.
- } else if (
- byte === 0x25 &&
- !/^[0-9A-Fa-f]{2}$/i.test(String.fromCharCode(input[i + 1], input[i + 2]))
- ) {
- output.push(0x25)
-
- // 3. Otherwise:
- } else {
- // 1. Let bytePoint be the two bytes after byte in input,
- // decoded, and then interpreted as hexadecimal number.
- const nextTwoBytes = String.fromCharCode(input[i + 1], input[i + 2])
- const bytePoint = Number.parseInt(nextTwoBytes, 16)
-
- // 2. Append a byte whose value is bytePoint to output.
- output.push(bytePoint)
-
- // 3. Skip the next two bytes in input.
- i += 2
- }
- }
-
- // 3. Return output.
- return Uint8Array.of(...output)
-}
-
-// https://mimesniff.spec.whatwg.org/#parse-a-mime-type
-/** @param {string} input */
-function parseMIMEType (input) {
- // 1. Remove any leading and trailing HTTP whitespace
- // from input.
- input = input.trim()
-
- // 2. Let position be a position variable for input,
- // initially pointing at the start of input.
- const position = { position: 0 }
-
- // 3. Let type be the result of collecting a sequence
- // of code points that are not U+002F (/) from
- // input, given position.
- const type = collectASequenceOfCodePoints(
- (char) => char !== '/',
- input,
- position
- )
-
- // 4. If type is the empty string or does not solely
- // contain HTTP token code points, then return failure.
- // https://mimesniff.spec.whatwg.org/#http-token-code-point
- if (type.length === 0 || !/^[!#$%&'*+-.^_|~A-z0-9]+$/.test(type)) {
- return 'failure'
- }
-
- // 5. If position is past the end of input, then return
- // failure
- if (position.position > input.length) {
- return 'failure'
- }
-
- // 6. Advance position by 1. (This skips past U+002F (/).)
- position.position++
-
- // 7. Let subtype be the result of collecting a sequence of
- // code points that are not U+003B (;) from input, given
- // position.
- let subtype = collectASequenceOfCodePoints(
- (char) => char !== ';',
- input,
- position
- )
-
- // 8. Remove any trailing HTTP whitespace from subtype.
- subtype = subtype.trim()
-
- // 9. If subtype is the empty string or does not solely
- // contain HTTP token code points, then return failure.
- if (subtype.length === 0 || !/^[!#$%&'*+-.^_|~A-z0-9]+$/.test(subtype)) {
- return 'failure'
- }
-
- // 10. Let mimeType be a new MIME type record whose type
- // is type, in ASCII lowercase, and subtype is subtype,
- // in ASCII lowercase.
- // https://mimesniff.spec.whatwg.org/#mime-type
- const mimeType = {
- type: type.toLowerCase(),
- subtype: subtype.toLowerCase(),
- /** @type {Map} */
- parameters: new Map()
- }
-
- // 11. While position is not past the end of input:
- while (position.position < input.length) {
- // 1. Advance position by 1. (This skips past U+003B (;).)
- position.position++
-
- // 2. Collect a sequence of code points that are HTTP
- // whitespace from input given position.
- collectASequenceOfCodePoints(
- // https://fetch.spec.whatwg.org/#http-whitespace
- (char) => /(\u000A|\u000D|\u0009|\u0020)/.test(char), // eslint-disable-line
- input,
- position
- )
-
- // 3. Let parameterName be the result of collecting a
- // sequence of code points that are not U+003B (;)
- // or U+003D (=) from input, given position.
- let parameterName = collectASequenceOfCodePoints(
- (char) => char !== ';' && char !== '=',
- input,
- position
- )
-
- // 4. Set parameterName to parameterName, in ASCII
- // lowercase.
- parameterName = parameterName.toLowerCase()
-
- // 5. If position is not past the end of input, then:
- if (position.position < input.length) {
- // 1. If the code point at position within input is
- // U+003B (;), then continue.
- if (input[position.position] === ';') {
- continue
- }
-
- // 2. Advance position by 1. (This skips past U+003D (=).)
- position.position++
- }
-
- // 6. If position is past the end of input, then break.
- if (position.position > input.length) {
- break
- }
-
- // 7. Let parameterValue be null.
- let parameterValue = null
-
- // 8. If the code point at position within input is
- // U+0022 ("), then:
- if (input[position.position] === '"') {
- // 1. Set parameterValue to the result of collecting
- // an HTTP quoted string from input, given position
- // and the extract-value flag.
- // Undici implementation note: extract-value is never
- // defined or mentioned anywhere.
- parameterValue = collectAnHTTPQuotedString(input, position/*, extractValue */)
-
- // 2. Collect a sequence of code points that are not
- // U+003B (;) from input, given position.
- collectASequenceOfCodePoints(
- (char) => char !== ';',
- input,
- position
- )
-
- // 9. Otherwise:
- } else {
- // 1. Set parameterValue to the result of collecting
- // a sequence of code points that are not U+003B (;)
- // from input, given position.
- parameterValue = collectASequenceOfCodePoints(
- (char) => char !== ';',
- input,
- position
- )
-
- // 2. Remove any trailing HTTP whitespace from parameterValue.
- parameterValue = parameterValue.trim()
-
- // 3. If parameterValue is the empty string, then continue.
- if (parameterValue.length === 0) {
- continue
- }
- }
-
- // 10. If all of the following are true
- // - parameterName is not the empty string
- // - parameterName solely contains HTTP token code points
- // - parameterValue solely contains HTTP quoted-string token code points
- // - mimeType’s parameters[parameterName] does not exist
- // then set mimeType’s parameters[parameterName] to parameterValue.
- if (
- parameterName.length !== 0 &&
- /^[!#$%&'*+-.^_|~A-z0-9]+$/.test(parameterName) &&
- // https://mimesniff.spec.whatwg.org/#http-quoted-string-token-code-point
- !/^(\u0009|\x{0020}-\x{007E}|\x{0080}-\x{00FF})+$/.test(parameterValue) && // eslint-disable-line
- !mimeType.parameters.has(parameterName)
- ) {
- mimeType.parameters.set(parameterName, parameterValue)
- }
- }
-
- // 12. Return mimeType.
- return mimeType
-}
-
-// https://infra.spec.whatwg.org/#forgiving-base64-decode
-/** @param {string} data */
-function forgivingBase64 (data) {
- // 1. Remove all ASCII whitespace from data.
- data = data.replace(/[\u0009\u000A\u000C\u000D\u0020]/g, '') // eslint-disable-line
-
- // 2. If data’s code point length divides by 4 leaving
- // no remainder, then:
- if (data.length % 4 === 0) {
- // 1. If data ends with one or two U+003D (=) code points,
- // then remove them from data.
- data = data.replace(/=?=$/, '')
- }
-
- // 3. If data’s code point length divides by 4 leaving
- // a remainder of 1, then return failure.
- if (data.length % 4 === 1) {
- return 'failure'
- }
-
- // 4. If data contains a code point that is not one of
- // U+002B (+)
- // U+002F (/)
- // ASCII alphanumeric
- // then return failure.
- if (/[^+/0-9A-Za-z]/.test(data)) {
- return 'failure'
- }
-
- const binary = atob(data)
- const bytes = new Uint8Array(binary.length)
-
- for (let byte = 0; byte < binary.length; byte++) {
- bytes[byte] = binary.charCodeAt(byte)
- }
-
- return bytes
-}
-
-// https://fetch.spec.whatwg.org/#collect-an-http-quoted-string
-// tests: https://fetch.spec.whatwg.org/#example-http-quoted-string
-/**
- * @param {string} input
- * @param {{ position: number }} position
- * @param {boolean?} extractValue
- */
-function collectAnHTTPQuotedString (input, position, extractValue) {
- // 1. Let positionStart be position.
- const positionStart = position.position
-
- // 2. Let value be the empty string.
- let value = ''
-
- // 3. Assert: the code point at position within input
- // is U+0022 (").
- assert(input[position.position] === '"')
-
- // 4. Advance position by 1.
- position.position++
-
- // 5. While true:
- while (true) {
- // 1. Append the result of collecting a sequence of code points
- // that are not U+0022 (") or U+005C (\) from input, given
- // position, to value.
- value += collectASequenceOfCodePoints(
- (char) => char !== '"' && char !== '\\',
- input,
- position
- )
-
- // 2. If position is past the end of input, then break.
- if (position.position >= input.length) {
- break
- }
-
- // 3. Let quoteOrBackslash be the code point at position within
- // input.
- const quoteOrBackslash = input[position.position]
-
- // 4. Advance position by 1.
- position.position++
-
- // 5. If quoteOrBackslash is U+005C (\), then:
- if (quoteOrBackslash === '\\') {
- // 1. If position is past the end of input, then append
- // U+005C (\) to value and break.
- if (position.position >= input.length) {
- value += '\\'
- break
- }
-
- // 2. Append the code point at position within input to value.
- value += input[position.position]
-
- // 3. Advance position by 1.
- position.position++
-
- // 6. Otherwise:
- } else {
- // 1. Assert: quoteOrBackslash is U+0022 (").
- assert(quoteOrBackslash === '"')
-
- // 2. Break.
- break
- }
- }
-
- // 6. If the extract-value flag is set, then return value.
- if (extractValue) {
- return value
- }
-
- // 7. Return the code points from positionStart to position,
- // inclusive, within input.
- return input.slice(positionStart, position.position)
-}
-
-module.exports = {
- dataURLProcessor,
- URLSerializer,
- collectASequenceOfCodePoints,
- stringPercentDecode,
- parseMIMEType,
- collectAnHTTPQuotedString
-}
diff --git a/node_modules/undici/lib/fetch/file.js b/node_modules/undici/lib/fetch/file.js
deleted file mode 100644
index 647fc5f..0000000
--- a/node_modules/undici/lib/fetch/file.js
+++ /dev/null
@@ -1,313 +0,0 @@
-'use strict'
-
-const { Blob } = require('buffer')
-const { types } = require('util')
-const { kState } = require('./symbols')
-const { isBlobLike } = require('./util')
-const { webidl } = require('./webidl')
-
-class File extends Blob {
- constructor (fileBits, fileName, options = {}) {
- // The File constructor is invoked with two or three parameters, depending
- // on whether the optional dictionary parameter is used. When the File()
- // constructor is invoked, user agents must run the following steps:
- if (arguments.length < 2) {
- throw new TypeError('2 arguments required')
- }
-
- fileBits = webidl.converters['sequence'](fileBits)
- fileName = webidl.converters.USVString(fileName)
- options = webidl.converters.FilePropertyBag(options)
-
- // 1. Let bytes be the result of processing blob parts given fileBits and
- // options.
- // Note: Blob handles this for us
-
- // 2. Let n be the fileName argument to the constructor.
- const n = fileName
-
- // 3. Process FilePropertyBag dictionary argument by running the following
- // substeps:
-
- // 1. If the type member is provided and is not the empty string, let t
- // be set to the type dictionary member. If t contains any characters
- // outside the range U+0020 to U+007E, then set t to the empty string
- // and return from these substeps.
- // 2. Convert every character in t to ASCII lowercase.
- // Note: Blob handles both of these steps for us
-
- // 3. If the lastModified member is provided, let d be set to the
- // lastModified dictionary member. If it is not provided, set d to the
- // current date and time represented as the number of milliseconds since
- // the Unix Epoch (which is the equivalent of Date.now() [ECMA-262]).
- const d = options.lastModified
-
- // 4. Return a new File object F such that:
- // F refers to the bytes byte sequence.
- // F.size is set to the number of total bytes in bytes.
- // F.name is set to n.
- // F.type is set to t.
- // F.lastModified is set to d.
-
- super(processBlobParts(fileBits, options), { type: options.type })
- this[kState] = {
- name: n,
- lastModified: d
- }
- }
-
- get name () {
- if (!(this instanceof File)) {
- throw new TypeError('Illegal invocation')
- }
-
- return this[kState].name
- }
-
- get lastModified () {
- if (!(this instanceof File)) {
- throw new TypeError('Illegal invocation')
- }
-
- return this[kState].lastModified
- }
-
- get [Symbol.toStringTag] () {
- return this.constructor.name
- }
-}
-
-class FileLike {
- constructor (blobLike, fileName, options = {}) {
- // TODO: argument idl type check
-
- // The File constructor is invoked with two or three parameters, depending
- // on whether the optional dictionary parameter is used. When the File()
- // constructor is invoked, user agents must run the following steps:
-
- // 1. Let bytes be the result of processing blob parts given fileBits and
- // options.
-
- // 2. Let n be the fileName argument to the constructor.
- const n = fileName
-
- // 3. Process FilePropertyBag dictionary argument by running the following
- // substeps:
-
- // 1. If the type member is provided and is not the empty string, let t
- // be set to the type dictionary member. If t contains any characters
- // outside the range U+0020 to U+007E, then set t to the empty string
- // and return from these substeps.
- // TODO
- const t = options.type
-
- // 2. Convert every character in t to ASCII lowercase.
- // TODO
-
- // 3. If the lastModified member is provided, let d be set to the
- // lastModified dictionary member. If it is not provided, set d to the
- // current date and time represented as the number of milliseconds since
- // the Unix Epoch (which is the equivalent of Date.now() [ECMA-262]).
- const d = options.lastModified ?? Date.now()
-
- // 4. Return a new File object F such that:
- // F refers to the bytes byte sequence.
- // F.size is set to the number of total bytes in bytes.
- // F.name is set to n.
- // F.type is set to t.
- // F.lastModified is set to d.
-
- this[kState] = {
- blobLike,
- name: n,
- type: t,
- lastModified: d
- }
- }
-
- stream (...args) {
- if (!(this instanceof FileLike)) {
- throw new TypeError('Illegal invocation')
- }
-
- return this[kState].blobLike.stream(...args)
- }
-
- arrayBuffer (...args) {
- if (!(this instanceof FileLike)) {
- throw new TypeError('Illegal invocation')
- }
-
- return this[kState].blobLike.arrayBuffer(...args)
- }
-
- slice (...args) {
- if (!(this instanceof FileLike)) {
- throw new TypeError('Illegal invocation')
- }
-
- return this[kState].blobLike.slice(...args)
- }
-
- text (...args) {
- if (!(this instanceof FileLike)) {
- throw new TypeError('Illegal invocation')
- }
-
- return this[kState].blobLike.text(...args)
- }
-
- get size () {
- if (!(this instanceof FileLike)) {
- throw new TypeError('Illegal invocation')
- }
-
- return this[kState].blobLike.size
- }
-
- get type () {
- if (!(this instanceof FileLike)) {
- throw new TypeError('Illegal invocation')
- }
-
- return this[kState].blobLike.type
- }
-
- get name () {
- if (!(this instanceof FileLike)) {
- throw new TypeError('Illegal invocation')
- }
-
- return this[kState].name
- }
-
- get lastModified () {
- if (!(this instanceof FileLike)) {
- throw new TypeError('Illegal invocation')
- }
-
- return this[kState].lastModified
- }
-
- get [Symbol.toStringTag] () {
- return 'File'
- }
-}
-
-webidl.converters.Blob = webidl.interfaceConverter(Blob)
-
-webidl.converters.BlobPart = function (V, opts) {
- if (webidl.util.Type(V) === 'Object') {
- if (isBlobLike(V)) {
- return webidl.converters.Blob(V, { strict: false })
- }
-
- return webidl.converters.BufferSource(V, opts)
- } else {
- return webidl.converters.USVString(V, opts)
- }
-}
-
-webidl.converters['sequence'] = webidl.sequenceConverter(
- webidl.converters.BlobPart
-)
-
-// https://www.w3.org/TR/FileAPI/#dfn-FilePropertyBag
-webidl.converters.FilePropertyBag = webidl.dictionaryConverter([
- {
- key: 'lastModified',
- converter: webidl.converters['long long'],
- get defaultValue () {
- return Date.now()
- }
- },
- {
- key: 'type',
- converter: webidl.converters.DOMString,
- defaultValue: ''
- },
- {
- key: 'endings',
- converter: (value) => {
- value = webidl.converters.DOMString(value)
- value = value.toLowerCase()
-
- if (value !== 'native') {
- value = 'transparent'
- }
-
- return value
- },
- defaultValue: 'transparent'
- }
-])
-
-/**
- * @see https://www.w3.org/TR/FileAPI/#process-blob-parts
- * @param {(NodeJS.TypedArray|Blob|string)[]} parts
- * @param {{ type: string, endings: string }} options
- */
-function processBlobParts (parts, options) {
- // 1. Let bytes be an empty sequence of bytes.
- /** @type {NodeJS.TypedArray[]} */
- const bytes = []
-
- // 2. For each element in parts:
- for (const element of parts) {
- // 1. If element is a USVString, run the following substeps:
- if (typeof element === 'string') {
- // 1. Let s be element.
- let s = element
-
- // 2. If the endings member of options is "native", set s
- // to the result of converting line endings to native
- // of element.
- if (options.endings === 'native') {
- s = convertLineEndingsNative(s)
- }
-
- // 3. Append the result of UTF-8 encoding s to bytes.
- bytes.push(new TextEncoder().encode(s))
- } else if (
- types.isAnyArrayBuffer(element) ||
- types.isTypedArray(element)
- ) {
- // 2. If element is a BufferSource, get a copy of the
- // bytes held by the buffer source, and append those
- // bytes to bytes.
- if (!element.buffer) { // ArrayBuffer
- bytes.push(new Uint8Array(element))
- } else {
- bytes.push(element.buffer)
- }
- } else if (isBlobLike(element)) {
- // 3. If element is a Blob, append the bytes it represents
- // to bytes.
- bytes.push(element)
- }
- }
-
- // 3. Return bytes.
- return bytes
-}
-
-/**
- * @see https://www.w3.org/TR/FileAPI/#convert-line-endings-to-native
- * @param {string} s
- */
-function convertLineEndingsNative (s) {
- // 1. Let native line ending be be the code point U+000A LF.
- let nativeLineEnding = '\n'
-
- // 2. If the underlying platform’s conventions are to
- // represent newlines as a carriage return and line feed
- // sequence, set native line ending to the code point
- // U+000D CR followed by the code point U+000A LF.
- if (process.platform === 'win32') {
- nativeLineEnding = '\r\n'
- }
-
- return s.replace(/\r?\n/g, nativeLineEnding)
-}
-
-module.exports = { File, FileLike }
diff --git a/node_modules/undici/lib/fetch/formdata.js b/node_modules/undici/lib/fetch/formdata.js
deleted file mode 100644
index e4b9841..0000000
--- a/node_modules/undici/lib/fetch/formdata.js
+++ /dev/null
@@ -1,321 +0,0 @@
-'use strict'
-
-const { isBlobLike, isFileLike, toUSVString, makeIterator } = require('./util')
-const { kState } = require('./symbols')
-const { File, FileLike } = require('./file')
-const { webidl } = require('./webidl')
-const { Blob } = require('buffer')
-
-// https://xhr.spec.whatwg.org/#formdata
-class FormData {
- static name = 'FormData'
-
- constructor (form) {
- if (arguments.length > 0 && form != null) {
- webidl.errors.conversionFailed({
- prefix: 'FormData constructor',
- argument: 'Argument 1',
- types: ['null']
- })
- }
-
- this[kState] = []
- }
-
- append (name, value, filename = undefined) {
- if (!(this instanceof FormData)) {
- throw new TypeError('Illegal invocation')
- }
-
- if (arguments.length < 2) {
- throw new TypeError(
- `Failed to execute 'append' on 'FormData': 2 arguments required, but only ${arguments.length} present.`
- )
- }
-
- if (arguments.length === 3 && !isBlobLike(value)) {
- throw new TypeError(
- "Failed to execute 'append' on 'FormData': parameter 2 is not of type 'Blob'"
- )
- }
-
- // 1. Let value be value if given; otherwise blobValue.
-
- name = webidl.converters.USVString(name)
- value = isBlobLike(value)
- ? webidl.converters.Blob(value, { strict: false })
- : webidl.converters.USVString(value)
- filename = arguments.length === 3
- ? webidl.converters.USVString(filename)
- : undefined
-
- // 2. Let entry be the result of creating an entry with
- // name, value, and filename if given.
- const entry = makeEntry(name, value, filename)
-
- // 3. Append entry to this’s entry list.
- this[kState].push(entry)
- }
-
- delete (name) {
- if (!(this instanceof FormData)) {
- throw new TypeError('Illegal invocation')
- }
-
- if (arguments.length < 1) {
- throw new TypeError(
- `Failed to execute 'delete' on 'FormData': 1 arguments required, but only ${arguments.length} present.`
- )
- }
-
- name = webidl.converters.USVString(name)
-
- // The delete(name) method steps are to remove all entries whose name
- // is name from this’s entry list.
- const next = []
- for (const entry of this[kState]) {
- if (entry.name !== name) {
- next.push(entry)
- }
- }
-
- this[kState] = next
- }
-
- get (name) {
- if (!(this instanceof FormData)) {
- throw new TypeError('Illegal invocation')
- }
-
- if (arguments.length < 1) {
- throw new TypeError(
- `Failed to execute 'get' on 'FormData': 1 arguments required, but only ${arguments.length} present.`
- )
- }
-
- name = webidl.converters.USVString(name)
-
- // 1. If there is no entry whose name is name in this’s entry list,
- // then return null.
- const idx = this[kState].findIndex((entry) => entry.name === name)
- if (idx === -1) {
- return null
- }
-
- // 2. Return the value of the first entry whose name is name from
- // this’s entry list.
- return this[kState][idx].value
- }
-
- getAll (name) {
- if (!(this instanceof FormData)) {
- throw new TypeError('Illegal invocation')
- }
-
- if (arguments.length < 1) {
- throw new TypeError(
- `Failed to execute 'getAll' on 'FormData': 1 arguments required, but only ${arguments.length} present.`
- )
- }
-
- name = webidl.converters.USVString(name)
-
- // 1. If there is no entry whose name is name in this’s entry list,
- // then return the empty list.
- // 2. Return the values of all entries whose name is name, in order,
- // from this’s entry list.
- return this[kState]
- .filter((entry) => entry.name === name)
- .map((entry) => entry.value)
- }
-
- has (name) {
- if (!(this instanceof FormData)) {
- throw new TypeError('Illegal invocation')
- }
-
- if (arguments.length < 1) {
- throw new TypeError(
- `Failed to execute 'has' on 'FormData': 1 arguments required, but only ${arguments.length} present.`
- )
- }
-
- name = webidl.converters.USVString(name)
-
- // The has(name) method steps are to return true if there is an entry
- // whose name is name in this’s entry list; otherwise false.
- return this[kState].findIndex((entry) => entry.name === name) !== -1
- }
-
- set (name, value, filename = undefined) {
- if (!(this instanceof FormData)) {
- throw new TypeError('Illegal invocation')
- }
-
- if (arguments.length < 2) {
- throw new TypeError(
- `Failed to execute 'set' on 'FormData': 2 arguments required, but only ${arguments.length} present.`
- )
- }
-
- if (arguments.length === 3 && !isBlobLike(value)) {
- throw new TypeError(
- "Failed to execute 'set' on 'FormData': parameter 2 is not of type 'Blob'"
- )
- }
-
- // The set(name, value) and set(name, blobValue, filename) method steps
- // are:
-
- // 1. Let value be value if given; otherwise blobValue.
-
- name = webidl.converters.USVString(name)
- value = isBlobLike(value)
- ? webidl.converters.Blob(value, { strict: false })
- : webidl.converters.USVString(value)
- filename = arguments.length === 3
- ? toUSVString(filename)
- : undefined
-
- // 2. Let entry be the result of creating an entry with name, value, and
- // filename if given.
- const entry = makeEntry(name, value, filename)
-
- // 3. If there are entries in this’s entry list whose name is name, then
- // replace the first such entry with entry and remove the others.
- const idx = this[kState].findIndex((entry) => entry.name === name)
- if (idx !== -1) {
- this[kState] = [
- ...this[kState].slice(0, idx),
- entry,
- ...this[kState].slice(idx + 1).filter((entry) => entry.name !== name)
- ]
- } else {
- // 4. Otherwise, append entry to this’s entry list.
- this[kState].push(entry)
- }
- }
-
- get [Symbol.toStringTag] () {
- return this.constructor.name
- }
-
- entries () {
- if (!(this instanceof FormData)) {
- throw new TypeError('Illegal invocation')
- }
-
- return makeIterator(
- makeIterable(this[kState], 'entries'),
- 'FormData'
- )
- }
-
- keys () {
- if (!(this instanceof FormData)) {
- throw new TypeError('Illegal invocation')
- }
-
- return makeIterator(
- makeIterable(this[kState], 'keys'),
- 'FormData'
- )
- }
-
- values () {
- if (!(this instanceof FormData)) {
- throw new TypeError('Illegal invocation')
- }
-
- return makeIterator(
- makeIterable(this[kState], 'values'),
- 'FormData'
- )
- }
-
- /**
- * @param {(value: string, key: string, self: FormData) => void} callbackFn
- * @param {unknown} thisArg
- */
- forEach (callbackFn, thisArg = globalThis) {
- if (!(this instanceof FormData)) {
- throw new TypeError('Illegal invocation')
- }
-
- if (arguments.length < 1) {
- throw new TypeError(
- `Failed to execute 'forEach' on 'FormData': 1 argument required, but only ${arguments.length} present.`
- )
- }
-
- if (typeof callbackFn !== 'function') {
- throw new TypeError(
- "Failed to execute 'forEach' on 'FormData': parameter 1 is not of type 'Function'."
- )
- }
-
- for (const [key, value] of this) {
- callbackFn.apply(thisArg, [value, key, this])
- }
- }
-}
-
-FormData.prototype[Symbol.iterator] = FormData.prototype.entries
-
-/**
- * @see https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#create-an-entry
- * @param {string} name
- * @param {string|Blob} value
- * @param {?string} filename
- * @returns
- */
-function makeEntry (name, value, filename) {
- // 1. Set name to the result of converting name into a scalar value string.
- // "To convert a string into a scalar value string, replace any surrogates
- // with U+FFFD."
- // see: https://nodejs.org/dist/latest-v18.x/docs/api/buffer.html#buftostringencoding-start-end
- name = Buffer.from(name).toString('utf8')
-
- // 2. If value is a string, then set value to the result of converting
- // value into a scalar value string.
- if (typeof value === 'string') {
- value = Buffer.from(value).toString('utf8')
- } else {
- // 3. Otherwise:
-
- // 1. If value is not a File object, then set value to a new File object,
- // representing the same bytes, whose name attribute value is "blob"
- if (!isFileLike(value)) {
- value = value instanceof Blob
- ? new File([value], 'blob', { type: value.type })
- : new FileLike(value, 'blob', { type: value.type })
- }
-
- // 2. If filename is given, then set value to a new File object,
- // representing the same bytes, whose name attribute is filename.
- if (filename !== undefined) {
- value = value instanceof File
- ? new File([value], filename, { type: value.type })
- : new FileLike(value, filename, { type: value.type })
- }
- }
-
- // 4. Return an entry whose name is name and whose value is value.
- return { name, value }
-}
-
-function * makeIterable (entries, type) {
- // The value pairs to iterate over are this’s entry list’s entries
- // with the key being the name and the value being the value.
- for (const { name, value } of entries) {
- if (type === 'entries') {
- yield [name, value]
- } else if (type === 'values') {
- yield value
- } else {
- yield name
- }
- }
-}
-
-module.exports = { FormData }
diff --git a/node_modules/undici/lib/fetch/headers.js b/node_modules/undici/lib/fetch/headers.js
deleted file mode 100644
index cca9616..0000000
--- a/node_modules/undici/lib/fetch/headers.js
+++ /dev/null
@@ -1,501 +0,0 @@
-// https://github.com/Ethan-Arrowood/undici-fetch
-
-'use strict'
-
-const { kHeadersList } = require('../core/symbols')
-const { kGuard } = require('./symbols')
-const { kEnumerableProperty } = require('../core/util')
-const {
- makeIterator,
- isValidHeaderName,
- isValidHeaderValue
-} = require('./util')
-const { webidl } = require('./webidl')
-
-const kHeadersMap = Symbol('headers map')
-const kHeadersSortedMap = Symbol('headers map sorted')
-
-/**
- * @see https://fetch.spec.whatwg.org/#concept-header-value-normalize
- * @param {string} potentialValue
- */
-function headerValueNormalize (potentialValue) {
- // To normalize a byte sequence potentialValue, remove
- // any leading and trailing HTTP whitespace bytes from
- // potentialValue.
- return potentialValue.replace(
- /^[\r\n\t ]+|[\r\n\t ]+$/g,
- ''
- )
-}
-
-function fill (headers, object) {
- // To fill a Headers object headers with a given object object, run these steps:
-
- // 1. If object is a sequence, then for each header in object:
- // Note: webidl conversion to array has already been done.
- if (Array.isArray(object)) {
- for (const header of object) {
- // 1. If header does not contain exactly two items, then throw a TypeError.
- if (header.length !== 2) {
- webidl.errors.exception({
- header: 'Headers constructor',
- message: `expected name/value pair to be length 2, found ${header.length}.`
- })
- }
-
- // 2. Append (header’s first item, header’s second item) to headers.
- headers.append(header[0], header[1])
- }
- } else if (typeof object === 'object' && object !== null) {
- // Note: null should throw
-
- // 2. Otherwise, object is a record, then for each key → value in object,
- // append (key, value) to headers
- for (const [key, value] of Object.entries(object)) {
- headers.append(key, value)
- }
- } else {
- webidl.errors.conversionFailed({
- prefix: 'Headers constructor',
- argument: 'Argument 1',
- types: ['sequence>', 'record']
- })
- }
-}
-
-class HeadersList {
- constructor (init) {
- if (init instanceof HeadersList) {
- this[kHeadersMap] = new Map(init[kHeadersMap])
- this[kHeadersSortedMap] = init[kHeadersSortedMap]
- } else {
- this[kHeadersMap] = new Map(init)
- this[kHeadersSortedMap] = null
- }
- }
-
- // https://fetch.spec.whatwg.org/#header-list-contains
- contains (name) {
- // A header list list contains a header name name if list
- // contains a header whose name is a byte-case-insensitive
- // match for name.
- name = name.toLowerCase()
-
- return this[kHeadersMap].has(name)
- }
-
- clear () {
- this[kHeadersMap].clear()
- this[kHeadersSortedMap] = null
- }
-
- // https://fetch.spec.whatwg.org/#concept-header-list-append
- append (name, value) {
- this[kHeadersSortedMap] = null
-
- // 1. If list contains name, then set name to the first such
- // header’s name.
- name = name.toLowerCase()
- const exists = this[kHeadersMap].get(name)
-
- // 2. Append (name, value) to list.
- if (exists) {
- this[kHeadersMap].set(name, `${exists}, ${value}`)
- } else {
- this[kHeadersMap].set(name, `${value}`)
- }
- }
-
- // https://fetch.spec.whatwg.org/#concept-header-list-set
- set (name, value) {
- this[kHeadersSortedMap] = null
-
- // 1. If list contains name, then set the value of
- // the first such header to value and remove the
- // others.
- // 2. Otherwise, append header (name, value) to list.
- return this[kHeadersMap].set(name, value)
- }
-
- // https://fetch.spec.whatwg.org/#concept-header-list-delete
- delete (name) {
- this[kHeadersSortedMap] = null
-
- name = name.toLowerCase()
- return this[kHeadersMap].delete(name)
- }
-
- // https://fetch.spec.whatwg.org/#concept-header-list-get
- get (name) {
- name = name.toLowerCase()
-
- // 1. If list does not contain name, then return null.
- if (!this.contains(name)) {
- return null
- }
-
- // 2. Return the values of all headers in list whose name
- // is a byte-case-insensitive match for name,
- // separated from each other by 0x2C 0x20, in order.
- return this[kHeadersMap].get(name) ?? null
- }
-
- has (name) {
- name = name.toLowerCase()
- return this[kHeadersMap].has(name)
- }
-
- keys () {
- return this[kHeadersMap].keys()
- }
-
- values () {
- return this[kHeadersMap].values()
- }
-
- entries () {
- return this[kHeadersMap].entries()
- }
-
- [Symbol.iterator] () {
- return this[kHeadersMap][Symbol.iterator]()
- }
-}
-
-// https://fetch.spec.whatwg.org/#headers-class
-class Headers {
- constructor (init = undefined) {
- this[kHeadersList] = new HeadersList()
-
- // The new Headers(init) constructor steps are:
-
- // 1. Set this’s guard to "none".
- this[kGuard] = 'none'
-
- // 2. If init is given, then fill this with init.
- if (init !== undefined) {
- init = webidl.converters.HeadersInit(init)
- fill(this, init)
- }
- }
-
- get [Symbol.toStringTag] () {
- return this.constructor.name
- }
-
- // https://fetch.spec.whatwg.org/#dom-headers-append
- append (name, value) {
- if (!(this instanceof Headers)) {
- throw new TypeError('Illegal invocation')
- }
-
- if (arguments.length < 2) {
- throw new TypeError(
- `Failed to execute 'append' on 'Headers': 2 arguments required, but only ${arguments.length} present.`
- )
- }
-
- name = webidl.converters.ByteString(name)
- value = webidl.converters.ByteString(value)
-
- // 1. Normalize value.
- value = headerValueNormalize(value)
-
- // 2. If name is not a header name or value is not a
- // header value, then throw a TypeError.
- if (!isValidHeaderName(name)) {
- webidl.errors.invalidArgument({
- prefix: 'Headers.append',
- value: name,
- type: 'header name'
- })
- } else if (!isValidHeaderValue(value)) {
- webidl.errors.invalidArgument({
- prefix: 'Headers.append',
- value,
- type: 'header value'
- })
- }
-
- // 3. If headers’s guard is "immutable", then throw a TypeError.
- // 4. Otherwise, if headers’s guard is "request" and name is a
- // forbidden header name, return.
- // Note: undici does not implement forbidden header names
- if (this[kGuard] === 'immutable') {
- throw new TypeError('immutable')
- } else if (this[kGuard] === 'request-no-cors') {
- // 5. Otherwise, if headers’s guard is "request-no-cors":
- // TODO
- }
-
- // 6. Otherwise, if headers’s guard is "response" and name is a
- // forbidden response-header name, return.
-
- // 7. Append (name, value) to headers’s header list.
- // 8. If headers’s guard is "request-no-cors", then remove
- // privileged no-CORS request headers from headers
- return this[kHeadersList].append(name, value)
- }
-
- // https://fetch.spec.whatwg.org/#dom-headers-delete
- delete (name) {
- if (!(this instanceof Headers)) {
- throw new TypeError('Illegal invocation')
- }
-
- if (arguments.length < 1) {
- throw new TypeError(
- `Failed to execute 'delete' on 'Headers': 1 argument required, but only ${arguments.length} present.`
- )
- }
-
- name = webidl.converters.ByteString(name)
-
- // 1. If name is not a header name, then throw a TypeError.
- if (!isValidHeaderName(name)) {
- webidl.errors.invalidArgument({
- prefix: 'Headers.delete',
- value: name,
- type: 'header name'
- })
- }
-
- // 2. If this’s guard is "immutable", then throw a TypeError.
- // 3. Otherwise, if this’s guard is "request" and name is a
- // forbidden header name, return.
- // 4. Otherwise, if this’s guard is "request-no-cors", name
- // is not a no-CORS-safelisted request-header name, and
- // name is not a privileged no-CORS request-header name,
- // return.
- // 5. Otherwise, if this’s guard is "response" and name is
- // a forbidden response-header name, return.
- // Note: undici does not implement forbidden header names
- if (this[kGuard] === 'immutable') {
- throw new TypeError('immutable')
- } else if (this[kGuard] === 'request-no-cors') {
- // TODO
- }
-
- // 6. If this’s header list does not contain name, then
- // return.
- if (!this[kHeadersList].contains(name)) {
- return
- }
-
- // 7. Delete name from this’s header list.
- // 8. If this’s guard is "request-no-cors", then remove
- // privileged no-CORS request headers from this.
- return this[kHeadersList].delete(name)
- }
-
- // https://fetch.spec.whatwg.org/#dom-headers-get
- get (name) {
- if (!(this instanceof Headers)) {
- throw new TypeError('Illegal invocation')
- }
-
- if (arguments.length < 1) {
- throw new TypeError(
- `Failed to execute 'get' on 'Headers': 1 argument required, but only ${arguments.length} present.`
- )
- }
-
- name = webidl.converters.ByteString(name)
-
- // 1. If name is not a header name, then throw a TypeError.
- if (!isValidHeaderName(name)) {
- webidl.errors.invalidArgument({
- prefix: 'Headers.get',
- value: name,
- type: 'header name'
- })
- }
-
- // 2. Return the result of getting name from this’s header
- // list.
- return this[kHeadersList].get(name)
- }
-
- // https://fetch.spec.whatwg.org/#dom-headers-has
- has (name) {
- if (!(this instanceof Headers)) {
- throw new TypeError('Illegal invocation')
- }
-
- if (arguments.length < 1) {
- throw new TypeError(
- `Failed to execute 'has' on 'Headers': 1 argument required, but only ${arguments.length} present.`
- )
- }
-
- name = webidl.converters.ByteString(name)
-
- // 1. If name is not a header name, then throw a TypeError.
- if (!isValidHeaderName(name)) {
- webidl.errors.invalidArgument({
- prefix: 'Headers.has',
- value: name,
- type: 'header name'
- })
- }
-
- // 2. Return true if this’s header list contains name;
- // otherwise false.
- return this[kHeadersList].contains(name)
- }
-
- // https://fetch.spec.whatwg.org/#dom-headers-set
- set (name, value) {
- if (!(this instanceof Headers)) {
- throw new TypeError('Illegal invocation')
- }
-
- if (arguments.length < 2) {
- throw new TypeError(
- `Failed to execute 'set' on 'Headers': 2 arguments required, but only ${arguments.length} present.`
- )
- }
-
- name = webidl.converters.ByteString(name)
- value = webidl.converters.ByteString(value)
-
- // 1. Normalize value.
- value = headerValueNormalize(value)
-
- // 2. If name is not a header name or value is not a
- // header value, then throw a TypeError.
- if (!isValidHeaderName(name)) {
- webidl.errors.invalidArgument({
- prefix: 'Headers.set',
- value: name,
- type: 'header name'
- })
- } else if (!isValidHeaderValue(value)) {
- webidl.errors.invalidArgument({
- prefix: 'Headers.set',
- value,
- type: 'header value'
- })
- }
-
- // 3. If this’s guard is "immutable", then throw a TypeError.
- // 4. Otherwise, if this’s guard is "request" and name is a
- // forbidden header name, return.
- // 5. Otherwise, if this’s guard is "request-no-cors" and
- // name/value is not a no-CORS-safelisted request-header,
- // return.
- // 6. Otherwise, if this’s guard is "response" and name is a
- // forbidden response-header name, return.
- // Note: undici does not implement forbidden header names
- if (this[kGuard] === 'immutable') {
- throw new TypeError('immutable')
- } else if (this[kGuard] === 'request-no-cors') {
- // TODO
- }
-
- // 7. Set (name, value) in this’s header list.
- // 8. If this’s guard is "request-no-cors", then remove
- // privileged no-CORS request headers from this
- return this[kHeadersList].set(name, value)
- }
-
- get [kHeadersSortedMap] () {
- this[kHeadersList][kHeadersSortedMap] ??= new Map([...this[kHeadersList]].sort((a, b) => a[0] < b[0] ? -1 : 1))
- return this[kHeadersList][kHeadersSortedMap]
- }
-
- keys () {
- if (!(this instanceof Headers)) {
- throw new TypeError('Illegal invocation')
- }
-
- return makeIterator(this[kHeadersSortedMap].keys(), 'Headers')
- }
-
- values () {
- if (!(this instanceof Headers)) {
- throw new TypeError('Illegal invocation')
- }
-
- return makeIterator(this[kHeadersSortedMap].values(), 'Headers')
- }
-
- entries () {
- if (!(this instanceof Headers)) {
- throw new TypeError('Illegal invocation')
- }
-
- return makeIterator(this[kHeadersSortedMap].entries(), 'Headers')
- }
-
- /**
- * @param {(value: string, key: string, self: Headers) => void} callbackFn
- * @param {unknown} thisArg
- */
- forEach (callbackFn, thisArg = globalThis) {
- if (!(this instanceof Headers)) {
- throw new TypeError('Illegal invocation')
- }
-
- if (arguments.length < 1) {
- throw new TypeError(
- `Failed to execute 'forEach' on 'Headers': 1 argument required, but only ${arguments.length} present.`
- )
- }
-
- if (typeof callbackFn !== 'function') {
- throw new TypeError(
- "Failed to execute 'forEach' on 'Headers': parameter 1 is not of type 'Function'."
- )
- }
-
- for (const [key, value] of this) {
- callbackFn.apply(thisArg, [value, key, this])
- }
- }
-
- [Symbol.for('nodejs.util.inspect.custom')] () {
- if (!(this instanceof Headers)) {
- throw new TypeError('Illegal invocation')
- }
-
- return this[kHeadersList]
- }
-}
-
-Headers.prototype[Symbol.iterator] = Headers.prototype.entries
-
-Object.defineProperties(Headers.prototype, {
- append: kEnumerableProperty,
- delete: kEnumerableProperty,
- get: kEnumerableProperty,
- has: kEnumerableProperty,
- set: kEnumerableProperty,
- keys: kEnumerableProperty,
- values: kEnumerableProperty,
- entries: kEnumerableProperty,
- forEach: kEnumerableProperty
-})
-
-webidl.converters.HeadersInit = function (V) {
- if (webidl.util.Type(V) === 'Object') {
- if (V[Symbol.iterator]) {
- return webidl.converters['sequence>'](V)
- }
-
- return webidl.converters['record'](V)
- }
-
- webidl.errors.conversionFailed({
- prefix: 'Headers constructor',
- argument: 'Argument 1',
- types: ['sequence>', 'record']
- })
-}
-
-module.exports = {
- fill,
- Headers,
- HeadersList
-}
diff --git a/node_modules/undici/lib/fetch/index.js b/node_modules/undici/lib/fetch/index.js
deleted file mode 100644
index cf91a5d..0000000
--- a/node_modules/undici/lib/fetch/index.js
+++ /dev/null
@@ -1,2039 +0,0 @@
-// https://github.com/Ethan-Arrowood/undici-fetch
-
-'use strict'
-
-const {
- Response,
- makeNetworkError,
- makeAppropriateNetworkError,
- filterResponse,
- makeResponse
-} = require('./response')
-const { Headers } = require('./headers')
-const { Request, makeRequest } = require('./request')
-const zlib = require('zlib')
-const {
- matchRequestIntegrity,
- makePolicyContainer,
- clonePolicyContainer,
- requestBadPort,
- TAOCheck,
- appendRequestOriginHeader,
- responseLocationURL,
- requestCurrentURL,
- setRequestReferrerPolicyOnRedirect,
- tryUpgradeRequestToAPotentiallyTrustworthyURL,
- createOpaqueTimingInfo,
- appendFetchMetadata,
- corsCheck,
- crossOriginResourcePolicyCheck,
- determineRequestsReferrer,
- coarsenedSharedCurrentTime,
- createDeferredPromise,
- isBlobLike,
- sameOrigin,
- isCancelled,
- isAborted
-} = require('./util')
-const { kState, kHeaders, kGuard, kRealm } = require('./symbols')
-const assert = require('assert')
-const { safelyExtractBody, extractBody } = require('./body')
-const {
- redirectStatus,
- nullBodyStatus,
- safeMethods,
- requestBodyHeader,
- subresource,
- DOMException
-} = require('./constants')
-const { kHeadersList } = require('../core/symbols')
-const EE = require('events')
-const { Readable, pipeline } = require('stream')
-const { isErrored, isReadable } = require('../core/util')
-const { dataURLProcessor } = require('./dataURL')
-const { TransformStream } = require('stream/web')
-
-/** @type {import('buffer').resolveObjectURL} */
-let resolveObjectURL
-let ReadableStream
-
-const nodeVersion = process.versions.node.split('.')
-const nodeMajor = Number(nodeVersion[0])
-const nodeMinor = Number(nodeVersion[1])
-
-class Fetch extends EE {
- constructor (dispatcher) {
- super()
-
- this.dispatcher = dispatcher
- this.connection = null
- this.dump = false
- this.state = 'ongoing'
- }
-
- terminate (reason) {
- if (this.state !== 'ongoing') {
- return
- }
-
- this.state = 'terminated'
- this.connection?.destroy(reason)
- this.emit('terminated', reason)
- }
-
- abort () {
- if (this.state !== 'ongoing') {
- return
- }
-
- const reason = new DOMException('The operation was aborted.', 'AbortError')
-
- this.state = 'aborted'
- this.connection?.destroy(reason)
- this.emit('terminated', reason)
- }
-}
-
-// https://fetch.spec.whatwg.org/#fetch-method
-async function fetch (input, init = {}) {
- if (arguments.length < 1) {
- throw new TypeError(
- `Failed to execute 'fetch' on 'Window': 1 argument required, but only ${arguments.length} present.`
- )
- }
-
- // 1. Let p be a new promise.
- const p = createDeferredPromise()
-
- // 2. Let requestObject be the result of invoking the initial value of
- // Request as constructor with input and init as arguments. If this throws
- // an exception, reject p with it and return p.
- let requestObject
-
- try {
- requestObject = new Request(input, init)
- } catch (e) {
- p.reject(e)
- return p.promise
- }
-
- // 3. Let request be requestObject’s request.
- const request = requestObject[kState]
-
- // 4. If requestObject’s signal’s aborted flag is set, then:
- if (requestObject.signal.aborted) {
- // 1. Abort fetch with p, request, and null.
- abortFetch(p, request, null)
-
- // 2. Return p.
- return p.promise
- }
-
- // 5. Let globalObject be request’s client’s global object.
- const globalObject = request.client.globalObject
-
- // 6. If globalObject is a ServiceWorkerGlobalScope object, then set
- // request’s service-workers mode to "none".
- if (globalObject?.constructor?.name === 'ServiceWorkerGlobalScope') {
- request.serviceWorkers = 'none'
- }
-
- // 7. Let responseObject be null.
- let responseObject = null
-
- // 8. Let relevantRealm be this’s relevant Realm.
- const relevantRealm = null
-
- // 9. Let locallyAborted be false.
- let locallyAborted = false
-
- // 10. Let controller be null.
- let controller = null
-
- // 11. Add the following abort steps to requestObject’s signal:
- requestObject.signal.addEventListener(
- 'abort',
- () => {
- // 1. Set locallyAborted to true.
- locallyAborted = true
-
- // 2. Abort fetch with p, request, and responseObject.
- abortFetch(p, request, responseObject)
-
- // 3. If controller is not null, then abort controller.
- if (controller != null) {
- controller.abort()
- }
- },
- { once: true }
- )
-
- // 12. Let handleFetchDone given response response be to finalize and
- // report timing with response, globalObject, and "fetch".
- const handleFetchDone = (response) =>
- finalizeAndReportTiming(response, 'fetch')
-
- // 13. Set controller to the result of calling fetch given request,
- // with processResponseEndOfBody set to handleFetchDone, and processResponse
- // given response being these substeps:
-
- const processResponse = (response) => {
- // 1. If locallyAborted is true, terminate these substeps.
- if (locallyAborted) {
- return
- }
-
- // 2. If response’s aborted flag is set, then abort fetch with p,
- // request, and responseObject, and terminate these substeps.
- if (response.aborted) {
- abortFetch(p, request, responseObject)
- return
- }
-
- // 3. If response is a network error, then reject p with a TypeError
- // and terminate these substeps.
- if (response.type === 'error') {
- p.reject(
- Object.assign(new TypeError('fetch failed'), { cause: response.error })
- )
- return
- }
-
- // 4. Set responseObject to the result of creating a Response object,
- // given response, "immutable", and relevantRealm.
- responseObject = new Response()
- responseObject[kState] = response
- responseObject[kRealm] = relevantRealm
- responseObject[kHeaders][kHeadersList] = response.headersList
- responseObject[kHeaders][kGuard] = 'immutable'
- responseObject[kHeaders][kRealm] = relevantRealm
-
- // 5. Resolve p with responseObject.
- p.resolve(responseObject)
- }
-
- controller = fetching({
- request,
- processResponseEndOfBody: handleFetchDone,
- processResponse,
- dispatcher: this // undici
- })
-
- // 14. Return p.
- return p.promise
-}
-
-// https://fetch.spec.whatwg.org/#finalize-and-report-timing
-function finalizeAndReportTiming (response, initiatorType = 'other') {
- // 1. If response is an aborted network error, then return.
- if (response.type === 'error' && response.aborted) {
- return
- }
-
- // 2. If response’s URL list is null or empty, then return.
- if (!response.urlList?.length) {
- return
- }
-
- // 3. Let originalURL be response’s URL list[0].
- const originalURL = response.urlList[0]
-
- // 4. Let timingInfo be response’s timing info.
- let timingInfo = response.timingInfo
-
- // 5. Let cacheState be response’s cache state.
- let cacheState = response.cacheState
-
- // 6. If originalURL’s scheme is not an HTTP(S) scheme, then return.
- if (!/^https?:/.test(originalURL.protocol)) {
- return
- }
-
- // 7. If timingInfo is null, then return.
- if (timingInfo === null) {
- return
- }
-
- // 8. If response’s timing allow passed flag is not set, then:
- if (!timingInfo.timingAllowPassed) {
- // 1. Set timingInfo to a the result of creating an opaque timing info for timingInfo.
- timingInfo = createOpaqueTimingInfo({
- startTime: timingInfo.startTime
- })
-
- // 2. Set cacheState to the empty string.
- cacheState = ''
- }
-
- // 9. Set timingInfo’s end time to the coarsened shared current time
- // given global’s relevant settings object’s cross-origin isolated
- // capability.
- // TODO: given global’s relevant settings object’s cross-origin isolated
- // capability?
- response.timingInfo.endTime = coarsenedSharedCurrentTime()
-
- // 10. Set response’s timing info to timingInfo.
- response.timingInfo = timingInfo
-
- // 11. Mark resource timing for timingInfo, originalURL, initiatorType,
- // global, and cacheState.
- markResourceTiming(
- timingInfo,
- originalURL,
- initiatorType,
- globalThis,
- cacheState
- )
-}
-
-// https://w3c.github.io/resource-timing/#dfn-mark-resource-timing
-function markResourceTiming (timingInfo, originalURL, initiatorType, globalThis, cacheState) {
- if (nodeMajor >= 18 && nodeMinor >= 2) {
- performance.markResourceTiming(timingInfo, originalURL, initiatorType, globalThis, cacheState)
- }
-}
-
-// https://fetch.spec.whatwg.org/#abort-fetch
-function abortFetch (p, request, responseObject) {
- // 1. Let error be an "AbortError" DOMException.
- const error = new DOMException('The operation was aborted.', 'AbortError')
-
- // 2. Reject promise with error.
- p.reject(error)
-
- // 3. If request’s body is not null and is readable, then cancel request’s
- // body with error.
- if (request.body != null && isReadable(request.body?.stream)) {
- request.body.stream.cancel(error).catch((err) => {
- if (err.code === 'ERR_INVALID_STATE') {
- // Node bug?
- return
- }
- throw err
- })
- }
-
- // 4. If responseObject is null, then return.
- if (responseObject == null) {
- return
- }
-
- // 5. Let response be responseObject’s response.
- const response = responseObject[kState]
-
- // 6. If response’s body is not null and is readable, then error response’s
- // body with error.
- if (response.body != null && isReadable(response.body?.stream)) {
- response.body.stream.cancel(error).catch((err) => {
- if (err.code === 'ERR_INVALID_STATE') {
- // Node bug?
- return
- }
- throw err
- })
- }
-}
-
-// https://fetch.spec.whatwg.org/#fetching
-function fetching ({
- request,
- processRequestBodyChunkLength,
- processRequestEndOfBody,
- processResponse,
- processResponseEndOfBody,
- processResponseConsumeBody,
- useParallelQueue = false,
- dispatcher // undici
-}) {
- // 1. Let taskDestination be null.
- let taskDestination = null
-
- // 2. Let crossOriginIsolatedCapability be false.
- let crossOriginIsolatedCapability = false
-
- // 3. If request’s client is non-null, then:
- if (request.client != null) {
- // 1. Set taskDestination to request’s client’s global object.
- taskDestination = request.client.globalObject
-
- // 2. Set crossOriginIsolatedCapability to request’s client’s cross-origin
- // isolated capability.
- crossOriginIsolatedCapability =
- request.client.crossOriginIsolatedCapability
- }
-
- // 4. If useParallelQueue is true, then set taskDestination to the result of
- // starting a new parallel queue.
- // TODO
-
- // 5. Let timingInfo be a new fetch timing info whose start time and
- // post-redirect start time are the coarsened shared current time given
- // crossOriginIsolatedCapability.
- const currenTime = coarsenedSharedCurrentTime(crossOriginIsolatedCapability)
- const timingInfo = createOpaqueTimingInfo({
- startTime: currenTime
- })
-
- // 6. Let fetchParams be a new fetch params whose
- // request is request,
- // timing info is timingInfo,
- // process request body chunk length is processRequestBodyChunkLength,
- // process request end-of-body is processRequestEndOfBody,
- // process response is processResponse,
- // process response consume body is processResponseConsumeBody,
- // process response end-of-body is processResponseEndOfBody,
- // task destination is taskDestination,
- // and cross-origin isolated capability is crossOriginIsolatedCapability.
- const fetchParams = {
- controller: new Fetch(dispatcher),
- request,
- timingInfo,
- processRequestBodyChunkLength,
- processRequestEndOfBody,
- processResponse,
- processResponseConsumeBody,
- processResponseEndOfBody,
- taskDestination,
- crossOriginIsolatedCapability
- }
-
- // 7. If request’s body is a byte sequence, then set request’s body to the
- // first return value of safely extracting request’s body.
- // NOTE: Since fetching is only called from fetch, body should already be
- // extracted.
- assert(!request.body || request.body.stream)
-
- // 8. If request’s window is "client", then set request’s window to request’s
- // client, if request’s client’s global object is a Window object; otherwise
- // "no-window".
- if (request.window === 'client') {
- // TODO: What if request.client is null?
- request.window =
- request.client?.globalObject?.constructor?.name === 'Window'
- ? request.client
- : 'no-window'
- }
-
- // 9. If request’s origin is "client", then set request’s origin to request’s
- // client’s origin.
- if (request.origin === 'client') {
- // TODO: What if request.client is null?
- request.origin = request.client?.origin
- }
-
- // 10. If all of the following conditions are true:
- // TODO
-
- // 11. If request’s policy container is "client", then:
- if (request.policyContainer === 'client') {
- // 1. If request’s client is non-null, then set request’s policy
- // container to a clone of request’s client’s policy container. [HTML]
- if (request.client != null) {
- request.policyContainer = clonePolicyContainer(
- request.client.policyContainer
- )
- } else {
- // 2. Otherwise, set request’s policy container to a new policy
- // container.
- request.policyContainer = makePolicyContainer()
- }
- }
-
- // 12. If request’s header list does not contain `Accept`, then:
- if (!request.headersList.has('accept')) {
- // 1. Let value be `*/*`.
- const value = '*/*'
-
- // 2. A user agent should set value to the first matching statement, if
- // any, switching on request’s destination:
- // "document"
- // "frame"
- // "iframe"
- // `text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8`
- // "image"
- // `image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5`
- // "style"
- // `text/css,*/*;q=0.1`
- // TODO
-
- // 3. Append `Accept`/value to request’s header list.
- request.headersList.append('accept', value)
- }
-
- // 13. If request’s header list does not contain `Accept-Language`, then
- // user agents should append `Accept-Language`/an appropriate value to
- // request’s header list.
- if (!request.headersList.has('accept-language')) {
- request.headersList.append('accept-language', '*')
- }
-
- // 14. If request’s priority is null, then use request’s initiator and
- // destination appropriately in setting request’s priority to a
- // user-agent-defined object.
- if (request.priority === null) {
- // TODO
- }
-
- // 15. If request is a subresource request, then:
- if (subresource.includes(request.destination)) {
- // TODO
- }
-
- // 16. Run main fetch given fetchParams.
- mainFetch(fetchParams)
- .catch(err => {
- fetchParams.controller.terminate(err)
- })
-
- // 17. Return fetchParam's controller
- return fetchParams.controller
-}
-
-// https://fetch.spec.whatwg.org/#concept-main-fetch
-async function mainFetch (fetchParams, recursive = false) {
- // 1. Let request be fetchParams’s request.
- const request = fetchParams.request
-
- // 2. Let response be null.
- let response = null
-
- // 3. If request’s local-URLs-only flag is set and request’s current URL is
- // not local, then set response to a network error.
- if (
- request.localURLsOnly &&
- !/^(about|blob|data):/.test(requestCurrentURL(request).protocol)
- ) {
- response = makeNetworkError('local URLs only')
- }
-
- // 4. Run report Content Security Policy violations for request.
- // TODO
-
- // 5. Upgrade request to a potentially trustworthy URL, if appropriate.
- tryUpgradeRequestToAPotentiallyTrustworthyURL(request)
-
- // 6. If should request be blocked due to a bad port, should fetching request
- // be blocked as mixed content, or should request be blocked by Content
- // Security Policy returns blocked, then set response to a network error.
- if (requestBadPort(request) === 'blocked') {
- response = makeNetworkError('bad port')
- }
- // TODO: should fetching request be blocked as mixed content?
- // TODO: should request be blocked by Content Security Policy?
-
- // 7. If request’s referrer policy is the empty string, then set request’s
- // referrer policy to request’s policy container’s referrer policy.
- if (request.referrerPolicy === '') {
- request.referrerPolicy = request.policyContainer.referrerPolicy
- }
-
- // 8. If request’s referrer is not "no-referrer", then set request’s
- // referrer to the result of invoking determine request’s referrer.
- if (request.referrer !== 'no-referrer') {
- request.referrer = determineRequestsReferrer(request)
- }
-
- // 9. Set request’s current URL’s scheme to "https" if all of the following
- // conditions are true:
- // - request’s current URL’s scheme is "http"
- // - request’s current URL’s host is a domain
- // - Matching request’s current URL’s host per Known HSTS Host Domain Name
- // Matching results in either a superdomain match with an asserted
- // includeSubDomains directive or a congruent match (with or without an
- // asserted includeSubDomains directive). [HSTS]
- // TODO
-
- // 10. If recursive is false, then run the remaining steps in parallel.
- // TODO
-
- // 11. If response is null, then set response to the result of running
- // the steps corresponding to the first matching statement:
- if (response === null) {
- response = await (async () => {
- const currentURL = requestCurrentURL(request)
-
- if (
- // - request’s current URL’s origin is same origin with request’s origin,
- // and request’s response tainting is "basic"
- (sameOrigin(currentURL, request.url) && request.responseTainting === 'basic') ||
- // request’s current URL’s scheme is "data"
- (currentURL.protocol === 'data:') ||
- // - request’s mode is "navigate" or "websocket"
- (request.mode === 'navigate' || request.mode === 'websocket')
- ) {
- // 1. Set request’s response tainting to "basic".
- request.responseTainting = 'basic'
-
- // 2. Return the result of running scheme fetch given fetchParams.
- return await schemeFetch(fetchParams)
- }
-
- // request’s mode is "same-origin"
- if (request.mode === 'same-origin') {
- // 1. Return a network error.
- return makeNetworkError('request mode cannot be "same-origin"')
- }
-
- // request’s mode is "no-cors"
- if (request.mode === 'no-cors') {
- // 1. If request’s redirect mode is not "follow", then return a network
- // error.
- if (request.redirect !== 'follow') {
- return makeNetworkError(
- 'redirect mode cannot be "follow" for "no-cors" request'
- )
- }
-
- // 2. Set request’s response tainting to "opaque".
- request.responseTainting = 'opaque'
-
- // 3. Return the result of running scheme fetch given fetchParams.
- return await schemeFetch(fetchParams)
- }
-
- // request’s current URL’s scheme is not an HTTP(S) scheme
- if (!/^https?:/.test(requestCurrentURL(request).protocol)) {
- // Return a network error.
- return makeNetworkError('URL scheme must be a HTTP(S) scheme')
- }
-
- // - request’s use-CORS-preflight flag is set
- // - request’s unsafe-request flag is set and either request’s method is
- // not a CORS-safelisted method or CORS-unsafe request-header names with
- // request’s header list is not empty
- // 1. Set request’s response tainting to "cors".
- // 2. Let corsWithPreflightResponse be the result of running HTTP fetch
- // given fetchParams and true.
- // 3. If corsWithPreflightResponse is a network error, then clear cache
- // entries using request.
- // 4. Return corsWithPreflightResponse.
- // TODO
-
- // Otherwise
- // 1. Set request’s response tainting to "cors".
- request.responseTainting = 'cors'
-
- // 2. Return the result of running HTTP fetch given fetchParams.
- return await httpFetch(fetchParams)
- })()
- }
-
- // 12. If recursive is true, then return response.
- if (recursive) {
- return response
- }
-
- // 13. If response is not a network error and response is not a filtered
- // response, then:
- if (response.status !== 0 && !response.internalResponse) {
- // If request’s response tainting is "cors", then:
- if (request.responseTainting === 'cors') {
- // 1. Let headerNames be the result of extracting header list values
- // given `Access-Control-Expose-Headers` and response’s header list.
- // TODO
- // 2. If request’s credentials mode is not "include" and headerNames
- // contains `*`, then set response’s CORS-exposed header-name list to
- // all unique header names in response’s header list.
- // TODO
- // 3. Otherwise, if headerNames is not null or failure, then set
- // response’s CORS-exposed header-name list to headerNames.
- // TODO
- }
-
- // Set response to the following filtered response with response as its
- // internal response, depending on request’s response tainting:
- if (request.responseTainting === 'basic') {
- response = filterResponse(response, 'basic')
- } else if (request.responseTainting === 'cors') {
- response = filterResponse(response, 'cors')
- } else if (request.responseTainting === 'opaque') {
- response = filterResponse(response, 'opaque')
- } else {
- assert(false)
- }
- }
-
- // 14. Let internalResponse be response, if response is a network error,
- // and response’s internal response otherwise.
- let internalResponse =
- response.status === 0 ? response : response.internalResponse
-
- // 15. If internalResponse’s URL list is empty, then set it to a clone of
- // request’s URL list.
- if (internalResponse.urlList.length === 0) {
- internalResponse.urlList.push(...request.urlList)
- }
-
- // 16. If request’s timing allow failed flag is unset, then set
- // internalResponse’s timing allow passed flag.
- if (!request.timingAllowFailed) {
- response.timingAllowPassed = true
- }
-
- // 17. If response is not a network error and any of the following returns
- // blocked
- // - should internalResponse to request be blocked as mixed content
- // - should internalResponse to request be blocked by Content Security Policy
- // - should internalResponse to request be blocked due to its MIME type
- // - should internalResponse to request be blocked due to nosniff
- // TODO
-
- // 18. If response’s type is "opaque", internalResponse’s status is 206,
- // internalResponse’s range-requested flag is set, and request’s header
- // list does not contain `Range`, then set response and internalResponse
- // to a network error.
- if (
- response.type === 'opaque' &&
- internalResponse.status === 206 &&
- internalResponse.rangeRequested &&
- !request.headers.has('range')
- ) {
- response = internalResponse = makeNetworkError()
- }
-
- // 19. If response is not a network error and either request’s method is
- // `HEAD` or `CONNECT`, or internalResponse’s status is a null body status,
- // set internalResponse’s body to null and disregard any enqueuing toward
- // it (if any).
- if (
- response.status !== 0 &&
- (request.method === 'HEAD' ||
- request.method === 'CONNECT' ||
- nullBodyStatus.includes(internalResponse.status))
- ) {
- internalResponse.body = null
- fetchParams.controller.dump = true
- }
-
- // 20. If request’s integrity metadata is not the empty string, then:
- if (request.integrity) {
- // 1. Let processBodyError be this step: run fetch finale given fetchParams
- // and a network error.
- const processBodyError = (reason) =>
- fetchFinale(fetchParams, makeNetworkError(reason))
-
- // 2. If request’s response tainting is "opaque", or response’s body is null,
- // then run processBodyError and abort these steps.
- if (request.responseTainting === 'opaque' || response.body == null) {
- processBodyError(response.error)
- return
- }
-
- // 3. Let processBody given bytes be these steps:
- const processBody = (bytes) => {
- // 1. If bytes do not match request’s integrity metadata,
- // then run processBodyError and abort these steps. [SRI]
- if (!matchRequestIntegrity(request, bytes)) {
- processBodyError('integrity mismatch')
- return
- }
-
- // 2. Set response’s body to the first return value of safely
- // extracting bytes.
- response.body = safelyExtractBody(bytes)[0]
-
- // 3. Run fetch finale given fetchParams and response.
- fetchFinale(fetchParams, response)
- }
-
- // 4. Fully read response’s body given processBody and processBodyError.
- try {
- processBody(await response.arrayBuffer())
- } catch (err) {
- processBodyError(err)
- }
- } else {
- // 21. Otherwise, run fetch finale given fetchParams and response.
- fetchFinale(fetchParams, response)
- }
-}
-
-// https://fetch.spec.whatwg.org/#concept-scheme-fetch
-// given a fetch params fetchParams
-async function schemeFetch (fetchParams) {
- // let request be fetchParams’s request
- const { request } = fetchParams
-
- const {
- protocol: scheme,
- pathname: path
- } = requestCurrentURL(request)
-
- // switch on request’s current URL’s scheme, and run the associated steps:
- switch (scheme) {
- case 'about:': {
- // If request’s current URL’s path is the string "blank", then return a new response
- // whose status message is `OK`, header list is « (`Content-Type`, `text/html;charset=utf-8`) »,
- // and body is the empty byte sequence.
- if (path === 'blank') {
- const resp = makeResponse({
- statusText: 'OK',
- headersList: [
- ['content-type', 'text/html;charset=utf-8']
- ]
- })
-
- resp.urlList = [new URL('about:blank')]
- return resp
- }
-
- // Otherwise, return a network error.
- return makeNetworkError('invalid path called')
- }
- case 'blob:': {
- resolveObjectURL = resolveObjectURL || require('buffer').resolveObjectURL
-
- // 1. Run these steps, but abort when the ongoing fetch is terminated:
- // 1. Let blob be request’s current URL’s blob URL entry’s object.
- // https://w3c.github.io/FileAPI/#blob-url-entry
- // P.S. Thank God this method is available in node.
- const currentURL = requestCurrentURL(request)
-
- // https://github.com/web-platform-tests/wpt/blob/7b0ebaccc62b566a1965396e5be7bb2bc06f841f/FileAPI/url/resources/fetch-tests.js#L52-L56
- // Buffer.resolveObjectURL does not ignore URL queries.
- if (currentURL.search.length !== 0) {
- return makeNetworkError('NetworkError when attempting to fetch resource.')
- }
-
- const blob = resolveObjectURL(currentURL.toString())
-
- // 2. If request’s method is not `GET` or blob is not a Blob object, then return a network error. [FILEAPI]
- if (request.method !== 'GET' || !isBlobLike(blob)) {
- return makeNetworkError('invalid method')
- }
-
- // 3. Let response be a new response whose status message is `OK`.
- const response = makeResponse({ statusText: 'OK', urlList: [currentURL] })
-
- // 4. Append (`Content-Length`, blob’s size attribute value) to response’s header list.
- response.headersList.set('content-length', `${blob.size}`)
-
- // 5. Append (`Content-Type`, blob’s type attribute value) to response’s header list.
- response.headersList.set('content-type', blob.type)
-
- // 6. Set response’s body to the result of performing the read operation on blob.
- // TODO (fix): This needs to read?
- response.body = extractBody(blob)[0]
-
- // 7. Return response.
- return response
-
- // 2. If aborted, then return the appropriate network error for fetchParams.
- // TODO
- }
- case 'data:': {
- // 1. Let dataURLStruct be the result of running the
- // data: URL processor on request’s current URL.
- const currentURL = requestCurrentURL(request)
- const dataURLStruct = dataURLProcessor(currentURL)
-
- // 2. If dataURLStruct is failure, then return a
- // network error.
- if (dataURLStruct === 'failure') {
- return makeNetworkError('failed to fetch the data URL')
- }
-
- // 3. Let mimeType be dataURLStruct’s MIME type, serialized.
- const { mimeType } = dataURLStruct
-
- /** @type {string} */
- let contentType = `${mimeType.type}/${mimeType.subtype}`
- const contentTypeParams = []
-
- if (mimeType.parameters.size > 0) {
- contentType += ';'
- }
-
- for (const [key, value] of mimeType.parameters) {
- if (value.length > 0) {
- contentTypeParams.push(`${key}=${value}`)
- } else {
- contentTypeParams.push(key)
- }
- }
-
- contentType += contentTypeParams.join(',')
-
- // 4. Return a response whose status message is `OK`,
- // header list is « (`Content-Type`, mimeType) »,
- // and body is dataURLStruct’s body.
- return makeResponse({
- statusText: 'OK',
- headersList: [
- ['content-type', contentType]
- ],
- body: extractBody(dataURLStruct.body)[0]
- })
- }
- case 'file:': {
- // For now, unfortunate as it is, file URLs are left as an exercise for the reader.
- // When in doubt, return a network error.
- return makeNetworkError('not implemented... yet...')
- }
- case 'http:':
- case 'https:': {
- // Return the result of running HTTP fetch given fetchParams.
-
- return await httpFetch(fetchParams)
- .catch((err) => makeNetworkError(err))
- }
- default: {
- return makeNetworkError('unknown scheme')
- }
- }
-}
-
-// https://fetch.spec.whatwg.org/#finalize-response
-function finalizeResponse (fetchParams, response) {
- // 1. Set fetchParams’s request’s done flag.
- fetchParams.request.done = true
-
- // 2, If fetchParams’s process response done is not null, then queue a fetch
- // task to run fetchParams’s process response done given response, with
- // fetchParams’s task destination.
- if (fetchParams.processResponseDone != null) {
- queueMicrotask(() => fetchParams.processResponseDone(response))
- }
-}
-
-// https://fetch.spec.whatwg.org/#fetch-finale
-async function fetchFinale (fetchParams, response) {
- // 1. If response is a network error, then:
- if (response.type === 'error') {
- // 1. Set response’s URL list to « fetchParams’s request’s URL list[0] ».
- response.urlList = [fetchParams.request.urlList[0]]
-
- // 2. Set response’s timing info to the result of creating an opaque timing
- // info for fetchParams’s timing info.
- response.timingInfo = createOpaqueTimingInfo({
- startTime: fetchParams.timingInfo.startTime
- })
- }
-
- // 2. Let processResponseEndOfBody be the following steps:
- const processResponseEndOfBody = () => {
- // 1. Set fetchParams’s request’s done flag.
- fetchParams.request.done = true
-
- // If fetchParams’s process response end-of-body is not null,
- // then queue a fetch task to run fetchParams’s process response
- // end-of-body given response with fetchParams’s task destination.
- if (fetchParams.processResponseEndOfBody != null) {
- queueMicrotask(() => fetchParams.processResponseEndOfBody(response))
- }
- }
-
- // 3. If fetchParams’s process response is non-null, then queue a fetch task
- // to run fetchParams’s process response given response, with fetchParams’s
- // task destination.
- if (fetchParams.processResponse != null) {
- queueMicrotask(() => fetchParams.processResponse(response))
- }
-
- // 4. If response’s body is null, then run processResponseEndOfBody.
- if (response.body == null) {
- processResponseEndOfBody()
- } else {
- // 5. Otherwise:
-
- // 1. Let transformStream be a new a TransformStream.
-
- // 2. Let identityTransformAlgorithm be an algorithm which, given chunk,
- // enqueues chunk in transformStream.
- const identityTransformAlgorithm = (chunk, controller) => {
- controller.enqueue(chunk)
- }
-
- // 3. Set up transformStream with transformAlgorithm set to identityTransformAlgorithm
- // and flushAlgorithm set to processResponseEndOfBody.
- const transformStream = new TransformStream({
- start () {},
- transform: identityTransformAlgorithm,
- flush: processResponseEndOfBody
- })
-
- // 4. Set response’s body to the result of piping response’s body through transformStream.
- response.body = { stream: response.body.stream.pipeThrough(transformStream) }
- }
-
- // 6. If fetchParams’s process response consume body is non-null, then:
- if (fetchParams.processResponseConsumeBody != null) {
- // 1. Let processBody given nullOrBytes be this step: run fetchParams’s
- // process response consume body given response and nullOrBytes.
- const processBody = (nullOrBytes) => fetchParams.processResponseConsumeBody(response, nullOrBytes)
-
- // 2. Let processBodyError be this step: run fetchParams’s process
- // response consume body given response and failure.
- const processBodyError = (failure) => fetchParams.processResponseConsumeBody(response, failure)
-
- // 3. If response’s body is null, then queue a fetch task to run processBody
- // given null, with fetchParams’s task destination.
- if (response.body == null) {
- queueMicrotask(() => processBody(null))
- } else {
- // 4. Otherwise, fully read response’s body given processBody, processBodyError,
- // and fetchParams’s task destination.
- try {
- processBody(await response.body.stream.arrayBuffer())
- } catch (err) {
- processBodyError(err)
- }
- }
- }
-}
-
-// https://fetch.spec.whatwg.org/#http-fetch
-async function httpFetch (fetchParams) {
- // 1. Let request be fetchParams’s request.
- const request = fetchParams.request
-
- // 2. Let response be null.
- let response = null
-
- // 3. Let actualResponse be null.
- let actualResponse = null
-
- // 4. Let timingInfo be fetchParams’s timing info.
- const timingInfo = fetchParams.timingInfo
-
- // 5. If request’s service-workers mode is "all", then:
- if (request.serviceWorkers === 'all') {
- // TODO
- }
-
- // 6. If response is null, then:
- if (response === null) {
- // 1. If makeCORSPreflight is true and one of these conditions is true:
- // TODO
-
- // 2. If request’s redirect mode is "follow", then set request’s
- // service-workers mode to "none".
- if (request.redirect === 'follow') {
- request.serviceWorkers = 'none'
- }
-
- // 3. Set response and actualResponse to the result of running
- // HTTP-network-or-cache fetch given fetchParams.
- actualResponse = response = await httpNetworkOrCacheFetch(fetchParams)
-
- // 4. If request’s response tainting is "cors" and a CORS check
- // for request and response returns failure, then return a network error.
- if (
- request.responseTainting === 'cors' &&
- corsCheck(request, response) === 'failure'
- ) {
- return makeNetworkError('cors failure')
- }
-
- // 5. If the TAO check for request and response returns failure, then set
- // request’s timing allow failed flag.
- if (TAOCheck(request, response) === 'failure') {
- request.timingAllowFailed = true
- }
- }
-
- // 7. If either request’s response tainting or response’s type
- // is "opaque", and the cross-origin resource policy check with
- // request’s origin, request’s client, request’s destination,
- // and actualResponse returns blocked, then return a network error.
- if (
- (request.responseTainting === 'opaque' || response.type === 'opaque') &&
- crossOriginResourcePolicyCheck(
- request.origin,
- request.client,
- request.destination,
- actualResponse
- ) === 'blocked'
- ) {
- return makeNetworkError('blocked')
- }
-
- // 8. If actualResponse’s status is a redirect status, then:
- if (redirectStatus.includes(actualResponse.status)) {
- // 1. If actualResponse’s status is not 303, request’s body is not null,
- // and the connection uses HTTP/2, then user agents may, and are even
- // encouraged to, transmit an RST_STREAM frame.
- // See, https://github.com/whatwg/fetch/issues/1288
- fetchParams.controller.connection.destroy()
-
- // 2. Switch on request’s redirect mode:
- if (request.redirect === 'error') {
- // Set response to a network error.
- response = makeNetworkError('unexpected redirect')
- } else if (request.redirect === 'manual') {
- // Set response to an opaque-redirect filtered response whose internal
- // response is actualResponse.
- // NOTE(spec): On the web this would return an `opaqueredirect` response,
- // but that doesn't make sense server side.
- // See https://github.com/nodejs/undici/issues/1193.
- response = actualResponse
- } else if (request.redirect === 'follow') {
- // Set response to the result of running HTTP-redirect fetch given
- // fetchParams and response.
- response = await httpRedirectFetch(fetchParams, response)
- } else {
- assert(false)
- }
- }
-
- // 9. Set response’s timing info to timingInfo.
- response.timingInfo = timingInfo
-
- // 10. Return response.
- return response
-}
-
-// https://fetch.spec.whatwg.org/#http-redirect-fetch
-async function httpRedirectFetch (fetchParams, response) {
- // 1. Let request be fetchParams’s request.
- const request = fetchParams.request
-
- // 2. Let actualResponse be response, if response is not a filtered response,
- // and response’s internal response otherwise.
- const actualResponse = response.internalResponse
- ? response.internalResponse
- : response
-
- // 3. Let locationURL be actualResponse’s location URL given request’s current
- // URL’s fragment.
- let locationURL
-
- try {
- locationURL = responseLocationURL(
- actualResponse,
- requestCurrentURL(request).hash
- )
-
- // 4. If locationURL is null, then return response.
- if (locationURL == null) {
- return response
- }
- } catch (err) {
- // 5. If locationURL is failure, then return a network error.
- return makeNetworkError(err)
- }
-
- // 6. If locationURL’s scheme is not an HTTP(S) scheme, then return a network
- // error.
- if (!/^https?:/.test(locationURL.protocol)) {
- return makeNetworkError('URL scheme must be a HTTP(S) scheme')
- }
-
- // 7. If request’s redirect count is twenty, return a network error.
- if (request.redirectCount === 20) {
- return makeNetworkError('redirect count exceeded')
- }
-
- // 8. Increase request’s redirect count by one.
- request.redirectCount += 1
-
- // 9. If request’s mode is "cors", locationURL includes credentials, and
- // request’s origin is not same origin with locationURL’s origin, then return
- // a network error.
- if (
- request.mode === 'cors' &&
- (locationURL.username || locationURL.password) &&
- !sameOrigin(request, locationURL)
- ) {
- return makeNetworkError('cross origin not allowed for request mode "cors"')
- }
-
- // 10. If request’s response tainting is "cors" and locationURL includes
- // credentials, then return a network error.
- if (
- request.responseTainting === 'cors' &&
- (locationURL.username || locationURL.password)
- ) {
- return makeNetworkError(
- 'URL cannot contain credentials for request mode "cors"'
- )
- }
-
- // 11. If actualResponse’s status is not 303, request’s body is non-null,
- // and request’s body’s source is null, then return a network error.
- if (
- actualResponse.status !== 303 &&
- request.body != null &&
- request.body.source == null
- ) {
- return makeNetworkError()
- }
-
- // 12. If one of the following is true
- // - actualResponse’s status is 301 or 302 and request’s method is `POST`
- // - actualResponse’s status is 303 and request’s method is not `GET` or `HEAD`
- if (
- ([301, 302].includes(actualResponse.status) && request.method === 'POST') ||
- (actualResponse.status === 303 &&
- !['GET', 'HEAD'].includes(request.method))
- ) {
- // then:
- // 1. Set request’s method to `GET` and request’s body to null.
- request.method = 'GET'
- request.body = null
-
- // 2. For each headerName of request-body-header name, delete headerName from
- // request’s header list.
- for (const headerName of requestBodyHeader) {
- request.headersList.delete(headerName)
- }
- }
-
- // 13. If request’s body is non-null, then set request’s body to the first return
- // value of safely extracting request’s body’s source.
- if (request.body != null) {
- assert(request.body.source)
- request.body = safelyExtractBody(request.body.source)[0]
- }
-
- // 14. Let timingInfo be fetchParams’s timing info.
- const timingInfo = fetchParams.timingInfo
-
- // 15. Set timingInfo’s redirect end time and post-redirect start time to the
- // coarsened shared current time given fetchParams’s cross-origin isolated
- // capability.
- timingInfo.redirectEndTime = timingInfo.postRedirectStartTime =
- coarsenedSharedCurrentTime(fetchParams.crossOriginIsolatedCapability)
-
- // 16. If timingInfo’s redirect start time is 0, then set timingInfo’s
- // redirect start time to timingInfo’s start time.
- if (timingInfo.redirectStartTime === 0) {
- timingInfo.redirectStartTime = timingInfo.startTime
- }
-
- // 17. Append locationURL to request’s URL list.
- request.urlList.push(locationURL)
-
- // 18. Invoke set request’s referrer policy on redirect on request and
- // actualResponse.
- setRequestReferrerPolicyOnRedirect(request, actualResponse)
-
- // 19. Return the result of running main fetch given fetchParams and true.
- return mainFetch(fetchParams, true)
-}
-
-// https://fetch.spec.whatwg.org/#http-network-or-cache-fetch
-async function httpNetworkOrCacheFetch (
- fetchParams,
- isAuthenticationFetch = false,
- isNewConnectionFetch = false
-) {
- // 1. Let request be fetchParams’s request.
- const request = fetchParams.request
-
- // 2. Let httpFetchParams be null.
- let httpFetchParams = null
-
- // 3. Let httpRequest be null.
- let httpRequest = null
-
- // 4. Let response be null.
- let response = null
-
- // 5. Let storedResponse be null.
- // TODO: cache
-
- // 6. Let httpCache be null.
- const httpCache = null
-
- // 7. Let the revalidatingFlag be unset.
- const revalidatingFlag = false
-
- // 8. Run these steps, but abort when the ongoing fetch is terminated:
-
- // 1. If request’s window is "no-window" and request’s redirect mode is
- // "error", then set httpFetchParams to fetchParams and httpRequest to
- // request.
- if (request.window === 'no-window' && request.redirect === 'error') {
- httpFetchParams = fetchParams
- httpRequest = request
- } else {
- // Otherwise:
-
- // 1. Set httpRequest to a clone of request.
- httpRequest = makeRequest(request)
-
- // 2. Set httpFetchParams to a copy of fetchParams.
- httpFetchParams = { ...fetchParams }
-
- // 3. Set httpFetchParams’s request to httpRequest.
- httpFetchParams.request = httpRequest
- }
-
- // 3. Let includeCredentials be true if one of
- const includeCredentials =
- request.credentials === 'include' ||
- (request.credentials === 'same-origin' &&
- request.responseTainting === 'basic')
-
- // 4. Let contentLength be httpRequest’s body’s length, if httpRequest’s
- // body is non-null; otherwise null.
- const contentLength = httpRequest.body ? httpRequest.body.length : null
-
- // 5. Let contentLengthHeaderValue be null.
- let contentLengthHeaderValue = null
-
- // 6. If httpRequest’s body is null and httpRequest’s method is `POST` or
- // `PUT`, then set contentLengthHeaderValue to `0`.
- if (
- httpRequest.body == null &&
- ['POST', 'PUT'].includes(httpRequest.method)
- ) {
- contentLengthHeaderValue = '0'
- }
-
- // 7. If contentLength is non-null, then set contentLengthHeaderValue to
- // contentLength, serialized and isomorphic encoded.
- if (contentLength != null) {
- // TODO: isomorphic encoded
- contentLengthHeaderValue = String(contentLength)
- }
-
- // 8. If contentLengthHeaderValue is non-null, then append
- // `Content-Length`/contentLengthHeaderValue to httpRequest’s header
- // list.
- if (contentLengthHeaderValue != null) {
- httpRequest.headersList.append('content-length', contentLengthHeaderValue)
- }
-
- // 9. If contentLengthHeaderValue is non-null, then append (`Content-Length`,
- // contentLengthHeaderValue) to httpRequest’s header list.
-
- // 10. If contentLength is non-null and httpRequest’s keepalive is true,
- // then:
- if (contentLength != null && httpRequest.keepalive) {
- // NOTE: keepalive is a noop outside of browser context.
- }
-
- // 11. If httpRequest’s referrer is a URL, then append
- // `Referer`/httpRequest’s referrer, serialized and isomorphic encoded,
- // to httpRequest’s header list.
- if (httpRequest.referrer instanceof URL) {
- // TODO: isomorphic encoded
- httpRequest.headersList.append('referer', httpRequest.referrer.href)
- }
-
- // 12. Append a request `Origin` header for httpRequest.
- appendRequestOriginHeader(httpRequest)
-
- // 13. Append the Fetch metadata headers for httpRequest. [FETCH-METADATA]
- appendFetchMetadata(httpRequest)
-
- // 14. If httpRequest’s header list does not contain `User-Agent`, then
- // user agents should append `User-Agent`/default `User-Agent` value to
- // httpRequest’s header list.
- if (!httpRequest.headersList.has('user-agent')) {
- httpRequest.headersList.append('user-agent', 'undici')
- }
-
- // 15. If httpRequest’s cache mode is "default" and httpRequest’s header
- // list contains `If-Modified-Since`, `If-None-Match`,
- // `If-Unmodified-Since`, `If-Match`, or `If-Range`, then set
- // httpRequest’s cache mode to "no-store".
- if (
- httpRequest.cache === 'default' &&
- (httpRequest.headersList.has('if-modified-since') ||
- httpRequest.headersList.has('if-none-match') ||
- httpRequest.headersList.has('if-unmodified-since') ||
- httpRequest.headersList.has('if-match') ||
- httpRequest.headersList.has('if-range'))
- ) {
- httpRequest.cache = 'no-store'
- }
-
- // 16. If httpRequest’s cache mode is "no-cache", httpRequest’s prevent
- // no-cache cache-control header modification flag is unset, and
- // httpRequest’s header list does not contain `Cache-Control`, then append
- // `Cache-Control`/`max-age=0` to httpRequest’s header list.
- if (
- httpRequest.cache === 'no-cache' &&
- !httpRequest.preventNoCacheCacheControlHeaderModification &&
- !httpRequest.headersList.has('cache-control')
- ) {
- httpRequest.headersList.append('cache-control', 'max-age=0')
- }
-
- // 17. If httpRequest’s cache mode is "no-store" or "reload", then:
- if (httpRequest.cache === 'no-store' || httpRequest.cache === 'reload') {
- // 1. If httpRequest’s header list does not contain `Pragma`, then append
- // `Pragma`/`no-cache` to httpRequest’s header list.
- if (!httpRequest.headersList.has('pragma')) {
- httpRequest.headersList.append('pragma', 'no-cache')
- }
-
- // 2. If httpRequest’s header list does not contain `Cache-Control`,
- // then append `Cache-Control`/`no-cache` to httpRequest’s header list.
- if (!httpRequest.headersList.has('cache-control')) {
- httpRequest.headersList.append('cache-control', 'no-cache')
- }
- }
-
- // 18. If httpRequest’s header list contains `Range`, then append
- // `Accept-Encoding`/`identity` to httpRequest’s header list.
- if (httpRequest.headersList.has('range')) {
- httpRequest.headersList.append('accept-encoding', 'identity')
- }
-
- // 19. Modify httpRequest’s header list per HTTP. Do not append a given
- // header if httpRequest’s header list contains that header’s name.
- // TODO: https://github.com/whatwg/fetch/issues/1285#issuecomment-896560129
- if (!httpRequest.headersList.has('accept-encoding')) {
- if (/^https:/.test(requestCurrentURL(httpRequest).protocol)) {
- httpRequest.headersList.append('accept-encoding', 'br, gzip, deflate')
- } else {
- httpRequest.headersList.append('accept-encoding', 'gzip, deflate')
- }
- }
-
- // 20. If includeCredentials is true, then:
- if (includeCredentials) {
- // 1. If the user agent is not configured to block cookies for httpRequest
- // (see section 7 of [COOKIES]), then:
- // TODO: credentials
- // 2. If httpRequest’s header list does not contain `Authorization`, then:
- // TODO: credentials
- }
-
- // 21. If there’s a proxy-authentication entry, use it as appropriate.
- // TODO: proxy-authentication
-
- // 22. Set httpCache to the result of determining the HTTP cache
- // partition, given httpRequest.
- // TODO: cache
-
- // 23. If httpCache is null, then set httpRequest’s cache mode to
- // "no-store".
- if (httpCache == null) {
- httpRequest.cache = 'no-store'
- }
-
- // 24. If httpRequest’s cache mode is neither "no-store" nor "reload",
- // then:
- if (httpRequest.mode !== 'no-store' && httpRequest.mode !== 'reload') {
- // TODO: cache
- }
-
- // 9. If aborted, then return the appropriate network error for fetchParams.
- // TODO
-
- // 10. If response is null, then:
- if (response == null) {
- // 1. If httpRequest’s cache mode is "only-if-cached", then return a
- // network error.
- if (httpRequest.mode === 'only-if-cached') {
- return makeNetworkError('only if cached')
- }
-
- // 2. Let forwardResponse be the result of running HTTP-network fetch
- // given httpFetchParams, includeCredentials, and isNewConnectionFetch.
- const forwardResponse = await httpNetworkFetch(
- httpFetchParams,
- includeCredentials,
- isNewConnectionFetch
- )
-
- // 3. If httpRequest’s method is unsafe and forwardResponse’s status is
- // in the range 200 to 399, inclusive, invalidate appropriate stored
- // responses in httpCache, as per the "Invalidation" chapter of HTTP
- // Caching, and set storedResponse to null. [HTTP-CACHING]
- if (
- !safeMethods.includes(httpRequest.method) &&
- forwardResponse.status >= 200 &&
- forwardResponse.status <= 399
- ) {
- // TODO: cache
- }
-
- // 4. If the revalidatingFlag is set and forwardResponse’s status is 304,
- // then:
- if (revalidatingFlag && forwardResponse.status === 304) {
- // TODO: cache
- }
-
- // 5. If response is null, then:
- if (response == null) {
- // 1. Set response to forwardResponse.
- response = forwardResponse
-
- // 2. Store httpRequest and forwardResponse in httpCache, as per the
- // "Storing Responses in Caches" chapter of HTTP Caching. [HTTP-CACHING]
- // TODO: cache
- }
- }
-
- // 11. Set response’s URL list to a clone of httpRequest’s URL list.
- response.urlList = [...httpRequest.urlList]
-
- // 12. If httpRequest’s header list contains `Range`, then set response’s
- // range-requested flag.
- if (httpRequest.headersList.has('range')) {
- response.rangeRequested = true
- }
-
- // 13. Set response’s request-includes-credentials to includeCredentials.
- response.requestIncludesCredentials = includeCredentials
-
- // 14. If response’s status is 401, httpRequest’s response tainting is not
- // "cors", includeCredentials is true, and request’s window is an environment
- // settings object, then:
- // TODO
-
- // 15. If response’s status is 407, then:
- if (response.status === 407) {
- // 1. If request’s window is "no-window", then return a network error.
- if (request.window === 'no-window') {
- return makeNetworkError()
- }
-
- // 2. ???
-
- // 3. If fetchParams is canceled, then return the appropriate network error for fetchParams.
- if (isCancelled(fetchParams)) {
- return makeAppropriateNetworkError(fetchParams)
- }
-
- // 4. Prompt the end user as appropriate in request’s window and store
- // the result as a proxy-authentication entry. [HTTP-AUTH]
- // TODO: Invoke some kind of callback?
-
- // 5. Set response to the result of running HTTP-network-or-cache fetch given
- // fetchParams.
- // TODO
- return makeNetworkError('proxy authentication required')
- }
-
- // 16. If all of the following are true
- if (
- // response’s status is 421
- response.status === 421 &&
- // isNewConnectionFetch is false
- !isNewConnectionFetch &&
- // request’s body is null, or request’s body is non-null and request’s body’s source is non-null
- (request.body == null || request.body.source != null)
- ) {
- // then:
-
- // 1. If fetchParams is canceled, then return the appropriate network error for fetchParams.
- if (isCancelled(fetchParams)) {
- return makeAppropriateNetworkError(fetchParams)
- }
-
- // 2. Set response to the result of running HTTP-network-or-cache
- // fetch given fetchParams, isAuthenticationFetch, and true.
-
- // TODO (spec): The spec doesn't specify this but we need to cancel
- // the active response before we can start a new one.
- // https://github.com/whatwg/fetch/issues/1293
- fetchParams.controller.connection.destroy()
-
- response = await httpNetworkOrCacheFetch(
- fetchParams,
- isAuthenticationFetch,
- true
- )
- }
-
- // 17. If isAuthenticationFetch is true, then create an authentication entry
- if (isAuthenticationFetch) {
- // TODO
- }
-
- // 18. Return response.
- return response
-}
-
-// https://fetch.spec.whatwg.org/#http-network-fetch
-async function httpNetworkFetch (
- fetchParams,
- includeCredentials = false,
- forceNewConnection = false
-) {
- assert(!fetchParams.controller.connection || fetchParams.controller.connection.destroyed)
-
- fetchParams.controller.connection = {
- abort: null,
- destroyed: false,
- destroy (err) {
- if (!this.destroyed) {
- this.destroyed = true
- this.abort?.(err ?? new DOMException('The operation was aborted.', 'AbortError'))
- }
- }
- }
-
- // 1. Let request be fetchParams’s request.
- const request = fetchParams.request
-
- // 2. Let response be null.
- let response = null
-
- // 3. Let timingInfo be fetchParams’s timing info.
- const timingInfo = fetchParams.timingInfo
-
- // 4. Let httpCache be the result of determining the HTTP cache partition,
- // given request.
- // TODO: cache
- const httpCache = null
-
- // 5. If httpCache is null, then set request’s cache mode to "no-store".
- if (httpCache == null) {
- request.cache = 'no-store'
- }
-
- // 6. Let networkPartitionKey be the result of determining the network
- // partition key given request.
- // TODO
-
- // 7. Let newConnection be "yes" if forceNewConnection is true; otherwise
- // "no".
- const newConnection = forceNewConnection ? 'yes' : 'no' // eslint-disable-line no-unused-vars
-
- // 8. Switch on request’s mode:
- if (request.mode === 'websocket') {
- // Let connection be the result of obtaining a WebSocket connection,
- // given request’s current URL.
- // TODO
- } else {
- // Let connection be the result of obtaining a connection, given
- // networkPartitionKey, request’s current URL’s origin,
- // includeCredentials, and forceNewConnection.
- // TODO
- }
-
- // 9. Run these steps, but abort when the ongoing fetch is terminated:
-
- // 1. If connection is failure, then return a network error.
-
- // 2. Set timingInfo’s final connection timing info to the result of
- // calling clamp and coarsen connection timing info with connection’s
- // timing info, timingInfo’s post-redirect start time, and fetchParams’s
- // cross-origin isolated capability.
-
- // 3. If connection is not an HTTP/2 connection, request’s body is non-null,
- // and request’s body’s source is null, then append (`Transfer-Encoding`,
- // `chunked`) to request’s header list.
-
- // 4. Set timingInfo’s final network-request start time to the coarsened
- // shared current time given fetchParams’s cross-origin isolated
- // capability.
-
- // 5. Set response to the result of making an HTTP request over connection
- // using request with the following caveats:
-
- // - Follow the relevant requirements from HTTP. [HTTP] [HTTP-SEMANTICS]
- // [HTTP-COND] [HTTP-CACHING] [HTTP-AUTH]
-
- // - If request’s body is non-null, and request’s body’s source is null,
- // then the user agent may have a buffer of up to 64 kibibytes and store
- // a part of request’s body in that buffer. If the user agent reads from
- // request’s body beyond that buffer’s size and the user agent needs to
- // resend request, then instead return a network error.
-
- // - Set timingInfo’s final network-response start time to the coarsened
- // shared current time given fetchParams’s cross-origin isolated capability,
- // immediately after the user agent’s HTTP parser receives the first byte
- // of the response (e.g., frame header bytes for HTTP/2 or response status
- // line for HTTP/1.x).
-
- // - Wait until all the headers are transmitted.
-
- // - Any responses whose status is in the range 100 to 199, inclusive,
- // and is not 101, are to be ignored, except for the purposes of setting
- // timingInfo’s final network-response start time above.
-
- // - If request’s header list contains `Transfer-Encoding`/`chunked` and
- // response is transferred via HTTP/1.0 or older, then return a network
- // error.
-
- // - If the HTTP request results in a TLS client certificate dialog, then:
-
- // 1. If request’s window is an environment settings object, make the
- // dialog available in request’s window.
-
- // 2. Otherwise, return a network error.
-
- // To transmit request’s body body, run these steps:
- let requestBody = null
- // 1. If body is null and fetchParams’s process request end-of-body is
- // non-null, then queue a fetch task given fetchParams’s process request
- // end-of-body and fetchParams’s task destination.
- if (request.body == null && fetchParams.processRequestEndOfBody) {
- queueMicrotask(() => fetchParams.processRequestEndOfBody())
- } else if (request.body != null) {
- // 2. Otherwise, if body is non-null:
-
- // 1. Let processBodyChunk given bytes be these steps:
- const processBodyChunk = async function * (bytes) {
- // 1. If the ongoing fetch is terminated, then abort these steps.
- if (isCancelled(fetchParams)) {
- return
- }
-
- // 2. Run this step in parallel: transmit bytes.
- yield bytes
-
- // 3. If fetchParams’s process request body is non-null, then run
- // fetchParams’s process request body given bytes’s length.
- fetchParams.processRequestBodyChunkLength?.(bytes.byteLength)
- }
-
- // 2. Let processEndOfBody be these steps:
- const processEndOfBody = () => {
- // 1. If fetchParams is canceled, then abort these steps.
- if (isCancelled(fetchParams)) {
- return
- }
-
- // 2. If fetchParams’s process request end-of-body is non-null,
- // then run fetchParams’s process request end-of-body.
- if (fetchParams.processRequestEndOfBody) {
- fetchParams.processRequestEndOfBody()
- }
- }
-
- // 3. Let processBodyError given e be these steps:
- const processBodyError = (e) => {
- // 1. If fetchParams is canceled, then abort these steps.
- if (isCancelled(fetchParams)) {
- return
- }
-
- // 2. If e is an "AbortError" DOMException, then abort fetchParams’s controller.
- if (e.name === 'AbortError') {
- fetchParams.controller.abort()
- } else {
- fetchParams.controller.terminate(e)
- }
- }
-
- // 4. Incrementally read request’s body given processBodyChunk, processEndOfBody,
- // processBodyError, and fetchParams’s task destination.
- requestBody = (async function * () {
- try {
- for await (const bytes of request.body.stream) {
- yield * processBodyChunk(bytes)
- }
- processEndOfBody()
- } catch (err) {
- processBodyError(err)
- }
- })()
- }
-
- try {
- const { body, status, statusText, headersList } = await dispatch({ body: requestBody })
-
- const iterator = body[Symbol.asyncIterator]()
- fetchParams.controller.next = () => iterator.next()
-
- response = makeResponse({ status, statusText, headersList })
- } catch (err) {
- // 10. If aborted, then:
- if (err.name === 'AbortError') {
- // 1. If connection uses HTTP/2, then transmit an RST_STREAM frame.
- fetchParams.controller.connection.destroy()
-
- // 2. Return the appropriate network error for fetchParams.
- return makeAppropriateNetworkError(fetchParams)
- }
-
- return makeNetworkError(err)
- }
-
- // 11. Let pullAlgorithm be an action that resumes the ongoing fetch
- // if it is suspended.
- const pullAlgorithm = () => {
- fetchParams.controller.resume()
- }
-
- // 12. Let cancelAlgorithm be an algorithm that aborts fetchParams’s
- // controller.
- const cancelAlgorithm = () => {
- fetchParams.controller.abort()
- }
-
- // 13. Let highWaterMark be a non-negative, non-NaN number, chosen by
- // the user agent.
- // TODO
-
- // 14. Let sizeAlgorithm be an algorithm that accepts a chunk object
- // and returns a non-negative, non-NaN, non-infinite number, chosen by the user agent.
- // TODO
-
- // 15. Let stream be a new ReadableStream.
- // 16. Set up stream with pullAlgorithm set to pullAlgorithm,
- // cancelAlgorithm set to cancelAlgorithm, highWaterMark set to
- // highWaterMark, and sizeAlgorithm set to sizeAlgorithm.
- if (!ReadableStream) {
- ReadableStream = require('stream/web').ReadableStream
- }
-
- const stream = new ReadableStream(
- {
- async start (controller) {
- fetchParams.controller.controller = controller
- },
- async pull (controller) {
- await pullAlgorithm(controller)
- },
- async cancel (reason) {
- await cancelAlgorithm(reason)
- }
- },
- { highWaterMark: 0 }
- )
-
- // 17. Run these steps, but abort when the ongoing fetch is terminated:
-
- // 1. Set response’s body to a new body whose stream is stream.
- response.body = { stream }
-
- // 2. If response is not a network error and request’s cache mode is
- // not "no-store", then update response in httpCache for request.
- // TODO
-
- // 3. If includeCredentials is true and the user agent is not configured
- // to block cookies for request (see section 7 of [COOKIES]), then run the
- // "set-cookie-string" parsing algorithm (see section 5.2 of [COOKIES]) on
- // the value of each header whose name is a byte-case-insensitive match for
- // `Set-Cookie` in response’s header list, if any, and request’s current URL.
- // TODO
-
- // 18. If aborted, then:
- // TODO
-
- // 19. Run these steps in parallel:
-
- // 1. Run these steps, but abort when fetchParams is canceled:
- fetchParams.controller.on('terminated', onAborted)
- fetchParams.controller.resume = async () => {
- // 1. While true
- while (true) {
- // 1-3. See onData...
-
- // 4. Set bytes to the result of handling content codings given
- // codings and bytes.
- let bytes
- try {
- const { done, value } = await fetchParams.controller.next()
-
- if (isAborted(fetchParams)) {
- break
- }
-
- bytes = done ? undefined : value
- } catch (err) {
- if (fetchParams.controller.ended && !timingInfo.encodedBodySize) {
- // zlib doesn't like empty streams.
- bytes = undefined
- } else {
- bytes = err
- }
- }
-
- if (bytes === undefined) {
- // 2. Otherwise, if the bytes transmission for response’s message
- // body is done normally and stream is readable, then close
- // stream, finalize response for fetchParams and response, and
- // abort these in-parallel steps.
- try {
- fetchParams.controller.controller.close()
- } catch (err) {
- // TODO (fix): How/Why can this happen? Do we have a bug?
- if (!/Controller is already closed/.test(err)) {
- throw err
- }
- }
-
- finalizeResponse(fetchParams, response)
-
- return
- }
-
- // 5. Increase timingInfo’s decoded body size by bytes’s length.
- timingInfo.decodedBodySize += bytes?.byteLength ?? 0
-
- // 6. If bytes is failure, then terminate fetchParams’s controller.
- if (bytes instanceof Error) {
- fetchParams.controller.terminate(bytes)
- return
- }
-
- // 7. Enqueue a Uint8Array wrapping an ArrayBuffer containing bytes
- // into stream.
- fetchParams.controller.controller.enqueue(new Uint8Array(bytes))
-
- // 8. If stream is errored, then terminate the ongoing fetch.
- if (isErrored(stream)) {
- fetchParams.controller.terminate()
- return
- }
-
- // 9. If stream doesn’t need more data ask the user agent to suspend
- // the ongoing fetch.
- if (!fetchParams.controller.controller.desiredSize) {
- return
- }
- }
- }
-
- // 2. If aborted, then:
- function onAborted (reason) {
- // 2. If fetchParams is aborted, then:
- if (isAborted(fetchParams)) {
- // 1. Set response’s aborted flag.
- response.aborted = true
-
- // 2. If stream is readable, error stream with an "AbortError" DOMException.
- if (isReadable(stream)) {
- fetchParams.controller.controller.error(
- new DOMException('The operation was aborted.', 'AbortError')
- )
- }
- } else {
- // 3. Otherwise, if stream is readable, error stream with a TypeError.
- if (isReadable(stream)) {
- fetchParams.controller.controller.error(new TypeError('terminated', {
- cause: reason instanceof Error ? reason : undefined
- }))
- }
- }
-
- // 4. If connection uses HTTP/2, then transmit an RST_STREAM frame.
- // 5. Otherwise, the user agent should close connection unless it would be bad for performance to do so.
- fetchParams.controller.connection.destroy()
- }
-
- // 20. Return response.
- return response
-
- async function dispatch ({ body }) {
- const url = requestCurrentURL(request)
- return new Promise((resolve, reject) => fetchParams.controller.dispatcher.dispatch(
- {
- path: url.pathname + url.search,
- origin: url.origin,
- method: request.method,
- body: fetchParams.controller.dispatcher.isMockActive ? request.body && request.body.source : body,
- headers: [...request.headersList].flat(),
- maxRedirections: 0,
- bodyTimeout: 300_000,
- headersTimeout: 300_000
- },
- {
- body: null,
- abort: null,
-
- onConnect (abort) {
- // TODO (fix): Do we need connection here?
- const { connection } = fetchParams.controller
-
- if (connection.destroyed) {
- abort(new DOMException('The operation was aborted.', 'AbortError'))
- } else {
- fetchParams.controller.on('terminated', abort)
- this.abort = connection.abort = abort
- }
- },
-
- onHeaders (status, headersList, resume, statusText) {
- if (status < 200) {
- return
- }
-
- let codings = []
-
- const headers = new Headers()
- for (let n = 0; n < headersList.length; n += 2) {
- const key = headersList[n + 0].toString()
- const val = headersList[n + 1].toString()
-
- if (key.toLowerCase() === 'content-encoding') {
- codings = val.split(',').map((x) => x.trim())
- }
-
- headers.append(key, val)
- }
-
- this.body = new Readable({ read: resume })
-
- const decoders = []
-
- // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding
- if (request.method !== 'HEAD' && request.method !== 'CONNECT' && !nullBodyStatus.includes(status)) {
- for (const coding of codings) {
- if (/(x-)?gzip/.test(coding)) {
- decoders.push(zlib.createGunzip())
- } else if (/(x-)?deflate/.test(coding)) {
- decoders.push(zlib.createInflate())
- } else if (coding === 'br') {
- decoders.push(zlib.createBrotliDecompress())
- } else {
- decoders.length = 0
- break
- }
- }
- }
-
- resolve({
- status,
- statusText,
- headersList: headers[kHeadersList],
- body: decoders.length
- ? pipeline(this.body, ...decoders, () => {})
- : this.body.on('error', () => {})
- })
-
- return true
- },
-
- onData (chunk) {
- if (fetchParams.controller.dump) {
- return
- }
-
- // 1. If one or more bytes have been transmitted from response’s
- // message body, then:
-
- // 1. Let bytes be the transmitted bytes.
- const bytes = chunk
-
- // 2. Let codings be the result of extracting header list values
- // given `Content-Encoding` and response’s header list.
- // See pullAlgorithm.
-
- // 3. Increase timingInfo’s encoded body size by bytes’s length.
- timingInfo.encodedBodySize += bytes.byteLength
-
- // 4. See pullAlgorithm...
-
- return this.body.push(bytes)
- },
-
- onComplete () {
- if (this.abort) {
- fetchParams.controller.off('terminated', this.abort)
- }
-
- fetchParams.controller.ended = true
-
- this.body.push(null)
- },
-
- onError (error) {
- if (this.abort) {
- fetchParams.controller.off('terminated', this.abort)
- }
-
- this.body?.destroy(error)
-
- fetchParams.controller.terminate(error)
-
- reject(error)
- }
- }
- ))
- }
-}
-
-module.exports = fetch
diff --git a/node_modules/undici/lib/fetch/request.js b/node_modules/undici/lib/fetch/request.js
deleted file mode 100644
index 7e1b3d8..0000000
--- a/node_modules/undici/lib/fetch/request.js
+++ /dev/null
@@ -1,926 +0,0 @@
-/* globals AbortController */
-
-'use strict'
-
-const { extractBody, mixinBody, cloneBody } = require('./body')
-const { Headers, fill: fillHeaders, HeadersList } = require('./headers')
-const util = require('../core/util')
-const {
- isValidHTTPToken,
- sameOrigin,
- normalizeMethod
-} = require('./util')
-const {
- forbiddenMethods,
- corsSafeListedMethods,
- referrerPolicy,
- requestRedirect,
- requestMode,
- requestCredentials,
- requestCache
-} = require('./constants')
-const { kEnumerableProperty } = util
-const { kHeaders, kSignal, kState, kGuard, kRealm } = require('./symbols')
-const { webidl } = require('./webidl')
-const { kHeadersList } = require('../core/symbols')
-const assert = require('assert')
-
-let TransformStream
-
-const kInit = Symbol('init')
-
-const requestFinalizer = new FinalizationRegistry(({ signal, abort }) => {
- signal.removeEventListener('abort', abort)
-})
-
-// https://fetch.spec.whatwg.org/#request-class
-class Request {
- // https://fetch.spec.whatwg.org/#dom-request
- constructor (input, init = {}) {
- if (input === kInit) {
- return
- }
-
- if (arguments.length < 1) {
- throw new TypeError(
- `Failed to construct 'Request': 1 argument required, but only ${arguments.length} present.`
- )
- }
-
- input = webidl.converters.RequestInfo(input)
- init = webidl.converters.RequestInit(init)
-
- // TODO
- this[kRealm] = { settingsObject: {} }
-
- // 1. Let request be null.
- let request = null
-
- // 2. Let fallbackMode be null.
- let fallbackMode = null
-
- // 3. Let baseURL be this’s relevant settings object’s API base URL.
- const baseUrl = this[kRealm].settingsObject.baseUrl
-
- // 4. Let signal be null.
- let signal = null
-
- // 5. If input is a string, then:
- if (typeof input === 'string') {
- // 1. Let parsedURL be the result of parsing input with baseURL.
- // 2. If parsedURL is failure, then throw a TypeError.
- let parsedURL
- try {
- parsedURL = new URL(input, baseUrl)
- } catch (err) {
- throw new TypeError('Failed to parse URL from ' + input, { cause: err })
- }
-
- // 3. If parsedURL includes credentials, then throw a TypeError.
- if (parsedURL.username || parsedURL.password) {
- throw new TypeError(
- 'Request cannot be constructed from a URL that includes credentials: ' +
- input
- )
- }
-
- // 4. Set request to a new request whose URL is parsedURL.
- request = makeRequest({ urlList: [parsedURL] })
-
- // 5. Set fallbackMode to "cors".
- fallbackMode = 'cors'
- } else {
- // 6. Otherwise:
-
- // 7. Assert: input is a Request object.
- assert(input instanceof Request)
-
- // 8. Set request to input’s request.
- request = input[kState]
-
- // 9. Set signal to input’s signal.
- signal = input[kSignal]
- }
-
- // 7. Let origin be this’s relevant settings object’s origin.
- const origin = this[kRealm].settingsObject.origin
-
- // 8. Let window be "client".
- let window = 'client'
-
- // 9. If request’s window is an environment settings object and its origin
- // is same origin with origin, then set window to request’s window.
- if (
- request.window?.constructor?.name === 'EnvironmentSettingsObject' &&
- sameOrigin(request.window, origin)
- ) {
- window = request.window
- }
-
- // 10. If init["window"] exists and is non-null, then throw a TypeError.
- if (init.window !== undefined && init.window != null) {
- throw new TypeError(`'window' option '${window}' must be null`)
- }
-
- // 11. If init["window"] exists, then set window to "no-window".
- if (init.window !== undefined) {
- window = 'no-window'
- }
-
- // 12. Set request to a new request with the following properties:
- request = makeRequest({
- // URL request’s URL.
- // undici implementation note: this is set as the first item in request's urlList in makeRequest
- // method request’s method.
- method: request.method,
- // header list A copy of request’s header list.
- // undici implementation note: headersList is cloned in makeRequest
- headersList: request.headersList,
- // unsafe-request flag Set.
- unsafeRequest: request.unsafeRequest,
- // client This’s relevant settings object.
- client: this[kRealm].settingsObject,
- // window window.
- window,
- // priority request’s priority.
- priority: request.priority,
- // origin request’s origin. The propagation of the origin is only significant for navigation requests
- // being handled by a service worker. In this scenario a request can have an origin that is different
- // from the current client.
- origin: request.origin,
- // referrer request’s referrer.
- referrer: request.referrer,
- // referrer policy request’s referrer policy.
- referrerPolicy: request.referrerPolicy,
- // mode request’s mode.
- mode: request.mode,
- // credentials mode request’s credentials mode.
- credentials: request.credentials,
- // cache mode request’s cache mode.
- cache: request.cache,
- // redirect mode request’s redirect mode.
- redirect: request.redirect,
- // integrity metadata request’s integrity metadata.
- integrity: request.integrity,
- // keepalive request’s keepalive.
- keepalive: request.keepalive,
- // reload-navigation flag request’s reload-navigation flag.
- reloadNavigation: request.reloadNavigation,
- // history-navigation flag request’s history-navigation flag.
- historyNavigation: request.historyNavigation,
- // URL list A clone of request’s URL list.
- urlList: [...request.urlList]
- })
-
- // 13. If init is not empty, then:
- if (Object.keys(init).length > 0) {
- // 1. If request’s mode is "navigate", then set it to "same-origin".
- if (request.mode === 'navigate') {
- request.mode = 'same-origin'
- }
-
- // 2. Unset request’s reload-navigation flag.
- request.reloadNavigation = false
-
- // 3. Unset request’s history-navigation flag.
- request.historyNavigation = false
-
- // 4. Set request’s origin to "client".
- request.origin = 'client'
-
- // 5. Set request’s referrer to "client"
- request.referrer = 'client'
-
- // 6. Set request’s referrer policy to the empty string.
- request.referrerPolicy = ''
-
- // 7. Set request’s URL to request’s current URL.
- request.url = request.urlList[request.urlList.length - 1]
-
- // 8. Set request’s URL list to « request’s URL ».
- request.urlList = [request.url]
- }
-
- // 14. If init["referrer"] exists, then:
- if (init.referrer !== undefined) {
- // 1. Let referrer be init["referrer"].
- const referrer = init.referrer
-
- // 2. If referrer is the empty string, then set request’s referrer to "no-referrer".
- if (referrer === '') {
- request.referrer = 'no-referrer'
- } else {
- // 1. Let parsedReferrer be the result of parsing referrer with
- // baseURL.
- // 2. If parsedReferrer is failure, then throw a TypeError.
- let parsedReferrer
- try {
- parsedReferrer = new URL(referrer, baseUrl)
- } catch (err) {
- throw new TypeError(`Referrer "${referrer}" is not a valid URL.`, { cause: err })
- }
-
- // 3. If one of the following is true
- // parsedReferrer’s cannot-be-a-base-URL is true, scheme is "about",
- // and path contains a single string "client"
- // parsedReferrer’s origin is not same origin with origin
- // then set request’s referrer to "client".
- // TODO
-
- // 4. Otherwise, set request’s referrer to parsedReferrer.
- request.referrer = parsedReferrer
- }
- }
-
- // 15. If init["referrerPolicy"] exists, then set request’s referrer policy
- // to it.
- if (init.referrerPolicy !== undefined) {
- request.referrerPolicy = init.referrerPolicy
- if (!referrerPolicy.includes(request.referrerPolicy)) {
- throw new TypeError(
- `Failed to construct 'Request': The provided value '${request.referrerPolicy}' is not a valid enum value of type ReferrerPolicy.`
- )
- }
- }
-
- // 16. Let mode be init["mode"] if it exists, and fallbackMode otherwise.
- let mode
- if (init.mode !== undefined) {
- mode = init.mode
- if (!requestMode.includes(mode)) {
- throw new TypeError(
- `Failed to construct 'Request': The provided value '${request.mode}' is not a valid enum value of type RequestMode.`
- )
- }
- } else {
- mode = fallbackMode
- }
-
- // 17. If mode is "navigate", then throw a TypeError.
- if (mode === 'navigate') {
- webidl.errors.exception({
- header: 'Request constructor',
- message: 'invalid request mode navigate.'
- })
- }
-
- // 18. If mode is non-null, set request’s mode to mode.
- if (mode != null) {
- request.mode = mode
- }
-
- // 19. If init["credentials"] exists, then set request’s credentials mode
- // to it.
- if (init.credentials !== undefined) {
- request.credentials = init.credentials
- if (!requestCredentials.includes(request.credentials)) {
- throw new TypeError(
- `Failed to construct 'Request': The provided value '${request.credentials}' is not a valid enum value of type RequestCredentials.`
- )
- }
- }
-
- // 18. If init["cache"] exists, then set request’s cache mode to it.
- if (init.cache !== undefined) {
- request.cache = init.cache
- if (!requestCache.includes(request.cache)) {
- throw new TypeError(
- `Failed to construct 'Request': The provided value '${request.cache}' is not a valid enum value of type RequestCache.`
- )
- }
- }
-
- // 21. If request’s cache mode is "only-if-cached" and request’s mode is
- // not "same-origin", then throw a TypeError.
- if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') {
- throw new TypeError(
- "'only-if-cached' can be set only with 'same-origin' mode"
- )
- }
-
- // 22. If init["redirect"] exists, then set request’s redirect mode to it.
- if (init.redirect !== undefined) {
- request.redirect = init.redirect
- if (!requestRedirect.includes(request.redirect)) {
- throw new TypeError(
- `Failed to construct 'Request': The provided value '${request.redirect}' is not a valid enum value of type RequestRedirect.`
- )
- }
- }
-
- // 23. If init["integrity"] exists, then set request’s integrity metadata to it.
- if (init.integrity !== undefined && init.integrity != null) {
- request.integrity = String(init.integrity)
- }
-
- // 24. If init["keepalive"] exists, then set request’s keepalive to it.
- if (init.keepalive !== undefined) {
- request.keepalive = Boolean(init.keepalive)
- }
-
- // 25. If init["method"] exists, then:
- if (init.method !== undefined) {
- // 1. Let method be init["method"].
- let method = init.method
-
- // 2. If method is not a method or method is a forbidden method, then
- // throw a TypeError.
- if (!isValidHTTPToken(init.method)) {
- throw TypeError(`'${init.method}' is not a valid HTTP method.`)
- }
-
- if (forbiddenMethods.indexOf(method.toUpperCase()) !== -1) {
- throw TypeError(`'${init.method}' HTTP method is unsupported.`)
- }
-
- // 3. Normalize method.
- method = normalizeMethod(init.method)
-
- // 4. Set request’s method to method.
- request.method = method
- }
-
- // 26. If init["signal"] exists, then set signal to it.
- if (init.signal !== undefined) {
- signal = init.signal
- }
-
- // 27. Set this’s request to request.
- this[kState] = request
-
- // 28. Set this’s signal to a new AbortSignal object with this’s relevant
- // Realm.
- const ac = new AbortController()
- this[kSignal] = ac.signal
- this[kSignal][kRealm] = this[kRealm]
-
- // 29. If signal is not null, then make this’s signal follow signal.
- if (signal != null) {
- if (
- !signal ||
- typeof signal.aborted !== 'boolean' ||
- typeof signal.addEventListener !== 'function'
- ) {
- throw new TypeError(
- "Failed to construct 'Request': member signal is not of type AbortSignal."
- )
- }
-
- if (signal.aborted) {
- ac.abort()
- } else {
- const abort = () => ac.abort()
- signal.addEventListener('abort', abort, { once: true })
- requestFinalizer.register(this, { signal, abort })
- }
- }
-
- // 30. Set this’s headers to a new Headers object with this’s relevant
- // Realm, whose header list is request’s header list and guard is
- // "request".
- this[kHeaders] = new Headers()
- this[kHeaders][kHeadersList] = request.headersList
- this[kHeaders][kGuard] = 'request'
- this[kHeaders][kRealm] = this[kRealm]
-
- // 31. If this’s request’s mode is "no-cors", then:
- if (mode === 'no-cors') {
- // 1. If this’s request’s method is not a CORS-safelisted method,
- // then throw a TypeError.
- if (!corsSafeListedMethods.includes(request.method)) {
- throw new TypeError(
- `'${request.method} is unsupported in no-cors mode.`
- )
- }
-
- // 2. Set this’s headers’s guard to "request-no-cors".
- this[kHeaders][kGuard] = 'request-no-cors'
- }
-
- // 32. If init is not empty, then:
- if (Object.keys(init).length !== 0) {
- // 1. Let headers be a copy of this’s headers and its associated header
- // list.
- let headers = new Headers(this[kHeaders])
-
- // 2. If init["headers"] exists, then set headers to init["headers"].
- if (init.headers !== undefined) {
- headers = init.headers
- }
-
- // 3. Empty this’s headers’s header list.
- this[kHeaders][kHeadersList].clear()
-
- // 4. If headers is a Headers object, then for each header in its header
- // list, append header’s name/header’s value to this’s headers.
- if (headers.constructor.name === 'Headers') {
- for (const [key, val] of headers) {
- this[kHeaders].append(key, val)
- }
- } else {
- // 5. Otherwise, fill this’s headers with headers.
- fillHeaders(this[kHeaders], headers)
- }
- }
-
- // 33. Let inputBody be input’s request’s body if input is a Request
- // object; otherwise null.
- const inputBody = input instanceof Request ? input[kState].body : null
-
- // 34. If either init["body"] exists and is non-null or inputBody is
- // non-null, and request’s method is `GET` or `HEAD`, then throw a
- // TypeError.
- if (
- ((init.body !== undefined && init.body != null) || inputBody != null) &&
- (request.method === 'GET' || request.method === 'HEAD')
- ) {
- throw new TypeError('Request with GET/HEAD method cannot have body.')
- }
-
- // 35. Let initBody be null.
- let initBody = null
-
- // 36. If init["body"] exists and is non-null, then:
- if (init.body !== undefined && init.body != null) {
- // 1. Let Content-Type be null.
- // 2. Set initBody and Content-Type to the result of extracting
- // init["body"], with keepalive set to request’s keepalive.
- const [extractedBody, contentType] = extractBody(
- init.body,
- request.keepalive
- )
- initBody = extractedBody
-
- // 3, If Content-Type is non-null and this’s headers’s header list does
- // not contain `Content-Type`, then append `Content-Type`/Content-Type to
- // this’s headers.
- if (contentType && !this[kHeaders].has('content-type')) {
- this[kHeaders].append('content-type', contentType)
- }
- }
-
- // 37. Let inputOrInitBody be initBody if it is non-null; otherwise
- // inputBody.
- const inputOrInitBody = initBody ?? inputBody
-
- // 38. If inputOrInitBody is non-null and inputOrInitBody’s source is
- // null, then:
- if (inputOrInitBody != null && inputOrInitBody.source == null) {
- // 1. If this’s request’s mode is neither "same-origin" nor "cors",
- // then throw a TypeError.
- if (request.mode !== 'same-origin' && request.mode !== 'cors') {
- throw new TypeError(
- 'If request is made from ReadableStream, mode should be "same-origin" or "cors"'
- )
- }
-
- // 2. Set this’s request’s use-CORS-preflight flag.
- request.useCORSPreflightFlag = true
- }
-
- // 39. Let finalBody be inputOrInitBody.
- let finalBody = inputOrInitBody
-
- // 40. If initBody is null and inputBody is non-null, then:
- if (initBody == null && inputBody != null) {
- // 1. If input is unusable, then throw a TypeError.
- if (util.isDisturbed(inputBody.stream) || inputBody.stream.locked) {
- throw new TypeError(
- 'Cannot construct a Request with a Request object that has already been used.'
- )
- }
-
- // 2. Set finalBody to the result of creating a proxy for inputBody.
- if (!TransformStream) {
- TransformStream = require('stream/web').TransformStream
- }
-
- // https://streams.spec.whatwg.org/#readablestream-create-a-proxy
- const identityTransform = new TransformStream()
- inputBody.stream.pipeThrough(identityTransform)
- finalBody = {
- source: inputBody.source,
- length: inputBody.length,
- stream: identityTransform.readable
- }
- }
-
- // 41. Set this’s request’s body to finalBody.
- this[kState].body = finalBody
- }
-
- get [Symbol.toStringTag] () {
- return this.constructor.name
- }
-
- // Returns request’s HTTP method, which is "GET" by default.
- get method () {
- if (!(this instanceof Request)) {
- throw new TypeError('Illegal invocation')
- }
-
- // The method getter steps are to return this’s request’s method.
- return this[kState].method
- }
-
- // Returns the URL of request as a string.
- get url () {
- if (!(this instanceof Request)) {
- throw new TypeError('Illegal invocation')
- }
-
- // The url getter steps are to return this’s request’s URL, serialized.
- return this[kState].url.toString()
- }
-
- // Returns a Headers object consisting of the headers associated with request.
- // Note that headers added in the network layer by the user agent will not
- // be accounted for in this object, e.g., the "Host" header.
- get headers () {
- if (!(this instanceof Request)) {
- throw new TypeError('Illegal invocation')
- }
-
- // The headers getter steps are to return this’s headers.
- return this[kHeaders]
- }
-
- // Returns the kind of resource requested by request, e.g., "document"
- // or "script".
- get destination () {
- if (!(this instanceof Request)) {
- throw new TypeError('Illegal invocation')
- }
-
- // The destination getter are to return this’s request’s destination.
- return this[kState].destination
- }
-
- // Returns the referrer of request. Its value can be a same-origin URL if
- // explicitly set in init, the empty string to indicate no referrer, and
- // "about:client" when defaulting to the global’s default. This is used
- // during fetching to determine the value of the `Referer` header of the
- // request being made.
- get referrer () {
- if (!(this instanceof Request)) {
- throw new TypeError('Illegal invocation')
- }
-
- // 1. If this’s request’s referrer is "no-referrer", then return the
- // empty string.
- if (this[kState].referrer === 'no-referrer') {
- return ''
- }
-
- // 2. If this’s request’s referrer is "client", then return
- // "about:client".
- if (this[kState].referrer === 'client') {
- return 'about:client'
- }
-
- // Return this’s request’s referrer, serialized.
- return this[kState].referrer.toString()
- }
-
- // Returns the referrer policy associated with request.
- // This is used during fetching to compute the value of the request’s
- // referrer.
- get referrerPolicy () {
- if (!(this instanceof Request)) {
- throw new TypeError('Illegal invocation')
- }
-
- // The referrerPolicy getter steps are to return this’s request’s referrer policy.
- return this[kState].referrerPolicy
- }
-
- // Returns the mode associated with request, which is a string indicating
- // whether the request will use CORS, or will be restricted to same-origin
- // URLs.
- get mode () {
- if (!(this instanceof Request)) {
- throw new TypeError('Illegal invocation')
- }
-
- // The mode getter steps are to return this’s request’s mode.
- return this[kState].mode
- }
-
- // Returns the credentials mode associated with request,
- // which is a string indicating whether credentials will be sent with the
- // request always, never, or only when sent to a same-origin URL.
- get credentials () {
- // The credentials getter steps are to return this’s request’s credentials mode.
- return this[kState].credentials
- }
-
- // Returns the cache mode associated with request,
- // which is a string indicating how the request will
- // interact with the browser’s cache when fetching.
- get cache () {
- if (!(this instanceof Request)) {
- throw new TypeError('Illegal invocation')
- }
-
- // The cache getter steps are to return this’s request’s cache mode.
- return this[kState].cache
- }
-
- // Returns the redirect mode associated with request,
- // which is a string indicating how redirects for the
- // request will be handled during fetching. A request
- // will follow redirects by default.
- get redirect () {
- if (!(this instanceof Request)) {
- throw new TypeError('Illegal invocation')
- }
-
- // The redirect getter steps are to return this’s request’s redirect mode.
- return this[kState].redirect
- }
-
- // Returns request’s subresource integrity metadata, which is a
- // cryptographic hash of the resource being fetched. Its value
- // consists of multiple hashes separated by whitespace. [SRI]
- get integrity () {
- if (!(this instanceof Request)) {
- throw new TypeError('Illegal invocation')
- }
-
- // The integrity getter steps are to return this’s request’s integrity
- // metadata.
- return this[kState].integrity
- }
-
- // Returns a boolean indicating whether or not request can outlive the
- // global in which it was created.
- get keepalive () {
- if (!(this instanceof Request)) {
- throw new TypeError('Illegal invocation')
- }
-
- // The keepalive getter steps are to return this’s request’s keepalive.
- return this[kState].keepalive
- }
-
- // Returns a boolean indicating whether or not request is for a reload
- // navigation.
- get isReloadNavigation () {
- if (!(this instanceof Request)) {
- throw new TypeError('Illegal invocation')
- }
-
- // The isReloadNavigation getter steps are to return true if this’s
- // request’s reload-navigation flag is set; otherwise false.
- return this[kState].reloadNavigation
- }
-
- // Returns a boolean indicating whether or not request is for a history
- // navigation (a.k.a. back-foward navigation).
- get isHistoryNavigation () {
- if (!(this instanceof Request)) {
- throw new TypeError('Illegal invocation')
- }
-
- // The isHistoryNavigation getter steps are to return true if this’s request’s
- // history-navigation flag is set; otherwise false.
- return this[kState].historyNavigation
- }
-
- // Returns the signal associated with request, which is an AbortSignal
- // object indicating whether or not request has been aborted, and its
- // abort event handler.
- get signal () {
- if (!(this instanceof Request)) {
- throw new TypeError('Illegal invocation')
- }
-
- // The signal getter steps are to return this’s signal.
- return this[kSignal]
- }
-
- // Returns a clone of request.
- clone () {
- if (!(this instanceof Request)) {
- throw new TypeError('Illegal invocation')
- }
-
- // 1. If this is unusable, then throw a TypeError.
- if (this.bodyUsed || this.body?.locked) {
- throw new TypeError('unusable')
- }
-
- // 2. Let clonedRequest be the result of cloning this’s request.
- const clonedRequest = cloneRequest(this[kState])
-
- // 3. Let clonedRequestObject be the result of creating a Request object,
- // given clonedRequest, this’s headers’s guard, and this’s relevant Realm.
- const clonedRequestObject = new Request(kInit)
- clonedRequestObject[kState] = clonedRequest
- clonedRequestObject[kRealm] = this[kRealm]
- clonedRequestObject[kHeaders] = new Headers()
- clonedRequestObject[kHeaders][kHeadersList] = clonedRequest.headersList
- clonedRequestObject[kHeaders][kGuard] = this[kHeaders][kGuard]
- clonedRequestObject[kHeaders][kRealm] = this[kHeaders][kRealm]
-
- // 4. Make clonedRequestObject’s signal follow this’s signal.
- const ac = new AbortController()
- if (this.signal.aborted) {
- ac.abort()
- } else {
- this.signal.addEventListener(
- 'abort',
- function () {
- ac.abort()
- },
- { once: true }
- )
- }
- clonedRequestObject[kSignal] = ac.signal
-
- // 4. Return clonedRequestObject.
- return clonedRequestObject
- }
-}
-
-mixinBody(Request)
-
-function makeRequest (init) {
- // https://fetch.spec.whatwg.org/#requests
- const request = {
- method: 'GET',
- localURLsOnly: false,
- unsafeRequest: false,
- body: null,
- client: null,
- reservedClient: null,
- replacesClientId: '',
- window: 'client',
- keepalive: false,
- serviceWorkers: 'all',
- initiator: '',
- destination: '',
- priority: null,
- origin: 'client',
- policyContainer: 'client',
- referrer: 'client',
- referrerPolicy: '',
- mode: 'no-cors',
- useCORSPreflightFlag: false,
- credentials: 'same-origin',
- useCredentials: false,
- cache: 'default',
- redirect: 'follow',
- integrity: '',
- cryptoGraphicsNonceMetadata: '',
- parserMetadata: '',
- reloadNavigation: false,
- historyNavigation: false,
- userActivation: false,
- taintedOrigin: false,
- redirectCount: 0,
- responseTainting: 'basic',
- preventNoCacheCacheControlHeaderModification: false,
- done: false,
- timingAllowFailed: false,
- ...init,
- headersList: init.headersList
- ? new HeadersList(init.headersList)
- : new HeadersList()
- }
- request.url = request.urlList[0]
- return request
-}
-
-// https://fetch.spec.whatwg.org/#concept-request-clone
-function cloneRequest (request) {
- // To clone a request request, run these steps:
-
- // 1. Let newRequest be a copy of request, except for its body.
- const newRequest = makeRequest({ ...request, body: null })
-
- // 2. If request’s body is non-null, set newRequest’s body to the
- // result of cloning request’s body.
- if (request.body != null) {
- newRequest.body = cloneBody(request.body)
- }
-
- // 3. Return newRequest.
- return newRequest
-}
-
-Object.defineProperties(Request.prototype, {
- method: kEnumerableProperty,
- url: kEnumerableProperty,
- headers: kEnumerableProperty,
- redirect: kEnumerableProperty,
- clone: kEnumerableProperty,
- signal: kEnumerableProperty
-})
-
-webidl.converters.Request = webidl.interfaceConverter(
- Request
-)
-
-// https://fetch.spec.whatwg.org/#requestinfo
-webidl.converters.RequestInfo = function (V) {
- if (typeof V === 'string') {
- return webidl.converters.USVString(V)
- }
-
- if (V instanceof Request) {
- return webidl.converters.Request(V)
- }
-
- return webidl.converters.USVString(V)
-}
-
-webidl.converters.AbortSignal = webidl.interfaceConverter(
- AbortSignal
-)
-
-// https://fetch.spec.whatwg.org/#requestinit
-webidl.converters.RequestInit = webidl.dictionaryConverter([
- {
- key: 'method',
- converter: webidl.converters.ByteString
- },
- {
- key: 'headers',
- converter: webidl.converters.HeadersInit
- },
- {
- key: 'body',
- converter: webidl.nullableConverter(
- webidl.converters.BodyInit
- )
- },
- {
- key: 'referrer',
- converter: webidl.converters.USVString
- },
- {
- key: 'referrerPolicy',
- converter: webidl.converters.DOMString,
- // https://w3c.github.io/webappsec-referrer-policy/#referrer-policy
- allowedValues: [
- '', 'no-referrer', 'no-referrer-when-downgrade',
- 'same-origin', 'origin', 'strict-origin',
- 'origin-when-cross-origin', 'strict-origin-when-cross-origin',
- 'unsafe-url'
- ]
- },
- {
- key: 'mode',
- converter: webidl.converters.DOMString,
- // https://fetch.spec.whatwg.org/#concept-request-mode
- allowedValues: [
- 'same-origin', 'cors', 'no-cors', 'navigate', 'websocket'
- ]
- },
- {
- key: 'credentials',
- converter: webidl.converters.DOMString,
- // https://fetch.spec.whatwg.org/#requestcredentials
- allowedValues: [
- 'omit', 'same-origin', 'include'
- ]
- },
- {
- key: 'cache',
- converter: webidl.converters.DOMString,
- // https://fetch.spec.whatwg.org/#requestcache
- allowedValues: [
- 'default', 'no-store', 'reload', 'no-cache', 'force-cache',
- 'only-if-cached'
- ]
- },
- {
- key: 'redirect',
- converter: webidl.converters.DOMString,
- // https://fetch.spec.whatwg.org/#requestredirect
- allowedValues: [
- 'follow', 'error', 'manual'
- ]
- },
- {
- key: 'integrity',
- converter: webidl.converters.DOMString
- },
- {
- key: 'keepalive',
- converter: webidl.converters.boolean
- },
- {
- key: 'signal',
- converter: webidl.nullableConverter(
- webidl.converters.AbortSignal
- )
- },
- {
- key: 'window',
- converter: webidl.converters.any
- }
-])
-
-module.exports = { Request, makeRequest }
diff --git a/node_modules/undici/lib/fetch/response.js b/node_modules/undici/lib/fetch/response.js
deleted file mode 100644
index 4649a5d..0000000
--- a/node_modules/undici/lib/fetch/response.js
+++ /dev/null
@@ -1,580 +0,0 @@
-'use strict'
-
-const { Headers, HeadersList, fill } = require('./headers')
-const { extractBody, cloneBody, mixinBody } = require('./body')
-const util = require('../core/util')
-const { kEnumerableProperty } = util
-const {
- responseURL,
- isValidReasonPhrase,
- isCancelled,
- isAborted,
- isBlobLike,
- serializeJavascriptValueToJSONString
-} = require('./util')
-const {
- redirectStatus,
- nullBodyStatus,
- DOMException
-} = require('./constants')
-const { kState, kHeaders, kGuard, kRealm } = require('./symbols')
-const { webidl } = require('./webidl')
-const { FormData } = require('./formdata')
-const { kHeadersList } = require('../core/symbols')
-const assert = require('assert')
-const { types } = require('util')
-
-const ReadableStream = globalThis.ReadableStream || require('stream/web').ReadableStream
-
-// https://fetch.spec.whatwg.org/#response-class
-class Response {
- // Creates network error Response.
- static error () {
- // TODO
- const relevantRealm = { settingsObject: {} }
-
- // The static error() method steps are to return the result of creating a
- // Response object, given a new network error, "immutable", and this’s
- // relevant Realm.
- const responseObject = new Response()
- responseObject[kState] = makeNetworkError()
- responseObject[kRealm] = relevantRealm
- responseObject[kHeaders][kHeadersList] = responseObject[kState].headersList
- responseObject[kHeaders][kGuard] = 'immutable'
- responseObject[kHeaders][kRealm] = relevantRealm
- return responseObject
- }
-
- // https://fetch.spec.whatwg.org/#dom-response-json
- static json (data, init = {}) {
- if (arguments.length === 0) {
- throw new TypeError(
- 'Failed to execute \'json\' on \'Response\': 1 argument required, but 0 present.'
- )
- }
-
- if (init !== null) {
- init = webidl.converters.ResponseInit(init)
- }
-
- // 1. Let bytes the result of running serialize a JavaScript value to JSON bytes on data.
- const bytes = new TextEncoder('utf-8').encode(
- serializeJavascriptValueToJSONString(data)
- )
-
- // 2. Let body be the result of extracting bytes.
- const body = extractBody(bytes)
-
- // 3. Let responseObject be the result of creating a Response object, given a new response,
- // "response", and this’s relevant Realm.
- const relevantRealm = { settingsObject: {} }
- const responseObject = new Response()
- responseObject[kRealm] = relevantRealm
- responseObject[kHeaders][kGuard] = 'response'
- responseObject[kHeaders][kRealm] = relevantRealm
-
- // 4. Perform initialize a response given responseObject, init, and (body, "application/json").
- initializeResponse(responseObject, init, { body: body[0], type: 'application/json' })
-
- // 5. Return responseObject.
- return responseObject
- }
-
- // Creates a redirect Response that redirects to url with status status.
- static redirect (url, status = 302) {
- const relevantRealm = { settingsObject: {} }
-
- if (arguments.length < 1) {
- throw new TypeError(
- `Failed to execute 'redirect' on 'Response': 1 argument required, but only ${arguments.length} present.`
- )
- }
-
- url = webidl.converters.USVString(url)
- status = webidl.converters['unsigned short'](status)
-
- // 1. Let parsedURL be the result of parsing url with current settings
- // object’s API base URL.
- // 2. If parsedURL is failure, then throw a TypeError.
- // TODO: base-URL?
- let parsedURL
- try {
- parsedURL = new URL(url)
- } catch (err) {
- throw Object.assign(new TypeError('Failed to parse URL from ' + url), {
- cause: err
- })
- }
-
- // 3. If status is not a redirect status, then throw a RangeError.
- if (!redirectStatus.includes(status)) {
- throw new RangeError('Invalid status code')
- }
-
- // 4. Let responseObject be the result of creating a Response object,
- // given a new response, "immutable", and this’s relevant Realm.
- const responseObject = new Response()
- responseObject[kRealm] = relevantRealm
- responseObject[kHeaders][kGuard] = 'immutable'
- responseObject[kHeaders][kRealm] = relevantRealm
-
- // 5. Set responseObject’s response’s status to status.
- responseObject[kState].status = status
-
- // 6. Let value be parsedURL, serialized and isomorphic encoded.
- // TODO: isomorphic encoded?
- const value = parsedURL.toString()
-
- // 7. Append `Location`/value to responseObject’s response’s header list.
- responseObject[kState].headersList.append('location', value)
-
- // 8. Return responseObject.
- return responseObject
- }
-
- // https://fetch.spec.whatwg.org/#dom-response
- constructor (body = null, init = {}) {
- if (body !== null) {
- body = webidl.converters.BodyInit(body)
- }
-
- init = webidl.converters.ResponseInit(init)
-
- // TODO
- this[kRealm] = { settingsObject: {} }
-
- // 1. Set this’s response to a new response.
- this[kState] = makeResponse({})
-
- // 2. Set this’s headers to a new Headers object with this’s relevant
- // Realm, whose header list is this’s response’s header list and guard
- // is "response".
- this[kHeaders] = new Headers()
- this[kHeaders][kGuard] = 'response'
- this[kHeaders][kHeadersList] = this[kState].headersList
- this[kHeaders][kRealm] = this[kRealm]
-
- // 3. Let bodyWithType be null.
- let bodyWithType = null
-
- // 4. If body is non-null, then set bodyWithType to the result of extracting body.
- if (body != null) {
- const [extractedBody, type] = extractBody(body)
- bodyWithType = { body: extractedBody, type }
- }
-
- // 5. Perform initialize a response given this, init, and bodyWithType.
- initializeResponse(this, init, bodyWithType)
- }
-
- get [Symbol.toStringTag] () {
- return this.constructor.name
- }
-
- // Returns response’s type, e.g., "cors".
- get type () {
- if (!(this instanceof Response)) {
- throw new TypeError('Illegal invocation')
- }
-
- // The type getter steps are to return this’s response’s type.
- return this[kState].type
- }
-
- // Returns response’s URL, if it has one; otherwise the empty string.
- get url () {
- if (!(this instanceof Response)) {
- throw new TypeError('Illegal invocation')
- }
-
- // The url getter steps are to return the empty string if this’s
- // response’s URL is null; otherwise this’s response’s URL,
- // serialized with exclude fragment set to true.
- let url = responseURL(this[kState])
-
- if (url == null) {
- return ''
- }
-
- if (url.hash) {
- url = new URL(url)
- url.hash = ''
- }
-
- return url.toString()
- }
-
- // Returns whether response was obtained through a redirect.
- get redirected () {
- if (!(this instanceof Response)) {
- throw new TypeError('Illegal invocation')
- }
-
- // The redirected getter steps are to return true if this’s response’s URL
- // list has more than one item; otherwise false.
- return this[kState].urlList.length > 1
- }
-
- // Returns response’s status.
- get status () {
- if (!(this instanceof Response)) {
- throw new TypeError('Illegal invocation')
- }
-
- // The status getter steps are to return this’s response’s status.
- return this[kState].status
- }
-
- // Returns whether response’s status is an ok status.
- get ok () {
- if (!(this instanceof Response)) {
- throw new TypeError('Illegal invocation')
- }
-
- // The ok getter steps are to return true if this’s response’s status is an
- // ok status; otherwise false.
- return this[kState].status >= 200 && this[kState].status <= 299
- }
-
- // Returns response’s status message.
- get statusText () {
- if (!(this instanceof Response)) {
- throw new TypeError('Illegal invocation')
- }
-
- // The statusText getter steps are to return this’s response’s status
- // message.
- return this[kState].statusText
- }
-
- // Returns response’s headers as Headers.
- get headers () {
- if (!(this instanceof Response)) {
- throw new TypeError('Illegal invocation')
- }
-
- // The headers getter steps are to return this’s headers.
- return this[kHeaders]
- }
-
- // Returns a clone of response.
- clone () {
- if (!(this instanceof Response)) {
- throw new TypeError('Illegal invocation')
- }
-
- // 1. If this is unusable, then throw a TypeError.
- if (this.bodyUsed || (this.body && this.body.locked)) {
- webidl.errors.exception({
- header: 'Response.clone',
- message: 'Body has already been consumed.'
- })
- }
-
- // 2. Let clonedResponse be the result of cloning this’s response.
- const clonedResponse = cloneResponse(this[kState])
-
- // 3. Return the result of creating a Response object, given
- // clonedResponse, this’s headers’s guard, and this’s relevant Realm.
- const clonedResponseObject = new Response()
- clonedResponseObject[kState] = clonedResponse
- clonedResponseObject[kRealm] = this[kRealm]
- clonedResponseObject[kHeaders][kHeadersList] = clonedResponse.headersList
- clonedResponseObject[kHeaders][kGuard] = this[kHeaders][kGuard]
- clonedResponseObject[kHeaders][kRealm] = this[kHeaders][kRealm]
-
- return clonedResponseObject
- }
-}
-
-mixinBody(Response)
-
-Object.defineProperties(Response.prototype, {
- type: kEnumerableProperty,
- url: kEnumerableProperty,
- status: kEnumerableProperty,
- ok: kEnumerableProperty,
- redirected: kEnumerableProperty,
- statusText: kEnumerableProperty,
- headers: kEnumerableProperty,
- clone: kEnumerableProperty
-})
-
-// https://fetch.spec.whatwg.org/#concept-response-clone
-function cloneResponse (response) {
- // To clone a response response, run these steps:
-
- // 1. If response is a filtered response, then return a new identical
- // filtered response whose internal response is a clone of response’s
- // internal response.
- if (response.internalResponse) {
- return filterResponse(
- cloneResponse(response.internalResponse),
- response.type
- )
- }
-
- // 2. Let newResponse be a copy of response, except for its body.
- const newResponse = makeResponse({ ...response, body: null })
-
- // 3. If response’s body is non-null, then set newResponse’s body to the
- // result of cloning response’s body.
- if (response.body != null) {
- newResponse.body = cloneBody(response.body)
- }
-
- // 4. Return newResponse.
- return newResponse
-}
-
-function makeResponse (init) {
- return {
- aborted: false,
- rangeRequested: false,
- timingAllowPassed: false,
- requestIncludesCredentials: false,
- type: 'default',
- status: 200,
- timingInfo: null,
- cacheState: '',
- statusText: '',
- ...init,
- headersList: init.headersList
- ? new HeadersList(init.headersList)
- : new HeadersList(),
- urlList: init.urlList ? [...init.urlList] : []
- }
-}
-
-function makeNetworkError (reason) {
- return makeResponse({
- type: 'error',
- status: 0,
- error:
- reason instanceof Error
- ? reason
- : new Error(reason ? String(reason) : reason, {
- cause: reason instanceof Error ? reason : undefined
- }),
- aborted: reason && reason.name === 'AbortError'
- })
-}
-
-function makeFilteredResponse (response, state) {
- state = {
- internalResponse: response,
- ...state
- }
-
- return new Proxy(response, {
- get (target, p) {
- return p in state ? state[p] : target[p]
- },
- set (target, p, value) {
- assert(!(p in state))
- target[p] = value
- return true
- }
- })
-}
-
-// https://fetch.spec.whatwg.org/#concept-filtered-response
-function filterResponse (response, type) {
- // Set response to the following filtered response with response as its
- // internal response, depending on request’s response tainting:
- if (type === 'basic') {
- // A basic filtered response is a filtered response whose type is "basic"
- // and header list excludes any headers in internal response’s header list
- // whose name is a forbidden response-header name.
-
- // Note: undici does not implement forbidden response-header names
- return makeFilteredResponse(response, {
- type: 'basic',
- headersList: response.headersList
- })
- } else if (type === 'cors') {
- // A CORS filtered response is a filtered response whose type is "cors"
- // and header list excludes any headers in internal response’s header
- // list whose name is not a CORS-safelisted response-header name, given
- // internal response’s CORS-exposed header-name list.
-
- // Note: undici does not implement CORS-safelisted response-header names
- return makeFilteredResponse(response, {
- type: 'cors',
- headersList: response.headersList
- })
- } else if (type === 'opaque') {
- // An opaque filtered response is a filtered response whose type is
- // "opaque", URL list is the empty list, status is 0, status message
- // is the empty byte sequence, header list is empty, and body is null.
-
- return makeFilteredResponse(response, {
- type: 'opaque',
- urlList: Object.freeze([]),
- status: 0,
- statusText: '',
- body: null
- })
- } else if (type === 'opaqueredirect') {
- // An opaque-redirect filtered response is a filtered response whose type
- // is "opaqueredirect", status is 0, status message is the empty byte
- // sequence, header list is empty, and body is null.
-
- return makeFilteredResponse(response, {
- type: 'opaqueredirect',
- status: 0,
- statusText: '',
- headersList: [],
- body: null
- })
- } else {
- assert(false)
- }
-}
-
-// https://fetch.spec.whatwg.org/#appropriate-network-error
-function makeAppropriateNetworkError (fetchParams) {
- // 1. Assert: fetchParams is canceled.
- assert(isCancelled(fetchParams))
-
- // 2. Return an aborted network error if fetchParams is aborted;
- // otherwise return a network error.
- return isAborted(fetchParams)
- ? makeNetworkError(new DOMException('The operation was aborted.', 'AbortError'))
- : makeNetworkError(fetchParams.controller.terminated.reason)
-}
-
-// https://whatpr.org/fetch/1392.html#initialize-a-response
-function initializeResponse (response, init, body) {
- // 1. If init["status"] is not in the range 200 to 599, inclusive, then
- // throw a RangeError.
- if (init.status !== null && (init.status < 200 || init.status > 599)) {
- throw new RangeError('init["status"] must be in the range of 200 to 599, inclusive.')
- }
-
- // 2. If init["statusText"] does not match the reason-phrase token production,
- // then throw a TypeError.
- if ('statusText' in init && init.statusText != null) {
- // See, https://datatracker.ietf.org/doc/html/rfc7230#section-3.1.2:
- // reason-phrase = *( HTAB / SP / VCHAR / obs-text )
- if (!isValidReasonPhrase(String(init.statusText))) {
- throw new TypeError('Invalid statusText')
- }
- }
-
- // 3. Set response’s response’s status to init["status"].
- if ('status' in init && init.status != null) {
- response[kState].status = init.status
- }
-
- // 4. Set response’s response’s status message to init["statusText"].
- if ('statusText' in init && init.statusText != null) {
- response[kState].statusText = init.statusText
- }
-
- // 5. If init["headers"] exists, then fill response’s headers with init["headers"].
- if ('headers' in init && init.headers != null) {
- fill(response[kState].headersList, init.headers)
- }
-
- // 6. If body was given, then:
- if (body) {
- // 1. If response's status is a null body status, then throw a TypeError.
- if (nullBodyStatus.includes(response.status)) {
- webidl.errors.exception({
- header: 'Response constructor',
- message: 'Invalid response status code.'
- })
- }
-
- // 2. Set response's body to body's body.
- response[kState].body = body.body
-
- // 3. If body's type is non-null and response's header list does not contain
- // `Content-Type`, then append (`Content-Type`, body's type) to response's header list.
- if (body.type != null && !response[kState].headersList.has('Content-Type')) {
- response[kState].headersList.append('content-type', body.type)
- }
- }
-}
-
-webidl.converters.ReadableStream = webidl.interfaceConverter(
- ReadableStream
-)
-
-webidl.converters.FormData = webidl.interfaceConverter(
- FormData
-)
-
-webidl.converters.URLSearchParams = webidl.interfaceConverter(
- URLSearchParams
-)
-
-// https://fetch.spec.whatwg.org/#typedefdef-xmlhttprequestbodyinit
-webidl.converters.XMLHttpRequestBodyInit = function (V) {
- if (typeof V === 'string') {
- return webidl.converters.USVString(V)
- }
-
- if (isBlobLike(V)) {
- return webidl.converters.Blob(V)
- }
-
- if (
- types.isAnyArrayBuffer(V) ||
- types.isTypedArray(V) ||
- types.isDataView(V)
- ) {
- return webidl.converters.BufferSource(V)
- }
-
- if (V instanceof FormData) {
- return webidl.converters.FormData(V)
- }
-
- if (V instanceof URLSearchParams) {
- return webidl.converters.URLSearchParams(V)
- }
-
- return webidl.converters.DOMString(V)
-}
-
-// https://fetch.spec.whatwg.org/#bodyinit
-webidl.converters.BodyInit = function (V) {
- if (V instanceof ReadableStream) {
- return webidl.converters.ReadableStream(V)
- }
-
- // Note: the spec doesn't include async iterables,
- // this is an undici extension.
- if (V?.[Symbol.asyncIterator]) {
- return V
- }
-
- return webidl.converters.XMLHttpRequestBodyInit(V)
-}
-
-webidl.converters.ResponseInit = webidl.dictionaryConverter([
- {
- key: 'status',
- converter: webidl.converters['unsigned short'],
- defaultValue: 200
- },
- {
- key: 'statusText',
- converter: webidl.converters.ByteString,
- defaultValue: ''
- },
- {
- key: 'headers',
- converter: webidl.converters.HeadersInit
- }
-])
-
-module.exports = {
- makeNetworkError,
- makeResponse,
- makeAppropriateNetworkError,
- filterResponse,
- Response
-}
diff --git a/node_modules/undici/lib/fetch/symbols.js b/node_modules/undici/lib/fetch/symbols.js
deleted file mode 100644
index 0b947d5..0000000
--- a/node_modules/undici/lib/fetch/symbols.js
+++ /dev/null
@@ -1,10 +0,0 @@
-'use strict'
-
-module.exports = {
- kUrl: Symbol('url'),
- kHeaders: Symbol('headers'),
- kSignal: Symbol('signal'),
- kState: Symbol('state'),
- kGuard: Symbol('guard'),
- kRealm: Symbol('realm')
-}
diff --git a/node_modules/undici/lib/fetch/util.js b/node_modules/undici/lib/fetch/util.js
deleted file mode 100644
index e309e32..0000000
--- a/node_modules/undici/lib/fetch/util.js
+++ /dev/null
@@ -1,467 +0,0 @@
-'use strict'
-
-const { redirectStatus } = require('./constants')
-const { performance } = require('perf_hooks')
-const { isBlobLike, toUSVString, ReadableStreamFrom } = require('../core/util')
-const assert = require('assert')
-
-let File
-
-// https://fetch.spec.whatwg.org/#block-bad-port
-const badPorts = [
- '1', '7', '9', '11', '13', '15', '17', '19', '20', '21', '22', '23', '25', '37', '42', '43', '53', '69', '77', '79',
- '87', '95', '101', '102', '103', '104', '109', '110', '111', '113', '115', '117', '119', '123', '135', '137',
- '139', '143', '161', '179', '389', '427', '465', '512', '513', '514', '515', '526', '530', '531', '532',
- '540', '548', '554', '556', '563', '587', '601', '636', '989', '990', '993', '995', '1719', '1720', '1723',
- '2049', '3659', '4045', '5060', '5061', '6000', '6566', '6665', '6666', '6667', '6668', '6669', '6697',
- '10080'
-]
-
-function responseURL (response) {
- // https://fetch.spec.whatwg.org/#responses
- // A response has an associated URL. It is a pointer to the last URL
- // in response’s URL list and null if response’s URL list is empty.
- const urlList = response.urlList
- const length = urlList.length
- return length === 0 ? null : urlList[length - 1].toString()
-}
-
-// https://fetch.spec.whatwg.org/#concept-response-location-url
-function responseLocationURL (response, requestFragment) {
- // 1. If response’s status is not a redirect status, then return null.
- if (!redirectStatus.includes(response.status)) {
- return null
- }
-
- // 2. Let location be the result of extracting header list values given
- // `Location` and response’s header list.
- let location = response.headersList.get('location')
-
- // 3. If location is a value, then set location to the result of parsing
- // location with response’s URL.
- location = location ? new URL(location, responseURL(response)) : null
-
- // 4. If location is a URL whose fragment is null, then set location’s
- // fragment to requestFragment.
- if (location && !location.hash) {
- location.hash = requestFragment
- }
-
- // 5. Return location.
- return location
-}
-
-/** @returns {URL} */
-function requestCurrentURL (request) {
- return request.urlList[request.urlList.length - 1]
-}
-
-function requestBadPort (request) {
- // 1. Let url be request’s current URL.
- const url = requestCurrentURL(request)
-
- // 2. If url’s scheme is an HTTP(S) scheme and url’s port is a bad port,
- // then return blocked.
- if (/^https?:/.test(url.protocol) && badPorts.includes(url.port)) {
- return 'blocked'
- }
-
- // 3. Return allowed.
- return 'allowed'
-}
-
-function isFileLike (object) {
- if (!File) {
- File = require('./file').File
- }
- return object instanceof File || (
- object &&
- (typeof object.stream === 'function' ||
- typeof object.arrayBuffer === 'function') &&
- /^(File)$/.test(object[Symbol.toStringTag])
- )
-}
-
-// Check whether |statusText| is a ByteString and
-// matches the Reason-Phrase token production.
-// RFC 2616: https://tools.ietf.org/html/rfc2616
-// RFC 7230: https://tools.ietf.org/html/rfc7230
-// "reason-phrase = *( HTAB / SP / VCHAR / obs-text )"
-// https://github.com/chromium/chromium/blob/94.0.4604.1/third_party/blink/renderer/core/fetch/response.cc#L116
-function isValidReasonPhrase (statusText) {
- for (let i = 0; i < statusText.length; ++i) {
- const c = statusText.charCodeAt(i)
- if (
- !(
- (
- c === 0x09 || // HTAB
- (c >= 0x20 && c <= 0x7e) || // SP / VCHAR
- (c >= 0x80 && c <= 0xff)
- ) // obs-text
- )
- ) {
- return false
- }
- }
- return true
-}
-
-function isTokenChar (c) {
- return !(
- c >= 0x7f ||
- c <= 0x20 ||
- c === '(' ||
- c === ')' ||
- c === '<' ||
- c === '>' ||
- c === '@' ||
- c === ',' ||
- c === ';' ||
- c === ':' ||
- c === '\\' ||
- c === '"' ||
- c === '/' ||
- c === '[' ||
- c === ']' ||
- c === '?' ||
- c === '=' ||
- c === '{' ||
- c === '}'
- )
-}
-
-// See RFC 7230, Section 3.2.6.
-// https://github.com/chromium/chromium/blob/d7da0240cae77824d1eda25745c4022757499131/third_party/blink/renderer/platform/network/http_parsers.cc#L321
-function isValidHTTPToken (characters) {
- if (!characters || typeof characters !== 'string') {
- return false
- }
- for (let i = 0; i < characters.length; ++i) {
- const c = characters.charCodeAt(i)
- if (c > 0x7f || !isTokenChar(c)) {
- return false
- }
- }
- return true
-}
-
-// https://fetch.spec.whatwg.org/#header-name
-// https://github.com/chromium/chromium/blob/b3d37e6f94f87d59e44662d6078f6a12de845d17/net/http/http_util.cc#L342
-function isValidHeaderName (potentialValue) {
- if (potentialValue.length === 0) {
- return false
- }
-
- for (const char of potentialValue) {
- if (!isValidHTTPToken(char)) {
- return false
- }
- }
-
- return true
-}
-
-/**
- * @see https://fetch.spec.whatwg.org/#header-value
- * @param {string} potentialValue
- */
-function isValidHeaderValue (potentialValue) {
- // - Has no leading or trailing HTTP tab or space bytes.
- // - Contains no 0x00 (NUL) or HTTP newline bytes.
- if (
- potentialValue.startsWith('\t') ||
- potentialValue.startsWith(' ') ||
- potentialValue.endsWith('\t') ||
- potentialValue.endsWith(' ')
- ) {
- return false
- }
-
- if (
- potentialValue.includes('\0') ||
- potentialValue.includes('\r') ||
- potentialValue.includes('\n')
- ) {
- return false
- }
-
- return true
-}
-
-// https://w3c.github.io/webappsec-referrer-policy/#set-requests-referrer-policy-on-redirect
-function setRequestReferrerPolicyOnRedirect (request, actualResponse) {
- // Given a request request and a response actualResponse, this algorithm
- // updates request’s referrer policy according to the Referrer-Policy
- // header (if any) in actualResponse.
-
- // 1. Let policy be the result of executing § 8.1 Parse a referrer policy
- // from a Referrer-Policy header on actualResponse.
- // TODO: https://w3c.github.io/webappsec-referrer-policy/#parse-referrer-policy-from-header
- const policy = ''
-
- // 2. If policy is not the empty string, then set request’s referrer policy to policy.
- if (policy !== '') {
- request.referrerPolicy = policy
- }
-}
-
-// https://fetch.spec.whatwg.org/#cross-origin-resource-policy-check
-function crossOriginResourcePolicyCheck () {
- // TODO
- return 'allowed'
-}
-
-// https://fetch.spec.whatwg.org/#concept-cors-check
-function corsCheck () {
- // TODO
- return 'success'
-}
-
-// https://fetch.spec.whatwg.org/#concept-tao-check
-function TAOCheck () {
- // TODO
- return 'success'
-}
-
-function appendFetchMetadata (httpRequest) {
- // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-dest-header
- // TODO
-
- // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-mode-header
-
- // 1. Assert: r’s url is a potentially trustworthy URL.
- // TODO
-
- // 2. Let header be a Structured Header whose value is a token.
- let header = null
-
- // 3. Set header’s value to r’s mode.
- header = httpRequest.mode
-
- // 4. Set a structured field value `Sec-Fetch-Mode`/header in r’s header list.
- httpRequest.headersList.set('sec-fetch-mode', header)
-
- // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-site-header
- // TODO
-
- // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-user-header
- // TODO
-}
-
-// https://fetch.spec.whatwg.org/#append-a-request-origin-header
-function appendRequestOriginHeader (request) {
- // 1. Let serializedOrigin be the result of byte-serializing a request origin with request.
- let serializedOrigin = request.origin
-
- // 2. If request’s response tainting is "cors" or request’s mode is "websocket", then append (`Origin`, serializedOrigin) to request’s header list.
- if (request.responseTainting === 'cors' || request.mode === 'websocket') {
- if (serializedOrigin) {
- request.headersList.append('Origin', serializedOrigin)
- }
-
- // 3. Otherwise, if request’s method is neither `GET` nor `HEAD`, then:
- } else if (request.method !== 'GET' && request.method !== 'HEAD') {
- // 1. Switch on request’s referrer policy:
- switch (request.referrerPolicy) {
- case 'no-referrer':
- // Set serializedOrigin to `null`.
- serializedOrigin = null
- break
- case 'no-referrer-when-downgrade':
- case 'strict-origin':
- case 'strict-origin-when-cross-origin':
- // If request’s origin is a tuple origin, its scheme is "https", and request’s current URL’s scheme is not "https", then set serializedOrigin to `null`.
- if (/^https:/.test(request.origin) && !/^https:/.test(requestCurrentURL(request))) {
- serializedOrigin = null
- }
- break
- case 'same-origin':
- // If request’s origin is not same origin with request’s current URL’s origin, then set serializedOrigin to `null`.
- if (!sameOrigin(request, requestCurrentURL(request))) {
- serializedOrigin = null
- }
- break
- default:
- // Do nothing.
- }
-
- if (serializedOrigin) {
- // 2. Append (`Origin`, serializedOrigin) to request’s header list.
- request.headersList.append('Origin', serializedOrigin)
- }
- }
-}
-
-function coarsenedSharedCurrentTime (crossOriginIsolatedCapability) {
- // TODO
- return performance.now()
-}
-
-// https://fetch.spec.whatwg.org/#create-an-opaque-timing-info
-function createOpaqueTimingInfo (timingInfo) {
- return {
- startTime: timingInfo.startTime ?? 0,
- redirectStartTime: 0,
- redirectEndTime: 0,
- postRedirectStartTime: timingInfo.startTime ?? 0,
- finalServiceWorkerStartTime: 0,
- finalNetworkResponseStartTime: 0,
- finalNetworkRequestStartTime: 0,
- endTime: 0,
- encodedBodySize: 0,
- decodedBodySize: 0,
- finalConnectionTimingInfo: null
- }
-}
-
-// https://html.spec.whatwg.org/multipage/origin.html#policy-container
-function makePolicyContainer () {
- // TODO
- return {}
-}
-
-// https://html.spec.whatwg.org/multipage/origin.html#clone-a-policy-container
-function clonePolicyContainer () {
- // TODO
- return {}
-}
-
-// https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer
-function determineRequestsReferrer (request) {
- // TODO
- return 'no-referrer'
-}
-
-function matchRequestIntegrity (request, bytes) {
- return false
-}
-
-// https://w3c.github.io/webappsec-upgrade-insecure-requests/#upgrade-request
-function tryUpgradeRequestToAPotentiallyTrustworthyURL (request) {
- // TODO
-}
-
-/**
- * @link {https://html.spec.whatwg.org/multipage/origin.html#same-origin}
- * @param {URL} A
- * @param {URL} B
- */
-function sameOrigin (A, B) {
- // 1. If A and B are the same opaque origin, then return true.
- // "opaque origin" is an internal value we cannot access, ignore.
-
- // 2. If A and B are both tuple origins and their schemes,
- // hosts, and port are identical, then return true.
- if (A.protocol === B.protocol && A.hostname === B.hostname && A.port === B.port) {
- return true
- }
-
- // 3. Return false.
- return false
-}
-
-function createDeferredPromise () {
- let res
- let rej
- const promise = new Promise((resolve, reject) => {
- res = resolve
- rej = reject
- })
-
- return { promise, resolve: res, reject: rej }
-}
-
-function isAborted (fetchParams) {
- return fetchParams.controller.state === 'aborted'
-}
-
-function isCancelled (fetchParams) {
- return fetchParams.controller.state === 'aborted' ||
- fetchParams.controller.state === 'terminated'
-}
-
-// https://fetch.spec.whatwg.org/#concept-method-normalize
-function normalizeMethod (method) {
- return /^(DELETE|GET|HEAD|OPTIONS|POST|PUT)$/i.test(method)
- ? method.toUpperCase()
- : method
-}
-
-// https://infra.spec.whatwg.org/#serialize-a-javascript-value-to-a-json-string
-function serializeJavascriptValueToJSONString (value) {
- // 1. Let result be ? Call(%JSON.stringify%, undefined, « value »).
- const result = JSON.stringify(value)
-
- // 2. If result is undefined, then throw a TypeError.
- if (result === undefined) {
- throw new TypeError('Value is not JSON serializable')
- }
-
- // 3. Assert: result is a string.
- assert(typeof result === 'string')
-
- // 4. Return result.
- return result
-}
-
-// https://tc39.es/ecma262/#sec-%25iteratorprototype%25-object
-const esIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))
-
-// https://webidl.spec.whatwg.org/#dfn-iterator-prototype-object
-function makeIterator (iterator, name) {
- const i = {
- next () {
- if (Object.getPrototypeOf(this) !== i) {
- throw new TypeError(
- `'next' called on an object that does not implement interface ${name} Iterator.`
- )
- }
-
- return iterator.next()
- },
- // The class string of an iterator prototype object for a given interface is the
- // result of concatenating the identifier of the interface and the string " Iterator".
- [Symbol.toStringTag]: `${name} Iterator`
- }
-
- // The [[Prototype]] internal slot of an iterator prototype object must be %IteratorPrototype%.
- Object.setPrototypeOf(i, esIteratorPrototype)
- // esIteratorPrototype needs to be the prototype of i
- // which is the prototype of an empty object. Yes, it's confusing.
- return Object.setPrototypeOf({}, i)
-}
-
-module.exports = {
- isAborted,
- isCancelled,
- createDeferredPromise,
- ReadableStreamFrom,
- toUSVString,
- tryUpgradeRequestToAPotentiallyTrustworthyURL,
- coarsenedSharedCurrentTime,
- matchRequestIntegrity,
- determineRequestsReferrer,
- makePolicyContainer,
- clonePolicyContainer,
- appendFetchMetadata,
- appendRequestOriginHeader,
- TAOCheck,
- corsCheck,
- crossOriginResourcePolicyCheck,
- createOpaqueTimingInfo,
- setRequestReferrerPolicyOnRedirect,
- isValidHTTPToken,
- requestBadPort,
- requestCurrentURL,
- responseURL,
- responseLocationURL,
- isBlobLike,
- isFileLike,
- isValidReasonPhrase,
- sameOrigin,
- normalizeMethod,
- serializeJavascriptValueToJSONString,
- makeIterator,
- isValidHeaderName,
- isValidHeaderValue
-}
diff --git a/node_modules/undici/lib/fetch/webidl.js b/node_modules/undici/lib/fetch/webidl.js
deleted file mode 100644
index 252dab2..0000000
--- a/node_modules/undici/lib/fetch/webidl.js
+++ /dev/null
@@ -1,594 +0,0 @@
-'use strict'
-
-const { toUSVString, types } = require('util')
-
-const webidl = {}
-webidl.converters = {}
-webidl.util = {}
-webidl.errors = {}
-
-/**
- *
- * @param {{
- * header: string
- * message: string
- * }} message
- */
-webidl.errors.exception = function (message) {
- throw new TypeError(`${message.header}: ${message.message}`)
-}
-
-/**
- * Throw an error when conversion from one type to another has failed
- * @param {{
- * prefix: string
- * argument: string
- * types: string[]
- * }} context
- */
-webidl.errors.conversionFailed = function (context) {
- const plural = context.types.length === 1 ? '' : ' one of'
- const message =
- `${context.argument} could not be converted to` +
- `${plural}: ${context.types.join(', ')}.`
-
- return webidl.errors.exception({
- header: context.prefix,
- message
- })
-}
-
-/**
- * Throw an error when an invalid argument is provided
- * @param {{
- * prefix: string
- * value: string
- * type: string
- * }} context
- */
-webidl.errors.invalidArgument = function (context) {
- return webidl.errors.exception({
- header: context.prefix,
- message: `"${context.value}" is an invalid ${context.type}.`
- })
-}
-
-// https://tc39.es/ecma262/#sec-ecmascript-data-types-and-values
-webidl.util.Type = function (V) {
- switch (typeof V) {
- case 'undefined': return 'Undefined'
- case 'boolean': return 'Boolean'
- case 'string': return 'String'
- case 'symbol': return 'Symbol'
- case 'number': return 'Number'
- case 'bigint': return 'BigInt'
- case 'function':
- case 'object': {
- if (V === null) {
- return 'Null'
- }
-
- return 'Object'
- }
- }
-}
-
-// https://webidl.spec.whatwg.org/#abstract-opdef-converttoint
-webidl.util.ConvertToInt = function (V, bitLength, signedness, opts = {}) {
- let upperBound
- let lowerBound
-
- // 1. If bitLength is 64, then:
- if (bitLength === 64) {
- // 1. Let upperBound be 2^53 − 1.
- upperBound = Math.pow(2, 53) - 1
-
- // 2. If signedness is "unsigned", then let lowerBound be 0.
- if (signedness === 'unsigned') {
- lowerBound = 0
- } else {
- // 3. Otherwise let lowerBound be −2^53 + 1.
- lowerBound = Math.pow(-2, 53) + 1
- }
- } else if (signedness === 'unsigned') {
- // 2. Otherwise, if signedness is "unsigned", then:
-
- // 1. Let lowerBound be 0.
- lowerBound = 0
-
- // 2. Let upperBound be 2^bitLength − 1.
- upperBound = Math.pow(2, bitLength) - 1
- } else {
- // 3. Otherwise:
-
- // 1. Let lowerBound be -2^bitLength − 1.
- lowerBound = Math.pow(-2, bitLength) - 1
-
- // 2. Let upperBound be 2^bitLength − 1 − 1.
- upperBound = Math.pow(2, bitLength - 1) - 1
- }
-
- // 4. Let x be ? ToNumber(V).
- let x = Number(V)
-
- // 5. If x is −0, then set x to +0.
- if (Object.is(-0, x)) {
- x = 0
- }
-
- // 6. If the conversion is to an IDL type associated
- // with the [EnforceRange] extended attribute, then:
- if (opts.enforceRange === true) {
- // 1. If x is NaN, +∞, or −∞, then throw a TypeError.
- if (
- Number.isNaN(x) ||
- x === Number.POSITIVE_INFINITY ||
- x === Number.NEGATIVE_INFINITY
- ) {
- webidl.errors.exception({
- header: 'Integer conversion',
- message: `Could not convert ${V} to an integer.`
- })
- }
-
- // 2. Set x to IntegerPart(x).
- x = webidl.util.IntegerPart(x)
-
- // 3. If x < lowerBound or x > upperBound, then
- // throw a TypeError.
- if (x < lowerBound || x > upperBound) {
- webidl.errors.exception({
- header: 'Integer conversion',
- message: `Value must be between ${lowerBound}-${upperBound}, got ${x}.`
- })
- }
-
- // 4. Return x.
- return x
- }
-
- // 7. If x is not NaN and the conversion is to an IDL
- // type associated with the [Clamp] extended
- // attribute, then:
- if (!Number.isNaN(x) && opts.clamp === true) {
- // 1. Set x to min(max(x, lowerBound), upperBound).
- x = Math.min(Math.max(x, lowerBound), upperBound)
-
- // 2. Round x to the nearest integer, choosing the
- // even integer if it lies halfway between two,
- // and choosing +0 rather than −0.
- if (Math.floor(x) % 2 === 0) {
- x = Math.floor(x)
- } else {
- x = Math.ceil(x)
- }
-
- // 3. Return x.
- return x
- }
-
- // 8. If x is NaN, +0, +∞, or −∞, then return +0.
- if (
- Number.isNaN(x) ||
- Object.is(0, x) ||
- x === Number.POSITIVE_INFINITY ||
- x === Number.NEGATIVE_INFINITY
- ) {
- return 0
- }
-
- // 9. Set x to IntegerPart(x).
- x = webidl.util.IntegerPart(x)
-
- // 10. Set x to x modulo 2^bitLength.
- x = x % Math.pow(2, bitLength)
-
- // 11. If signedness is "signed" and x ≥ 2^bitLength − 1,
- // then return x − 2^bitLength.
- if (signedness === 'signed' && x >= Math.pow(2, bitLength) - 1) {
- return x - Math.pow(2, bitLength)
- }
-
- // 12. Otherwise, return x.
- return x
-}
-
-// https://webidl.spec.whatwg.org/#abstract-opdef-integerpart
-webidl.util.IntegerPart = function (n) {
- // 1. Let r be floor(abs(n)).
- const r = Math.floor(Math.abs(n))
-
- // 2. If n < 0, then return -1 × r.
- if (n < 0) {
- return -1 * r
- }
-
- // 3. Otherwise, return r.
- return r
-}
-
-// https://webidl.spec.whatwg.org/#es-sequence
-webidl.sequenceConverter = function (converter) {
- return (V) => {
- // 1. If Type(V) is not Object, throw a TypeError.
- if (webidl.util.Type(V) !== 'Object') {
- webidl.errors.exception({
- header: 'Sequence',
- message: `Value of type ${webidl.util.Type(V)} is not an Object.`
- })
- }
-
- // 2. Let method be ? GetMethod(V, @@iterator).
- /** @type {Generator} */
- const method = V?.[Symbol.iterator]?.()
- const seq = []
-
- // 3. If method is undefined, throw a TypeError.
- if (
- method === undefined ||
- typeof method.next !== 'function'
- ) {
- webidl.errors.exception({
- header: 'Sequence',
- message: 'Object is not an iterator.'
- })
- }
-
- // https://webidl.spec.whatwg.org/#create-sequence-from-iterable
- while (true) {
- const { done, value } = method.next()
-
- if (done) {
- break
- }
-
- seq.push(converter(value))
- }
-
- return seq
- }
-}
-
-webidl.recordConverter = function (keyConverter, valueConverter) {
- return (V) => {
- const record = {}
- const type = webidl.util.Type(V)
-
- if (type === 'Undefined' || type === 'Null') {
- return record
- }
-
- if (type !== 'Object') {
- webidl.errors.exception({
- header: 'Record',
- message: `Expected ${V} to be an Object type.`
- })
- }
-
- for (let [key, value] of Object.entries(V)) {
- key = keyConverter(key)
- value = valueConverter(value)
-
- record[key] = value
- }
-
- return record
- }
-}
-
-webidl.interfaceConverter = function (i) {
- return (V, opts = {}) => {
- if (opts.strict !== false && !(V instanceof i)) {
- webidl.errors.exception({
- header: i.name,
- message: `Expected ${V} to be an instance of ${i.name}.`
- })
- }
-
- return V
- }
-}
-
-/**
- * @param {{
- * key: string,
- * defaultValue?: any,
- * required?: boolean,
- * converter: (...args: unknown[]) => unknown,
- * allowedValues?: any[]
- * }[]} converters
- * @returns
- */
-webidl.dictionaryConverter = function (converters) {
- return (dictionary) => {
- const type = webidl.util.Type(dictionary)
- const dict = {}
-
- if (type !== 'Null' && type !== 'Undefined' && type !== 'Object') {
- webidl.errors.exception({
- header: 'Dictionary',
- message: `Expected ${dictionary} to be one of: Null, Undefined, Object.`
- })
- }
-
- for (const options of converters) {
- const { key, defaultValue, required, converter } = options
-
- if (required === true) {
- if (!Object.hasOwn(dictionary, key)) {
- webidl.errors.exception({
- header: 'Dictionary',
- message: `Missing required key "${key}".`
- })
- }
- }
-
- let value = dictionary[key]
- const hasDefault = Object.hasOwn(options, 'defaultValue')
-
- // Only use defaultValue if value is undefined and
- // a defaultValue options was provided.
- if (hasDefault && value !== null) {
- value = value ?? defaultValue
- }
-
- // A key can be optional and have no default value.
- // When this happens, do not perform a conversion,
- // and do not assign the key a value.
- if (required || hasDefault || value !== undefined) {
- value = converter(value)
-
- if (
- options.allowedValues &&
- !options.allowedValues.includes(value)
- ) {
- webidl.errors.exception({
- header: 'Dictionary',
- message: `${value} is not an accepted type. Expected one of ${options.allowedValues.join(', ')}.`
- })
- }
-
- dict[key] = value
- }
- }
-
- return dict
- }
-}
-
-webidl.nullableConverter = function (converter) {
- return (V) => {
- if (V === null) {
- return V
- }
-
- return converter(V)
- }
-}
-
-// https://webidl.spec.whatwg.org/#es-DOMString
-webidl.converters.DOMString = function (V, opts = {}) {
- // 1. If V is null and the conversion is to an IDL type
- // associated with the [LegacyNullToEmptyString]
- // extended attribute, then return the DOMString value
- // that represents the empty string.
- if (V === null && opts.legacyNullToEmptyString) {
- return ''
- }
-
- // 2. Let x be ? ToString(V).
- if (typeof V === 'symbol') {
- throw new TypeError('Could not convert argument of type symbol to string.')
- }
-
- // 3. Return the IDL DOMString value that represents the
- // same sequence of code units as the one the
- // ECMAScript String value x represents.
- return String(V)
-}
-
-// eslint-disable-next-line no-control-regex
-const isNotLatin1 = /[^\u0000-\u00ff]/
-
-// https://webidl.spec.whatwg.org/#es-ByteString
-webidl.converters.ByteString = function (V) {
- // 1. Let x be ? ToString(V).
- // Note: DOMString converter perform ? ToString(V)
- const x = webidl.converters.DOMString(V)
-
- // 2. If the value of any element of x is greater than
- // 255, then throw a TypeError.
- if (isNotLatin1.test(x)) {
- throw new TypeError('Argument is not a ByteString')
- }
-
- // 3. Return an IDL ByteString value whose length is the
- // length of x, and where the value of each element is
- // the value of the corresponding element of x.
- return x
-}
-
-// https://webidl.spec.whatwg.org/#es-USVString
-// TODO: ensure that util.toUSVString follows webidl spec
-webidl.converters.USVString = toUSVString
-
-// https://webidl.spec.whatwg.org/#es-boolean
-webidl.converters.boolean = function (V) {
- // 1. Let x be the result of computing ToBoolean(V).
- const x = Boolean(V)
-
- // 2. Return the IDL boolean value that is the one that represents
- // the same truth value as the ECMAScript Boolean value x.
- return x
-}
-
-// https://webidl.spec.whatwg.org/#es-any
-webidl.converters.any = function (V) {
- return V
-}
-
-// https://webidl.spec.whatwg.org/#es-long-long
-webidl.converters['long long'] = function (V, opts) {
- // 1. Let x be ? ConvertToInt(V, 64, "signed").
- const x = webidl.util.ConvertToInt(V, 64, 'signed', opts)
-
- // 2. Return the IDL long long value that represents
- // the same numeric value as x.
- return x
-}
-
-// https://webidl.spec.whatwg.org/#es-unsigned-short
-webidl.converters['unsigned short'] = function (V) {
- // 1. Let x be ? ConvertToInt(V, 16, "unsigned").
- const x = webidl.util.ConvertToInt(V, 16, 'unsigned')
-
- // 2. Return the IDL unsigned short value that represents
- // the same numeric value as x.
- return x
-}
-
-// https://webidl.spec.whatwg.org/#idl-ArrayBuffer
-webidl.converters.ArrayBuffer = function (V, opts = {}) {
- // 1. If Type(V) is not Object, or V does not have an
- // [[ArrayBufferData]] internal slot, then throw a
- // TypeError.
- // see: https://tc39.es/ecma262/#sec-properties-of-the-arraybuffer-instances
- // see: https://tc39.es/ecma262/#sec-properties-of-the-sharedarraybuffer-instances
- if (
- webidl.util.Type(V) !== 'Object' ||
- !types.isAnyArrayBuffer(V)
- ) {
- webidl.errors.conversionFailed({
- prefix: `${V}`,
- argument: `${V}`,
- types: ['ArrayBuffer']
- })
- }
-
- // 2. If the conversion is not to an IDL type associated
- // with the [AllowShared] extended attribute, and
- // IsSharedArrayBuffer(V) is true, then throw a
- // TypeError.
- if (opts.allowShared === false && types.isSharedArrayBuffer(V)) {
- webidl.errors.exception({
- header: 'ArrayBuffer',
- message: 'SharedArrayBuffer is not allowed.'
- })
- }
-
- // 3. If the conversion is not to an IDL type associated
- // with the [AllowResizable] extended attribute, and
- // IsResizableArrayBuffer(V) is true, then throw a
- // TypeError.
- // Note: resizable ArrayBuffers are currently a proposal.
-
- // 4. Return the IDL ArrayBuffer value that is a
- // reference to the same object as V.
- return V
-}
-
-webidl.converters.TypedArray = function (V, T, opts = {}) {
- // 1. Let T be the IDL type V is being converted to.
-
- // 2. If Type(V) is not Object, or V does not have a
- // [[TypedArrayName]] internal slot with a value
- // equal to T’s name, then throw a TypeError.
- if (
- webidl.util.Type(V) !== 'Object' ||
- !types.isTypedArray(V) ||
- V.constructor.name !== T.name
- ) {
- webidl.errors.conversionFailed({
- prefix: `${T.name}`,
- argument: `${V}`,
- types: [T.name]
- })
- }
-
- // 3. If the conversion is not to an IDL type associated
- // with the [AllowShared] extended attribute, and
- // IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is
- // true, then throw a TypeError.
- if (opts.allowShared === false && types.isSharedArrayBuffer(V.buffer)) {
- webidl.errors.exception({
- header: 'ArrayBuffer',
- message: 'SharedArrayBuffer is not allowed.'
- })
- }
-
- // 4. If the conversion is not to an IDL type associated
- // with the [AllowResizable] extended attribute, and
- // IsResizableArrayBuffer(V.[[ViewedArrayBuffer]]) is
- // true, then throw a TypeError.
- // Note: resizable array buffers are currently a proposal
-
- // 5. Return the IDL value of type T that is a reference
- // to the same object as V.
- return V
-}
-
-webidl.converters.DataView = function (V, opts = {}) {
- // 1. If Type(V) is not Object, or V does not have a
- // [[DataView]] internal slot, then throw a TypeError.
- if (webidl.util.Type(V) !== 'Object' || !types.isDataView(V)) {
- webidl.errors.exception({
- header: 'DataView',
- message: 'Object is not a DataView.'
- })
- }
-
- // 2. If the conversion is not to an IDL type associated
- // with the [AllowShared] extended attribute, and
- // IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is true,
- // then throw a TypeError.
- if (opts.allowShared === false && types.isSharedArrayBuffer(V.buffer)) {
- webidl.errors.exception({
- header: 'ArrayBuffer',
- message: 'SharedArrayBuffer is not allowed.'
- })
- }
-
- // 3. If the conversion is not to an IDL type associated
- // with the [AllowResizable] extended attribute, and
- // IsResizableArrayBuffer(V.[[ViewedArrayBuffer]]) is
- // true, then throw a TypeError.
- // Note: resizable ArrayBuffers are currently a proposal
-
- // 4. Return the IDL DataView value that is a reference
- // to the same object as V.
- return V
-}
-
-// https://webidl.spec.whatwg.org/#BufferSource
-webidl.converters.BufferSource = function (V, opts = {}) {
- if (types.isAnyArrayBuffer(V)) {
- return webidl.converters.ArrayBuffer(V, opts)
- }
-
- if (types.isTypedArray(V)) {
- return webidl.converters.TypedArray(V, V.constructor)
- }
-
- if (types.isDataView(V)) {
- return webidl.converters.DataView(V, opts)
- }
-
- throw new TypeError(`Could not convert ${V} to a BufferSource.`)
-}
-
-webidl.converters['sequence'] = webidl.sequenceConverter(
- webidl.converters.ByteString
-)
-
-webidl.converters['sequence>'] = webidl.sequenceConverter(
- webidl.converters['sequence']
-)
-
-webidl.converters['record'] = webidl.recordConverter(
- webidl.converters.ByteString,
- webidl.converters.ByteString
-)
-
-module.exports = {
- webidl
-}
diff --git a/node_modules/undici/lib/global.js b/node_modules/undici/lib/global.js
deleted file mode 100644
index 18bfd73..0000000
--- a/node_modules/undici/lib/global.js
+++ /dev/null
@@ -1,32 +0,0 @@
-'use strict'
-
-// We include a version number for the Dispatcher API. In case of breaking changes,
-// this version number must be increased to avoid conflicts.
-const globalDispatcher = Symbol.for('undici.globalDispatcher.1')
-const { InvalidArgumentError } = require('./core/errors')
-const Agent = require('./agent')
-
-if (getGlobalDispatcher() === undefined) {
- setGlobalDispatcher(new Agent())
-}
-
-function setGlobalDispatcher (agent) {
- if (!agent || typeof agent.dispatch !== 'function') {
- throw new InvalidArgumentError('Argument agent must implement Agent')
- }
- Object.defineProperty(globalThis, globalDispatcher, {
- value: agent,
- writable: true,
- enumerable: false,
- configurable: false
- })
-}
-
-function getGlobalDispatcher () {
- return globalThis[globalDispatcher]
-}
-
-module.exports = {
- setGlobalDispatcher,
- getGlobalDispatcher
-}
diff --git a/node_modules/undici/lib/handler/redirect.js b/node_modules/undici/lib/handler/redirect.js
deleted file mode 100644
index 998a8c2..0000000
--- a/node_modules/undici/lib/handler/redirect.js
+++ /dev/null
@@ -1,214 +0,0 @@
-'use strict'
-
-const util = require('../core/util')
-const { kBodyUsed } = require('../core/symbols')
-const assert = require('assert')
-const { InvalidArgumentError } = require('../core/errors')
-const EE = require('events')
-
-const redirectableStatusCodes = [300, 301, 302, 303, 307, 308]
-
-const kBody = Symbol('body')
-
-class BodyAsyncIterable {
- constructor (body) {
- this[kBody] = body
- this[kBodyUsed] = false
- }
-
- async * [Symbol.asyncIterator] () {
- assert(!this[kBodyUsed], 'disturbed')
- this[kBodyUsed] = true
- yield * this[kBody]
- }
-}
-
-class RedirectHandler {
- constructor (dispatcher, maxRedirections, opts, handler) {
- if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) {
- throw new InvalidArgumentError('maxRedirections must be a positive number')
- }
-
- util.validateHandler(handler, opts.method, opts.upgrade)
-
- this.dispatcher = dispatcher
- this.location = null
- this.abort = null
- this.opts = { ...opts, maxRedirections: 0 } // opts must be a copy
- this.maxRedirections = maxRedirections
- this.handler = handler
- this.history = []
-
- if (util.isStream(this.opts.body)) {
- // TODO (fix): Provide some way for the user to cache the file to e.g. /tmp
- // so that it can be dispatched again?
- // TODO (fix): Do we need 100-expect support to provide a way to do this properly?
- if (util.bodyLength(this.opts.body) === 0) {
- this.opts.body
- .on('data', function () {
- assert(false)
- })
- }
-
- if (typeof this.opts.body.readableDidRead !== 'boolean') {
- this.opts.body[kBodyUsed] = false
- EE.prototype.on.call(this.opts.body, 'data', function () {
- this[kBodyUsed] = true
- })
- }
- } else if (this.opts.body && typeof this.opts.body.pipeTo === 'function') {
- // TODO (fix): We can't access ReadableStream internal state
- // to determine whether or not it has been disturbed. This is just
- // a workaround.
- this.opts.body = new BodyAsyncIterable(this.opts.body)
- } else if (
- this.opts.body &&
- typeof this.opts.body !== 'string' &&
- !ArrayBuffer.isView(this.opts.body) &&
- util.isIterable(this.opts.body)
- ) {
- // TODO: Should we allow re-using iterable if !this.opts.idempotent
- // or through some other flag?
- this.opts.body = new BodyAsyncIterable(this.opts.body)
- }
- }
-
- onConnect (abort) {
- this.abort = abort
- this.handler.onConnect(abort, { history: this.history })
- }
-
- onUpgrade (statusCode, headers, socket) {
- this.handler.onUpgrade(statusCode, headers, socket)
- }
-
- onError (error) {
- this.handler.onError(error)
- }
-
- onHeaders (statusCode, headers, resume, statusText) {
- this.location = this.history.length >= this.maxRedirections || util.isDisturbed(this.opts.body)
- ? null
- : parseLocation(statusCode, headers)
-
- if (this.opts.origin) {
- this.history.push(new URL(this.opts.path, this.opts.origin))
- }
-
- if (!this.location) {
- return this.handler.onHeaders(statusCode, headers, resume, statusText)
- }
-
- const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)))
- const path = search ? `${pathname}${search}` : pathname
-
- // Remove headers referring to the original URL.
- // By default it is Host only, unless it's a 303 (see below), which removes also all Content-* headers.
- // https://tools.ietf.org/html/rfc7231#section-6.4
- this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin)
- this.opts.path = path
- this.opts.origin = origin
- this.opts.maxRedirections = 0
-
- // https://tools.ietf.org/html/rfc7231#section-6.4.4
- // In case of HTTP 303, always replace method to be either HEAD or GET
- if (statusCode === 303 && this.opts.method !== 'HEAD') {
- this.opts.method = 'GET'
- this.opts.body = null
- }
- }
-
- onData (chunk) {
- if (this.location) {
- /*
- https://tools.ietf.org/html/rfc7231#section-6.4
-
- TLDR: undici always ignores 3xx response bodies.
-
- Redirection is used to serve the requested resource from another URL, so it is assumes that
- no body is generated (and thus can be ignored). Even though generating a body is not prohibited.
-
- For status 301, 302, 303, 307 and 308 (the latter from RFC 7238), the specs mention that the body usually
- (which means it's optional and not mandated) contain just an hyperlink to the value of
- the Location response header, so the body can be ignored safely.
-
- For status 300, which is "Multiple Choices", the spec mentions both generating a Location
- response header AND a response body with the other possible location to follow.
- Since the spec explicitily chooses not to specify a format for such body and leave it to
- servers and browsers implementors, we ignore the body as there is no specified way to eventually parse it.
- */
- } else {
- return this.handler.onData(chunk)
- }
- }
-
- onComplete (trailers) {
- if (this.location) {
- /*
- https://tools.ietf.org/html/rfc7231#section-6.4
-
- TLDR: undici always ignores 3xx response trailers as they are not expected in case of redirections
- and neither are useful if present.
-
- See comment on onData method above for more detailed informations.
- */
-
- this.location = null
- this.abort = null
-
- this.dispatcher.dispatch(this.opts, this)
- } else {
- this.handler.onComplete(trailers)
- }
- }
-
- onBodySent (chunk) {
- if (this.handler.onBodySent) {
- this.handler.onBodySent(chunk)
- }
- }
-}
-
-function parseLocation (statusCode, headers) {
- if (redirectableStatusCodes.indexOf(statusCode) === -1) {
- return null
- }
-
- for (let i = 0; i < headers.length; i += 2) {
- if (headers[i].toString().toLowerCase() === 'location') {
- return headers[i + 1]
- }
- }
-}
-
-// https://tools.ietf.org/html/rfc7231#section-6.4.4
-function shouldRemoveHeader (header, removeContent, unknownOrigin) {
- return (
- (header.length === 4 && header.toString().toLowerCase() === 'host') ||
- (removeContent && header.toString().toLowerCase().indexOf('content-') === 0) ||
- (unknownOrigin && header.length === 13 && header.toString().toLowerCase() === 'authorization')
- )
-}
-
-// https://tools.ietf.org/html/rfc7231#section-6.4
-function cleanRequestHeaders (headers, removeContent, unknownOrigin) {
- const ret = []
- if (Array.isArray(headers)) {
- for (let i = 0; i < headers.length; i += 2) {
- if (!shouldRemoveHeader(headers[i], removeContent, unknownOrigin)) {
- ret.push(headers[i], headers[i + 1])
- }
- }
- } else if (headers && typeof headers === 'object') {
- for (const key of Object.keys(headers)) {
- if (!shouldRemoveHeader(key, removeContent, unknownOrigin)) {
- ret.push(key, headers[key])
- }
- }
- } else {
- assert(headers == null, 'headers must be an object or an array')
- }
- return ret
-}
-
-module.exports = RedirectHandler
diff --git a/node_modules/undici/lib/llhttp/constants.d.ts b/node_modules/undici/lib/llhttp/constants.d.ts
deleted file mode 100644
index b75ab1b..0000000
--- a/node_modules/undici/lib/llhttp/constants.d.ts
+++ /dev/null
@@ -1,199 +0,0 @@
-import { IEnumMap } from './utils';
-export declare type HTTPMode = 'loose' | 'strict';
-export declare enum ERROR {
- OK = 0,
- INTERNAL = 1,
- STRICT = 2,
- LF_EXPECTED = 3,
- UNEXPECTED_CONTENT_LENGTH = 4,
- CLOSED_CONNECTION = 5,
- INVALID_METHOD = 6,
- INVALID_URL = 7,
- INVALID_CONSTANT = 8,
- INVALID_VERSION = 9,
- INVALID_HEADER_TOKEN = 10,
- INVALID_CONTENT_LENGTH = 11,
- INVALID_CHUNK_SIZE = 12,
- INVALID_STATUS = 13,
- INVALID_EOF_STATE = 14,
- INVALID_TRANSFER_ENCODING = 15,
- CB_MESSAGE_BEGIN = 16,
- CB_HEADERS_COMPLETE = 17,
- CB_MESSAGE_COMPLETE = 18,
- CB_CHUNK_HEADER = 19,
- CB_CHUNK_COMPLETE = 20,
- PAUSED = 21,
- PAUSED_UPGRADE = 22,
- PAUSED_H2_UPGRADE = 23,
- USER = 24
-}
-export declare enum TYPE {
- BOTH = 0,
- REQUEST = 1,
- RESPONSE = 2
-}
-export declare enum FLAGS {
- CONNECTION_KEEP_ALIVE = 1,
- CONNECTION_CLOSE = 2,
- CONNECTION_UPGRADE = 4,
- CHUNKED = 8,
- UPGRADE = 16,
- CONTENT_LENGTH = 32,
- SKIPBODY = 64,
- TRAILING = 128,
- TRANSFER_ENCODING = 512
-}
-export declare enum LENIENT_FLAGS {
- HEADERS = 1,
- CHUNKED_LENGTH = 2,
- KEEP_ALIVE = 4
-}
-export declare enum METHODS {
- DELETE = 0,
- GET = 1,
- HEAD = 2,
- POST = 3,
- PUT = 4,
- CONNECT = 5,
- OPTIONS = 6,
- TRACE = 7,
- COPY = 8,
- LOCK = 9,
- MKCOL = 10,
- MOVE = 11,
- PROPFIND = 12,
- PROPPATCH = 13,
- SEARCH = 14,
- UNLOCK = 15,
- BIND = 16,
- REBIND = 17,
- UNBIND = 18,
- ACL = 19,
- REPORT = 20,
- MKACTIVITY = 21,
- CHECKOUT = 22,
- MERGE = 23,
- 'M-SEARCH' = 24,
- NOTIFY = 25,
- SUBSCRIBE = 26,
- UNSUBSCRIBE = 27,
- PATCH = 28,
- PURGE = 29,
- MKCALENDAR = 30,
- LINK = 31,
- UNLINK = 32,
- SOURCE = 33,
- PRI = 34,
- DESCRIBE = 35,
- ANNOUNCE = 36,
- SETUP = 37,
- PLAY = 38,
- PAUSE = 39,
- TEARDOWN = 40,
- GET_PARAMETER = 41,
- SET_PARAMETER = 42,
- REDIRECT = 43,
- RECORD = 44,
- FLUSH = 45
-}
-export declare const METHODS_HTTP: METHODS[];
-export declare const METHODS_ICE: METHODS[];
-export declare const METHODS_RTSP: METHODS[];
-export declare const METHOD_MAP: IEnumMap;
-export declare const H_METHOD_MAP: IEnumMap;
-export declare enum FINISH {
- SAFE = 0,
- SAFE_WITH_CB = 1,
- UNSAFE = 2
-}
-export declare type CharList = Array;
-export declare const ALPHA: CharList;
-export declare const NUM_MAP: {
- 0: number;
- 1: number;
- 2: number;
- 3: number;
- 4: number;
- 5: number;
- 6: number;
- 7: number;
- 8: number;
- 9: number;
-};
-export declare const HEX_MAP: {
- 0: number;
- 1: number;
- 2: number;
- 3: number;
- 4: number;
- 5: number;
- 6: number;
- 7: number;
- 8: number;
- 9: number;
- A: number;
- B: number;
- C: number;
- D: number;
- E: number;
- F: number;
- a: number;
- b: number;
- c: number;
- d: number;
- e: number;
- f: number;
-};
-export declare const NUM: CharList;
-export declare const ALPHANUM: CharList;
-export declare const MARK: CharList;
-export declare const USERINFO_CHARS: CharList;
-export declare const STRICT_URL_CHAR: CharList;
-export declare const URL_CHAR: CharList;
-export declare const HEX: CharList;
-export declare const STRICT_TOKEN: CharList;
-export declare const TOKEN: CharList;
-export declare const HEADER_CHARS: CharList;
-export declare const CONNECTION_TOKEN_CHARS: CharList;
-export declare const MAJOR: {
- 0: number;
- 1: number;
- 2: number;
- 3: number;
- 4: number;
- 5: number;
- 6: number;
- 7: number;
- 8: number;
- 9: number;
-};
-export declare const MINOR: {
- 0: number;
- 1: number;
- 2: number;
- 3: number;
- 4: number;
- 5: number;
- 6: number;
- 7: number;
- 8: number;
- 9: number;
-};
-export declare enum HEADER_STATE {
- GENERAL = 0,
- CONNECTION = 1,
- CONTENT_LENGTH = 2,
- TRANSFER_ENCODING = 3,
- UPGRADE = 4,
- CONNECTION_KEEP_ALIVE = 5,
- CONNECTION_CLOSE = 6,
- CONNECTION_UPGRADE = 7,
- TRANSFER_ENCODING_CHUNKED = 8
-}
-export declare const SPECIAL_HEADERS: {
- connection: HEADER_STATE;
- 'content-length': HEADER_STATE;
- 'proxy-connection': HEADER_STATE;
- 'transfer-encoding': HEADER_STATE;
- upgrade: HEADER_STATE;
-};
diff --git a/node_modules/undici/lib/llhttp/constants.js b/node_modules/undici/lib/llhttp/constants.js
deleted file mode 100644
index fb0b5a2..0000000
--- a/node_modules/undici/lib/llhttp/constants.js
+++ /dev/null
@@ -1,278 +0,0 @@
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.SPECIAL_HEADERS = exports.HEADER_STATE = exports.MINOR = exports.MAJOR = exports.CONNECTION_TOKEN_CHARS = exports.HEADER_CHARS = exports.TOKEN = exports.STRICT_TOKEN = exports.HEX = exports.URL_CHAR = exports.STRICT_URL_CHAR = exports.USERINFO_CHARS = exports.MARK = exports.ALPHANUM = exports.NUM = exports.HEX_MAP = exports.NUM_MAP = exports.ALPHA = exports.FINISH = exports.H_METHOD_MAP = exports.METHOD_MAP = exports.METHODS_RTSP = exports.METHODS_ICE = exports.METHODS_HTTP = exports.METHODS = exports.LENIENT_FLAGS = exports.FLAGS = exports.TYPE = exports.ERROR = void 0;
-const utils_1 = require("./utils");
-// C headers
-var ERROR;
-(function (ERROR) {
- ERROR[ERROR["OK"] = 0] = "OK";
- ERROR[ERROR["INTERNAL"] = 1] = "INTERNAL";
- ERROR[ERROR["STRICT"] = 2] = "STRICT";
- ERROR[ERROR["LF_EXPECTED"] = 3] = "LF_EXPECTED";
- ERROR[ERROR["UNEXPECTED_CONTENT_LENGTH"] = 4] = "UNEXPECTED_CONTENT_LENGTH";
- ERROR[ERROR["CLOSED_CONNECTION"] = 5] = "CLOSED_CONNECTION";
- ERROR[ERROR["INVALID_METHOD"] = 6] = "INVALID_METHOD";
- ERROR[ERROR["INVALID_URL"] = 7] = "INVALID_URL";
- ERROR[ERROR["INVALID_CONSTANT"] = 8] = "INVALID_CONSTANT";
- ERROR[ERROR["INVALID_VERSION"] = 9] = "INVALID_VERSION";
- ERROR[ERROR["INVALID_HEADER_TOKEN"] = 10] = "INVALID_HEADER_TOKEN";
- ERROR[ERROR["INVALID_CONTENT_LENGTH"] = 11] = "INVALID_CONTENT_LENGTH";
- ERROR[ERROR["INVALID_CHUNK_SIZE"] = 12] = "INVALID_CHUNK_SIZE";
- ERROR[ERROR["INVALID_STATUS"] = 13] = "INVALID_STATUS";
- ERROR[ERROR["INVALID_EOF_STATE"] = 14] = "INVALID_EOF_STATE";
- ERROR[ERROR["INVALID_TRANSFER_ENCODING"] = 15] = "INVALID_TRANSFER_ENCODING";
- ERROR[ERROR["CB_MESSAGE_BEGIN"] = 16] = "CB_MESSAGE_BEGIN";
- ERROR[ERROR["CB_HEADERS_COMPLETE"] = 17] = "CB_HEADERS_COMPLETE";
- ERROR[ERROR["CB_MESSAGE_COMPLETE"] = 18] = "CB_MESSAGE_COMPLETE";
- ERROR[ERROR["CB_CHUNK_HEADER"] = 19] = "CB_CHUNK_HEADER";
- ERROR[ERROR["CB_CHUNK_COMPLETE"] = 20] = "CB_CHUNK_COMPLETE";
- ERROR[ERROR["PAUSED"] = 21] = "PAUSED";
- ERROR[ERROR["PAUSED_UPGRADE"] = 22] = "PAUSED_UPGRADE";
- ERROR[ERROR["PAUSED_H2_UPGRADE"] = 23] = "PAUSED_H2_UPGRADE";
- ERROR[ERROR["USER"] = 24] = "USER";
-})(ERROR = exports.ERROR || (exports.ERROR = {}));
-var TYPE;
-(function (TYPE) {
- TYPE[TYPE["BOTH"] = 0] = "BOTH";
- TYPE[TYPE["REQUEST"] = 1] = "REQUEST";
- TYPE[TYPE["RESPONSE"] = 2] = "RESPONSE";
-})(TYPE = exports.TYPE || (exports.TYPE = {}));
-var FLAGS;
-(function (FLAGS) {
- FLAGS[FLAGS["CONNECTION_KEEP_ALIVE"] = 1] = "CONNECTION_KEEP_ALIVE";
- FLAGS[FLAGS["CONNECTION_CLOSE"] = 2] = "CONNECTION_CLOSE";
- FLAGS[FLAGS["CONNECTION_UPGRADE"] = 4] = "CONNECTION_UPGRADE";
- FLAGS[FLAGS["CHUNKED"] = 8] = "CHUNKED";
- FLAGS[FLAGS["UPGRADE"] = 16] = "UPGRADE";
- FLAGS[FLAGS["CONTENT_LENGTH"] = 32] = "CONTENT_LENGTH";
- FLAGS[FLAGS["SKIPBODY"] = 64] = "SKIPBODY";
- FLAGS[FLAGS["TRAILING"] = 128] = "TRAILING";
- // 1 << 8 is unused
- FLAGS[FLAGS["TRANSFER_ENCODING"] = 512] = "TRANSFER_ENCODING";
-})(FLAGS = exports.FLAGS || (exports.FLAGS = {}));
-var LENIENT_FLAGS;
-(function (LENIENT_FLAGS) {
- LENIENT_FLAGS[LENIENT_FLAGS["HEADERS"] = 1] = "HEADERS";
- LENIENT_FLAGS[LENIENT_FLAGS["CHUNKED_LENGTH"] = 2] = "CHUNKED_LENGTH";
- LENIENT_FLAGS[LENIENT_FLAGS["KEEP_ALIVE"] = 4] = "KEEP_ALIVE";
-})(LENIENT_FLAGS = exports.LENIENT_FLAGS || (exports.LENIENT_FLAGS = {}));
-var METHODS;
-(function (METHODS) {
- METHODS[METHODS["DELETE"] = 0] = "DELETE";
- METHODS[METHODS["GET"] = 1] = "GET";
- METHODS[METHODS["HEAD"] = 2] = "HEAD";
- METHODS[METHODS["POST"] = 3] = "POST";
- METHODS[METHODS["PUT"] = 4] = "PUT";
- /* pathological */
- METHODS[METHODS["CONNECT"] = 5] = "CONNECT";
- METHODS[METHODS["OPTIONS"] = 6] = "OPTIONS";
- METHODS[METHODS["TRACE"] = 7] = "TRACE";
- /* WebDAV */
- METHODS[METHODS["COPY"] = 8] = "COPY";
- METHODS[METHODS["LOCK"] = 9] = "LOCK";
- METHODS[METHODS["MKCOL"] = 10] = "MKCOL";
- METHODS[METHODS["MOVE"] = 11] = "MOVE";
- METHODS[METHODS["PROPFIND"] = 12] = "PROPFIND";
- METHODS[METHODS["PROPPATCH"] = 13] = "PROPPATCH";
- METHODS[METHODS["SEARCH"] = 14] = "SEARCH";
- METHODS[METHODS["UNLOCK"] = 15] = "UNLOCK";
- METHODS[METHODS["BIND"] = 16] = "BIND";
- METHODS[METHODS["REBIND"] = 17] = "REBIND";
- METHODS[METHODS["UNBIND"] = 18] = "UNBIND";
- METHODS[METHODS["ACL"] = 19] = "ACL";
- /* subversion */
- METHODS[METHODS["REPORT"] = 20] = "REPORT";
- METHODS[METHODS["MKACTIVITY"] = 21] = "MKACTIVITY";
- METHODS[METHODS["CHECKOUT"] = 22] = "CHECKOUT";
- METHODS[METHODS["MERGE"] = 23] = "MERGE";
- /* upnp */
- METHODS[METHODS["M-SEARCH"] = 24] = "M-SEARCH";
- METHODS[METHODS["NOTIFY"] = 25] = "NOTIFY";
- METHODS[METHODS["SUBSCRIBE"] = 26] = "SUBSCRIBE";
- METHODS[METHODS["UNSUBSCRIBE"] = 27] = "UNSUBSCRIBE";
- /* RFC-5789 */
- METHODS[METHODS["PATCH"] = 28] = "PATCH";
- METHODS[METHODS["PURGE"] = 29] = "PURGE";
- /* CalDAV */
- METHODS[METHODS["MKCALENDAR"] = 30] = "MKCALENDAR";
- /* RFC-2068, section 19.6.1.2 */
- METHODS[METHODS["LINK"] = 31] = "LINK";
- METHODS[METHODS["UNLINK"] = 32] = "UNLINK";
- /* icecast */
- METHODS[METHODS["SOURCE"] = 33] = "SOURCE";
- /* RFC-7540, section 11.6 */
- METHODS[METHODS["PRI"] = 34] = "PRI";
- /* RFC-2326 RTSP */
- METHODS[METHODS["DESCRIBE"] = 35] = "DESCRIBE";
- METHODS[METHODS["ANNOUNCE"] = 36] = "ANNOUNCE";
- METHODS[METHODS["SETUP"] = 37] = "SETUP";
- METHODS[METHODS["PLAY"] = 38] = "PLAY";
- METHODS[METHODS["PAUSE"] = 39] = "PAUSE";
- METHODS[METHODS["TEARDOWN"] = 40] = "TEARDOWN";
- METHODS[METHODS["GET_PARAMETER"] = 41] = "GET_PARAMETER";
- METHODS[METHODS["SET_PARAMETER"] = 42] = "SET_PARAMETER";
- METHODS[METHODS["REDIRECT"] = 43] = "REDIRECT";
- METHODS[METHODS["RECORD"] = 44] = "RECORD";
- /* RAOP */
- METHODS[METHODS["FLUSH"] = 45] = "FLUSH";
-})(METHODS = exports.METHODS || (exports.METHODS = {}));
-exports.METHODS_HTTP = [
- METHODS.DELETE,
- METHODS.GET,
- METHODS.HEAD,
- METHODS.POST,
- METHODS.PUT,
- METHODS.CONNECT,
- METHODS.OPTIONS,
- METHODS.TRACE,
- METHODS.COPY,
- METHODS.LOCK,
- METHODS.MKCOL,
- METHODS.MOVE,
- METHODS.PROPFIND,
- METHODS.PROPPATCH,
- METHODS.SEARCH,
- METHODS.UNLOCK,
- METHODS.BIND,
- METHODS.REBIND,
- METHODS.UNBIND,
- METHODS.ACL,
- METHODS.REPORT,
- METHODS.MKACTIVITY,
- METHODS.CHECKOUT,
- METHODS.MERGE,
- METHODS['M-SEARCH'],
- METHODS.NOTIFY,
- METHODS.SUBSCRIBE,
- METHODS.UNSUBSCRIBE,
- METHODS.PATCH,
- METHODS.PURGE,
- METHODS.MKCALENDAR,
- METHODS.LINK,
- METHODS.UNLINK,
- METHODS.PRI,
- // TODO(indutny): should we allow it with HTTP?
- METHODS.SOURCE,
-];
-exports.METHODS_ICE = [
- METHODS.SOURCE,
-];
-exports.METHODS_RTSP = [
- METHODS.OPTIONS,
- METHODS.DESCRIBE,
- METHODS.ANNOUNCE,
- METHODS.SETUP,
- METHODS.PLAY,
- METHODS.PAUSE,
- METHODS.TEARDOWN,
- METHODS.GET_PARAMETER,
- METHODS.SET_PARAMETER,
- METHODS.REDIRECT,
- METHODS.RECORD,
- METHODS.FLUSH,
- // For AirPlay
- METHODS.GET,
- METHODS.POST,
-];
-exports.METHOD_MAP = utils_1.enumToMap(METHODS);
-exports.H_METHOD_MAP = {};
-Object.keys(exports.METHOD_MAP).forEach((key) => {
- if (/^H/.test(key)) {
- exports.H_METHOD_MAP[key] = exports.METHOD_MAP[key];
- }
-});
-var FINISH;
-(function (FINISH) {
- FINISH[FINISH["SAFE"] = 0] = "SAFE";
- FINISH[FINISH["SAFE_WITH_CB"] = 1] = "SAFE_WITH_CB";
- FINISH[FINISH["UNSAFE"] = 2] = "UNSAFE";
-})(FINISH = exports.FINISH || (exports.FINISH = {}));
-exports.ALPHA = [];
-for (let i = 'A'.charCodeAt(0); i <= 'Z'.charCodeAt(0); i++) {
- // Upper case
- exports.ALPHA.push(String.fromCharCode(i));
- // Lower case
- exports.ALPHA.push(String.fromCharCode(i + 0x20));
-}
-exports.NUM_MAP = {
- 0: 0, 1: 1, 2: 2, 3: 3, 4: 4,
- 5: 5, 6: 6, 7: 7, 8: 8, 9: 9,
-};
-exports.HEX_MAP = {
- 0: 0, 1: 1, 2: 2, 3: 3, 4: 4,
- 5: 5, 6: 6, 7: 7, 8: 8, 9: 9,
- A: 0XA, B: 0XB, C: 0XC, D: 0XD, E: 0XE, F: 0XF,
- a: 0xa, b: 0xb, c: 0xc, d: 0xd, e: 0xe, f: 0xf,
-};
-exports.NUM = [
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-];
-exports.ALPHANUM = exports.ALPHA.concat(exports.NUM);
-exports.MARK = ['-', '_', '.', '!', '~', '*', '\'', '(', ')'];
-exports.USERINFO_CHARS = exports.ALPHANUM
- .concat(exports.MARK)
- .concat(['%', ';', ':', '&', '=', '+', '$', ',']);
-// TODO(indutny): use RFC
-exports.STRICT_URL_CHAR = [
- '!', '"', '$', '%', '&', '\'',
- '(', ')', '*', '+', ',', '-', '.', '/',
- ':', ';', '<', '=', '>',
- '@', '[', '\\', ']', '^', '_',
- '`',
- '{', '|', '}', '~',
-].concat(exports.ALPHANUM);
-exports.URL_CHAR = exports.STRICT_URL_CHAR
- .concat(['\t', '\f']);
-// All characters with 0x80 bit set to 1
-for (let i = 0x80; i <= 0xff; i++) {
- exports.URL_CHAR.push(i);
-}
-exports.HEX = exports.NUM.concat(['a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F']);
-/* Tokens as defined by rfc 2616. Also lowercases them.
- * token = 1*
- * separators = "(" | ")" | "<" | ">" | "@"
- * | "," | ";" | ":" | "\" | <">
- * | "/" | "[" | "]" | "?" | "="
- * | "{" | "}" | SP | HT
- */
-exports.STRICT_TOKEN = [
- '!', '#', '$', '%', '&', '\'',
- '*', '+', '-', '.',
- '^', '_', '`',
- '|', '~',
-].concat(exports.ALPHANUM);
-exports.TOKEN = exports.STRICT_TOKEN.concat([' ']);
-/*
- * Verify that a char is a valid visible (printable) US-ASCII
- * character or %x80-FF
- */
-exports.HEADER_CHARS = ['\t'];
-for (let i = 32; i <= 255; i++) {
- if (i !== 127) {
- exports.HEADER_CHARS.push(i);
- }
-}
-// ',' = \x44
-exports.CONNECTION_TOKEN_CHARS = exports.HEADER_CHARS.filter((c) => c !== 44);
-exports.MAJOR = exports.NUM_MAP;
-exports.MINOR = exports.MAJOR;
-var HEADER_STATE;
-(function (HEADER_STATE) {
- HEADER_STATE[HEADER_STATE["GENERAL"] = 0] = "GENERAL";
- HEADER_STATE[HEADER_STATE["CONNECTION"] = 1] = "CONNECTION";
- HEADER_STATE[HEADER_STATE["CONTENT_LENGTH"] = 2] = "CONTENT_LENGTH";
- HEADER_STATE[HEADER_STATE["TRANSFER_ENCODING"] = 3] = "TRANSFER_ENCODING";
- HEADER_STATE[HEADER_STATE["UPGRADE"] = 4] = "UPGRADE";
- HEADER_STATE[HEADER_STATE["CONNECTION_KEEP_ALIVE"] = 5] = "CONNECTION_KEEP_ALIVE";
- HEADER_STATE[HEADER_STATE["CONNECTION_CLOSE"] = 6] = "CONNECTION_CLOSE";
- HEADER_STATE[HEADER_STATE["CONNECTION_UPGRADE"] = 7] = "CONNECTION_UPGRADE";
- HEADER_STATE[HEADER_STATE["TRANSFER_ENCODING_CHUNKED"] = 8] = "TRANSFER_ENCODING_CHUNKED";
-})(HEADER_STATE = exports.HEADER_STATE || (exports.HEADER_STATE = {}));
-exports.SPECIAL_HEADERS = {
- 'connection': HEADER_STATE.CONNECTION,
- 'content-length': HEADER_STATE.CONTENT_LENGTH,
- 'proxy-connection': HEADER_STATE.CONNECTION,
- 'transfer-encoding': HEADER_STATE.TRANSFER_ENCODING,
- 'upgrade': HEADER_STATE.UPGRADE,
-};
-//# sourceMappingURL=constants.js.map
\ No newline at end of file
diff --git a/node_modules/undici/lib/llhttp/constants.js.map b/node_modules/undici/lib/llhttp/constants.js.map
deleted file mode 100644
index 6ac54bc..0000000
--- a/node_modules/undici/lib/llhttp/constants.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/llhttp/constants.ts"],"names":[],"mappings":";;;AAAA,mCAA8C;AAI9C,YAAY;AAEZ,IAAY,KA6BX;AA7BD,WAAY,KAAK;IACf,6BAAM,CAAA;IACN,yCAAQ,CAAA;IACR,qCAAM,CAAA;IACN,+CAAW,CAAA;IACX,2EAAyB,CAAA;IACzB,2DAAiB,CAAA;IACjB,qDAAc,CAAA;IACd,+CAAW,CAAA;IACX,yDAAgB,CAAA;IAChB,uDAAe,CAAA;IACf,kEAAoB,CAAA;IACpB,sEAAsB,CAAA;IACtB,8DAAkB,CAAA;IAClB,sDAAc,CAAA;IACd,4DAAiB,CAAA;IACjB,4EAAyB,CAAA;IAEzB,0DAAgB,CAAA;IAChB,gEAAmB,CAAA;IACnB,gEAAmB,CAAA;IACnB,wDAAe,CAAA;IACf,4DAAiB,CAAA;IAEjB,sCAAM,CAAA;IACN,sDAAc,CAAA;IACd,4DAAiB,CAAA;IAEjB,kCAAI,CAAA;AACN,CAAC,EA7BW,KAAK,GAAL,aAAK,KAAL,aAAK,QA6BhB;AAED,IAAY,IAIX;AAJD,WAAY,IAAI;IACd,+BAAQ,CAAA;IACR,qCAAO,CAAA;IACP,uCAAQ,CAAA;AACV,CAAC,EAJW,IAAI,GAAJ,YAAI,KAAJ,YAAI,QAIf;AAED,IAAY,KAWX;AAXD,WAAY,KAAK;IACf,mEAA8B,CAAA;IAC9B,yDAAyB,CAAA;IACzB,6DAA2B,CAAA;IAC3B,uCAAgB,CAAA;IAChB,wCAAgB,CAAA;IAChB,sDAAuB,CAAA;IACvB,0CAAiB,CAAA;IACjB,2CAAiB,CAAA;IACjB,mBAAmB;IACnB,6DAA0B,CAAA;AAC5B,CAAC,EAXW,KAAK,GAAL,aAAK,KAAL,aAAK,QAWhB;AAED,IAAY,aAIX;AAJD,WAAY,aAAa;IACvB,uDAAgB,CAAA;IAChB,qEAAuB,CAAA;IACvB,6DAAmB,CAAA;AACrB,CAAC,EAJW,aAAa,GAAb,qBAAa,KAAb,qBAAa,QAIxB;AAED,IAAY,OA0DX;AA1DD,WAAY,OAAO;IACjB,yCAAU,CAAA;IACV,mCAAO,CAAA;IACP,qCAAQ,CAAA;IACR,qCAAQ,CAAA;IACR,mCAAO,CAAA;IACP,kBAAkB;IAClB,2CAAW,CAAA;IACX,2CAAW,CAAA;IACX,uCAAS,CAAA;IACT,YAAY;IACZ,qCAAQ,CAAA;IACR,qCAAQ,CAAA;IACR,wCAAU,CAAA;IACV,sCAAS,CAAA;IACT,8CAAa,CAAA;IACb,gDAAc,CAAA;IACd,0CAAW,CAAA;IACX,0CAAW,CAAA;IACX,sCAAS,CAAA;IACT,0CAAW,CAAA;IACX,0CAAW,CAAA;IACX,oCAAQ,CAAA;IACR,gBAAgB;IAChB,0CAAW,CAAA;IACX,kDAAe,CAAA;IACf,8CAAa,CAAA;IACb,wCAAU,CAAA;IACV,UAAU;IACV,8CAAe,CAAA;IACf,0CAAW,CAAA;IACX,gDAAc,CAAA;IACd,oDAAgB,CAAA;IAChB,cAAc;IACd,wCAAU,CAAA;IACV,wCAAU,CAAA;IACV,YAAY;IACZ,kDAAe,CAAA;IACf,gCAAgC;IAChC,sCAAS,CAAA;IACT,0CAAW,CAAA;IACX,aAAa;IACb,0CAAW,CAAA;IACX,4BAA4B;IAC5B,oCAAQ,CAAA;IACR,mBAAmB;IACnB,8CAAa,CAAA;IACb,8CAAa,CAAA;IACb,wCAAU,CAAA;IACV,sCAAS,CAAA;IACT,wCAAU,CAAA;IACV,8CAAa,CAAA;IACb,wDAAkB,CAAA;IAClB,wDAAkB,CAAA;IAClB,8CAAa,CAAA;IACb,0CAAW,CAAA;IACX,UAAU;IACV,wCAAU,CAAA;AACZ,CAAC,EA1DW,OAAO,GAAP,eAAO,KAAP,eAAO,QA0DlB;AAEY,QAAA,YAAY,GAAG;IAC1B,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,UAAU,CAAC;IACnB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,GAAG;IAEX,+CAA+C;IAC/C,OAAO,CAAC,MAAM;CACf,CAAC;AAEW,QAAA,WAAW,GAAG;IACzB,OAAO,CAAC,MAAM;CACf,CAAC;AAEW,QAAA,YAAY,GAAG;IAC1B,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,KAAK;IAEb,cAAc;IACd,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,IAAI;CACb,CAAC;AAEW,QAAA,UAAU,GAAG,iBAAS,CAAC,OAAO,CAAC,CAAC;AAChC,QAAA,YAAY,GAAa,EAAE,CAAC;AAEzC,MAAM,CAAC,IAAI,CAAC,kBAAU,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;IACtC,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;QAClB,oBAAY,CAAC,GAAG,CAAC,GAAG,kBAAU,CAAC,GAAG,CAAC,CAAC;KACrC;AACH,CAAC,CAAC,CAAC;AAEH,IAAY,MAIX;AAJD,WAAY,MAAM;IAChB,mCAAQ,CAAA;IACR,mDAAY,CAAA;IACZ,uCAAM,CAAA;AACR,CAAC,EAJW,MAAM,GAAN,cAAM,KAAN,cAAM,QAIjB;AAMY,QAAA,KAAK,GAAa,EAAE,CAAC;AAElC,KAAK,IAAI,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;IAC3D,aAAa;IACb,aAAK,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IAEnC,aAAa;IACb,aAAK,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;CAC3C;AAEY,QAAA,OAAO,GAAG;IACrB,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;IAC5B,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;CAC7B,CAAC;AAEW,QAAA,OAAO,GAAG;IACrB,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;IAC5B,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;IAC5B,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;IAC9C,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;CAC/C,CAAC;AAEW,QAAA,GAAG,GAAa;IAC3B,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG;CACjD,CAAC;AAEW,QAAA,QAAQ,GAAa,aAAK,CAAC,MAAM,CAAC,WAAG,CAAC,CAAC;AACvC,QAAA,IAAI,GAAa,CAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,CAAE,CAAC;AAClE,QAAA,cAAc,GAAa,gBAAQ;KAC7C,MAAM,CAAC,YAAI,CAAC;KACZ,MAAM,CAAC,CAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAE,CAAC,CAAC;AAEtD,yBAAyB;AACZ,QAAA,eAAe,GAAc;IACxC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI;IAC7B,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG;IACtC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG;IACvB,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG;IAC7B,GAAG;IACH,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG;CACN,CAAC,MAAM,CAAC,gBAAQ,CAAC,CAAC;AAEnB,QAAA,QAAQ,GAAa,uBAAe;KAC9C,MAAM,CAAE,CAAE,IAAI,EAAE,IAAI,CAAe,CAAC,CAAC;AAExC,wCAAwC;AACxC,KAAK,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,EAAE;IACjC,gBAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;CAClB;AAEY,QAAA,GAAG,GAAa,WAAG,CAAC,MAAM,CACrC,CAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAE,CAAC,CAAC;AAElE;;;;;;GAMG;AACU,QAAA,YAAY,GAAc;IACrC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI;IAC7B,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG;IAClB,GAAG,EAAE,GAAG,EAAE,GAAG;IACb,GAAG,EAAE,GAAG;CACI,CAAC,MAAM,CAAC,gBAAQ,CAAC,CAAC;AAEnB,QAAA,KAAK,GAAa,oBAAY,CAAC,MAAM,CAAC,CAAE,GAAG,CAAE,CAAC,CAAC;AAE5D;;;GAGG;AACU,QAAA,YAAY,GAAa,CAAE,IAAI,CAAE,CAAC;AAC/C,KAAK,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,EAAE,EAAE;IAC9B,IAAI,CAAC,KAAK,GAAG,EAAE;QACb,oBAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KACtB;CACF;AAED,aAAa;AACA,QAAA,sBAAsB,GACjC,oBAAY,CAAC,MAAM,CAAC,CAAC,CAAkB,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;AAE3C,QAAA,KAAK,GAAG,eAAO,CAAC;AAChB,QAAA,KAAK,GAAG,aAAK,CAAC;AAE3B,IAAY,YAWX;AAXD,WAAY,YAAY;IACtB,qDAAW,CAAA;IACX,2DAAU,CAAA;IACV,mEAAc,CAAA;IACd,yEAAiB,CAAA;IACjB,qDAAO,CAAA;IAEP,iFAAqB,CAAA;IACrB,uEAAgB,CAAA;IAChB,2EAAkB,CAAA;IAClB,yFAAyB,CAAA;AAC3B,CAAC,EAXW,YAAY,GAAZ,oBAAY,KAAZ,oBAAY,QAWvB;AAEY,QAAA,eAAe,GAAG;IAC7B,YAAY,EAAE,YAAY,CAAC,UAAU;IACrC,gBAAgB,EAAE,YAAY,CAAC,cAAc;IAC7C,kBAAkB,EAAE,YAAY,CAAC,UAAU;IAC3C,mBAAmB,EAAE,YAAY,CAAC,iBAAiB;IACnD,SAAS,EAAE,YAAY,CAAC,OAAO;CAChC,CAAC"}
\ No newline at end of file
diff --git a/node_modules/undici/lib/llhttp/llhttp.wasm b/node_modules/undici/lib/llhttp/llhttp.wasm
deleted file mode 100755
index 3f596bb..0000000
Binary files a/node_modules/undici/lib/llhttp/llhttp.wasm and /dev/null differ
diff --git a/node_modules/undici/lib/llhttp/llhttp.wasm.js b/node_modules/undici/lib/llhttp/llhttp.wasm.js
deleted file mode 100644
index 753bbc9..0000000
--- a/node_modules/undici/lib/llhttp/llhttp.wasm.js
+++ /dev/null
@@ -1 +0,0 @@
-module.exports = 'AGFzbQEAAAABMAhgAX8Bf2ADf39/AX9gBH9/f38Bf2AAAGADf39/AGABfwBgAn9/AGAGf39/f39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQACA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAAzk4AwMEAAAFAAAAAAAABQEFAAUFBQAABgAAAAYGAQEBAQEBAQEBAQEBAQEBAQABAAABAQcAAAUFAAMEBQFwAQ4OBQMBAAIGCAF/AUGgtwQLB/UEHwZtZW1vcnkCAAtfaW5pdGlhbGl6ZQAJGV9faW5kaXJlY3RfZnVuY3Rpb25fdGFibGUBAAtsbGh0dHBfaW5pdAAKGGxsaHR0cF9zaG91bGRfa2VlcF9hbGl2ZQA1DGxsaHR0cF9hbGxvYwAMBm1hbGxvYwA6C2xsaHR0cF9mcmVlAA0EZnJlZQA8D2xsaHR0cF9nZXRfdHlwZQAOFWxsaHR0cF9nZXRfaHR0cF9tYWpvcgAPFWxsaHR0cF9nZXRfaHR0cF9taW5vcgAQEWxsaHR0cF9nZXRfbWV0aG9kABEWbGxodHRwX2dldF9zdGF0dXNfY29kZQASEmxsaHR0cF9nZXRfdXBncmFkZQATDGxsaHR0cF9yZXNldAAUDmxsaHR0cF9leGVjdXRlABUUbGxodHRwX3NldHRpbmdzX2luaXQAFg1sbGh0dHBfZmluaXNoABcMbGxodHRwX3BhdXNlABgNbGxodHRwX3Jlc3VtZQAZG2xsaHR0cF9yZXN1bWVfYWZ0ZXJfdXBncmFkZQAaEGxsaHR0cF9nZXRfZXJybm8AGxdsbGh0dHBfZ2V0X2Vycm9yX3JlYXNvbgAcF2xsaHR0cF9zZXRfZXJyb3JfcmVhc29uAB0UbGxodHRwX2dldF9lcnJvcl9wb3MAHhFsbGh0dHBfZXJybm9fbmFtZQAfEmxsaHR0cF9tZXRob2RfbmFtZQAgGmxsaHR0cF9zZXRfbGVu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QZx/akHkAEkNACAAQcwBRg0AIABBsAJGDQBBBCEFIARBiARxQYAERg0CIARBKHFFDQILQQAPC0EAQQMgACkDIFAbIQULIAULXQECf0EAIQECQCAALQAoQQFGDQAgAC8BMiICQZx/akHkAEkNACACQcwBRg0AIAJBsAJGDQAgAC8BMCIAQcAAcQ0AQQEhASAAQYgEcUGABEYNACAAQShxRSEBCyABC6IBAQN/AkACQAJAIAAtACpFDQAgAC0AK0UNAEEAIQMgAC8BMCIEQQJxRQ0BDAILQQAhAyAALwEwIgRBAXFFDQELQQEhAyAALQAoQQFGDQAgAC8BMiIFQZx/akHkAEkNACAFQcwBRg0AIAVBsAJGDQAgBEHAAHENAEEAIQMgBEGIBHFBgARGDQAgBEEocUEARyEDCyAAQQA7ATAgAEEAOgAvIAMLlAEBAn8CQAJAAkAgAC0AKkUNACAALQArRQ0AQQAhASAALwEwIgJBAnFFDQEMAgtBACEBIAAvATAiAkEBcUUNAQtBASEBIAAtAChBAUYNACAALwEyIgBBnH9qQeQASQ0AIABBzAFGDQAgAEGwAkYNACACQcAAcQ0AQQAhASACQYgEcUGABEYNACACQShxQQBHIQELIAELTwAgAEEYakIANwMAIABCADcDACAAQTBqQgA3AwAgAEEoakIANwMAIABBIGpCADcDACAAQRBqQgA3AwAgAEEIakIANwMAIABBuAE2AhxBAAt7AQF/AkAgACgCDCIDDQACQCAAKAIERQ0AIAAgATYCBAsCQCAAIAEgAhC4gICAACIDDQAgACgCDA8LIAAgAzYCHEEAIQMgACgCBCIBRQ0AIAAgASACIAAoAggRgYCAgAAAIgFFDQAgACACNgIUIAAgATYCDCABIQMLIAML8soBAxl/A34FfyOAgICAAEEQayIDJICAgIAAIAEhBCABIQUgASEGIAEhByABIQggASEJIAEhCiABIQsgASEMIAEhDSABIQ4gASEPIAEhECABIREgASESIAEhEyABIRQgASEVIAEhFiABIRcgASEYIAEhGSABIRoCQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAC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QQEhGwwPC0GbASEbDA4LQZwBIRsMDQtBngEhGwwMC0GgASEbDAsLQZ8BIRsMCgtBoQEhGwwJC0GiASEbDAgLQaMBIRsMBwtBpAEhGwwGC0GlASEbDAULQaYBIRsMBAtBpwEhGwwDC0GoASEbDAILQakBIRsMAQtBrwEhGwsDQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAC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IAAgIDYCAAybAgsgAEEANgIAIB8gI2tBBWohAUEjIRsMswELAkAgASIEIAJHDQBB6wAhGwyaAgsCQAJAIAQtAABBtH9qDggAtgG2AbYBtgG2AbYBAbYBCyAEQQFqIQFB3QAhGwyPAgsgBEEBaiEBQd4AIRsMjgILAkAgASIEIAJHDQBB7AAhGwyZAgsgBC0AAEHFAEcNswEgBEEBaiEBDOQBC0HtACEbIAEiHyACRg2XAiACIB9rIAAoAgAiI2ohICAfIQQgIyEBAkADQCAELQAAIAFBqLKAgABqLQAARw2zASABQQNGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAICA2AgAMmAILIABBADYCACAfICNrQQRqIQFBLSEbDLABC0HuACEbIAEiHyACRg2WAiACIB9rIAAoAgAiI2ohICAfIQQgIyEBAkADQCAELQAAIAFB8LKAgABqLQAARw2yASABQQhGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAICA2AgAMlwILIABBADYCACAfICNrQQlqIQFBKSEbDK8BCwJAIAEiASACRw0AQe8AIRsMlgILQQEhGyABLQAAQd8ARw2uASABQQFqIQEM4gELQfAAIRsgASIfIAJGDZQCIAIgH2sgACgCACIjaiEgIB8hBCAjIQEDQCAELQAAIAFBrLKAgABqLQAARw2vASABQQFGDfoBIAFBAWohASAEQQFqIgQgAkcNAAsgACAgNgIADJQCC0HxACEbIAEiHyACRg2TAiACIB9rIAAoAgAiI2ohICAfIQQgIyEBAkADQCAELQAAIAFBrrKAgABqLQAARw2vASABQQJGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAICA2AgAMlAILIABBADYCACAfICNrQQNqIQFBAiEbDKwBC0HyACEbIAEiHyACRg2SAiACIB9rIAAoAgAiI2ohICAfIQQgIyEBAkADQCAELQAAIAFBkLOAgABqLQAARw2uASABQQFGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAICA2AgAMkwILIABBADYCACAfICNrQQJqIQFBHyEbDKsBC0HzACEbIAEiHyACRg2RAiACIB9rIAAoAgAiI2ohICAfIQQgIyEBAkADQCAELQAAIAFBkrOAgABqLQAARw2tASABQQFGDQEgAUEBaiEBIARBAWoiBCAC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c3QASW52YWxpZCBtZXRob2QgZm9yIFJUU1AveC54IHJlcXVlc3QARXhwZWN0ZWQgU09VUkNFIG1ldGhvZCBmb3IgSUNFL3gueCByZXF1ZXN0AEludmFsaWQgY2hhciBpbiB1cmwgZnJhZ21lbnQgc3RhcnQARXhwZWN0ZWQgZG90AFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fc3RhdHVzAEludmFsaWQgcmVzcG9uc2Ugc3RhdHVzAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIHBhcmFtZXRlcnMAVXNlciBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfaGVhZGVyYCBjYWxsYmFjayBlcnJvcgBgb25fbWVzc2FnZV9iZWdpbmAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fbWVzc2FnZV9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAVW5leHBlY3RlZCBjaGFyIGluIHVybCBzZXJ2ZXIASW52YWxpZCBoZWFkZXIgdmFsdWUgY2hhcgBJbnZhbGlkIGhlYWRlciBmaWVsZCBjaGFyAEludmFsaWQgbWlub3IgdmVyc2lvbgBJbnZhbGlkIG1ham9yIHZlcnNpb24ARXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgdmVyc2lvbgBFeHBlY3RlZCBDUkxGIGFmdGVyIHZlcnNpb24ASW52YWxpZCBoZWFkZXIgdG9rZW4AU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl91cmwASW52YWxpZCBjaGFyYWN0ZXJzIGluIHVybABVbmV4cGVjdGVkIHN0YXJ0IGNoYXIgaW4gdXJsAERvdWJsZSBAIGluIHVybABFbXB0eSBDb250ZW50LUxlbmd0aABJbnZhbGlkIGNoYXJhY3RlciBpbiBDb250ZW50LUxlbmd0aABEdXBsaWNhdGUgQ29udGVudC1MZW5ndGgASW52YWxpZCBjaGFyIGluIHVybCBwYXRoAENvbnRlbnQtTGVuZ3RoIGNhbid0IGJlIHByZXNlbnQgd2l0aCBUcmFuc2Zlci1FbmNvZGluZwBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBzaXplAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25faGVhZGVyX3ZhbHVlAE1pc3NpbmcgZXhwZWN0ZWQgTEYgYWZ0ZXIgaGVhZGVyIHZhbHVlAFBhdXNlZCBieSBvbl9oZWFkZXJzX2NvbXBsZXRlAEludmFsaWQgRU9GIHN0YXRlAG9uX2NodW5rX2hlYWRlciBwYXVzZQBvbl9tZXNzYWdlX2JlZ2luIHBhdXNlAG9uX2NodW5rX2NvbXBsZXRlIHBhdXNlAG9uX21lc3NhZ2VfY29tcGxldGUgcGF1c2UAUGF1c2Ugb24gQ09OTkVDVC9VcGdyYWRlAFBhdXNlIG9uIFBSSS9VcGdyYWRlAEV4cGVjdGVkIEhUVFAvMiBDb25uZWN0aW9uIFByZWZhY2UARXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgbWV0aG9kAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25faGVhZGVyX2ZpZWxkAFBhdXNlZABJbnZhbGlkIHdvcmQgZW5jb3VudGVyZWQASW52YWxpZCBtZXRob2QgZW5jb3VudGVyZWQAVW5leHBlY3RlZCBjaGFyIGluIHVybCBzY2hlbWEAUmVxdWVzdCBoYXMgaW52YWxpZCBgVHJhbnNmZXItRW5jb2RpbmdgAE1LQUNUSVZJVFkAQ09QWQBOT1RJRlkAUExBWQBQVVQAQ0hFQ0tPVVQAUE9TVABSRVBPUlQASFBFX0lOVkFMSURfQ09OU1RBTlQAR0VUAEhQRV9TVFJJQ1QAUkVESVJFQ1QAQ09OTkVDVABIUEVfSU5WQUxJRF9TVEFUVVMAT1BUSU9OUwBTRVRfUEFSQU1FVEVSAEdFVF9QQVJBTUVURVIASFBFX1VTRVIASFBFX0NCX0NIVU5LX0hFQURFUgBNS0NBTEVOREFSAFNFVFVQAFRFQVJET1dOAEhQRV9DTE9TRURfQ09OTkVDVElPTgBIUEVfSU5WQUxJRF9WRVJTSU9OAEhQRV9DQl9NRVNTQUdFX0JFR0lOAEhQRV9JTlZBTElEX0hFQURFUl9UT0tFTgBIUEVfSU5WQUxJRF9VUkwATUtDT0wAQUNMAEhQRV9JTlRFUk5BTABIUEVfT0sAVU5MSU5LAFVOTE9DSwBQUkkASFBFX0lOVkFMSURfQ09OVEVOVF9MRU5HVEgASFBFX1VORVhQRUNURURfQ09OVEVOVF9MRU5HVEgARkxVU0gAUFJPUFBBVENIAE0tU0VBUkNIAEhQRV9JTlZBTElEX1RSQU5TRkVSX0VOQ09ESU5HAEV4cGVjdGVkIENSTEYASFBFX0lOVkFMSURfQ0hVTktfU0laRQBNT1ZFAEhQRV9DQl9IRUFERVJTX0NPTVBMRVRFAEhQRV9DQl9DSFVOS19DT01QTEVURQBIUEVfQ0JfTUVTU0FHRV9DT01QTEVURQBERUxFVEUASFBFX0lOVkFMSURfRU9GX1NUQVRFAFBBVVNFAFBVUkdFAE1FUkdFAEhQRV9QQVVTRURfVVBHUkFERQBIUEVfUEFVU0VEX0gyX1VQR1JBREUAU09VUkNFAEFOTk9VTkNFAFRSQUNFAERFU0NSSUJFAFVOU1VCU0NSSUJFAFJFQ09SRABIUEVfSU5WQUxJRF9NRVRIT0QAUFJPUEZJTkQAVU5CSU5EAFJFQklORABIUEVfTEZfRVhQRUNURUQASFBFX1BBVVNFRABIRUFEAEV4cGVjdGVkIEhUVFAvAIwLAAB/CwAAgwoAADkNAADACwAADQsAAA8NAABlCwAAagoAACMLAABMCwAApQsAACMMAACfCgAAjAwAAPcLAAA3CwAAPwwAAG0MAADfCgAAVwwAAEkNAAC0DAAAxwwAANYKAACFDAAAfwoAAFQNAABeCgAAUQoAAJcKAACyCgAA7QwAAEAKAACcCwAAdQsAADoMAAAiDQAA5AsAAPALAACaCwAANA0AADINAAArDQAAewsAAGMKAAA1CgAAVQoAAK4MAADuCwAARQoAAP4MAAD8DAAA6AsAAKgMAADzCgAAlQsAAJMLAADdDAAAoQsAAPMMAADkDAAA/goAAEwKAACiDAAABAsAAMgKAAC6CgAAjgoAAAgNAADeCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAWxvc2VlZXAtYWxpdmUAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQECAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAWNodW5rZWQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAAEBAQEBAAABAQABAQABAQEBAQEBAQEBAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZWN0aW9uZW50LWxlbmd0aG9ucm94eS1jb25uZWN0aW9uAAAAAAAAAAAAAAAAAAAAcmFuc2Zlci1lbmNvZGluZ3BncmFkZQ0KDQoNClNNDQoNClRUUC9DRS9UU1AvAAAAAAAAAAAAAAAAAQIAAQMAAAAAAAAAAAAAAAAAAAAAAAAEAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAECAAEDAAAAAAAAAAAAAAAAAAAAAAAABAEBBQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAABAAABAAAAAAAAAAAAAAAAAAAAAAAAAAABAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAEAAAIAAAAAAAAAAAAAAAAAAAAAAAADBAAABAQEBAQEBAQEBAQFBAQEBAQEBAQEBAQEAAQABgcEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAABAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAQAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAACAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATk9VTkNFRUNLT1VUTkVDVEVURUNSSUJFTFVTSEVURUFEU0VBUkNIUkdFQ1RJVklUWUxFTkRBUlZFT1RJRllQVElPTlNDSFNFQVlTVEFUQ0hHRU9SRElSRUNUT1JUUkNIUEFSQU1FVEVSVVJDRUJTQ1JJQkVBUkRPV05BQ0VJTkROS0NLVUJTQ1JJQkVIVFRQL0FEVFAv'
diff --git a/node_modules/undici/lib/llhttp/llhttp_simd.wasm b/node_modules/undici/lib/llhttp/llhttp_simd.wasm
deleted file mode 100755
index bc2848b..0000000
Binary files a/node_modules/undici/lib/llhttp/llhttp_simd.wasm and /dev/null differ
diff --git a/node_modules/undici/lib/llhttp/llhttp_simd.wasm.js b/node_modules/undici/lib/llhttp/llhttp_simd.wasm.js
deleted file mode 100644
index 008f3e2..0000000
--- a/node_modules/undici/lib/llhttp/llhttp_simd.wasm.js
+++ /dev/null
@@ -1 +0,0 @@
-module.exports = 'AGFzbQEAAAABMAhgAX8Bf2ADf39/AX9gBH9/f38Bf2AAAGADf39/AGABfwBgAn9/AGAGf39/f39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQACA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAAzk4AwMEAAAFAAAAAAAABQEFAAUFBQAABgAAAAYGAQEBAQEBAQEBAQEBAQEBAQABAAABAQcAAAUFAAMEBQFwAQ4OBQMBAAIGCAF/AUGgtwQLB/UEHwZtZW1vcnkCAAtfaW5pdGlhbGl6ZQAJGV9faW5kaXJlY3RfZnVuY3Rpb25fdGFibGUBAAtsbGh0dHBfaW5pdAAKGGxsaHR0cF9zaG91bGRfa2VlcF9hbGl2ZQA1DGxsaHR0cF9hbGxvYwAMBm1hbGxvYwA6C2xsaHR0cF9mcmVlAA0EZnJlZQA8D2xsaHR0cF9nZXRfdHlwZQAOFWxsaHR0cF9nZXRfaHR0cF9tYWpvcgAPFWxsaHR0cF9nZXRfaHR0cF9taW5vcgAQEWxsaHR0cF9nZXRfbWV0aG9kABEWbGxodHRwX2dldF9zdGF0dXNfY29kZQASEmxsaHR0cF9nZXRfdXBncmFkZQATDGxsaHR0cF9yZXNldAAUDmxsaHR0cF9leGVjdXRlABUUbGxodHRwX3NldHRpbmdzX2luaXQAFg1sbGh0dHBfZmluaXNoABcMbGxodHRwX3BhdXNlABgNbGxodHRwX3Jlc3VtZQAZG2xsaHR0cF9yZXN1bWVfYWZ0ZXJfdXBncmFkZQAaEGxsaHR0cF9nZXRfZXJybm8AGxdsbGh0dHBfZ2V0X2Vycm9yX3JlYXNvbgAcF2xsaHR0cF9zZXRfZXJyb3JfcmVhc29uAB0UbGxodHRwX2dldF9lcnJvcl9wb3MAHhFsbGh0dHBfZXJybm9fbmFtZQAfEmxsaHR0cF9tZXRob2RfbmFtZQAgGmxsaHR0cF9zZXRfbGVu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C0GcASEbDA0LQZ4BIRsMDAtBoAEhGwwLC0GfASEbDAoLQaEBIRsMCQtBogEhGwwIC0GjASEbDAcLQaQBIRsMBgtBpQEhGwwFC0GmASEbDAQLQacBIRsMAwtBqAEhGwwCC0GpASEbDAELQa8BIRsLA0ACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIBsO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aG9kIGZvciBSVFNQL3gueCByZXF1ZXN0AEV4cGVjdGVkIFNPVVJDRSBtZXRob2QgZm9yIElDRS94LnggcmVxdWVzdABJbnZhbGlkIGNoYXIgaW4gdXJsIGZyYWdtZW50IHN0YXJ0AEV4cGVjdGVkIGRvdABTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3N0YXR1cwBJbnZhbGlkIHJlc3BvbnNlIHN0YXR1cwBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBwYXJhbWV0ZXJzAFVzZXIgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2hlYWRlcmAgY2FsbGJhY2sgZXJyb3IAYG9uX21lc3NhZ2VfYmVnaW5gIGNhbGxiYWNrIGVycm9yAGBvbl9jaHVua19jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX21lc3NhZ2VfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAFVuZXhwZWN0ZWQgY2hhciBpbiB1cmwgc2VydmVyAEludmFsaWQgaGVhZGVyIHZhbHVlIGNoYXIASW52YWxpZCBoZWFkZXIgZmllbGQgY2hhcgBJbnZhbGlkIG1pbm9yIHZlcnNpb24ASW52YWxpZCBtYWpvciB2ZXJzaW9uAEV4cGVjdGVkIHNwYWNlIGFmdGVyIHZlcnNpb24ARXhwZWN0ZWQgQ1JMRiBhZnRlciB2ZXJzaW9uAEludmFsaWQgaGVhZGVyIHRva2VuAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fdXJsAEludmFsaWQgY2hhcmFjdGVycyBpbiB1cmwAVW5leHBlY3RlZCBzdGFydCBjaGFyIGluIHVybABEb3VibGUgQCBpbiB1cmwARW1wdHkgQ29udGVudC1MZW5ndGgASW52YWxpZCBjaGFyYWN0ZXIgaW4gQ29udGVudC1MZW5ndGgARHVwbGljYXRlIENvbnRlbnQtTGVuZ3RoAEludmFsaWQgY2hhciBpbiB1cmwgcGF0aABDb250ZW50LUxlbmd0aCBjYW4ndCBiZSBwcmVzZW50IHdpdGggVHJhbnNmZXItRW5jb2RpbmcASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgc2l6ZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2hlYWRlcl92YWx1ZQBNaXNzaW5nIGV4cGVjdGVkIExGIGFmdGVyIGhlYWRlciB2YWx1ZQBQYXVzZWQgYnkgb25faGVhZGVyc19jb21wbGV0ZQBJbnZhbGlkIEVPRiBzdGF0ZQBvbl9jaHVua19oZWFkZXIgcGF1c2UAb25fbWVzc2FnZV9iZWdpbiBwYXVzZQBvbl9jaHVua19jb21wbGV0ZSBwYXVzZQBvbl9tZXNzYWdlX2NvbXBsZXRlIHBhdXNlAFBhdXNlIG9uIENPTk5FQ1QvVXBncmFkZQBQYXVzZSBvbiBQUkkvVXBncmFkZQBFeHBlY3RlZCBIVFRQLzIgQ29ubmVjdGlvbiBQcmVmYWNlAEV4cGVjdGVkIHNwYWNlIGFmdGVyIG1ldGhvZABTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2hlYWRlcl9maWVsZABQYXVzZWQASW52YWxpZCB3b3JkIGVuY291bnRlcmVkAEludmFsaWQgbWV0aG9kIGVuY291bnRlcmVkAFVuZXhwZWN0ZWQgY2hhciBpbiB1cmwgc2NoZW1hAFJlcXVlc3QgaGFzIGludmFsaWQgYFRyYW5zZmVyLUVuY29kaW5nYABNS0FDVElWSVRZAENPUFkATk9USUZZAFBMQVkAUFVUAENIRUNLT1VUAFBPU1QAUkVQT1JUAEhQRV9JTlZBTElEX0NPTlNUQU5UAEdFVABIUEVfU1RSSUNUAFJFRElSRUNUAENPTk5FQ1QASFBFX0lOVkFMSURfU1RBVFVTAE9QVElPTlMAU0VUX1BBUkFNRVRFUgBHRVRfUEFSQU1FVEVSAEhQRV9VU0VSAEhQRV9DQl9DSFVOS19IRUFERVIATUtDQUxFTkRBUgBTRVRVUABURUFSRE9XTgBIUEVfQ0xPU0VEX0NPTk5FQ1RJT04ASFBFX0lOVkFMSURfVkVSU0lPTgBIUEVfQ0JfTUVTU0FHRV9CRUdJTgBIUEVfSU5WQUxJRF9IRUFERVJfVE9LRU4ASFBFX0lOVkFMSURfVVJMAE1LQ09MAEFDTABIUEVfSU5URVJOQUwASFBFX09LAFVOTElOSwBVTkxPQ0sAUFJJAEhQRV9JTlZBTElEX0NPTlRFTlRfTEVOR1RIAEhQRV9VTkVYUEVDVEVEX0NPTlRFTlRfTEVOR1RIAEZMVVNIAFBS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bmdwZ3JhZGUNCg0KDQpTTQ0KDQpUVFAvQ0UvVFNQLwAAAAAAAAAAAAAAAAECAAEDAAAAAAAAAAAAAAAAAAAAAAAABAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAABAgABAwAAAAAAAAAAAAAAAAAAAAAAAAQBAQUBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAQAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAABAAACAAAAAAAAAAAAAAAAAAAAAAAAAwQAAAQEBAQEBAQEBAQEBQQEBAQEBAQEBAQEBAAEAAYHBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQABAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAQAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAEAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAgAAAAACAAAAAAAAAAAAAAAAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE5PVU5DRUVDS09VVE5FQ1RFVEVDUklCRUxVU0hFVEVBRFNFQVJDSFJHRUNUSVZJVFlMRU5EQVJWRU9USUZZUFRJT05TQ0hTRUFZU1RBVENIR0VPUkRJUkVDVE9SVFJDSFBBUkFNRVRFUlVSQ0VCU0NSSUJFQVJET1dOQUNFSU5ETktDS1VCU0NSSUJFSFRUUC9BRFRQLw=='
diff --git a/node_modules/undici/lib/llhttp/utils.d.ts b/node_modules/undici/lib/llhttp/utils.d.ts
deleted file mode 100644
index 15497f3..0000000
--- a/node_modules/undici/lib/llhttp/utils.d.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export interface IEnumMap {
- [key: string]: number;
-}
-export declare function enumToMap(obj: any): IEnumMap;
diff --git a/node_modules/undici/lib/llhttp/utils.js b/node_modules/undici/lib/llhttp/utils.js
deleted file mode 100644
index 8a32e56..0000000
--- a/node_modules/undici/lib/llhttp/utils.js
+++ /dev/null
@@ -1,15 +0,0 @@
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.enumToMap = void 0;
-function enumToMap(obj) {
- const res = {};
- Object.keys(obj).forEach((key) => {
- const value = obj[key];
- if (typeof value === 'number') {
- res[key] = value;
- }
- });
- return res;
-}
-exports.enumToMap = enumToMap;
-//# sourceMappingURL=utils.js.map
\ No newline at end of file
diff --git a/node_modules/undici/lib/llhttp/utils.js.map b/node_modules/undici/lib/llhttp/utils.js.map
deleted file mode 100644
index 2d7c356..0000000
--- a/node_modules/undici/lib/llhttp/utils.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/llhttp/utils.ts"],"names":[],"mappings":";;;AAIA,SAAgB,SAAS,CAAC,GAAQ;IAChC,MAAM,GAAG,GAAa,EAAE,CAAC;IAEzB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QAC/B,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QACvB,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;YAC7B,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;SAClB;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC;AAXD,8BAWC"}
\ No newline at end of file
diff --git a/node_modules/undici/lib/mock/mock-agent.js b/node_modules/undici/lib/mock/mock-agent.js
deleted file mode 100644
index 828e8af..0000000
--- a/node_modules/undici/lib/mock/mock-agent.js
+++ /dev/null
@@ -1,171 +0,0 @@
-'use strict'
-
-const { kClients } = require('../core/symbols')
-const Agent = require('../agent')
-const {
- kAgent,
- kMockAgentSet,
- kMockAgentGet,
- kDispatches,
- kIsMockActive,
- kNetConnect,
- kGetNetConnect,
- kOptions,
- kFactory
-} = require('./mock-symbols')
-const MockClient = require('./mock-client')
-const MockPool = require('./mock-pool')
-const { matchValue, buildMockOptions } = require('./mock-utils')
-const { InvalidArgumentError, UndiciError } = require('../core/errors')
-const Dispatcher = require('../dispatcher')
-const Pluralizer = require('./pluralizer')
-const PendingInterceptorsFormatter = require('./pending-interceptors-formatter')
-
-class FakeWeakRef {
- constructor (value) {
- this.value = value
- }
-
- deref () {
- return this.value
- }
-}
-
-class MockAgent extends Dispatcher {
- constructor (opts) {
- super(opts)
-
- this[kNetConnect] = true
- this[kIsMockActive] = true
-
- // Instantiate Agent and encapsulate
- if ((opts && opts.agent && typeof opts.agent.dispatch !== 'function')) {
- throw new InvalidArgumentError('Argument opts.agent must implement Agent')
- }
- const agent = opts && opts.agent ? opts.agent : new Agent(opts)
- this[kAgent] = agent
-
- this[kClients] = agent[kClients]
- this[kOptions] = buildMockOptions(opts)
- }
-
- get (origin) {
- let dispatcher = this[kMockAgentGet](origin)
-
- if (!dispatcher) {
- dispatcher = this[kFactory](origin)
- this[kMockAgentSet](origin, dispatcher)
- }
- return dispatcher
- }
-
- dispatch (opts, handler) {
- // Call MockAgent.get to perform additional setup before dispatching as normal
- this.get(opts.origin)
- return this[kAgent].dispatch(opts, handler)
- }
-
- async close () {
- await this[kAgent].close()
- this[kClients].clear()
- }
-
- deactivate () {
- this[kIsMockActive] = false
- }
-
- activate () {
- this[kIsMockActive] = true
- }
-
- enableNetConnect (matcher) {
- if (typeof matcher === 'string' || typeof matcher === 'function' || matcher instanceof RegExp) {
- if (Array.isArray(this[kNetConnect])) {
- this[kNetConnect].push(matcher)
- } else {
- this[kNetConnect] = [matcher]
- }
- } else if (typeof matcher === 'undefined') {
- this[kNetConnect] = true
- } else {
- throw new InvalidArgumentError('Unsupported matcher. Must be one of String|Function|RegExp.')
- }
- }
-
- disableNetConnect () {
- this[kNetConnect] = false
- }
-
- // This is required to bypass issues caused by using global symbols - see:
- // https://github.com/nodejs/undici/issues/1447
- get isMockActive () {
- return this[kIsMockActive]
- }
-
- [kMockAgentSet] (origin, dispatcher) {
- this[kClients].set(origin, new FakeWeakRef(dispatcher))
- }
-
- [kFactory] (origin) {
- const mockOptions = Object.assign({ agent: this }, this[kOptions])
- return this[kOptions] && this[kOptions].connections === 1
- ? new MockClient(origin, mockOptions)
- : new MockPool(origin, mockOptions)
- }
-
- [kMockAgentGet] (origin) {
- // First check if we can immediately find it
- const ref = this[kClients].get(origin)
- if (ref) {
- return ref.deref()
- }
-
- // If the origin is not a string create a dummy parent pool and return to user
- if (typeof origin !== 'string') {
- const dispatcher = this[kFactory]('http://localhost:9999')
- this[kMockAgentSet](origin, dispatcher)
- return dispatcher
- }
-
- // If we match, create a pool and assign the same dispatches
- for (const [keyMatcher, nonExplicitRef] of Array.from(this[kClients])) {
- const nonExplicitDispatcher = nonExplicitRef.deref()
- if (nonExplicitDispatcher && typeof keyMatcher !== 'string' && matchValue(keyMatcher, origin)) {
- const dispatcher = this[kFactory](origin)
- this[kMockAgentSet](origin, dispatcher)
- dispatcher[kDispatches] = nonExplicitDispatcher[kDispatches]
- return dispatcher
- }
- }
- }
-
- [kGetNetConnect] () {
- return this[kNetConnect]
- }
-
- pendingInterceptors () {
- const mockAgentClients = this[kClients]
-
- return Array.from(mockAgentClients.entries())
- .flatMap(([origin, scope]) => scope.deref()[kDispatches].map(dispatch => ({ ...dispatch, origin })))
- .filter(({ pending }) => pending)
- }
-
- assertNoPendingInterceptors ({ pendingInterceptorsFormatter = new PendingInterceptorsFormatter() } = {}) {
- const pending = this.pendingInterceptors()
-
- if (pending.length === 0) {
- return
- }
-
- const pluralizer = new Pluralizer('interceptor', 'interceptors').pluralize(pending.length)
-
- throw new UndiciError(`
-${pluralizer.count} ${pluralizer.noun} ${pluralizer.is} pending:
-
-${pendingInterceptorsFormatter.format(pending)}
-`.trim())
- }
-}
-
-module.exports = MockAgent
diff --git a/node_modules/undici/lib/mock/mock-client.js b/node_modules/undici/lib/mock/mock-client.js
deleted file mode 100644
index 5f31215..0000000
--- a/node_modules/undici/lib/mock/mock-client.js
+++ /dev/null
@@ -1,59 +0,0 @@
-'use strict'
-
-const { promisify } = require('util')
-const Client = require('../client')
-const { buildMockDispatch } = require('./mock-utils')
-const {
- kDispatches,
- kMockAgent,
- kClose,
- kOriginalClose,
- kOrigin,
- kOriginalDispatch,
- kConnected
-} = require('./mock-symbols')
-const { MockInterceptor } = require('./mock-interceptor')
-const Symbols = require('../core/symbols')
-const { InvalidArgumentError } = require('../core/errors')
-
-/**
- * MockClient provides an API that extends the Client to influence the mockDispatches.
- */
-class MockClient extends Client {
- constructor (origin, opts) {
- super(origin, opts)
-
- if (!opts || !opts.agent || typeof opts.agent.dispatch !== 'function') {
- throw new InvalidArgumentError('Argument opts.agent must implement Agent')
- }
-
- this[kMockAgent] = opts.agent
- this[kOrigin] = origin
- this[kDispatches] = []
- this[kConnected] = 1
- this[kOriginalDispatch] = this.dispatch
- this[kOriginalClose] = this.close.bind(this)
-
- this.dispatch = buildMockDispatch.call(this)
- this.close = this[kClose]
- }
-
- get [Symbols.kConnected] () {
- return this[kConnected]
- }
-
- /**
- * Sets up the base interceptor for mocking replies from undici.
- */
- intercept (opts) {
- return new MockInterceptor(opts, this[kDispatches])
- }
-
- async [kClose] () {
- await promisify(this[kOriginalClose])()
- this[kConnected] = 0
- this[kMockAgent][Symbols.kClients].delete(this[kOrigin])
- }
-}
-
-module.exports = MockClient
diff --git a/node_modules/undici/lib/mock/mock-errors.js b/node_modules/undici/lib/mock/mock-errors.js
deleted file mode 100644
index 5442c0e..0000000
--- a/node_modules/undici/lib/mock/mock-errors.js
+++ /dev/null
@@ -1,17 +0,0 @@
-'use strict'
-
-const { UndiciError } = require('../core/errors')
-
-class MockNotMatchedError extends UndiciError {
- constructor (message) {
- super(message)
- Error.captureStackTrace(this, MockNotMatchedError)
- this.name = 'MockNotMatchedError'
- this.message = message || 'The request does not match any registered mock dispatches'
- this.code = 'UND_MOCK_ERR_MOCK_NOT_MATCHED'
- }
-}
-
-module.exports = {
- MockNotMatchedError
-}
diff --git a/node_modules/undici/lib/mock/mock-interceptor.js b/node_modules/undici/lib/mock/mock-interceptor.js
deleted file mode 100644
index b51e6f2..0000000
--- a/node_modules/undici/lib/mock/mock-interceptor.js
+++ /dev/null
@@ -1,206 +0,0 @@
-'use strict'
-
-const { getResponseData, buildKey, addMockDispatch } = require('./mock-utils')
-const {
- kDispatches,
- kDispatchKey,
- kDefaultHeaders,
- kDefaultTrailers,
- kContentLength,
- kMockDispatch
-} = require('./mock-symbols')
-const { InvalidArgumentError } = require('../core/errors')
-const { buildURL } = require('../core/util')
-
-/**
- * Defines the scope API for an interceptor reply
- */
-class MockScope {
- constructor (mockDispatch) {
- this[kMockDispatch] = mockDispatch
- }
-
- /**
- * Delay a reply by a set amount in ms.
- */
- delay (waitInMs) {
- if (typeof waitInMs !== 'number' || !Number.isInteger(waitInMs) || waitInMs <= 0) {
- throw new InvalidArgumentError('waitInMs must be a valid integer > 0')
- }
-
- this[kMockDispatch].delay = waitInMs
- return this
- }
-
- /**
- * For a defined reply, never mark as consumed.
- */
- persist () {
- this[kMockDispatch].persist = true
- return this
- }
-
- /**
- * Allow one to define a reply for a set amount of matching requests.
- */
- times (repeatTimes) {
- if (typeof repeatTimes !== 'number' || !Number.isInteger(repeatTimes) || repeatTimes <= 0) {
- throw new InvalidArgumentError('repeatTimes must be a valid integer > 0')
- }
-
- this[kMockDispatch].times = repeatTimes
- return this
- }
-}
-
-/**
- * Defines an interceptor for a Mock
- */
-class MockInterceptor {
- constructor (opts, mockDispatches) {
- if (typeof opts !== 'object') {
- throw new InvalidArgumentError('opts must be an object')
- }
- if (typeof opts.path === 'undefined') {
- throw new InvalidArgumentError('opts.path must be defined')
- }
- if (typeof opts.method === 'undefined') {
- opts.method = 'GET'
- }
- // See https://github.com/nodejs/undici/issues/1245
- // As per RFC 3986, clients are not supposed to send URI
- // fragments to servers when they retrieve a document,
- if (typeof opts.path === 'string') {
- if (opts.query) {
- opts.path = buildURL(opts.path, opts.query)
- } else {
- // Matches https://github.com/nodejs/undici/blob/main/lib/fetch/index.js#L1811
- const parsedURL = new URL(opts.path, 'data://')
- opts.path = parsedURL.pathname + parsedURL.search
- }
- }
- if (typeof opts.method === 'string') {
- opts.method = opts.method.toUpperCase()
- }
-
- this[kDispatchKey] = buildKey(opts)
- this[kDispatches] = mockDispatches
- this[kDefaultHeaders] = {}
- this[kDefaultTrailers] = {}
- this[kContentLength] = false
- }
-
- createMockScopeDispatchData (statusCode, data, responseOptions = {}) {
- const responseData = getResponseData(data)
- const contentLength = this[kContentLength] ? { 'content-length': responseData.length } : {}
- const headers = { ...this[kDefaultHeaders], ...contentLength, ...responseOptions.headers }
- const trailers = { ...this[kDefaultTrailers], ...responseOptions.trailers }
-
- return { statusCode, data, headers, trailers }
- }
-
- validateReplyParameters (statusCode, data, responseOptions) {
- if (typeof statusCode === 'undefined') {
- throw new InvalidArgumentError('statusCode must be defined')
- }
- if (typeof data === 'undefined') {
- throw new InvalidArgumentError('data must be defined')
- }
- if (typeof responseOptions !== 'object') {
- throw new InvalidArgumentError('responseOptions must be an object')
- }
- }
-
- /**
- * Mock an undici request with a defined reply.
- */
- reply (replyData) {
- // Values of reply aren't available right now as they
- // can only be available when the reply callback is invoked.
- if (typeof replyData === 'function') {
- // We'll first wrap the provided callback in another function,
- // this function will properly resolve the data from the callback
- // when invoked.
- const wrappedDefaultsCallback = (opts) => {
- // Our reply options callback contains the parameter for statusCode, data and options.
- const resolvedData = replyData(opts)
-
- // Check if it is in the right format
- if (typeof resolvedData !== 'object') {
- throw new InvalidArgumentError('reply options callback must return an object')
- }
-
- const { statusCode, data, responseOptions = {} } = resolvedData
- this.validateReplyParameters(statusCode, data, responseOptions)
- // Since the values can be obtained immediately we return them
- // from this higher order function that will be resolved later.
- return {
- ...this.createMockScopeDispatchData(statusCode, data, responseOptions)
- }
- }
-
- // Add usual dispatch data, but this time set the data parameter to function that will eventually provide data.
- const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], wrappedDefaultsCallback)
- return new MockScope(newMockDispatch)
- }
-
- // We can have either one or three parameters, if we get here,
- // we should have 2-3 parameters. So we spread the arguments of
- // this function to obtain the parameters, since replyData will always
- // just be the statusCode.
- const [statusCode, data, responseOptions = {}] = [...arguments]
- this.validateReplyParameters(statusCode, data, responseOptions)
-
- // Send in-already provided data like usual
- const dispatchData = this.createMockScopeDispatchData(statusCode, data, responseOptions)
- const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], dispatchData)
- return new MockScope(newMockDispatch)
- }
-
- /**
- * Mock an undici request with a defined error.
- */
- replyWithError (error) {
- if (typeof error === 'undefined') {
- throw new InvalidArgumentError('error must be defined')
- }
-
- const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], { error })
- return new MockScope(newMockDispatch)
- }
-
- /**
- * Set default reply headers on the interceptor for subsequent replies
- */
- defaultReplyHeaders (headers) {
- if (typeof headers === 'undefined') {
- throw new InvalidArgumentError('headers must be defined')
- }
-
- this[kDefaultHeaders] = headers
- return this
- }
-
- /**
- * Set default reply trailers on the interceptor for subsequent replies
- */
- defaultReplyTrailers (trailers) {
- if (typeof trailers === 'undefined') {
- throw new InvalidArgumentError('trailers must be defined')
- }
-
- this[kDefaultTrailers] = trailers
- return this
- }
-
- /**
- * Set reply content length header for replies on the interceptor
- */
- replyContentLength () {
- this[kContentLength] = true
- return this
- }
-}
-
-module.exports.MockInterceptor = MockInterceptor
-module.exports.MockScope = MockScope
diff --git a/node_modules/undici/lib/mock/mock-pool.js b/node_modules/undici/lib/mock/mock-pool.js
deleted file mode 100644
index 0a3a7cd..0000000
--- a/node_modules/undici/lib/mock/mock-pool.js
+++ /dev/null
@@ -1,59 +0,0 @@
-'use strict'
-
-const { promisify } = require('util')
-const Pool = require('../pool')
-const { buildMockDispatch } = require('./mock-utils')
-const {
- kDispatches,
- kMockAgent,
- kClose,
- kOriginalClose,
- kOrigin,
- kOriginalDispatch,
- kConnected
-} = require('./mock-symbols')
-const { MockInterceptor } = require('./mock-interceptor')
-const Symbols = require('../core/symbols')
-const { InvalidArgumentError } = require('../core/errors')
-
-/**
- * MockPool provides an API that extends the Pool to influence the mockDispatches.
- */
-class MockPool extends Pool {
- constructor (origin, opts) {
- super(origin, opts)
-
- if (!opts || !opts.agent || typeof opts.agent.dispatch !== 'function') {
- throw new InvalidArgumentError('Argument opts.agent must implement Agent')
- }
-
- this[kMockAgent] = opts.agent
- this[kOrigin] = origin
- this[kDispatches] = []
- this[kConnected] = 1
- this[kOriginalDispatch] = this.dispatch
- this[kOriginalClose] = this.close.bind(this)
-
- this.dispatch = buildMockDispatch.call(this)
- this.close = this[kClose]
- }
-
- get [Symbols.kConnected] () {
- return this[kConnected]
- }
-
- /**
- * Sets up the base interceptor for mocking replies from undici.
- */
- intercept (opts) {
- return new MockInterceptor(opts, this[kDispatches])
- }
-
- async [kClose] () {
- await promisify(this[kOriginalClose])()
- this[kConnected] = 0
- this[kMockAgent][Symbols.kClients].delete(this[kOrigin])
- }
-}
-
-module.exports = MockPool
diff --git a/node_modules/undici/lib/mock/mock-symbols.js b/node_modules/undici/lib/mock/mock-symbols.js
deleted file mode 100644
index 8c4cbb6..0000000
--- a/node_modules/undici/lib/mock/mock-symbols.js
+++ /dev/null
@@ -1,23 +0,0 @@
-'use strict'
-
-module.exports = {
- kAgent: Symbol('agent'),
- kOptions: Symbol('options'),
- kFactory: Symbol('factory'),
- kDispatches: Symbol('dispatches'),
- kDispatchKey: Symbol('dispatch key'),
- kDefaultHeaders: Symbol('default headers'),
- kDefaultTrailers: Symbol('default trailers'),
- kContentLength: Symbol('content length'),
- kMockAgent: Symbol('mock agent'),
- kMockAgentSet: Symbol('mock agent set'),
- kMockAgentGet: Symbol('mock agent get'),
- kMockDispatch: Symbol('mock dispatch'),
- kClose: Symbol('close'),
- kOriginalClose: Symbol('original agent close'),
- kOrigin: Symbol('origin'),
- kIsMockActive: Symbol('is mock active'),
- kNetConnect: Symbol('net connect'),
- kGetNetConnect: Symbol('get net connect'),
- kConnected: Symbol('connected')
-}
diff --git a/node_modules/undici/lib/mock/mock-utils.js b/node_modules/undici/lib/mock/mock-utils.js
deleted file mode 100644
index 14bfcb1..0000000
--- a/node_modules/undici/lib/mock/mock-utils.js
+++ /dev/null
@@ -1,364 +0,0 @@
-'use strict'
-
-const { MockNotMatchedError } = require('./mock-errors')
-const {
- kDispatches,
- kMockAgent,
- kOriginalDispatch,
- kOrigin,
- kGetNetConnect
-} = require('./mock-symbols')
-const { buildURL } = require('../core/util')
-
-function matchValue (match, value) {
- if (typeof match === 'string') {
- return match === value
- }
- if (match instanceof RegExp) {
- return match.test(value)
- }
- if (typeof match === 'function') {
- return match(value) === true
- }
- return false
-}
-
-function lowerCaseEntries (headers) {
- return Object.fromEntries(
- Object.entries(headers).map(([headerName, headerValue]) => {
- return [headerName.toLocaleLowerCase(), headerValue]
- })
- )
-}
-
-/**
- * @param {import('../../index').Headers|string[]|Record} headers
- * @param {string} key
- */
-function getHeaderByName (headers, key) {
- if (Array.isArray(headers)) {
- for (let i = 0; i < headers.length; i += 2) {
- if (headers[i] === key) {
- return headers[i + 1]
- }
- }
-
- return undefined
- } else if (typeof headers.get === 'function') {
- return headers.get(key)
- } else {
- return headers[key]
- }
-}
-
-function matchHeaders (mockDispatch, headers) {
- if (typeof mockDispatch.headers === 'function') {
- if (Array.isArray(headers)) { // fetch HeadersList
- const clone = headers.slice()
- const entries = []
- for (let index = 0; index < clone.length; index += 2) {
- entries.push([clone[index], clone[index + 1]])
- }
- headers = Object.fromEntries(entries)
- }
- return mockDispatch.headers(headers ? lowerCaseEntries(headers) : {})
- }
- if (typeof mockDispatch.headers === 'undefined') {
- return true
- }
- if (typeof headers !== 'object' || typeof mockDispatch.headers !== 'object') {
- return false
- }
-
- for (const [matchHeaderName, matchHeaderValue] of Object.entries(mockDispatch.headers)) {
- const headerValue = getHeaderByName(headers, matchHeaderName)
-
- if (!matchValue(matchHeaderValue, headerValue)) {
- return false
- }
- }
- return true
-}
-
-function matchKey (mockDispatch, { path, method, body, headers }) {
- const pathMatch = matchValue(mockDispatch.path, path)
- const methodMatch = matchValue(mockDispatch.method, method)
- const bodyMatch = typeof mockDispatch.body !== 'undefined' ? matchValue(mockDispatch.body, body) : true
- const headersMatch = matchHeaders(mockDispatch, headers)
- return pathMatch && methodMatch && bodyMatch && headersMatch
-}
-
-function getResponseData (data) {
- if (Buffer.isBuffer(data)) {
- return data
- } else if (typeof data === 'object') {
- return JSON.stringify(data)
- } else {
- return data.toString()
- }
-}
-
-function getMockDispatch (mockDispatches, key) {
- const resolvedPath = key.query ? buildURL(key.path, key.query) : key.path
-
- // Match path
- let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path }) => matchValue(path, resolvedPath))
- if (matchedMockDispatches.length === 0) {
- throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`)
- }
-
- // Match method
- matchedMockDispatches = matchedMockDispatches.filter(({ method }) => matchValue(method, key.method))
- if (matchedMockDispatches.length === 0) {
- throw new MockNotMatchedError(`Mock dispatch not matched for method '${key.method}'`)
- }
-
- // Match body
- matchedMockDispatches = matchedMockDispatches.filter(({ body }) => typeof body !== 'undefined' ? matchValue(body, key.body) : true)
- if (matchedMockDispatches.length === 0) {
- throw new MockNotMatchedError(`Mock dispatch not matched for body '${key.body}'`)
- }
-
- // Match headers
- matchedMockDispatches = matchedMockDispatches.filter((mockDispatch) => matchHeaders(mockDispatch, key.headers))
- if (matchedMockDispatches.length === 0) {
- throw new MockNotMatchedError(`Mock dispatch not matched for headers '${typeof key.headers === 'object' ? JSON.stringify(key.headers) : key.headers}'`)
- }
-
- return matchedMockDispatches[0]
-}
-
-function addMockDispatch (mockDispatches, key, data) {
- const baseData = { timesInvoked: 0, times: 1, persist: false, consumed: false }
- const replyData = typeof data === 'function' ? { callback: data } : { ...data }
- const newMockDispatch = { ...baseData, ...key, pending: true, data: { error: null, ...replyData } }
- mockDispatches.push(newMockDispatch)
- return newMockDispatch
-}
-
-function deleteMockDispatch (mockDispatches, key) {
- const index = mockDispatches.findIndex(dispatch => {
- if (!dispatch.consumed) {
- return false
- }
- return matchKey(dispatch, key)
- })
- if (index !== -1) {
- mockDispatches.splice(index, 1)
- }
-}
-
-function buildKey (opts) {
- const { path, method, body, headers, query } = opts
- return {
- path,
- method,
- body,
- headers,
- query
- }
-}
-
-function generateKeyValues (data) {
- return Object.entries(data).reduce((keyValuePairs, [key, value]) => [...keyValuePairs, key, value], [])
-}
-
-/**
- * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
- * @param {number} statusCode
- */
-function getStatusText (statusCode) {
- switch (statusCode) {
- case 100: return 'Continue'
- case 101: return 'Switching Protocols'
- case 102: return 'Processing'
- case 103: return 'Early Hints'
- case 200: return 'OK'
- case 201: return 'Created'
- case 202: return 'Accepted'
- case 203: return 'Non-Authoritative Information'
- case 204: return 'No Content'
- case 205: return 'Reset Content'
- case 206: return 'Partial Content'
- case 207: return 'Multi-Status'
- case 208: return 'Already Reported'
- case 226: return 'IM Used'
- case 300: return 'Multiple Choice'
- case 301: return 'Moved Permanently'
- case 302: return 'Found'
- case 303: return 'See Other'
- case 304: return 'Not Modified'
- case 305: return 'Use Proxy'
- case 306: return 'unused'
- case 307: return 'Temporary Redirect'
- case 308: return 'Permanent Redirect'
- case 400: return 'Bad Request'
- case 401: return 'Unauthorized'
- case 402: return 'Payment Required'
- case 403: return 'Forbidden'
- case 404: return 'Not Found'
- case 405: return 'Method Not Allowed'
- case 406: return 'Not Acceptable'
- case 407: return 'Proxy Authentication Required'
- case 408: return 'Request Timeout'
- case 409: return 'Conflict'
- case 410: return 'Gone'
- case 411: return 'Length Required'
- case 412: return 'Precondition Failed'
- case 413: return 'Payload Too Large'
- case 414: return 'URI Too Large'
- case 415: return 'Unsupported Media Type'
- case 416: return 'Range Not Satisfiable'
- case 417: return 'Expectation Failed'
- case 418: return 'I\'m a teapot'
- case 421: return 'Misdirected Request'
- case 422: return 'Unprocessable Entity'
- case 423: return 'Locked'
- case 424: return 'Failed Dependency'
- case 425: return 'Too Early'
- case 426: return 'Upgrade Required'
- case 428: return 'Precondition Required'
- case 429: return 'Too Many Requests'
- case 431: return 'Request Header Fields Too Large'
- case 451: return 'Unavailable For Legal Reasons'
- case 500: return 'Internal Server Error'
- case 501: return 'Not Implemented'
- case 502: return 'Bad Gateway'
- case 503: return 'Service Unavailable'
- case 504: return 'Gateway Timeout'
- case 505: return 'HTTP Version Not Supported'
- case 506: return 'Variant Also Negotiates'
- case 507: return 'Insufficient Storage'
- case 508: return 'Loop Detected'
- case 510: return 'Not Extended'
- case 511: return 'Network Authentication Required'
- default: return 'unknown'
- }
-}
-
-async function getResponse (body) {
- const buffers = []
- for await (const data of body) {
- buffers.push(data)
- }
- return Buffer.concat(buffers).toString('utf8')
-}
-
-/**
- * Mock dispatch function used to simulate undici dispatches
- */
-function mockDispatch (opts, handler) {
- // Get mock dispatch from built key
- const key = buildKey(opts)
- const mockDispatch = getMockDispatch(this[kDispatches], key)
-
- mockDispatch.timesInvoked++
-
- // Here's where we resolve a callback if a callback is present for the dispatch data.
- if (mockDispatch.data.callback) {
- mockDispatch.data = { ...mockDispatch.data, ...mockDispatch.data.callback(opts) }
- }
-
- // Parse mockDispatch data
- const { data: { statusCode, data, headers, trailers, error }, delay, persist } = mockDispatch
- const { timesInvoked, times } = mockDispatch
-
- // If it's used up and not persistent, mark as consumed
- mockDispatch.consumed = !persist && timesInvoked >= times
- mockDispatch.pending = timesInvoked < times
-
- // If specified, trigger dispatch error
- if (error !== null) {
- deleteMockDispatch(this[kDispatches], key)
- handler.onError(error)
- return true
- }
-
- // Handle the request with a delay if necessary
- if (typeof delay === 'number' && delay > 0) {
- setTimeout(() => {
- handleReply(this[kDispatches])
- }, delay)
- } else {
- handleReply(this[kDispatches])
- }
-
- function handleReply (mockDispatches) {
- const responseData = getResponseData(typeof data === 'function' ? data(opts) : data)
- const responseHeaders = generateKeyValues(headers)
- const responseTrailers = generateKeyValues(trailers)
-
- handler.onHeaders(statusCode, responseHeaders, resume, getStatusText(statusCode))
- handler.onData(Buffer.from(responseData))
- handler.onComplete(responseTrailers)
- deleteMockDispatch(mockDispatches, key)
- }
-
- function resume () {}
-
- return true
-}
-
-function buildMockDispatch () {
- const agent = this[kMockAgent]
- const origin = this[kOrigin]
- const originalDispatch = this[kOriginalDispatch]
-
- return function dispatch (opts, handler) {
- if (agent.isMockActive) {
- try {
- mockDispatch.call(this, opts, handler)
- } catch (error) {
- if (error instanceof MockNotMatchedError) {
- const netConnect = agent[kGetNetConnect]()
- if (netConnect === false) {
- throw new MockNotMatchedError(`${error.message}: subsequent request to origin ${origin} was not allowed (net.connect disabled)`)
- }
- if (checkNetConnect(netConnect, origin)) {
- originalDispatch.call(this, opts, handler)
- } else {
- throw new MockNotMatchedError(`${error.message}: subsequent request to origin ${origin} was not allowed (net.connect is not enabled for this origin)`)
- }
- } else {
- throw error
- }
- }
- } else {
- originalDispatch.call(this, opts, handler)
- }
- }
-}
-
-function checkNetConnect (netConnect, origin) {
- const url = new URL(origin)
- if (netConnect === true) {
- return true
- } else if (Array.isArray(netConnect) && netConnect.some((matcher) => matchValue(matcher, url.host))) {
- return true
- }
- return false
-}
-
-function buildMockOptions (opts) {
- if (opts) {
- const { agent, ...mockOptions } = opts
- return mockOptions
- }
-}
-
-module.exports = {
- getResponseData,
- getMockDispatch,
- addMockDispatch,
- deleteMockDispatch,
- buildKey,
- generateKeyValues,
- matchValue,
- getResponse,
- getStatusText,
- mockDispatch,
- buildMockDispatch,
- checkNetConnect,
- buildMockOptions,
- getHeaderByName
-}
diff --git a/node_modules/undici/lib/mock/pending-interceptors-formatter.js b/node_modules/undici/lib/mock/pending-interceptors-formatter.js
deleted file mode 100644
index 1bc7539..0000000
--- a/node_modules/undici/lib/mock/pending-interceptors-formatter.js
+++ /dev/null
@@ -1,40 +0,0 @@
-'use strict'
-
-const { Transform } = require('stream')
-const { Console } = require('console')
-
-/**
- * Gets the output of `console.table(…)` as a string.
- */
-module.exports = class PendingInterceptorsFormatter {
- constructor ({ disableColors } = {}) {
- this.transform = new Transform({
- transform (chunk, _enc, cb) {
- cb(null, chunk)
- }
- })
-
- this.logger = new Console({
- stdout: this.transform,
- inspectOptions: {
- colors: !disableColors && !process.env.CI
- }
- })
- }
-
- format (pendingInterceptors) {
- const withPrettyHeaders = pendingInterceptors.map(
- ({ method, path, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
- Method: method,
- Origin: origin,
- Path: path,
- 'Status code': statusCode,
- Persistent: persist ? '✅' : '❌',
- Invocations: timesInvoked,
- Remaining: persist ? Infinity : times - timesInvoked
- }))
-
- this.logger.table(withPrettyHeaders)
- return this.transform.read().toString()
- }
-}
diff --git a/node_modules/undici/lib/mock/pluralizer.js b/node_modules/undici/lib/mock/pluralizer.js
deleted file mode 100644
index 47f150b..0000000
--- a/node_modules/undici/lib/mock/pluralizer.js
+++ /dev/null
@@ -1,29 +0,0 @@
-'use strict'
-
-const singulars = {
- pronoun: 'it',
- is: 'is',
- was: 'was',
- this: 'this'
-}
-
-const plurals = {
- pronoun: 'they',
- is: 'are',
- was: 'were',
- this: 'these'
-}
-
-module.exports = class Pluralizer {
- constructor (singular, plural) {
- this.singular = singular
- this.plural = plural
- }
-
- pluralize (count) {
- const one = count === 1
- const keys = one ? singulars : plurals
- const noun = one ? this.singular : this.plural
- return { ...keys, count, noun }
- }
-}
diff --git a/node_modules/undici/lib/node/fixed-queue.js b/node_modules/undici/lib/node/fixed-queue.js
deleted file mode 100644
index 3572681..0000000
--- a/node_modules/undici/lib/node/fixed-queue.js
+++ /dev/null
@@ -1,117 +0,0 @@
-/* eslint-disable */
-
-'use strict'
-
-// Extracted from node/lib/internal/fixed_queue.js
-
-// Currently optimal queue size, tested on V8 6.0 - 6.6. Must be power of two.
-const kSize = 2048;
-const kMask = kSize - 1;
-
-// The FixedQueue is implemented as a singly-linked list of fixed-size
-// circular buffers. It looks something like this:
-//
-// head tail
-// | |
-// v v
-// +-----------+ <-----\ +-----------+ <------\ +-----------+
-// | [null] | \----- | next | \------- | next |
-// +-----------+ +-----------+ +-----------+
-// | item | <-- bottom | item | <-- bottom | [empty] |
-// | item | | item | | [empty] |
-// | item | | item | | [empty] |
-// | item | | item | | [empty] |
-// | item | | item | bottom --> | item |
-// | item | | item | | item |
-// | ... | | ... | | ... |
-// | item | | item | | item |
-// | item | | item | | item |
-// | [empty] | <-- top | item | | item |
-// | [empty] | | item | | item |
-// | [empty] | | [empty] | <-- top top --> | [empty] |
-// +-----------+ +-----------+ +-----------+
-//
-// Or, if there is only one circular buffer, it looks something
-// like either of these:
-//
-// head tail head tail
-// | | | |
-// v v v v
-// +-----------+ +-----------+
-// | [null] | | [null] |
-// +-----------+ +-----------+
-// | [empty] | | item |
-// | [empty] | | item |
-// | item | <-- bottom top --> | [empty] |
-// | item | | [empty] |
-// | [empty] | <-- top bottom --> | item |
-// | [empty] | | item |
-// +-----------+ +-----------+
-//
-// Adding a value means moving `top` forward by one, removing means
-// moving `bottom` forward by one. After reaching the end, the queue
-// wraps around.
-//
-// When `top === bottom` the current queue is empty and when
-// `top + 1 === bottom` it's full. This wastes a single space of storage
-// but allows much quicker checks.
-
-class FixedCircularBuffer {
- constructor() {
- this.bottom = 0;
- this.top = 0;
- this.list = new Array(kSize);
- this.next = null;
- }
-
- isEmpty() {
- return this.top === this.bottom;
- }
-
- isFull() {
- return ((this.top + 1) & kMask) === this.bottom;
- }
-
- push(data) {
- this.list[this.top] = data;
- this.top = (this.top + 1) & kMask;
- }
-
- shift() {
- const nextItem = this.list[this.bottom];
- if (nextItem === undefined)
- return null;
- this.list[this.bottom] = undefined;
- this.bottom = (this.bottom + 1) & kMask;
- return nextItem;
- }
-}
-
-module.exports = class FixedQueue {
- constructor() {
- this.head = this.tail = new FixedCircularBuffer();
- }
-
- isEmpty() {
- return this.head.isEmpty();
- }
-
- push(data) {
- if (this.head.isFull()) {
- // Head is full: Creates a new queue, sets the old queue's `.next` to it,
- // and sets it as the new main queue.
- this.head = this.head.next = new FixedCircularBuffer();
- }
- this.head.push(data);
- }
-
- shift() {
- const tail = this.tail;
- const next = tail.shift();
- if (tail.isEmpty() && tail.next !== null) {
- // If there is another queue, it forms the new tail.
- this.tail = tail.next;
- }
- return next;
- }
-};
diff --git a/node_modules/undici/lib/pool-base.js b/node_modules/undici/lib/pool-base.js
deleted file mode 100644
index 2a909ee..0000000
--- a/node_modules/undici/lib/pool-base.js
+++ /dev/null
@@ -1,194 +0,0 @@
-'use strict'
-
-const DispatcherBase = require('./dispatcher-base')
-const FixedQueue = require('./node/fixed-queue')
-const { kConnected, kSize, kRunning, kPending, kQueued, kBusy, kFree, kUrl, kClose, kDestroy, kDispatch } = require('./core/symbols')
-const PoolStats = require('./pool-stats')
-
-const kClients = Symbol('clients')
-const kNeedDrain = Symbol('needDrain')
-const kQueue = Symbol('queue')
-const kClosedResolve = Symbol('closed resolve')
-const kOnDrain = Symbol('onDrain')
-const kOnConnect = Symbol('onConnect')
-const kOnDisconnect = Symbol('onDisconnect')
-const kOnConnectionError = Symbol('onConnectionError')
-const kGetDispatcher = Symbol('get dispatcher')
-const kAddClient = Symbol('add client')
-const kRemoveClient = Symbol('remove client')
-const kStats = Symbol('stats')
-
-class PoolBase extends DispatcherBase {
- constructor () {
- super()
-
- this[kQueue] = new FixedQueue()
- this[kClients] = []
- this[kQueued] = 0
-
- const pool = this
-
- this[kOnDrain] = function onDrain (origin, targets) {
- const queue = pool[kQueue]
-
- let needDrain = false
-
- while (!needDrain) {
- const item = queue.shift()
- if (!item) {
- break
- }
- pool[kQueued]--
- needDrain = !this.dispatch(item.opts, item.handler)
- }
-
- this[kNeedDrain] = needDrain
-
- if (!this[kNeedDrain] && pool[kNeedDrain]) {
- pool[kNeedDrain] = false
- pool.emit('drain', origin, [pool, ...targets])
- }
-
- if (pool[kClosedResolve] && queue.isEmpty()) {
- Promise
- .all(pool[kClients].map(c => c.close()))
- .then(pool[kClosedResolve])
- }
- }
-
- this[kOnConnect] = (origin, targets) => {
- pool.emit('connect', origin, [pool, ...targets])
- }
-
- this[kOnDisconnect] = (origin, targets, err) => {
- pool.emit('disconnect', origin, [pool, ...targets], err)
- }
-
- this[kOnConnectionError] = (origin, targets, err) => {
- pool.emit('connectionError', origin, [pool, ...targets], err)
- }
-
- this[kStats] = new PoolStats(this)
- }
-
- get [kBusy] () {
- return this[kNeedDrain]
- }
-
- get [kConnected] () {
- return this[kClients].filter(client => client[kConnected]).length
- }
-
- get [kFree] () {
- return this[kClients].filter(client => client[kConnected] && !client[kNeedDrain]).length
- }
-
- get [kPending] () {
- let ret = this[kQueued]
- for (const { [kPending]: pending } of this[kClients]) {
- ret += pending
- }
- return ret
- }
-
- get [kRunning] () {
- let ret = 0
- for (const { [kRunning]: running } of this[kClients]) {
- ret += running
- }
- return ret
- }
-
- get [kSize] () {
- let ret = this[kQueued]
- for (const { [kSize]: size } of this[kClients]) {
- ret += size
- }
- return ret
- }
-
- get stats () {
- return this[kStats]
- }
-
- async [kClose] () {
- if (this[kQueue].isEmpty()) {
- return Promise.all(this[kClients].map(c => c.close()))
- } else {
- return new Promise((resolve) => {
- this[kClosedResolve] = resolve
- })
- }
- }
-
- async [kDestroy] (err) {
- while (true) {
- const item = this[kQueue].shift()
- if (!item) {
- break
- }
- item.handler.onError(err)
- }
-
- return Promise.all(this[kClients].map(c => c.destroy(err)))
- }
-
- [kDispatch] (opts, handler) {
- const dispatcher = this[kGetDispatcher]()
-
- if (!dispatcher) {
- this[kNeedDrain] = true
- this[kQueue].push({ opts, handler })
- this[kQueued]++
- } else if (!dispatcher.dispatch(opts, handler)) {
- dispatcher[kNeedDrain] = true
- this[kNeedDrain] = !this[kGetDispatcher]()
- }
-
- return !this[kNeedDrain]
- }
-
- [kAddClient] (client) {
- client
- .on('drain', this[kOnDrain])
- .on('connect', this[kOnConnect])
- .on('disconnect', this[kOnDisconnect])
- .on('connectionError', this[kOnConnectionError])
-
- this[kClients].push(client)
-
- if (this[kNeedDrain]) {
- process.nextTick(() => {
- if (this[kNeedDrain]) {
- this[kOnDrain](client[kUrl], [this, client])
- }
- })
- }
-
- return this
- }
-
- [kRemoveClient] (client) {
- client.close(() => {
- const idx = this[kClients].indexOf(client)
- if (idx !== -1) {
- this[kClients].splice(idx, 1)
- }
- })
-
- this[kNeedDrain] = this[kClients].some(dispatcher => (
- !dispatcher[kNeedDrain] &&
- dispatcher.closed !== true &&
- dispatcher.destroyed !== true
- ))
- }
-}
-
-module.exports = {
- PoolBase,
- kClients,
- kNeedDrain,
- kAddClient,
- kRemoveClient,
- kGetDispatcher
-}
diff --git a/node_modules/undici/lib/pool-stats.js b/node_modules/undici/lib/pool-stats.js
deleted file mode 100644
index b4af8ae..0000000
--- a/node_modules/undici/lib/pool-stats.js
+++ /dev/null
@@ -1,34 +0,0 @@
-const { kFree, kConnected, kPending, kQueued, kRunning, kSize } = require('./core/symbols')
-const kPool = Symbol('pool')
-
-class PoolStats {
- constructor (pool) {
- this[kPool] = pool
- }
-
- get connected () {
- return this[kPool][kConnected]
- }
-
- get free () {
- return this[kPool][kFree]
- }
-
- get pending () {
- return this[kPool][kPending]
- }
-
- get queued () {
- return this[kPool][kQueued]
- }
-
- get running () {
- return this[kPool][kRunning]
- }
-
- get size () {
- return this[kPool][kSize]
- }
-}
-
-module.exports = PoolStats
diff --git a/node_modules/undici/lib/pool.js b/node_modules/undici/lib/pool.js
deleted file mode 100644
index 155dd36..0000000
--- a/node_modules/undici/lib/pool.js
+++ /dev/null
@@ -1,83 +0,0 @@
-'use strict'
-
-const {
- PoolBase,
- kClients,
- kNeedDrain,
- kAddClient,
- kGetDispatcher
-} = require('./pool-base')
-const Client = require('./client')
-const {
- InvalidArgumentError
-} = require('./core/errors')
-const util = require('./core/util')
-const { kUrl } = require('./core/symbols')
-const buildConnector = require('./core/connect')
-
-const kOptions = Symbol('options')
-const kConnections = Symbol('connections')
-const kFactory = Symbol('factory')
-
-function defaultFactory (origin, opts) {
- return new Client(origin, opts)
-}
-
-class Pool extends PoolBase {
- constructor (origin, {
- connections,
- factory = defaultFactory,
- connect,
- connectTimeout,
- tls,
- maxCachedSessions,
- socketPath,
- ...options
- } = {}) {
- super()
-
- if (connections != null && (!Number.isFinite(connections) || connections < 0)) {
- throw new InvalidArgumentError('invalid connections')
- }
-
- if (typeof factory !== 'function') {
- throw new InvalidArgumentError('factory must be a function.')
- }
-
- if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') {
- throw new InvalidArgumentError('connect must be a function or an object')
- }
-
- if (typeof connect !== 'function') {
- connect = buildConnector({
- ...tls,
- maxCachedSessions,
- socketPath,
- timeout: connectTimeout == null ? 10e3 : connectTimeout,
- ...connect
- })
- }
-
- this[kConnections] = connections || null
- this[kUrl] = util.parseOrigin(origin)
- this[kOptions] = { ...util.deepClone(options), connect }
- this[kFactory] = factory
- }
-
- [kGetDispatcher] () {
- let dispatcher = this[kClients].find(dispatcher => !dispatcher[kNeedDrain])
-
- if (dispatcher) {
- return dispatcher
- }
-
- if (!this[kConnections] || this[kClients].length < this[kConnections]) {
- dispatcher = this[kFactory](this[kUrl], this[kOptions])
- this[kAddClient](dispatcher)
- }
-
- return dispatcher
- }
-}
-
-module.exports = Pool
diff --git a/node_modules/undici/lib/proxy-agent.js b/node_modules/undici/lib/proxy-agent.js
deleted file mode 100644
index bfc75d7..0000000
--- a/node_modules/undici/lib/proxy-agent.js
+++ /dev/null
@@ -1,150 +0,0 @@
-'use strict'
-
-const { kClose, kDestroy } = require('./core/symbols')
-const Client = require('./agent')
-const Agent = require('./agent')
-const DispatcherBase = require('./dispatcher-base')
-const { InvalidArgumentError, RequestAbortedError } = require('./core/errors')
-const buildConnector = require('./core/connect')
-
-const kAgent = Symbol('proxy agent')
-const kClient = Symbol('proxy client')
-const kProxyHeaders = Symbol('proxy headers')
-const kRequestTls = Symbol('request tls settings')
-const kProxyTls = Symbol('proxy tls settings')
-const kConnectEndpoint = Symbol('connect endpoint function')
-
-function defaultProtocolPort (protocol) {
- return protocol === 'https:' ? 443 : 80
-}
-
-class ProxyAgent extends DispatcherBase {
- constructor (opts) {
- super(opts)
-
- if (typeof opts === 'string') {
- opts = { uri: opts }
- }
-
- if (!opts || !opts.uri) {
- throw new InvalidArgumentError('Proxy opts.uri is mandatory')
- }
-
- this[kRequestTls] = opts.requestTls
- this[kProxyTls] = opts.proxyTls
- this[kProxyHeaders] = {}
-
- if (opts.auth) {
- this[kProxyHeaders]['proxy-authorization'] = `Basic ${opts.auth}`
- }
-
- const { origin, port } = new URL(opts.uri)
-
- const connect = buildConnector({ ...opts.proxyTls })
- this[kConnectEndpoint] = buildConnector({ ...opts.requestTls })
- this[kClient] = new Client({ origin: opts.origin, connect })
- this[kAgent] = new Agent({
- ...opts,
- connect: async (opts, callback) => {
- let requestedHost = opts.host
- if (!opts.port) {
- requestedHost += `:${defaultProtocolPort(opts.protocol)}`
- }
- try {
- const { socket, statusCode } = await this[kClient].connect({
- origin,
- port,
- path: requestedHost,
- signal: opts.signal,
- headers: {
- ...this[kProxyHeaders],
- host: opts.host
- }
- })
- if (statusCode !== 200) {
- socket.on('error', () => {}).destroy()
- callback(new RequestAbortedError('Proxy response !== 200 when HTTP Tunneling'))
- }
- if (opts.protocol !== 'https:') {
- callback(null, socket)
- return
- }
- let servername
- if (this[kRequestTls]) {
- servername = this[kRequestTls].servername
- } else {
- servername = opts.servername
- }
- this[kConnectEndpoint]({ ...opts, servername, httpSocket: socket }, callback)
- } catch (err) {
- callback(err)
- }
- }
- })
- }
-
- dispatch (opts, handler) {
- const { host } = new URL(opts.origin)
- const headers = buildHeaders(opts.headers)
- throwIfProxyAuthIsSent(headers)
- return this[kAgent].dispatch(
- {
- ...opts,
- headers: {
- ...headers,
- host
- }
- },
- handler
- )
- }
-
- async [kClose] () {
- await this[kAgent].close()
- await this[kClient].close()
- }
-
- async [kDestroy] () {
- await this[kAgent].destroy()
- await this[kClient].destroy()
- }
-}
-
-/**
- * @param {string[] | Record} headers
- * @returns {Record}
- */
-function buildHeaders (headers) {
- // When using undici.fetch, the headers list is stored
- // as an array.
- if (Array.isArray(headers)) {
- /** @type {Record} */
- const headersPair = {}
-
- for (let i = 0; i < headers.length; i += 2) {
- headersPair[headers[i]] = headers[i + 1]
- }
-
- return headersPair
- }
-
- return headers
-}
-
-/**
- * @param {Record} headers
- *
- * Previous versions of ProxyAgent suggests the Proxy-Authorization in request headers
- * Nevertheless, it was changed and to avoid a security vulnerability by end users
- * this check was created.
- * It should be removed in the next major version for performance reasons
- */
-function throwIfProxyAuthIsSent (headers) {
- const existProxyAuth = headers && Object.keys(headers)
- .find((key) => key.toLowerCase() === 'proxy-authorization')
- if (existProxyAuth) {
- throw new InvalidArgumentError('Proxy-Authorization should be sent in ProxyAgent constructor')
- }
-}
-
-module.exports = ProxyAgent
diff --git a/node_modules/undici/package.json b/node_modules/undici/package.json
deleted file mode 100644
index 2bfb936..0000000
--- a/node_modules/undici/package.json
+++ /dev/null
@@ -1,125 +0,0 @@
-{
- "name": "undici",
- "version": "5.6.1",
- "description": "An HTTP/1.1 client, written from scratch for Node.js",
- "homepage": "https://undici.nodejs.org",
- "bugs": {
- "url": "https://github.com/nodejs/undici/issues"
- },
- "repository": {
- "type": "git",
- "url": "git+https://github.com/nodejs/undici.git"
- },
- "license": "MIT",
- "author": "Matteo Collina ",
- "contributors": [
- {
- "name": "Robert Nagy",
- "url": "https://github.com/ronag",
- "author": true
- }
- ],
- "keywords": [
- "fetch",
- "http",
- "https",
- "promise",
- "request",
- "curl",
- "wget",
- "xhr",
- "whatwg"
- ],
- "main": "index.js",
- "types": "index.d.ts",
- "files": [
- "*.d.ts",
- "index.js",
- "index-fetch.js",
- "lib",
- "types",
- "docs"
- ],
- "scripts": {
- "build:node": "npx esbuild@0.14.38 index-fetch.js --bundle --platform=node --outfile=undici-fetch.js",
- "prebuild:wasm": "docker build -t llhttp_wasm_builder -f build/Dockerfile .",
- "build:wasm": "node build/wasm.js --docker",
- "lint": "standard | snazzy",
- "lint:fix": "standard --fix | snazzy",
- "test": "npm run test:tap && npm run test:node-fetch && npm run test:fetch && npm run test:jest && tsd",
- "test:node-fetch": "node scripts/verifyVersion.js 16 || mocha test/node-fetch",
- "test:fetch": "node scripts/verifyVersion.js 16 || (npm run build:node && tap test/fetch/*.js && tap test/webidl/*.js)",
- "test:jest": "jest",
- "test:tap": "tap test/*.js test/diagnostics-channel/*.js",
- "test:tdd": "tap test/*.js test/diagnostics-channel/*.js -w",
- "test:typescript": "tsd",
- "coverage": "nyc --reporter=text --reporter=html npm run test",
- "coverage:ci": "nyc --reporter=lcov npm run test",
- "bench": "PORT=3042 concurrently -k -s first npm:bench:server npm:bench:run",
- "bench:server": "node benchmarks/server.js",
- "prebench:run": "node benchmarks/wait.js",
- "bench:run": "CONNECTIONS=1 node --experimental-wasm-simd benchmarks/benchmark.js; CONNECTIONS=50 node --experimental-wasm-simd benchmarks/benchmark.js",
- "serve:website": "docsify serve .",
- "prepare": "husky install",
- "fuzz": "jsfuzz test/fuzzing/fuzz.js corpus"
- },
- "devDependencies": {
- "@sinonjs/fake-timers": "^9.1.2",
- "@types/node": "^17.0.29",
- "abort-controller": "^3.0.0",
- "busboy": "^1.6.0",
- "chai": "^4.3.4",
- "chai-as-promised": "^7.1.1",
- "chai-iterator": "^3.0.2",
- "chai-string": "^1.5.0",
- "concurrently": "^7.1.0",
- "cronometro": "^1.0.5",
- "delay": "^5.0.0",
- "docsify-cli": "^4.4.3",
- "formdata-node": "^4.3.1",
- "https-pem": "^3.0.0",
- "husky": "^8.0.1",
- "import-fresh": "^3.3.0",
- "jest": "^28.0.1",
- "jsfuzz": "^1.0.15",
- "mocha": "^10.0.0",
- "p-timeout": "^3.2.0",
- "pre-commit": "^1.2.2",
- "proxy": "^1.0.2",
- "proxyquire": "^2.1.3",
- "semver": "^7.3.5",
- "sinon": "^14.0.0",
- "snazzy": "^9.0.0",
- "standard": "^17.0.0",
- "table": "^6.8.0",
- "tap": "^16.1.0",
- "tsd": "^0.22.0",
- "wait-on": "^6.0.0"
- },
- "engines": {
- "node": ">=12.18"
- },
- "standard": {
- "env": [
- "mocha"
- ],
- "ignore": [
- "lib/llhttp/constants.js",
- "lib/llhttp/utils.js"
- ]
- },
- "tsd": {
- "directory": "test/types",
- "compilerOptions": {
- "esModuleInterop": true,
- "lib": [
- "esnext"
- ]
- }
- },
- "jest": {
- "testMatch": [
- "/test/jest/**"
- ]
- }
-}
diff --git a/node_modules/undici/types/agent.d.ts b/node_modules/undici/types/agent.d.ts
deleted file mode 100644
index ebadc19..0000000
--- a/node_modules/undici/types/agent.d.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import { URL } from 'url'
-import Dispatcher = require('./dispatcher')
-import Pool = require('./pool')
-
-export = Agent
-
-declare class Agent extends Dispatcher{
- constructor(opts?: Agent.Options)
- /** `true` after `dispatcher.close()` has been called. */
- closed: boolean;
- /** `true` after `dispatcher.destroyed()` has been called or `dispatcher.close()` has been called and the dispatcher shutdown has completed. */
- destroyed: boolean;
- /** Dispatches a request. */
- dispatch(options: Agent.DispatchOptions, handler: Dispatcher.DispatchHandlers): boolean;
-}
-
-declare namespace Agent {
- export interface Options extends Pool.Options {
- /** Default: `(origin, opts) => new Pool(origin, opts)`. */
- factory?(origin: URL, opts: Object): Dispatcher;
- /** Integer. Default: `0` */
- maxRedirections?: number;
- }
-
- export interface DispatchOptions extends Dispatcher.DispatchOptions {
- /** Integer. */
- maxRedirections?: number;
- }
-}
diff --git a/node_modules/undici/types/api.d.ts b/node_modules/undici/types/api.d.ts
deleted file mode 100644
index 4bc3183..0000000
--- a/node_modules/undici/types/api.d.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import { URL, UrlObject } from 'url'
-import { Duplex } from 'stream'
-import Dispatcher = require('./dispatcher')
-
-export {
- request,
- stream,
- pipeline,
- connect,
- upgrade,
-}
-
-/** Performs an HTTP request. */
-declare function request(
- url: string | URL | UrlObject,
- options?: { dispatcher?: Dispatcher } & Omit & Partial>,
-): Promise;
-
-/** A faster version of `request`. */
-declare function stream(
- url: string | URL | UrlObject,
- options: { dispatcher?: Dispatcher } & Omit,
- factory: Dispatcher.StreamFactory
-): Promise;
-
-/** For easy use with `stream.pipeline`. */
-declare function pipeline(
- url: string | URL | UrlObject,
- options: { dispatcher?: Dispatcher } & Omit,
- handler: Dispatcher.PipelineHandler
-): Duplex;
-
-/** Starts two-way communications with the requested resource. */
-declare function connect(
- url: string | URL | UrlObject,
- options?: { dispatcher?: Dispatcher } & Omit
-): Promise;
-
-/** Upgrade to a different protocol. */
-declare function upgrade(
- url: string | URL | UrlObject,
- options?: { dispatcher?: Dispatcher } & Omit
-): Promise;
diff --git a/node_modules/undici/types/balanced-pool.d.ts b/node_modules/undici/types/balanced-pool.d.ts
deleted file mode 100644
index 5a765e1..0000000
--- a/node_modules/undici/types/balanced-pool.d.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import Client = require('./client')
-import Pool = require('./pool')
-import Dispatcher = require('./dispatcher')
-import { URL } from 'url'
-
-export = BalancedPool
-
-declare class BalancedPool extends Dispatcher {
- constructor(url: string | URL | string[], options?: Pool.Options);
-
- addUpstream(upstream: string): BalancedPool;
- removeUpstream(upstream: string): BalancedPool;
- upstreams: Array;
-
- /** `true` after `pool.close()` has been called. */
- closed: boolean;
- /** `true` after `pool.destroyed()` has been called or `pool.close()` has been called and the pool shutdown has completed. */
- destroyed: boolean;
-}
diff --git a/node_modules/undici/types/client.d.ts b/node_modules/undici/types/client.d.ts
deleted file mode 100644
index 22fcb42..0000000
--- a/node_modules/undici/types/client.d.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-import { URL } from 'url'
-import { TlsOptions } from 'tls'
-import Dispatcher = require('./dispatcher')
-import { DispatchOptions, RequestOptions } from './dispatcher'
-import buildConnector = require('./connector')
-
-export = Client
-
-/** A basic HTTP/1.1 client, mapped on top a single TCP/TLS connection. Pipelining is disabled by default. */
-declare class Client extends Dispatcher {
- constructor(url: string | URL, options?: Client.Options);
- /** Property to get and set the pipelining factor. */
- pipelining: number;
- /** `true` after `client.close()` has been called. */
- closed: boolean;
- /** `true` after `client.destroyed()` has been called or `client.close()` has been called and the client shutdown has completed. */
- destroyed: boolean;
-}
-
-declare namespace Client {
- export interface Options {
- /** the timeout after which a socket without active requests will time out. Monitors time between activity on a connected socket. This value may be overridden by *keep-alive* hints from the server. Default: `4e3` milliseconds (4s). */
- keepAliveTimeout?: number | null;
- /** the maximum allowed `idleTimeout` when overridden by *keep-alive* hints from the server. Default: `600e3` milliseconds (10min). */
- keepAliveMaxTimeout?: number | null;
- /** A number subtracted from server *keep-alive* hints when overriding `idleTimeout` to account for timing inaccuracies caused by e.g. transport latency. Default: `1e3` milliseconds (1s). */
- keepAliveTimeoutThreshold?: number | null;
- /** The amount of concurrent requests to be sent over the single TCP/TLS connection according to [RFC7230](https://tools.ietf.org/html/rfc7230#section-6.3.2). Default: `1`. */
- pipelining?: number | null;
- /** **/
- connect?: buildConnector.BuildOptions | Function | null;
- /** The maximum length of request headers in bytes. Default: `16384` (16KiB). */
- maxHeaderSize?: number | null;
- /** The timeout after which a request will time out, in milliseconds. Monitors time between receiving body data. Use `0` to disable it entirely. Default: `30e3` milliseconds (30s). */
- bodyTimeout?: number | null;
- /** The amount of time the parser will wait to receive the complete HTTP headers (Node 14 and above only). Default: `30e3` milliseconds (30s). */
- headersTimeout?: number | null;
- /** If `true`, an error is thrown when the request content-length header doesn't match the length of the request body. Default: `true`. */
- strictContentLength?: boolean;
- /** @deprecated use the connect option instead */
- tls?: TlsOptions | null;
- /** */
- maxRequestsPerClient?: number;
- }
-
- export interface SocketInfo {
- localAddress?: string
- localPort?: number
- remoteAddress?: string
- remotePort?: number
- remoteFamily?: string
- timeout?: number
- bytesWritten?: number
- bytesRead?: number
- }
-}
diff --git a/node_modules/undici/types/connector.d.ts b/node_modules/undici/types/connector.d.ts
deleted file mode 100644
index 38016b0..0000000
--- a/node_modules/undici/types/connector.d.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import {TLSSocket, ConnectionOptions} from 'tls'
-import {IpcNetConnectOpts, Socket, TcpNetConnectOpts} from 'net'
-
-export = buildConnector
-declare function buildConnector (options?: buildConnector.BuildOptions): typeof buildConnector.connector
-
-declare namespace buildConnector {
- export type BuildOptions = (ConnectionOptions | TcpNetConnectOpts | IpcNetConnectOpts) & {
- maxCachedSessions?: number | null;
- socketPath?: string | null;
- timeout?: number | null;
- port?: number;
- }
-
- export interface Options {
- hostname: string
- host?: string
- protocol: string
- port: number
- servername?: string
- }
-
- export type Callback = (err: Error | null, socket: Socket | TLSSocket | null) => void
-
- export function connector (options: buildConnector.Options, callback: buildConnector.Callback): Socket | TLSSocket;
-}
diff --git a/node_modules/undici/types/diagnostics-channel.d.ts b/node_modules/undici/types/diagnostics-channel.d.ts
deleted file mode 100644
index c613148..0000000
--- a/node_modules/undici/types/diagnostics-channel.d.ts
+++ /dev/null
@@ -1,67 +0,0 @@
-import { Socket } from "net";
-import { URL } from "url";
-import { connector } from "./connector";
-import { HttpMethod } from "./dispatcher";
-
-declare namespace DiagnosticsChannel {
- interface Request {
- origin?: string | URL;
- completed: boolean;
- method?: HttpMethod;
- path: string;
- headers: string;
- addHeader(key: string, value: string): Request;
- }
- interface Response {
- statusCode: number;
- statusText: string;
- headers: Array;
- }
- type Error = unknown;
- interface ConnectParams {
- host: URL["host"];
- hostname: URL["hostname"];
- protocol: URL["protocol"];
- port: URL["port"];
- servername: string | null;
- }
- type Connector = typeof connector;
- export interface RequestCreateMessage {
- request: Request;
- }
- export interface RequestBodySentMessage {
- request: Request;
- }
- export interface RequestHeadersMessage {
- request: Request;
- response: Response;
- }
- export interface RequestTrailersMessage {
- request: Request;
- trailers: Array;
- }
- export interface RequestErrorMessage {
- request: Request;
- error: Error;
- }
- export interface ClientSendHeadersMessage {
- request: Request;
- headers: string;
- socket: Socket;
- }
- export interface ClientBeforeConnectMessage {
- connectParams: ConnectParams;
- connector: Connector;
- }
- export interface ClientConnectedMessage {
- socket: Socket;
- connectParams: ConnectParams;
- connector: Connector;
- }
- export interface ClientConnectErrorMessage {
- error: Error;
- socket: Socket;
- connectParams: ConnectParams;
- connector: Connector;
- }
-}
diff --git a/node_modules/undici/types/dispatcher.d.ts b/node_modules/undici/types/dispatcher.d.ts
deleted file mode 100644
index 8744f04..0000000
--- a/node_modules/undici/types/dispatcher.d.ts
+++ /dev/null
@@ -1,175 +0,0 @@
-import { URL } from 'url'
-import { Duplex, Readable, Writable } from 'stream'
-import { EventEmitter } from 'events'
-import { IncomingHttpHeaders } from 'http'
-import { Blob } from 'buffer'
-import BodyReadable = require('./readable')
-import { FormData } from './formdata'
-
-type AbortSignal = unknown;
-
-export = Dispatcher;
-
-/** Dispatcher is the core API used to dispatch requests. */
-declare class Dispatcher extends EventEmitter {
- /** Dispatches a request. This API is expected to evolve through semver-major versions and is less stable than the preceding higher level APIs. It is primarily intended for library developers who implement higher level APIs on top of this. */
- dispatch(options: Dispatcher.DispatchOptions, handler: Dispatcher.DispatchHandlers): boolean;
- /** Starts two-way communications with the requested resource. */
- connect(options: Dispatcher.ConnectOptions): Promise;
- connect(options: Dispatcher.ConnectOptions, callback: (err: Error | null, data: Dispatcher.ConnectData) => void): void;
- /** Performs an HTTP request. */
- request(options: Dispatcher.RequestOptions): Promise;
- request(options: Dispatcher.RequestOptions, callback: (err: Error | null, data: Dispatcher.ResponseData) => void): void;
- /** For easy use with `stream.pipeline`. */
- pipeline(options: Dispatcher.PipelineOptions, handler: Dispatcher.PipelineHandler): Duplex;
- /** A faster version of `Dispatcher.request`. */
- stream(options: Dispatcher.RequestOptions, factory: Dispatcher.StreamFactory): Promise;
- stream(options: Dispatcher.RequestOptions, factory: Dispatcher.StreamFactory, callback: (err: Error | null, data: Dispatcher.StreamData) => void): void;
- /** Upgrade to a different protocol. */
- upgrade(options: Dispatcher.UpgradeOptions): Promise;
- upgrade(options: Dispatcher.UpgradeOptions, callback: (err: Error | null, data: Dispatcher.UpgradeData) => void): void;
- /** Closes the client and gracefully waits for enqueued requests to complete before invoking the callback (or returning a promise if no callback is provided). */
- close(): Promise;
- close(callback: () => void): void;
- /** Destroy the client abruptly with the given err. All the pending and running requests will be asynchronously aborted and error. Waits until socket is closed before invoking the callback (or returning a promise if no callback is provided). Since this operation is asynchronously dispatched there might still be some progress on dispatched requests. */
- destroy(): Promise;
- destroy(err: Error | null): Promise;
- destroy(callback: () => void): void;
- destroy(err: Error | null, callback: () => void): void;
-}
-
-declare namespace Dispatcher {
- export interface DispatchOptions {
- origin?: string | URL;
- path: string;
- method: HttpMethod;
- /** Default: `null` */
- body?: string | Buffer | Uint8Array | Readable | null | FormData;
- /** Default: `null` */
- headers?: IncomingHttpHeaders | string[] | null;
- /** Query string params to be embedded in the request URL. Default: `null` */
- query?: Record;
- /** Whether the requests can be safely retried or not. If `false` the request won't be sent until all preceding requests in the pipeline have completed. Default: `true` if `method` is `HEAD` or `GET`. */
- idempotent?: boolean;
- /** Upgrade the request. Should be used to specify the kind of upgrade i.e. `'Websocket'`. Default: `method === 'CONNECT' || null`. */
- upgrade?: boolean | string | null;
- /** The amount of time the parser will wait to receive the complete HTTP headers. Defaults to 30 seconds. */
- headersTimeout?: number | null;
- /** The timeout after which a request will time out, in milliseconds. Monitors time between receiving body data. Use 0 to disable it entirely. Defaults to 30 seconds. */
- bodyTimeout?: number | null;
- /** Whether Undici should throw an error upon receiving a 4xx or 5xx response from the server. Defaults to false */
- throwOnError?: boolean;
- }
- export interface ConnectOptions {
- path: string;
- /** Default: `null` */
- headers?: IncomingHttpHeaders | string[] | null;
- /** Default: `null` */
- signal?: AbortSignal | EventEmitter | null;
- /** This argument parameter is passed through to `ConnectData` */
- opaque?: unknown;
- /** Default: 0 */
- maxRedirections?: number;
- /** Default: `null` */
- responseHeader?: 'raw' | null;
- }
- export interface RequestOptions extends DispatchOptions {
- /** Default: `null` */
- opaque?: unknown;
- /** Default: `null` */
- signal?: AbortSignal | EventEmitter | null;
- /** Default: 0 */
- maxRedirections?: number;
- /** Default: `null` */
- onInfo?: (info: { statusCode: number, headers: Record }) => void;
- /** Default: `null` */
- responseHeader?: 'raw' | null;
- }
- export interface PipelineOptions extends RequestOptions {
- /** `true` if the `handler` will return an object stream. Default: `false` */
- objectMode?: boolean;
- }
- export interface UpgradeOptions {
- path: string;
- /** Default: `'GET'` */
- method?: string;
- /** Default: `null` */
- headers?: IncomingHttpHeaders | string[] | null;
- /** A string of comma separated protocols, in descending preference order. Default: `'Websocket'` */
- protocol?: string;
- /** Default: `null` */
- signal?: AbortSignal | EventEmitter | null;
- /** Default: 0 */
- maxRedirections?: number;
- /** Default: `null` */
- responseHeader?: 'raw' | null;
- }
- export interface ConnectData {
- statusCode: number;
- headers: IncomingHttpHeaders;
- socket: Duplex;
- opaque: unknown;
- }
- export interface ResponseData {
- statusCode: number;
- headers: IncomingHttpHeaders;
- body: BodyReadable & BodyMixin;
- trailers: Record;
- opaque: unknown;
- context: object;
- }
- export interface PipelineHandlerData {
- statusCode: number;
- headers: IncomingHttpHeaders;
- opaque: unknown;
- body: BodyReadable;
- context: object;
- }
- export interface StreamData {
- opaque: unknown;
- trailers: Record;
- }
- export interface UpgradeData {
- headers: IncomingHttpHeaders;
- socket: Duplex;
- opaque: unknown;
- }
- export interface StreamFactoryData {
- statusCode: number;
- headers: IncomingHttpHeaders;
- opaque: unknown;
- context: object;
- }
- export type StreamFactory = (data: StreamFactoryData) => Writable;
- export interface DispatchHandlers {
- /** Invoked before request is dispatched on socket. May be invoked multiple times when a request is retried when the request at the head of the pipeline fails. */
- onConnect?(abort: () => void): void;
- /** Invoked when an error has occurred. */
- onError?(err: Error): void;
- /** Invoked when request is upgraded either due to a `Upgrade` header or `CONNECT` method. */
- onUpgrade?(statusCode: number, headers: string[] | null, socket: Duplex): void;
- /** Invoked when statusCode and headers have been received. May be invoked multiple times due to 1xx informational headers. */
- onHeaders?(statusCode: number, headers: string[] | null, resume: () => void): boolean;
- /** Invoked when response payload data is received. */
- onData?(chunk: Buffer): boolean;
- /** Invoked when response payload and trailers have been received and the request has completed. */
- onComplete?(trailers: string[] | null): void;
- /** Invoked when a body chunk is sent to the server. May be invoked multiple times for chunked requests */
- onBodySent?(chunkSize: number, totalBytesSent: number): void;
- }
- export type PipelineHandler = (data: PipelineHandlerData) => Readable;
- export type HttpMethod = 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'CONNECT' | 'OPTIONS' | 'TRACE' | 'PATCH';
-
- /**
- * @link https://fetch.spec.whatwg.org/#body-mixin
- */
- interface BodyMixin {
- readonly body?: never; // throws on node v16.6.0
- readonly bodyUsed: boolean;
- arrayBuffer(): Promise;
- blob(): Promise;
- formData(): Promise;
- json(): Promise;
- text(): Promise;
- }
-}
diff --git a/node_modules/undici/types/errors.d.ts b/node_modules/undici/types/errors.d.ts
deleted file mode 100644
index ab0ecc8..0000000
--- a/node_modules/undici/types/errors.d.ts
+++ /dev/null
@@ -1,90 +0,0 @@
-import {IncomingHttpHeaders} from "http";
-
-export = Errors
-import { SocketInfo } from './client'
-
-declare namespace Errors {
- export class UndiciError extends Error { }
-
- /** A header exceeds the `headersTimeout` option. */
- export class HeadersTimeoutError extends UndiciError {
- name: 'HeadersTimeoutError';
- code: 'UND_ERR_HEADERS_TIMEOUT';
- }
-
- /** A body exceeds the `bodyTimeout` option. */
- export class BodyTimeoutError extends UndiciError {
- name: 'BodyTimeoutError';
- code: 'UND_ERR_BODY_TIMEOUT';
- }
-
- export class ResponseStatusCodeError extends UndiciError {
- name: 'ResponseStatusCodeError';
- code: 'UND_ERR_RESPONSE_STATUS_CODE';
- body: null | Record | string
- status: number
- statusCode: number
- headers: IncomingHttpHeaders | string[] | null;
- }
-
- /** A socket exceeds the `socketTimeout` option. */
- export class SocketTimeoutError extends UndiciError {
- name: 'SocketTimeoutError';
- code: 'UND_ERR_SOCKET_TIMEOUT';
- }
-
- /** Passed an invalid argument. */
- export class InvalidArgumentError extends UndiciError {
- name: 'InvalidArgumentError';
- code: 'UND_ERR_INVALID_ARG';
- }
-
- /** Returned an invalid value. */
- export class InvalidReturnError extends UndiciError {
- name: 'InvalidReturnError';
- code: 'UND_ERR_INVALID_RETURN_VALUE';
- }
-
- /** The request has been aborted by the user. */
- export class RequestAbortedError extends UndiciError {
- name: 'RequestAbortedError';
- code: 'UND_ERR_ABORTED';
- }
-
- /** Expected error with reason. */
- export class InformationalError extends UndiciError {
- name: 'InformationalError';
- code: 'UND_ERR_INFO';
- }
-
- /** Body does not match content-length header. */
- export class RequestContentLengthMismatchError extends UndiciError {
- name: 'RequestContentLengthMismatchError';
- code: 'UND_ERR_REQ_CONTENT_LENGTH_MISMATCH';
- }
-
- /** Trying to use a destroyed client. */
- export class ClientDestroyedError extends UndiciError {
- name: 'ClientDestroyedError';
- code: 'UND_ERR_DESTROYED';
- }
-
- /** Trying to use a closed client. */
- export class ClientClosedError extends UndiciError {
- name: 'ClientClosedError';
- code: 'UND_ERR_CLOSED';
- }
-
- /** There is an error with the socket. */
- export class SocketError extends UndiciError {
- name: 'SocketError';
- code: 'UND_ERR_SOCKET';
- socket: SocketInfo | null
- }
-
- /** Encountered unsupported functionality. */
- export class NotSupportedError extends UndiciError {
- name: 'NotSupportedError';
- code: 'UND_ERR_NOT_SUPPORTED';
- }
-}
diff --git a/node_modules/undici/types/fetch.d.ts b/node_modules/undici/types/fetch.d.ts
deleted file mode 100644
index 87980be..0000000
--- a/node_modules/undici/types/fetch.d.ts
+++ /dev/null
@@ -1,204 +0,0 @@
-// based on https://github.com/Ethan-Arrowood/undici-fetch/blob/249269714db874351589d2d364a0645d5160ae71/index.d.ts (MIT license)
-// and https://github.com/node-fetch/node-fetch/blob/914ce6be5ec67a8bab63d68510aabf07cb818b6d/index.d.ts (MIT license)
-///
-
-import { Blob } from 'buffer'
-import { URL, URLSearchParams } from 'url'
-import { ReadableStream } from 'stream/web'
-import { FormData } from './formdata'
-
-import Dispatcher = require('./dispatcher')
-
-export type RequestInfo = string | URL | Request
-
-export declare function fetch (
- input: RequestInfo,
- init?: RequestInit
-): Promise
-
-export type BodyInit =
- | ArrayBuffer
- | AsyncIterable
- | Blob
- | FormData
- | Iterable
- | NodeJS.ArrayBufferView
- | URLSearchParams
- | null
- | string
-
-export interface BodyMixin {
- readonly body: ReadableStream | null
- readonly bodyUsed: boolean
-
- readonly arrayBuffer: () => Promise
- readonly blob: () => Promise
- readonly formData: () => Promise
- readonly json: () => Promise
- readonly text: () => Promise
-}
-
-export interface SpecIterator {
- next(...args: [] | [TNext]): IteratorResult;
-}
-
-export interface SpecIterableIterator extends SpecIterator {
- [Symbol.iterator](): SpecIterableIterator;
-}
-
-export interface SpecIterable {
- [Symbol.iterator](): SpecIterator;
-}
-
-export type HeadersInit = string[][] | Record> | Headers
-
-export declare class Headers implements SpecIterable<[string, string]> {
- constructor (init?: HeadersInit)
- readonly append: (name: string, value: string) => void
- readonly delete: (name: string) => void
- readonly get: (name: string) => string | null
- readonly has: (name: string) => boolean
- readonly set: (name: string, value: string) => void
- readonly forEach: (
- callbackfn: (value: string, key: string, iterable: Headers) => void,
- thisArg?: unknown
- ) => void
-
- readonly keys: () => SpecIterableIterator
- readonly values: () => SpecIterableIterator
- readonly entries: () => SpecIterableIterator<[string, string]>
- readonly [Symbol.iterator]: () => SpecIterator<[string, string]>
-}
-
-export type RequestCache =
- | 'default'
- | 'force-cache'
- | 'no-cache'
- | 'no-store'
- | 'only-if-cached'
- | 'reload'
-
-export type RequestCredentials = 'omit' | 'include' | 'same-origin'
-
-type RequestDestination =
- | ''
- | 'audio'
- | 'audioworklet'
- | 'document'
- | 'embed'
- | 'font'
- | 'image'
- | 'manifest'
- | 'object'
- | 'paintworklet'
- | 'report'
- | 'script'
- | 'sharedworker'
- | 'style'
- | 'track'
- | 'video'
- | 'worker'
- | 'xslt'
-
-export interface RequestInit {
- method?: string
- keepalive?: boolean
- headers?: HeadersInit
- body?: BodyInit
- redirect?: RequestRedirect
- integrity?: string
- signal?: AbortSignal
- credentials?: RequestCredentials
- mode?: RequestMode
- referrer?: string
- referrerPolicy?: ReferrerPolicy
- window?: null
- dispatcher?: Dispatcher
-}
-
-export type ReferrerPolicy =
- | ''
- | 'no-referrer'
- | 'no-referrer-when-downgrade'
- | 'origin'
- | 'origin-when-cross-origin'
- | 'same-origin'
- | 'strict-origin'
- | 'strict-origin-when-cross-origin'
- | 'unsafe-url';
-
-export type RequestMode = 'cors' | 'navigate' | 'no-cors' | 'same-origin'
-
-export type RequestRedirect = 'error' | 'follow' | 'manual'
-
-export declare class Request implements BodyMixin {
- constructor (input: RequestInfo, init?: RequestInit)
-
- readonly cache: RequestCache
- readonly credentials: RequestCredentials
- readonly destination: RequestDestination
- readonly headers: Headers
- readonly integrity: string
- readonly method: string
- readonly mode: RequestMode
- readonly redirect: RequestRedirect
- readonly referrerPolicy: string
- readonly url: string
-
- readonly keepalive: boolean
- readonly signal: AbortSignal
-
- readonly body: ReadableStream | null
- readonly bodyUsed: boolean
-
- readonly arrayBuffer: () => Promise
- readonly blob: () => Promise
- readonly formData: () => Promise
- readonly json: () => Promise
- readonly text: () => Promise
-
- readonly clone: () => Request
-}
-
-export interface ResponseInit {
- readonly status?: number
- readonly statusText?: string
- readonly headers?: HeadersInit
-}
-
-export type ResponseType =
- | 'basic'
- | 'cors'
- | 'default'
- | 'error'
- | 'opaque'
- | 'opaqueredirect'
-
-export type ResponseRedirectStatus = 301 | 302 | 303 | 307 | 308
-
-export declare class Response implements BodyMixin {
- constructor (body?: BodyInit, init?: ResponseInit)
-
- readonly headers: Headers
- readonly ok: boolean
- readonly status: number
- readonly statusText: string
- readonly type: ResponseType
- readonly url: string
- readonly redirected: boolean
-
- readonly body: ReadableStream | null
- readonly bodyUsed: boolean
-
- readonly arrayBuffer: () => Promise
- readonly blob: () => Promise
- readonly formData: () => Promise
- readonly json: () => Promise
- readonly text: () => Promise
-
- readonly clone: () => Response
-
- static error (): Response
- static json(data: any, init?: ResponseInit): Response
- static redirect (url: string | URL, status: ResponseRedirectStatus): Response
-}
diff --git a/node_modules/undici/types/file.d.ts b/node_modules/undici/types/file.d.ts
deleted file mode 100644
index c695b7a..0000000
--- a/node_modules/undici/types/file.d.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-// Based on https://github.com/octet-stream/form-data/blob/2d0f0dc371517444ce1f22cdde13f51995d0953a/lib/File.ts (MIT)
-///
-
-import { Blob } from 'buffer'
-
-export interface BlobPropertyBag {
- type?: string
- endings?: 'native' | 'transparent'
-}
-
-export interface FilePropertyBag extends BlobPropertyBag {
- /**
- * The last modified date of the file as the number of milliseconds since the Unix epoch (January 1, 1970 at midnight). Files without a known last modified date return the current date.
- */
- lastModified?: number
-}
-
-export declare class File extends Blob {
- /**
- * Creates a new File instance.
- *
- * @param fileBits An `Array` strings, or [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer), [`ArrayBufferView`](https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView), [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) objects, or a mix of any of such objects, that will be put inside the [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File).
- * @param fileName The name of the file.
- * @param options An options object containing optional attributes for the file.
- */
- constructor(fileBits: ReadonlyArray, fileName: string, options?: FilePropertyBag)
-
- /**
- * Name of the file referenced by the File object.
- */
- readonly name: string
-
- /**
- * The last modified date of the file as the number of milliseconds since the Unix epoch (January 1, 1970 at midnight). Files without a known last modified date return the current date.
- */
- readonly lastModified: number
-
- readonly [Symbol.toStringTag]: string
-}
diff --git a/node_modules/undici/types/formdata.d.ts b/node_modules/undici/types/formdata.d.ts
deleted file mode 100644
index df29a57..0000000
--- a/node_modules/undici/types/formdata.d.ts
+++ /dev/null
@@ -1,108 +0,0 @@
-// Based on https://github.com/octet-stream/form-data/blob/2d0f0dc371517444ce1f22cdde13f51995d0953a/lib/FormData.ts (MIT)
-///
-
-import { File } from './file'
-import { SpecIterator, SpecIterableIterator } from './fetch'
-
-/**
- * A `string` or `File` that represents a single value from a set of `FormData` key-value pairs.
- */
-declare type FormDataEntryValue = string | File
-
-/**
- * Provides a way to easily construct a set of key/value pairs representing form fields and their values, which can then be easily sent using fetch().
- */
-export declare class FormData {
- /**
- * Appends a new value onto an existing key inside a FormData object,
- * or adds the key if it does not already exist.
- *
- * The difference between `set()` and `append()` is that if the specified key already exists, `set()` will overwrite all existing values with the new one, whereas `append()` will append the new value onto the end of the existing set of values.
- *
- * @param name The name of the field whose data is contained in `value`.
- * @param value The field's value. This can be [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob)
- or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File). If none of these are specified the value is converted to a string.
- * @param fileName The filename reported to the server, when a Blob or File is passed as the second parameter. The default filename for Blob objects is "blob". The default filename for File objects is the file's filename.
- */
- append(name: string, value: unknown, fileName?: string): void
-
- /**
- * Set a new value for an existing key inside FormData,
- * or add the new field if it does not already exist.
- *
- * @param name The name of the field whose data is contained in `value`.
- * @param value The field's value. This can be [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob)
- or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File). If none of these are specified the value is converted to a string.
- * @param fileName The filename reported to the server, when a Blob or File is passed as the second parameter. The default filename for Blob objects is "blob". The default filename for File objects is the file's filename.
- *
- */
- set(name: string, value: unknown, fileName?: string): void
-
- /**
- * Returns the first value associated with a given key from within a `FormData` object.
- * If you expect multiple values and want all of them, use the `getAll()` method instead.
- *
- * @param {string} name A name of the value you want to retrieve.
- *
- * @returns A `FormDataEntryValue` containing the value. If the key doesn't exist, the method returns null.
- */
- get(name: string): FormDataEntryValue | null
-
- /**
- * Returns all the values associated with a given key from within a `FormData` object.
- *
- * @param {string} name A name of the value you want to retrieve.
- *
- * @returns An array of `FormDataEntryValue` whose key matches the value passed in the `name` parameter. If the key doesn't exist, the method returns an empty list.
- */
- getAll(name: string): FormDataEntryValue[]
-
- /**
- * Returns a boolean stating whether a `FormData` object contains a certain key.
- *
- * @param name A string representing the name of the key you want to test for.
- *
- * @return A boolean value.
- */
- has(name: string): boolean
-
- /**
- * Deletes a key and its value(s) from a `FormData` object.
- *
- * @param name The name of the key you want to delete.
- */
- delete(name: string): void
-
- /**
- * Executes given callback function for each field of the FormData instance
- */
- forEach: (
- callbackfn: (value: FormDataEntryValue, key: string, iterable: FormData) => void,
- thisArg?: unknown
- ) => void
-
- /**
- * Returns an [`iterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) allowing to go through all keys contained in this `FormData` object.
- * Each key is a `string`.
- */
- keys: () => SpecIterableIterator
-
- /**
- * Returns an [`iterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) allowing to go through all values contained in this object `FormData` object.
- * Each value is a [`FormDataValue`](https://developer.mozilla.org/en-US/docs/Web/API/FormDataEntryValue).
- */
- values: () => SpecIterableIterator
-
- /**
- * Returns an [`iterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) allowing to go through the `FormData` key/value pairs.
- * The key of each pair is a string; the value is a [`FormDataValue`](https://developer.mozilla.org/en-US/docs/Web/API/FormDataEntryValue).
- */
- entries: () => SpecIterableIterator<[string, FormDataEntryValue]>
-
- /**
- * An alias for FormData#entries()
- */
- [Symbol.iterator]: () => SpecIterableIterator<[string, FormDataEntryValue]>
-
- readonly [Symbol.toStringTag]: string
-}
diff --git a/node_modules/undici/types/global-dispatcher.d.ts b/node_modules/undici/types/global-dispatcher.d.ts
deleted file mode 100644
index 56abd53..0000000
--- a/node_modules/undici/types/global-dispatcher.d.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import Dispatcher = require("./dispatcher");
-
-export {
- getGlobalDispatcher,
- setGlobalDispatcher
-}
-
-declare function setGlobalDispatcher(dispatcher: DispatcherImplementation): void;
-declare function getGlobalDispatcher(): Dispatcher;
diff --git a/node_modules/undici/types/mock-agent.d.ts b/node_modules/undici/types/mock-agent.d.ts
deleted file mode 100644
index 825d2ae..0000000
--- a/node_modules/undici/types/mock-agent.d.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import Agent = require('./agent')
-import Dispatcher = require('./dispatcher')
-import { Interceptable, MockInterceptor } from './mock-interceptor'
-import MockDispatch = MockInterceptor.MockDispatch;
-
-export = MockAgent
-
-interface PendingInterceptor extends MockDispatch {
- origin: string;
-}
-
-/** A mocked Agent class that implements the Agent API. It allows one to intercept HTTP requests made through undici and return mocked responses instead. */
-declare class MockAgent extends Dispatcher {
- constructor(options?: MockAgent.Options)
- /** Creates and retrieves mock Dispatcher instances which can then be used to intercept HTTP requests. If the number of connections on the mock agent is set to 1, a MockClient instance is returned. Otherwise a MockPool instance is returned. */
- get(origin: string): TInterceptable;
- get(origin: RegExp): TInterceptable;
- get(origin: ((origin: string) => boolean)): TInterceptable;
- /** Dispatches a mocked request. */
- dispatch(options: Agent.DispatchOptions, handler: Dispatcher.DispatchHandlers): boolean;
- /** Closes the mock agent and waits for registered mock pools and clients to also close before resolving. */
- close(): Promise;
- /** Disables mocking in MockAgent. */
- deactivate(): void;
- /** Enables mocking in a MockAgent instance. When instantiated, a MockAgent is automatically activated. Therefore, this method is only effective after `MockAgent.deactivate` has been called. */
- activate(): void;
- /** Define host matchers so only matching requests that aren't intercepted by the mock dispatchers will be attempted. */
- enableNetConnect(): void;
- enableNetConnect(host: string): void;
- enableNetConnect(host: RegExp): void;
- enableNetConnect(host: ((host: string) => boolean)): void;
- /** Causes all requests to throw when requests are not matched in a MockAgent intercept. */
- disableNetConnect(): void;
- pendingInterceptors(): PendingInterceptor[];
- assertNoPendingInterceptors(options?: {
- pendingInterceptorsFormatter?: PendingInterceptorsFormatter;
- }): void;
-}
-
-interface PendingInterceptorsFormatter {
- format(pendingInterceptors: readonly PendingInterceptor[]): string;
-}
-
-declare namespace MockAgent {
- /** MockAgent options. */
- export interface Options extends Agent.Options {
- /** A custom agent to be encapsulated by the MockAgent. */
- agent?: Agent;
- }
-}
diff --git a/node_modules/undici/types/mock-client.d.ts b/node_modules/undici/types/mock-client.d.ts
deleted file mode 100644
index 9e751f4..0000000
--- a/node_modules/undici/types/mock-client.d.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import Client = require('./client')
-import Dispatcher = require('./dispatcher')
-import MockAgent = require('./mock-agent')
-import { MockInterceptor, Interceptable } from './mock-interceptor'
-
-export = MockClient
-
-/** MockClient extends the Client API and allows one to mock requests. */
-declare class MockClient extends Client implements Interceptable {
- constructor(origin: string, options: MockClient.Options);
- /** Intercepts any matching requests that use the same origin as this mock client. */
- intercept(options: MockInterceptor.Options): MockInterceptor;
- /** Dispatches a mocked request. */
- dispatch(options: Dispatcher.DispatchOptions, handlers: Dispatcher.DispatchHandlers): boolean;
- /** Closes the mock client and gracefully waits for enqueued requests to complete. */
- close(): Promise;
-}
-
-declare namespace MockClient {
- /** MockClient options. */
- export interface Options extends Client.Options {
- /** The agent to associate this MockClient with. */
- agent: MockAgent;
- }
-}
diff --git a/node_modules/undici/types/mock-errors.d.ts b/node_modules/undici/types/mock-errors.d.ts
deleted file mode 100644
index 31e7ba2..0000000
--- a/node_modules/undici/types/mock-errors.d.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { UndiciError } from './errors'
-
-export = MockErrors
-
-declare namespace MockErrors {
- /** The request does not match any registered mock dispatches. */
- export class MockNotMatchedError extends UndiciError {
- constructor(message?: string);
- name: 'MockNotMatchedError';
- code: 'UND_MOCK_ERR_MOCK_NOT_MATCHED';
- }
-}
diff --git a/node_modules/undici/types/mock-interceptor.d.ts b/node_modules/undici/types/mock-interceptor.d.ts
deleted file mode 100644
index b7a2b33..0000000
--- a/node_modules/undici/types/mock-interceptor.d.ts
+++ /dev/null
@@ -1,93 +0,0 @@
-import { IncomingHttpHeaders } from 'http'
-import Dispatcher = require('./dispatcher');
-import { BodyInit, Headers } from './fetch'
-
-export {
- Interceptable,
- MockInterceptor,
- MockScope
-}
-
-/** The scope associated with a mock dispatch. */
-declare class MockScope {
- constructor(mockDispatch: MockInterceptor.MockDispatch);
- /** Delay a reply by a set amount of time in ms. */
- delay(waitInMs: number): MockScope;
- /** Persist the defined mock data for the associated reply. It will return the defined mock data indefinitely. */
- persist(): MockScope;
- /** Define a reply for a set amount of matching requests. */
- times(repeatTimes: number): MockScope;
-}
-
-/** The interceptor for a Mock. */
-declare class MockInterceptor {
- constructor(options: MockInterceptor.Options, mockDispatches: MockInterceptor.MockDispatch[]);
- /** Mock an undici request with the defined reply. */
- reply(replyOptionsCallback: MockInterceptor.MockReplyOptionsCallback): MockScope;
- reply(
- statusCode: number,
- data: TData | Buffer | string | MockInterceptor.MockResponseDataHandler,
- responseOptions?: MockInterceptor.MockResponseOptions
- ): MockScope;
- /** Mock an undici request by throwing the defined reply error. */
- replyWithError(error: TError): MockScope;
- /** Set default reply headers on the interceptor for subsequent mocked replies. */
- defaultReplyHeaders(headers: IncomingHttpHeaders): MockInterceptor;
- /** Set default reply trailers on the interceptor for subsequent mocked replies. */
- defaultReplyTrailers(trailers: Record): MockInterceptor;
- /** Set automatically calculated content-length header on subsequent mocked replies. */
- replyContentLength(): MockInterceptor;
-}
-
-declare namespace MockInterceptor {
- /** MockInterceptor options. */
- export interface Options {
- /** Path to intercept on. */
- path: string | RegExp | ((path: string) => boolean);
- /** Method to intercept on. Defaults to GET. */
- method?: string | RegExp | ((method: string) => boolean);
- /** Body to intercept on. */
- body?: string | RegExp | ((body: string) => boolean);
- /** Headers to intercept on. */
- headers?: Record boolean)> | ((headers: Record) => boolean);
- /** Query params to intercept on */
- query?: Record;
- }
- export interface MockDispatch extends Options {
- times: number | null;
- persist: boolean;
- consumed: boolean;
- data: MockDispatchData;
- }
- export interface MockDispatchData extends MockResponseOptions {
- error: TError | null;
- statusCode?: number;
- data?: TData | string;
- }
- export interface MockResponseOptions {
- headers?: IncomingHttpHeaders;
- trailers?: Record;
- }
-
- export interface MockResponseCallbackOptions {
- path: string;
- origin: string;
- method: string;
- body?: BodyInit | Dispatcher.DispatchOptions['body'];
- headers: Headers;
- maxRedirections: number;
- }
-
- export type MockResponseDataHandler = (
- opts: MockResponseCallbackOptions
- ) => TData | Buffer | string;
-
- export type MockReplyOptionsCallback = (
- opts: MockResponseCallbackOptions
- ) => { statusCode: number, data: TData | Buffer | string, responseOptions?: MockResponseOptions }
-}
-
-interface Interceptable extends Dispatcher {
- /** Intercepts any matching requests that use the same origin as this mock client. */
- intercept(options: MockInterceptor.Options): MockInterceptor;
-}
diff --git a/node_modules/undici/types/mock-pool.d.ts b/node_modules/undici/types/mock-pool.d.ts
deleted file mode 100644
index d0c9051..0000000
--- a/node_modules/undici/types/mock-pool.d.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import Pool = require('./pool')
-import MockAgent = require('./mock-agent')
-import { Interceptable, MockInterceptor } from './mock-interceptor'
-import Dispatcher = require('./dispatcher')
-
-export = MockPool
-
-/** MockPool extends the Pool API and allows one to mock requests. */
-declare class MockPool extends Pool implements Interceptable {
- constructor(origin: string, options: MockPool.Options);
- /** Intercepts any matching requests that use the same origin as this mock pool. */
- intercept(options: MockInterceptor.Options): MockInterceptor;
- /** Dispatches a mocked request. */
- dispatch(options: Dispatcher.DispatchOptions, handlers: Dispatcher.DispatchHandlers): boolean;
- /** Closes the mock pool and gracefully waits for enqueued requests to complete. */
- close(): Promise;
-}
-
-declare namespace MockPool {
- /** MockPool options. */
- export interface Options extends Pool.Options {
- /** The agent to associate this MockPool with. */
- agent: MockAgent;
- }
-}
diff --git a/node_modules/undici/types/pool.d.ts b/node_modules/undici/types/pool.d.ts
deleted file mode 100644
index 82aeb37..0000000
--- a/node_modules/undici/types/pool.d.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import Client = require('./client')
-import Dispatcher = require('./dispatcher')
-import { URL } from 'url'
-
-export = Pool
-
-declare class Pool extends Dispatcher {
- constructor(url: string | URL, options?: Pool.Options)
- /** `true` after `pool.close()` has been called. */
- closed: boolean;
- /** `true` after `pool.destroyed()` has been called or `pool.close()` has been called and the pool shutdown has completed. */
- destroyed: boolean;
-}
-
-declare namespace Pool {
- export interface Options extends Client.Options {
- /** Default: `(origin, opts) => new Client(origin, opts)`. */
- factory?(origin: URL, opts: object): Dispatcher;
- /** The max number of clients to create. `null` if no limit. Default `null`. */
- connections?: number | null;
- }
-}
diff --git a/node_modules/undici/types/proxy-agent.d.ts b/node_modules/undici/types/proxy-agent.d.ts
deleted file mode 100644
index 30fef45..0000000
--- a/node_modules/undici/types/proxy-agent.d.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { TlsOptions } from 'tls'
-import Agent = require('./agent')
-import Dispatcher = require('./dispatcher')
-
-export = ProxyAgent
-
-declare class ProxyAgent extends Dispatcher {
- constructor(options: ProxyAgent.Options | string)
-
- dispatch(options: Agent.DispatchOptions, handler: Dispatcher.DispatchHandlers): boolean;
- close(): Promise;
-}
-
-declare namespace ProxyAgent {
- export interface Options extends Agent.Options {
- uri: string;
- auth?: string;
- requestTls?: TlsOptions & { servername?: string };
- proxyTls?: TlsOptions & { servername?: string };
- }
-}
diff --git a/node_modules/undici/types/readable.d.ts b/node_modules/undici/types/readable.d.ts
deleted file mode 100644
index 0d82ba8..0000000
--- a/node_modules/undici/types/readable.d.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-import { Readable } from "stream";
-import { Blob } from 'buffer'
-
-export = BodyReadable
-
-declare class BodyReadable extends Readable {
- constructor(
- resume?: (this: Readable, size: number) => void | null,
- abort?: () => void | null,
- contentType?: string
- )
-
- /** Consumes and returns the body as a string
- * https://fetch.spec.whatwg.org/#dom-body-text
- */
- text(): Promise
-
- /** Consumes and returns the body as a JavaScript Object
- * https://fetch.spec.whatwg.org/#dom-body-json
- */
- json(): Promise
-
- /** Consumes and returns the body as a Blob
- * https://fetch.spec.whatwg.org/#dom-body-blob
- */
- blob(): Promise
-
- /** Consumes and returns the body as an ArrayBuffer
- * https://fetch.spec.whatwg.org/#dom-body-arraybuffer
- */
- arrayBuffer(): Promise
-
- /** Not implemented
- *
- * https://fetch.spec.whatwg.org/#dom-body-formdata
- */
- formData(): Promise
-
- /** Returns true if the body is not null and the body has been consumed
- *
- * Otherwise, returns false
- *
- * https://fetch.spec.whatwg.org/#dom-body-bodyused
- */
- readonly bodyUsed: boolean
-
- /** Throws on node 16.6.0
- *
- * If body is null, it should return null as the body
- *
- * If body is not null, should return the body as a ReadableStream
- *
- * https://fetch.spec.whatwg.org/#dom-body-body
- */
- readonly body: never | undefined
-
- /** Dumps the response body by reading `limit` number of bytes.
- * @param opts.limit Number of bytes to read (optional) - Default: 262144
- */
- dump(opts?: { limit: number }): Promise
-}
diff --git a/node_modules/web-streams-polyfill/LICENSE b/node_modules/web-streams-polyfill/LICENSE
new file mode 100644
index 0000000..4ca5166
--- /dev/null
+++ b/node_modules/web-streams-polyfill/LICENSE
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2020 Mattias Buelens
+Copyright (c) 2016 Diwank Singh Tomer
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/node_modules/web-streams-polyfill/README.md b/node_modules/web-streams-polyfill/README.md
new file mode 100644
index 0000000..7056882
--- /dev/null
+++ b/node_modules/web-streams-polyfill/README.md
@@ -0,0 +1,114 @@
+# web-streams-polyfill
+
+Web Streams, based on the WHATWG spec reference implementation.
+
+[](https://travis-ci.com/MattiasBuelens/web-streams-polyfill)
+[](https://www.npmjs.com/package/web-streams-polyfill)
+[](https://github.com/MattiasBuelens/web-streams-polyfill/blob/master/LICENSE)
+[](https://gitter.im/web-streams-polyfill/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+
+## Links
+
+ - [Official spec][spec]
+ - [Reference implementation][ref-impl]
+
+## Usage
+
+This library comes in multiple variants:
+* `web-streams-polyfill`: a polyfill that replaces the native stream implementations.
+ Recommended for use in web apps supporting older browsers through a `
+
+
+
+```
+Usage as a Node module:
+```js
+var streams = require("web-streams-polyfill/ponyfill");
+var readable = new streams.ReadableStream();
+```
+Usage as a ES2015 module:
+```js
+import { ReadableStream } from "web-streams-polyfill/ponyfill";
+const readable = new ReadableStream();
+```
+
+### Compatibility
+
+The `polyfill` and `ponyfill` variants work in any ES5-compatible environment that has a global `Promise`.
+If you need to support older browsers or Node versions that do not have a native `Promise` implementation
+(check the [support table][promise-support]), you must first include a `Promise` polyfill
+(e.g. [promise-polyfill][promise-polyfill]).
+
+The `polyfill/es6` and `ponyfill/es6` variants work in any ES2015-compatible environment.
+
+The `polyfill/es2018` and `ponyfill/es2018` variants work in any ES2018-compatible environment.
+
+[Async iterable support for `ReadableStream`][rs-asynciterator] is available in all variants, but requires an ES2018-compatible environment or a polyfill for `Symbol.asyncIterator`.
+
+[`WritableStreamDefaultController.signal`][ws-controller-signal] is available in all variants, but requires a global `AbortController` constructor. If necessary, consider using a polyfill such as [abortcontroller-polyfill].
+
+### Compliance
+
+The polyfill implements [version `4b6b93c` (25 Oct 2021)][spec-snapshot] of the streams specification.
+
+The polyfill is tested against the same [web platform tests][wpt] that are used by browsers to test their native implementations.
+The polyfill aims to pass all tests, although it allows some exceptions for practical reasons:
+* The `es2018` variant passes all of the tests, except for the ["bad buffers and views" tests for readable byte streams][wpt-bad-buffers].
+ These tests require the implementation to synchronously transfer the contents of an `ArrayBuffer`, which is not yet possible from JavaScript (although there is a [proposal][proposal-arraybuffer-transfer] to make it possible).
+ The reference implementation "cheats" on these tests [by making a copy instead][ref-impl-transferarraybuffer], but that is unacceptable for the polyfill's performance ([#3][issue-3]).
+* The `es6` variant passes the same tests as the `es2018` variant, except for the [test for the prototype of `ReadableStream`'s async iterator][wpt-async-iterator-prototype].
+ Retrieving the correct `%AsyncIteratorPrototype%` requires using an async generator (`async function* () {}`), which is invalid syntax before ES2018.
+ Instead, the polyfill [creates its own version][stub-async-iterator-prototype] which is functionally equivalent to the real prototype.
+* The `es5` variant passes the same tests as the `es6` variant, except for various tests about specific characteristics of the constructors, properties and methods.
+ These test failures do not affect the run-time behavior of the polyfill.
+ For example:
+ * The `name` property of down-leveled constructors is incorrect.
+ * The `length` property of down-leveled constructors and methods with optional arguments is incorrect.
+ * Not all properties and methods are correctly marked as non-enumerable.
+ * Down-leveled class methods are not correctly marked as non-constructable.
+
+The type definitions are compatible with the built-in stream types of TypeScript 3.3.
+
+### Contributors
+
+Thanks to these people for their work on [the original polyfill][creatorrr-polyfill]:
+
+ - Diwank Singh Tomer ([creatorrr](https://github.com/creatorrr))
+ - Anders Riutta ([ariutta](https://github.com/ariutta))
+
+[spec]: https://streams.spec.whatwg.org
+[ref-impl]: https://github.com/whatwg/streams
+[ponyfill]: https://github.com/sindresorhus/ponyfill
+[promise-support]: https://kangax.github.io/compat-table/es6/#test-Promise
+[promise-polyfill]: https://www.npmjs.com/package/promise-polyfill
+[rs-asynciterator]: https://streams.spec.whatwg.org/#rs-asynciterator
+[ws-controller-signal]: https://streams.spec.whatwg.org/#ws-default-controller-signal
+[abortcontroller-polyfill]: https://www.npmjs.com/package/abortcontroller-polyfill
+[spec-snapshot]: https://streams.spec.whatwg.org/commit-snapshots/4b6b93c69e531e2fe45a6ed4cb1484a7ba4eb8bb/
+[wpt]: https://github.com/web-platform-tests/wpt/tree/96ca25f0f7526282c0d47e6bf6a7edd439da1968/streams
+[wpt-bad-buffers]: https://github.com/web-platform-tests/wpt/blob/96ca25f0f7526282c0d47e6bf6a7edd439da1968/streams/readable-byte-streams/bad-buffers-and-views.any.js
+[proposal-arraybuffer-transfer]: https://github.com/domenic/proposal-arraybuffer-transfer
+[ref-impl-transferarraybuffer]: https://github.com/whatwg/streams/blob/4b6b93c69e531e2fe45a6ed4cb1484a7ba4eb8bb/reference-implementation/lib/abstract-ops/ecmascript.js#L16
+[issue-3]: https://github.com/MattiasBuelens/web-streams-polyfill/issues/3
+[wpt-async-iterator-prototype]: https://github.com/web-platform-tests/wpt/blob/96ca25f0f7526282c0d47e6bf6a7edd439da1968/streams/readable-streams/async-iterator.any.js#L24
+[stub-async-iterator-prototype]: https://github.com/MattiasBuelens/web-streams-polyfill/blob/v2.0.0/src/target/es5/stub/async-iterator-prototype.ts
+[creatorrr-polyfill]: https://github.com/creatorrr/web-streams-polyfill
diff --git a/node_modules/web-streams-polyfill/dist/polyfill.es2018.js b/node_modules/web-streams-polyfill/dist/polyfill.es2018.js
new file mode 100644
index 0000000..4e26968
--- /dev/null
+++ b/node_modules/web-streams-polyfill/dist/polyfill.es2018.js
@@ -0,0 +1,4241 @@
+/**
+ * web-streams-polyfill v3.2.1
+ */
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
+ typeof define === 'function' && define.amd ? define(['exports'], factory) :
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.WebStreamsPolyfill = {}));
+}(this, (function (exports) { 'use strict';
+
+ ///
+ const SymbolPolyfill = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ?
+ Symbol :
+ description => `Symbol(${description})`;
+
+ ///
+ function noop() {
+ return undefined;
+ }
+ function getGlobals() {
+ if (typeof self !== 'undefined') {
+ return self;
+ }
+ else if (typeof window !== 'undefined') {
+ return window;
+ }
+ else if (typeof global !== 'undefined') {
+ return global;
+ }
+ return undefined;
+ }
+ const globals = getGlobals();
+
+ function typeIsObject(x) {
+ return (typeof x === 'object' && x !== null) || typeof x === 'function';
+ }
+ const rethrowAssertionErrorRejection = noop;
+
+ const originalPromise = Promise;
+ const originalPromiseThen = Promise.prototype.then;
+ const originalPromiseResolve = Promise.resolve.bind(originalPromise);
+ const originalPromiseReject = Promise.reject.bind(originalPromise);
+ function newPromise(executor) {
+ return new originalPromise(executor);
+ }
+ function promiseResolvedWith(value) {
+ return originalPromiseResolve(value);
+ }
+ function promiseRejectedWith(reason) {
+ return originalPromiseReject(reason);
+ }
+ function PerformPromiseThen(promise, onFulfilled, onRejected) {
+ // There doesn't appear to be any way to correctly emulate the behaviour from JavaScript, so this is just an
+ // approximation.
+ return originalPromiseThen.call(promise, onFulfilled, onRejected);
+ }
+ function uponPromise(promise, onFulfilled, onRejected) {
+ PerformPromiseThen(PerformPromiseThen(promise, onFulfilled, onRejected), undefined, rethrowAssertionErrorRejection);
+ }
+ function uponFulfillment(promise, onFulfilled) {
+ uponPromise(promise, onFulfilled);
+ }
+ function uponRejection(promise, onRejected) {
+ uponPromise(promise, undefined, onRejected);
+ }
+ function transformPromiseWith(promise, fulfillmentHandler, rejectionHandler) {
+ return PerformPromiseThen(promise, fulfillmentHandler, rejectionHandler);
+ }
+ function setPromiseIsHandledToTrue(promise) {
+ PerformPromiseThen(promise, undefined, rethrowAssertionErrorRejection);
+ }
+ const queueMicrotask = (() => {
+ const globalQueueMicrotask = globals && globals.queueMicrotask;
+ if (typeof globalQueueMicrotask === 'function') {
+ return globalQueueMicrotask;
+ }
+ const resolvedPromise = promiseResolvedWith(undefined);
+ return (fn) => PerformPromiseThen(resolvedPromise, fn);
+ })();
+ function reflectCall(F, V, args) {
+ if (typeof F !== 'function') {
+ throw new TypeError('Argument is not a function');
+ }
+ return Function.prototype.apply.call(F, V, args);
+ }
+ function promiseCall(F, V, args) {
+ try {
+ return promiseResolvedWith(reflectCall(F, V, args));
+ }
+ catch (value) {
+ return promiseRejectedWith(value);
+ }
+ }
+
+ // Original from Chromium
+ // https://chromium.googlesource.com/chromium/src/+/0aee4434a4dba42a42abaea9bfbc0cd196a63bc1/third_party/blink/renderer/core/streams/SimpleQueue.js
+ const QUEUE_MAX_ARRAY_SIZE = 16384;
+ /**
+ * Simple queue structure.
+ *
+ * Avoids scalability issues with using a packed array directly by using
+ * multiple arrays in a linked list and keeping the array size bounded.
+ */
+ class SimpleQueue {
+ constructor() {
+ this._cursor = 0;
+ this._size = 0;
+ // _front and _back are always defined.
+ this._front = {
+ _elements: [],
+ _next: undefined
+ };
+ this._back = this._front;
+ // The cursor is used to avoid calling Array.shift().
+ // It contains the index of the front element of the array inside the
+ // front-most node. It is always in the range [0, QUEUE_MAX_ARRAY_SIZE).
+ this._cursor = 0;
+ // When there is only one node, size === elements.length - cursor.
+ this._size = 0;
+ }
+ get length() {
+ return this._size;
+ }
+ // For exception safety, this method is structured in order:
+ // 1. Read state
+ // 2. Calculate required state mutations
+ // 3. Perform state mutations
+ push(element) {
+ const oldBack = this._back;
+ let newBack = oldBack;
+ if (oldBack._elements.length === QUEUE_MAX_ARRAY_SIZE - 1) {
+ newBack = {
+ _elements: [],
+ _next: undefined
+ };
+ }
+ // push() is the mutation most likely to throw an exception, so it
+ // goes first.
+ oldBack._elements.push(element);
+ if (newBack !== oldBack) {
+ this._back = newBack;
+ oldBack._next = newBack;
+ }
+ ++this._size;
+ }
+ // Like push(), shift() follows the read -> calculate -> mutate pattern for
+ // exception safety.
+ shift() { // must not be called on an empty queue
+ const oldFront = this._front;
+ let newFront = oldFront;
+ const oldCursor = this._cursor;
+ let newCursor = oldCursor + 1;
+ const elements = oldFront._elements;
+ const element = elements[oldCursor];
+ if (newCursor === QUEUE_MAX_ARRAY_SIZE) {
+ newFront = oldFront._next;
+ newCursor = 0;
+ }
+ // No mutations before this point.
+ --this._size;
+ this._cursor = newCursor;
+ if (oldFront !== newFront) {
+ this._front = newFront;
+ }
+ // Permit shifted element to be garbage collected.
+ elements[oldCursor] = undefined;
+ return element;
+ }
+ // The tricky thing about forEach() is that it can be called
+ // re-entrantly. The queue may be mutated inside the callback. It is easy to
+ // see that push() within the callback has no negative effects since the end
+ // of the queue is checked for on every iteration. If shift() is called
+ // repeatedly within the callback then the next iteration may return an
+ // element that has been removed. In this case the callback will be called
+ // with undefined values until we either "catch up" with elements that still
+ // exist or reach the back of the queue.
+ forEach(callback) {
+ let i = this._cursor;
+ let node = this._front;
+ let elements = node._elements;
+ while (i !== elements.length || node._next !== undefined) {
+ if (i === elements.length) {
+ node = node._next;
+ elements = node._elements;
+ i = 0;
+ if (elements.length === 0) {
+ break;
+ }
+ }
+ callback(elements[i]);
+ ++i;
+ }
+ }
+ // Return the element that would be returned if shift() was called now,
+ // without modifying the queue.
+ peek() { // must not be called on an empty queue
+ const front = this._front;
+ const cursor = this._cursor;
+ return front._elements[cursor];
+ }
+ }
+
+ function ReadableStreamReaderGenericInitialize(reader, stream) {
+ reader._ownerReadableStream = stream;
+ stream._reader = reader;
+ if (stream._state === 'readable') {
+ defaultReaderClosedPromiseInitialize(reader);
+ }
+ else if (stream._state === 'closed') {
+ defaultReaderClosedPromiseInitializeAsResolved(reader);
+ }
+ else {
+ defaultReaderClosedPromiseInitializeAsRejected(reader, stream._storedError);
+ }
+ }
+ // A client of ReadableStreamDefaultReader and ReadableStreamBYOBReader may use these functions directly to bypass state
+ // check.
+ function ReadableStreamReaderGenericCancel(reader, reason) {
+ const stream = reader._ownerReadableStream;
+ return ReadableStreamCancel(stream, reason);
+ }
+ function ReadableStreamReaderGenericRelease(reader) {
+ if (reader._ownerReadableStream._state === 'readable') {
+ defaultReaderClosedPromiseReject(reader, new TypeError(`Reader was released and can no longer be used to monitor the stream's closedness`));
+ }
+ else {
+ defaultReaderClosedPromiseResetToRejected(reader, new TypeError(`Reader was released and can no longer be used to monitor the stream's closedness`));
+ }
+ reader._ownerReadableStream._reader = undefined;
+ reader._ownerReadableStream = undefined;
+ }
+ // Helper functions for the readers.
+ function readerLockException(name) {
+ return new TypeError('Cannot ' + name + ' a stream using a released reader');
+ }
+ // Helper functions for the ReadableStreamDefaultReader.
+ function defaultReaderClosedPromiseInitialize(reader) {
+ reader._closedPromise = newPromise((resolve, reject) => {
+ reader._closedPromise_resolve = resolve;
+ reader._closedPromise_reject = reject;
+ });
+ }
+ function defaultReaderClosedPromiseInitializeAsRejected(reader, reason) {
+ defaultReaderClosedPromiseInitialize(reader);
+ defaultReaderClosedPromiseReject(reader, reason);
+ }
+ function defaultReaderClosedPromiseInitializeAsResolved(reader) {
+ defaultReaderClosedPromiseInitialize(reader);
+ defaultReaderClosedPromiseResolve(reader);
+ }
+ function defaultReaderClosedPromiseReject(reader, reason) {
+ if (reader._closedPromise_reject === undefined) {
+ return;
+ }
+ setPromiseIsHandledToTrue(reader._closedPromise);
+ reader._closedPromise_reject(reason);
+ reader._closedPromise_resolve = undefined;
+ reader._closedPromise_reject = undefined;
+ }
+ function defaultReaderClosedPromiseResetToRejected(reader, reason) {
+ defaultReaderClosedPromiseInitializeAsRejected(reader, reason);
+ }
+ function defaultReaderClosedPromiseResolve(reader) {
+ if (reader._closedPromise_resolve === undefined) {
+ return;
+ }
+ reader._closedPromise_resolve(undefined);
+ reader._closedPromise_resolve = undefined;
+ reader._closedPromise_reject = undefined;
+ }
+
+ const AbortSteps = SymbolPolyfill('[[AbortSteps]]');
+ const ErrorSteps = SymbolPolyfill('[[ErrorSteps]]');
+ const CancelSteps = SymbolPolyfill('[[CancelSteps]]');
+ const PullSteps = SymbolPolyfill('[[PullSteps]]');
+
+ ///
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite#Polyfill
+ const NumberIsFinite = Number.isFinite || function (x) {
+ return typeof x === 'number' && isFinite(x);
+ };
+
+ ///
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc#Polyfill
+ const MathTrunc = Math.trunc || function (v) {
+ return v < 0 ? Math.ceil(v) : Math.floor(v);
+ };
+
+ // https://heycam.github.io/webidl/#idl-dictionaries
+ function isDictionary(x) {
+ return typeof x === 'object' || typeof x === 'function';
+ }
+ function assertDictionary(obj, context) {
+ if (obj !== undefined && !isDictionary(obj)) {
+ throw new TypeError(`${context} is not an object.`);
+ }
+ }
+ // https://heycam.github.io/webidl/#idl-callback-functions
+ function assertFunction(x, context) {
+ if (typeof x !== 'function') {
+ throw new TypeError(`${context} is not a function.`);
+ }
+ }
+ // https://heycam.github.io/webidl/#idl-object
+ function isObject(x) {
+ return (typeof x === 'object' && x !== null) || typeof x === 'function';
+ }
+ function assertObject(x, context) {
+ if (!isObject(x)) {
+ throw new TypeError(`${context} is not an object.`);
+ }
+ }
+ function assertRequiredArgument(x, position, context) {
+ if (x === undefined) {
+ throw new TypeError(`Parameter ${position} is required in '${context}'.`);
+ }
+ }
+ function assertRequiredField(x, field, context) {
+ if (x === undefined) {
+ throw new TypeError(`${field} is required in '${context}'.`);
+ }
+ }
+ // https://heycam.github.io/webidl/#idl-unrestricted-double
+ function convertUnrestrictedDouble(value) {
+ return Number(value);
+ }
+ function censorNegativeZero(x) {
+ return x === 0 ? 0 : x;
+ }
+ function integerPart(x) {
+ return censorNegativeZero(MathTrunc(x));
+ }
+ // https://heycam.github.io/webidl/#idl-unsigned-long-long
+ function convertUnsignedLongLongWithEnforceRange(value, context) {
+ const lowerBound = 0;
+ const upperBound = Number.MAX_SAFE_INTEGER;
+ let x = Number(value);
+ x = censorNegativeZero(x);
+ if (!NumberIsFinite(x)) {
+ throw new TypeError(`${context} is not a finite number`);
+ }
+ x = integerPart(x);
+ if (x < lowerBound || x > upperBound) {
+ throw new TypeError(`${context} is outside the accepted range of ${lowerBound} to ${upperBound}, inclusive`);
+ }
+ if (!NumberIsFinite(x) || x === 0) {
+ return 0;
+ }
+ // TODO Use BigInt if supported?
+ // let xBigInt = BigInt(integerPart(x));
+ // xBigInt = BigInt.asUintN(64, xBigInt);
+ // return Number(xBigInt);
+ return x;
+ }
+
+ function assertReadableStream(x, context) {
+ if (!IsReadableStream(x)) {
+ throw new TypeError(`${context} is not a ReadableStream.`);
+ }
+ }
+
+ // Abstract operations for the ReadableStream.
+ function AcquireReadableStreamDefaultReader(stream) {
+ return new ReadableStreamDefaultReader(stream);
+ }
+ // ReadableStream API exposed for controllers.
+ function ReadableStreamAddReadRequest(stream, readRequest) {
+ stream._reader._readRequests.push(readRequest);
+ }
+ function ReadableStreamFulfillReadRequest(stream, chunk, done) {
+ const reader = stream._reader;
+ const readRequest = reader._readRequests.shift();
+ if (done) {
+ readRequest._closeSteps();
+ }
+ else {
+ readRequest._chunkSteps(chunk);
+ }
+ }
+ function ReadableStreamGetNumReadRequests(stream) {
+ return stream._reader._readRequests.length;
+ }
+ function ReadableStreamHasDefaultReader(stream) {
+ const reader = stream._reader;
+ if (reader === undefined) {
+ return false;
+ }
+ if (!IsReadableStreamDefaultReader(reader)) {
+ return false;
+ }
+ return true;
+ }
+ /**
+ * A default reader vended by a {@link ReadableStream}.
+ *
+ * @public
+ */
+ class ReadableStreamDefaultReader {
+ constructor(stream) {
+ assertRequiredArgument(stream, 1, 'ReadableStreamDefaultReader');
+ assertReadableStream(stream, 'First parameter');
+ if (IsReadableStreamLocked(stream)) {
+ throw new TypeError('This stream has already been locked for exclusive reading by another reader');
+ }
+ ReadableStreamReaderGenericInitialize(this, stream);
+ this._readRequests = new SimpleQueue();
+ }
+ /**
+ * Returns a promise that will be fulfilled when the stream becomes closed,
+ * or rejected if the stream ever errors or the reader's lock is released before the stream finishes closing.
+ */
+ get closed() {
+ if (!IsReadableStreamDefaultReader(this)) {
+ return promiseRejectedWith(defaultReaderBrandCheckException('closed'));
+ }
+ return this._closedPromise;
+ }
+ /**
+ * If the reader is active, behaves the same as {@link ReadableStream.cancel | stream.cancel(reason)}.
+ */
+ cancel(reason = undefined) {
+ if (!IsReadableStreamDefaultReader(this)) {
+ return promiseRejectedWith(defaultReaderBrandCheckException('cancel'));
+ }
+ if (this._ownerReadableStream === undefined) {
+ return promiseRejectedWith(readerLockException('cancel'));
+ }
+ return ReadableStreamReaderGenericCancel(this, reason);
+ }
+ /**
+ * Returns a promise that allows access to the next chunk from the stream's internal queue, if available.
+ *
+ * If reading a chunk causes the queue to become empty, more data will be pulled from the underlying source.
+ */
+ read() {
+ if (!IsReadableStreamDefaultReader(this)) {
+ return promiseRejectedWith(defaultReaderBrandCheckException('read'));
+ }
+ if (this._ownerReadableStream === undefined) {
+ return promiseRejectedWith(readerLockException('read from'));
+ }
+ let resolvePromise;
+ let rejectPromise;
+ const promise = newPromise((resolve, reject) => {
+ resolvePromise = resolve;
+ rejectPromise = reject;
+ });
+ const readRequest = {
+ _chunkSteps: chunk => resolvePromise({ value: chunk, done: false }),
+ _closeSteps: () => resolvePromise({ value: undefined, done: true }),
+ _errorSteps: e => rejectPromise(e)
+ };
+ ReadableStreamDefaultReaderRead(this, readRequest);
+ return promise;
+ }
+ /**
+ * Releases the reader's lock on the corresponding stream. After the lock is released, the reader is no longer active.
+ * If the associated stream is errored when the lock is released, the reader will appear errored in the same way
+ * from now on; otherwise, the reader will appear closed.
+ *
+ * A reader's lock cannot be released while it still has a pending read request, i.e., if a promise returned by
+ * the reader's {@link ReadableStreamDefaultReader.read | read()} method has not yet been settled. Attempting to
+ * do so will throw a `TypeError` and leave the reader locked to the stream.
+ */
+ releaseLock() {
+ if (!IsReadableStreamDefaultReader(this)) {
+ throw defaultReaderBrandCheckException('releaseLock');
+ }
+ if (this._ownerReadableStream === undefined) {
+ return;
+ }
+ if (this._readRequests.length > 0) {
+ throw new TypeError('Tried to release a reader lock when that reader has pending read() calls un-settled');
+ }
+ ReadableStreamReaderGenericRelease(this);
+ }
+ }
+ Object.defineProperties(ReadableStreamDefaultReader.prototype, {
+ cancel: { enumerable: true },
+ read: { enumerable: true },
+ releaseLock: { enumerable: true },
+ closed: { enumerable: true }
+ });
+ if (typeof SymbolPolyfill.toStringTag === 'symbol') {
+ Object.defineProperty(ReadableStreamDefaultReader.prototype, SymbolPolyfill.toStringTag, {
+ value: 'ReadableStreamDefaultReader',
+ configurable: true
+ });
+ }
+ // Abstract operations for the readers.
+ function IsReadableStreamDefaultReader(x) {
+ if (!typeIsObject(x)) {
+ return false;
+ }
+ if (!Object.prototype.hasOwnProperty.call(x, '_readRequests')) {
+ return false;
+ }
+ return x instanceof ReadableStreamDefaultReader;
+ }
+ function ReadableStreamDefaultReaderRead(reader, readRequest) {
+ const stream = reader._ownerReadableStream;
+ stream._disturbed = true;
+ if (stream._state === 'closed') {
+ readRequest._closeSteps();
+ }
+ else if (stream._state === 'errored') {
+ readRequest._errorSteps(stream._storedError);
+ }
+ else {
+ stream._readableStreamController[PullSteps](readRequest);
+ }
+ }
+ // Helper functions for the ReadableStreamDefaultReader.
+ function defaultReaderBrandCheckException(name) {
+ return new TypeError(`ReadableStreamDefaultReader.prototype.${name} can only be used on a ReadableStreamDefaultReader`);
+ }
+
+ ///
+ /* eslint-disable @typescript-eslint/no-empty-function */
+ const AsyncIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf(async function* () { }).prototype);
+
+ ///
+ class ReadableStreamAsyncIteratorImpl {
+ constructor(reader, preventCancel) {
+ this._ongoingPromise = undefined;
+ this._isFinished = false;
+ this._reader = reader;
+ this._preventCancel = preventCancel;
+ }
+ next() {
+ const nextSteps = () => this._nextSteps();
+ this._ongoingPromise = this._ongoingPromise ?
+ transformPromiseWith(this._ongoingPromise, nextSteps, nextSteps) :
+ nextSteps();
+ return this._ongoingPromise;
+ }
+ return(value) {
+ const returnSteps = () => this._returnSteps(value);
+ return this._ongoingPromise ?
+ transformPromiseWith(this._ongoingPromise, returnSteps, returnSteps) :
+ returnSteps();
+ }
+ _nextSteps() {
+ if (this._isFinished) {
+ return Promise.resolve({ value: undefined, done: true });
+ }
+ const reader = this._reader;
+ if (reader._ownerReadableStream === undefined) {
+ return promiseRejectedWith(readerLockException('iterate'));
+ }
+ let resolvePromise;
+ let rejectPromise;
+ const promise = newPromise((resolve, reject) => {
+ resolvePromise = resolve;
+ rejectPromise = reject;
+ });
+ const readRequest = {
+ _chunkSteps: chunk => {
+ this._ongoingPromise = undefined;
+ // This needs to be delayed by one microtask, otherwise we stop pulling too early which breaks a test.
+ // FIXME Is this a bug in the specification, or in the test?
+ queueMicrotask(() => resolvePromise({ value: chunk, done: false }));
+ },
+ _closeSteps: () => {
+ this._ongoingPromise = undefined;
+ this._isFinished = true;
+ ReadableStreamReaderGenericRelease(reader);
+ resolvePromise({ value: undefined, done: true });
+ },
+ _errorSteps: reason => {
+ this._ongoingPromise = undefined;
+ this._isFinished = true;
+ ReadableStreamReaderGenericRelease(reader);
+ rejectPromise(reason);
+ }
+ };
+ ReadableStreamDefaultReaderRead(reader, readRequest);
+ return promise;
+ }
+ _returnSteps(value) {
+ if (this._isFinished) {
+ return Promise.resolve({ value, done: true });
+ }
+ this._isFinished = true;
+ const reader = this._reader;
+ if (reader._ownerReadableStream === undefined) {
+ return promiseRejectedWith(readerLockException('finish iterating'));
+ }
+ if (!this._preventCancel) {
+ const result = ReadableStreamReaderGenericCancel(reader, value);
+ ReadableStreamReaderGenericRelease(reader);
+ return transformPromiseWith(result, () => ({ value, done: true }));
+ }
+ ReadableStreamReaderGenericRelease(reader);
+ return promiseResolvedWith({ value, done: true });
+ }
+ }
+ const ReadableStreamAsyncIteratorPrototype = {
+ next() {
+ if (!IsReadableStreamAsyncIterator(this)) {
+ return promiseRejectedWith(streamAsyncIteratorBrandCheckException('next'));
+ }
+ return this._asyncIteratorImpl.next();
+ },
+ return(value) {
+ if (!IsReadableStreamAsyncIterator(this)) {
+ return promiseRejectedWith(streamAsyncIteratorBrandCheckException('return'));
+ }
+ return this._asyncIteratorImpl.return(value);
+ }
+ };
+ if (AsyncIteratorPrototype !== undefined) {
+ Object.setPrototypeOf(ReadableStreamAsyncIteratorPrototype, AsyncIteratorPrototype);
+ }
+ // Abstract operations for the ReadableStream.
+ function AcquireReadableStreamAsyncIterator(stream, preventCancel) {
+ const reader = AcquireReadableStreamDefaultReader(stream);
+ const impl = new ReadableStreamAsyncIteratorImpl(reader, preventCancel);
+ const iterator = Object.create(ReadableStreamAsyncIteratorPrototype);
+ iterator._asyncIteratorImpl = impl;
+ return iterator;
+ }
+ function IsReadableStreamAsyncIterator(x) {
+ if (!typeIsObject(x)) {
+ return false;
+ }
+ if (!Object.prototype.hasOwnProperty.call(x, '_asyncIteratorImpl')) {
+ return false;
+ }
+ try {
+ // noinspection SuspiciousTypeOfGuard
+ return x._asyncIteratorImpl instanceof
+ ReadableStreamAsyncIteratorImpl;
+ }
+ catch (_a) {
+ return false;
+ }
+ }
+ // Helper functions for the ReadableStream.
+ function streamAsyncIteratorBrandCheckException(name) {
+ return new TypeError(`ReadableStreamAsyncIterator.${name} can only be used on a ReadableSteamAsyncIterator`);
+ }
+
+ ///
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN#Polyfill
+ const NumberIsNaN = Number.isNaN || function (x) {
+ // eslint-disable-next-line no-self-compare
+ return x !== x;
+ };
+
+ function CreateArrayFromList(elements) {
+ // We use arrays to represent lists, so this is basically a no-op.
+ // Do a slice though just in case we happen to depend on the unique-ness.
+ return elements.slice();
+ }
+ function CopyDataBlockBytes(dest, destOffset, src, srcOffset, n) {
+ new Uint8Array(dest).set(new Uint8Array(src, srcOffset, n), destOffset);
+ }
+ // Not implemented correctly
+ function TransferArrayBuffer(O) {
+ return O;
+ }
+ // Not implemented correctly
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ function IsDetachedBuffer(O) {
+ return false;
+ }
+ function ArrayBufferSlice(buffer, begin, end) {
+ // ArrayBuffer.prototype.slice is not available on IE10
+ // https://www.caniuse.com/mdn-javascript_builtins_arraybuffer_slice
+ if (buffer.slice) {
+ return buffer.slice(begin, end);
+ }
+ const length = end - begin;
+ const slice = new ArrayBuffer(length);
+ CopyDataBlockBytes(slice, 0, buffer, begin, length);
+ return slice;
+ }
+
+ function IsNonNegativeNumber(v) {
+ if (typeof v !== 'number') {
+ return false;
+ }
+ if (NumberIsNaN(v)) {
+ return false;
+ }
+ if (v < 0) {
+ return false;
+ }
+ return true;
+ }
+ function CloneAsUint8Array(O) {
+ const buffer = ArrayBufferSlice(O.buffer, O.byteOffset, O.byteOffset + O.byteLength);
+ return new Uint8Array(buffer);
+ }
+
+ function DequeueValue(container) {
+ const pair = container._queue.shift();
+ container._queueTotalSize -= pair.size;
+ if (container._queueTotalSize < 0) {
+ container._queueTotalSize = 0;
+ }
+ return pair.value;
+ }
+ function EnqueueValueWithSize(container, value, size) {
+ if (!IsNonNegativeNumber(size) || size === Infinity) {
+ throw new RangeError('Size must be a finite, non-NaN, non-negative number.');
+ }
+ container._queue.push({ value, size });
+ container._queueTotalSize += size;
+ }
+ function PeekQueueValue(container) {
+ const pair = container._queue.peek();
+ return pair.value;
+ }
+ function ResetQueue(container) {
+ container._queue = new SimpleQueue();
+ container._queueTotalSize = 0;
+ }
+
+ /**
+ * A pull-into request in a {@link ReadableByteStreamController}.
+ *
+ * @public
+ */
+ class ReadableStreamBYOBRequest {
+ constructor() {
+ throw new TypeError('Illegal constructor');
+ }
+ /**
+ * Returns the view for writing in to, or `null` if the BYOB request has already been responded to.
+ */
+ get view() {
+ if (!IsReadableStreamBYOBRequest(this)) {
+ throw byobRequestBrandCheckException('view');
+ }
+ return this._view;
+ }
+ respond(bytesWritten) {
+ if (!IsReadableStreamBYOBRequest(this)) {
+ throw byobRequestBrandCheckException('respond');
+ }
+ assertRequiredArgument(bytesWritten, 1, 'respond');
+ bytesWritten = convertUnsignedLongLongWithEnforceRange(bytesWritten, 'First parameter');
+ if (this._associatedReadableByteStreamController === undefined) {
+ throw new TypeError('This BYOB request has been invalidated');
+ }
+ if (IsDetachedBuffer(this._view.buffer)) ;
+ ReadableByteStreamControllerRespond(this._associatedReadableByteStreamController, bytesWritten);
+ }
+ respondWithNewView(view) {
+ if (!IsReadableStreamBYOBRequest(this)) {
+ throw byobRequestBrandCheckException('respondWithNewView');
+ }
+ assertRequiredArgument(view, 1, 'respondWithNewView');
+ if (!ArrayBuffer.isView(view)) {
+ throw new TypeError('You can only respond with array buffer views');
+ }
+ if (this._associatedReadableByteStreamController === undefined) {
+ throw new TypeError('This BYOB request has been invalidated');
+ }
+ if (IsDetachedBuffer(view.buffer)) ;
+ ReadableByteStreamControllerRespondWithNewView(this._associatedReadableByteStreamController, view);
+ }
+ }
+ Object.defineProperties(ReadableStreamBYOBRequest.prototype, {
+ respond: { enumerable: true },
+ respondWithNewView: { enumerable: true },
+ view: { enumerable: true }
+ });
+ if (typeof SymbolPolyfill.toStringTag === 'symbol') {
+ Object.defineProperty(ReadableStreamBYOBRequest.prototype, SymbolPolyfill.toStringTag, {
+ value: 'ReadableStreamBYOBRequest',
+ configurable: true
+ });
+ }
+ /**
+ * Allows control of a {@link ReadableStream | readable byte stream}'s state and internal queue.
+ *
+ * @public
+ */
+ class ReadableByteStreamController {
+ constructor() {
+ throw new TypeError('Illegal constructor');
+ }
+ /**
+ * Returns the current BYOB pull request, or `null` if there isn't one.
+ */
+ get byobRequest() {
+ if (!IsReadableByteStreamController(this)) {
+ throw byteStreamControllerBrandCheckException('byobRequest');
+ }
+ return ReadableByteStreamControllerGetBYOBRequest(this);
+ }
+ /**
+ * Returns the desired size to fill the controlled stream's internal queue. It can be negative, if the queue is
+ * over-full. An underlying byte source ought to use this information to determine when and how to apply backpressure.
+ */
+ get desiredSize() {
+ if (!IsReadableByteStreamController(this)) {
+ throw byteStreamControllerBrandCheckException('desiredSize');
+ }
+ return ReadableByteStreamControllerGetDesiredSize(this);
+ }
+ /**
+ * Closes the controlled readable stream. Consumers will still be able to read any previously-enqueued chunks from
+ * the stream, but once those are read, the stream will become closed.
+ */
+ close() {
+ if (!IsReadableByteStreamController(this)) {
+ throw byteStreamControllerBrandCheckException('close');
+ }
+ if (this._closeRequested) {
+ throw new TypeError('The stream has already been closed; do not close it again!');
+ }
+ const state = this._controlledReadableByteStream._state;
+ if (state !== 'readable') {
+ throw new TypeError(`The stream (in ${state} state) is not in the readable state and cannot be closed`);
+ }
+ ReadableByteStreamControllerClose(this);
+ }
+ enqueue(chunk) {
+ if (!IsReadableByteStreamController(this)) {
+ throw byteStreamControllerBrandCheckException('enqueue');
+ }
+ assertRequiredArgument(chunk, 1, 'enqueue');
+ if (!ArrayBuffer.isView(chunk)) {
+ throw new TypeError('chunk must be an array buffer view');
+ }
+ if (chunk.byteLength === 0) {
+ throw new TypeError('chunk must have non-zero byteLength');
+ }
+ if (chunk.buffer.byteLength === 0) {
+ throw new TypeError(`chunk's buffer must have non-zero byteLength`);
+ }
+ if (this._closeRequested) {
+ throw new TypeError('stream is closed or draining');
+ }
+ const state = this._controlledReadableByteStream._state;
+ if (state !== 'readable') {
+ throw new TypeError(`The stream (in ${state} state) is not in the readable state and cannot be enqueued to`);
+ }
+ ReadableByteStreamControllerEnqueue(this, chunk);
+ }
+ /**
+ * Errors the controlled readable stream, making all future interactions with it fail with the given error `e`.
+ */
+ error(e = undefined) {
+ if (!IsReadableByteStreamController(this)) {
+ throw byteStreamControllerBrandCheckException('error');
+ }
+ ReadableByteStreamControllerError(this, e);
+ }
+ /** @internal */
+ [CancelSteps](reason) {
+ ReadableByteStreamControllerClearPendingPullIntos(this);
+ ResetQueue(this);
+ const result = this._cancelAlgorithm(reason);
+ ReadableByteStreamControllerClearAlgorithms(this);
+ return result;
+ }
+ /** @internal */
+ [PullSteps](readRequest) {
+ const stream = this._controlledReadableByteStream;
+ if (this._queueTotalSize > 0) {
+ const entry = this._queue.shift();
+ this._queueTotalSize -= entry.byteLength;
+ ReadableByteStreamControllerHandleQueueDrain(this);
+ const view = new Uint8Array(entry.buffer, entry.byteOffset, entry.byteLength);
+ readRequest._chunkSteps(view);
+ return;
+ }
+ const autoAllocateChunkSize = this._autoAllocateChunkSize;
+ if (autoAllocateChunkSize !== undefined) {
+ let buffer;
+ try {
+ buffer = new ArrayBuffer(autoAllocateChunkSize);
+ }
+ catch (bufferE) {
+ readRequest._errorSteps(bufferE);
+ return;
+ }
+ const pullIntoDescriptor = {
+ buffer,
+ bufferByteLength: autoAllocateChunkSize,
+ byteOffset: 0,
+ byteLength: autoAllocateChunkSize,
+ bytesFilled: 0,
+ elementSize: 1,
+ viewConstructor: Uint8Array,
+ readerType: 'default'
+ };
+ this._pendingPullIntos.push(pullIntoDescriptor);
+ }
+ ReadableStreamAddReadRequest(stream, readRequest);
+ ReadableByteStreamControllerCallPullIfNeeded(this);
+ }
+ }
+ Object.defineProperties(ReadableByteStreamController.prototype, {
+ close: { enumerable: true },
+ enqueue: { enumerable: true },
+ error: { enumerable: true },
+ byobRequest: { enumerable: true },
+ desiredSize: { enumerable: true }
+ });
+ if (typeof SymbolPolyfill.toStringTag === 'symbol') {
+ Object.defineProperty(ReadableByteStreamController.prototype, SymbolPolyfill.toStringTag, {
+ value: 'ReadableByteStreamController',
+ configurable: true
+ });
+ }
+ // Abstract operations for the ReadableByteStreamController.
+ function IsReadableByteStreamController(x) {
+ if (!typeIsObject(x)) {
+ return false;
+ }
+ if (!Object.prototype.hasOwnProperty.call(x, '_controlledReadableByteStream')) {
+ return false;
+ }
+ return x instanceof ReadableByteStreamController;
+ }
+ function IsReadableStreamBYOBRequest(x) {
+ if (!typeIsObject(x)) {
+ return false;
+ }
+ if (!Object.prototype.hasOwnProperty.call(x, '_associatedReadableByteStreamController')) {
+ return false;
+ }
+ return x instanceof ReadableStreamBYOBRequest;
+ }
+ function ReadableByteStreamControllerCallPullIfNeeded(controller) {
+ const shouldPull = ReadableByteStreamControllerShouldCallPull(controller);
+ if (!shouldPull) {
+ return;
+ }
+ if (controller._pulling) {
+ controller._pullAgain = true;
+ return;
+ }
+ controller._pulling = true;
+ // TODO: Test controller argument
+ const pullPromise = controller._pullAlgorithm();
+ uponPromise(pullPromise, () => {
+ controller._pulling = false;
+ if (controller._pullAgain) {
+ controller._pullAgain = false;
+ ReadableByteStreamControllerCallPullIfNeeded(controller);
+ }
+ }, e => {
+ ReadableByteStreamControllerError(controller, e);
+ });
+ }
+ function ReadableByteStreamControllerClearPendingPullIntos(controller) {
+ ReadableByteStreamControllerInvalidateBYOBRequest(controller);
+ controller._pendingPullIntos = new SimpleQueue();
+ }
+ function ReadableByteStreamControllerCommitPullIntoDescriptor(stream, pullIntoDescriptor) {
+ let done = false;
+ if (stream._state === 'closed') {
+ done = true;
+ }
+ const filledView = ReadableByteStreamControllerConvertPullIntoDescriptor(pullIntoDescriptor);
+ if (pullIntoDescriptor.readerType === 'default') {
+ ReadableStreamFulfillReadRequest(stream, filledView, done);
+ }
+ else {
+ ReadableStreamFulfillReadIntoRequest(stream, filledView, done);
+ }
+ }
+ function ReadableByteStreamControllerConvertPullIntoDescriptor(pullIntoDescriptor) {
+ const bytesFilled = pullIntoDescriptor.bytesFilled;
+ const elementSize = pullIntoDescriptor.elementSize;
+ return new pullIntoDescriptor.viewConstructor(pullIntoDescriptor.buffer, pullIntoDescriptor.byteOffset, bytesFilled / elementSize);
+ }
+ function ReadableByteStreamControllerEnqueueChunkToQueue(controller, buffer, byteOffset, byteLength) {
+ controller._queue.push({ buffer, byteOffset, byteLength });
+ controller._queueTotalSize += byteLength;
+ }
+ function ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(controller, pullIntoDescriptor) {
+ const elementSize = pullIntoDescriptor.elementSize;
+ const currentAlignedBytes = pullIntoDescriptor.bytesFilled - pullIntoDescriptor.bytesFilled % elementSize;
+ const maxBytesToCopy = Math.min(controller._queueTotalSize, pullIntoDescriptor.byteLength - pullIntoDescriptor.bytesFilled);
+ const maxBytesFilled = pullIntoDescriptor.bytesFilled + maxBytesToCopy;
+ const maxAlignedBytes = maxBytesFilled - maxBytesFilled % elementSize;
+ let totalBytesToCopyRemaining = maxBytesToCopy;
+ let ready = false;
+ if (maxAlignedBytes > currentAlignedBytes) {
+ totalBytesToCopyRemaining = maxAlignedBytes - pullIntoDescriptor.bytesFilled;
+ ready = true;
+ }
+ const queue = controller._queue;
+ while (totalBytesToCopyRemaining > 0) {
+ const headOfQueue = queue.peek();
+ const bytesToCopy = Math.min(totalBytesToCopyRemaining, headOfQueue.byteLength);
+ const destStart = pullIntoDescriptor.byteOffset + pullIntoDescriptor.bytesFilled;
+ CopyDataBlockBytes(pullIntoDescriptor.buffer, destStart, headOfQueue.buffer, headOfQueue.byteOffset, bytesToCopy);
+ if (headOfQueue.byteLength === bytesToCopy) {
+ queue.shift();
+ }
+ else {
+ headOfQueue.byteOffset += bytesToCopy;
+ headOfQueue.byteLength -= bytesToCopy;
+ }
+ controller._queueTotalSize -= bytesToCopy;
+ ReadableByteStreamControllerFillHeadPullIntoDescriptor(controller, bytesToCopy, pullIntoDescriptor);
+ totalBytesToCopyRemaining -= bytesToCopy;
+ }
+ return ready;
+ }
+ function ReadableByteStreamControllerFillHeadPullIntoDescriptor(controller, size, pullIntoDescriptor) {
+ pullIntoDescriptor.bytesFilled += size;
+ }
+ function ReadableByteStreamControllerHandleQueueDrain(controller) {
+ if (controller._queueTotalSize === 0 && controller._closeRequested) {
+ ReadableByteStreamControllerClearAlgorithms(controller);
+ ReadableStreamClose(controller._controlledReadableByteStream);
+ }
+ else {
+ ReadableByteStreamControllerCallPullIfNeeded(controller);
+ }
+ }
+ function ReadableByteStreamControllerInvalidateBYOBRequest(controller) {
+ if (controller._byobRequest === null) {
+ return;
+ }
+ controller._byobRequest._associatedReadableByteStreamController = undefined;
+ controller._byobRequest._view = null;
+ controller._byobRequest = null;
+ }
+ function ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller) {
+ while (controller._pendingPullIntos.length > 0) {
+ if (controller._queueTotalSize === 0) {
+ return;
+ }
+ const pullIntoDescriptor = controller._pendingPullIntos.peek();
+ if (ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(controller, pullIntoDescriptor)) {
+ ReadableByteStreamControllerShiftPendingPullInto(controller);
+ ReadableByteStreamControllerCommitPullIntoDescriptor(controller._controlledReadableByteStream, pullIntoDescriptor);
+ }
+ }
+ }
+ function ReadableByteStreamControllerPullInto(controller, view, readIntoRequest) {
+ const stream = controller._controlledReadableByteStream;
+ let elementSize = 1;
+ if (view.constructor !== DataView) {
+ elementSize = view.constructor.BYTES_PER_ELEMENT;
+ }
+ const ctor = view.constructor;
+ // try {
+ const buffer = TransferArrayBuffer(view.buffer);
+ // } catch (e) {
+ // readIntoRequest._errorSteps(e);
+ // return;
+ // }
+ const pullIntoDescriptor = {
+ buffer,
+ bufferByteLength: buffer.byteLength,
+ byteOffset: view.byteOffset,
+ byteLength: view.byteLength,
+ bytesFilled: 0,
+ elementSize,
+ viewConstructor: ctor,
+ readerType: 'byob'
+ };
+ if (controller._pendingPullIntos.length > 0) {
+ controller._pendingPullIntos.push(pullIntoDescriptor);
+ // No ReadableByteStreamControllerCallPullIfNeeded() call since:
+ // - No change happens on desiredSize
+ // - The source has already been notified of that there's at least 1 pending read(view)
+ ReadableStreamAddReadIntoRequest(stream, readIntoRequest);
+ return;
+ }
+ if (stream._state === 'closed') {
+ const emptyView = new ctor(pullIntoDescriptor.buffer, pullIntoDescriptor.byteOffset, 0);
+ readIntoRequest._closeSteps(emptyView);
+ return;
+ }
+ if (controller._queueTotalSize > 0) {
+ if (ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(controller, pullIntoDescriptor)) {
+ const filledView = ReadableByteStreamControllerConvertPullIntoDescriptor(pullIntoDescriptor);
+ ReadableByteStreamControllerHandleQueueDrain(controller);
+ readIntoRequest._chunkSteps(filledView);
+ return;
+ }
+ if (controller._closeRequested) {
+ const e = new TypeError('Insufficient bytes to fill elements in the given buffer');
+ ReadableByteStreamControllerError(controller, e);
+ readIntoRequest._errorSteps(e);
+ return;
+ }
+ }
+ controller._pendingPullIntos.push(pullIntoDescriptor);
+ ReadableStreamAddReadIntoRequest(stream, readIntoRequest);
+ ReadableByteStreamControllerCallPullIfNeeded(controller);
+ }
+ function ReadableByteStreamControllerRespondInClosedState(controller, firstDescriptor) {
+ const stream = controller._controlledReadableByteStream;
+ if (ReadableStreamHasBYOBReader(stream)) {
+ while (ReadableStreamGetNumReadIntoRequests(stream) > 0) {
+ const pullIntoDescriptor = ReadableByteStreamControllerShiftPendingPullInto(controller);
+ ReadableByteStreamControllerCommitPullIntoDescriptor(stream, pullIntoDescriptor);
+ }
+ }
+ }
+ function ReadableByteStreamControllerRespondInReadableState(controller, bytesWritten, pullIntoDescriptor) {
+ ReadableByteStreamControllerFillHeadPullIntoDescriptor(controller, bytesWritten, pullIntoDescriptor);
+ if (pullIntoDescriptor.bytesFilled < pullIntoDescriptor.elementSize) {
+ return;
+ }
+ ReadableByteStreamControllerShiftPendingPullInto(controller);
+ const remainderSize = pullIntoDescriptor.bytesFilled % pullIntoDescriptor.elementSize;
+ if (remainderSize > 0) {
+ const end = pullIntoDescriptor.byteOffset + pullIntoDescriptor.bytesFilled;
+ const remainder = ArrayBufferSlice(pullIntoDescriptor.buffer, end - remainderSize, end);
+ ReadableByteStreamControllerEnqueueChunkToQueue(controller, remainder, 0, remainder.byteLength);
+ }
+ pullIntoDescriptor.bytesFilled -= remainderSize;
+ ReadableByteStreamControllerCommitPullIntoDescriptor(controller._controlledReadableByteStream, pullIntoDescriptor);
+ ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller);
+ }
+ function ReadableByteStreamControllerRespondInternal(controller, bytesWritten) {
+ const firstDescriptor = controller._pendingPullIntos.peek();
+ ReadableByteStreamControllerInvalidateBYOBRequest(controller);
+ const state = controller._controlledReadableByteStream._state;
+ if (state === 'closed') {
+ ReadableByteStreamControllerRespondInClosedState(controller);
+ }
+ else {
+ ReadableByteStreamControllerRespondInReadableState(controller, bytesWritten, firstDescriptor);
+ }
+ ReadableByteStreamControllerCallPullIfNeeded(controller);
+ }
+ function ReadableByteStreamControllerShiftPendingPullInto(controller) {
+ const descriptor = controller._pendingPullIntos.shift();
+ return descriptor;
+ }
+ function ReadableByteStreamControllerShouldCallPull(controller) {
+ const stream = controller._controlledReadableByteStream;
+ if (stream._state !== 'readable') {
+ return false;
+ }
+ if (controller._closeRequested) {
+ return false;
+ }
+ if (!controller._started) {
+ return false;
+ }
+ if (ReadableStreamHasDefaultReader(stream) && ReadableStreamGetNumReadRequests(stream) > 0) {
+ return true;
+ }
+ if (ReadableStreamHasBYOBReader(stream) && ReadableStreamGetNumReadIntoRequests(stream) > 0) {
+ return true;
+ }
+ const desiredSize = ReadableByteStreamControllerGetDesiredSize(controller);
+ if (desiredSize > 0) {
+ return true;
+ }
+ return false;
+ }
+ function ReadableByteStreamControllerClearAlgorithms(controller) {
+ controller._pullAlgorithm = undefined;
+ controller._cancelAlgorithm = undefined;
+ }
+ // A client of ReadableByteStreamController may use these functions directly to bypass state check.
+ function ReadableByteStreamControllerClose(controller) {
+ const stream = controller._controlledReadableByteStream;
+ if (controller._closeRequested || stream._state !== 'readable') {
+ return;
+ }
+ if (controller._queueTotalSize > 0) {
+ controller._closeRequested = true;
+ return;
+ }
+ if (controller._pendingPullIntos.length > 0) {
+ const firstPendingPullInto = controller._pendingPullIntos.peek();
+ if (firstPendingPullInto.bytesFilled > 0) {
+ const e = new TypeError('Insufficient bytes to fill elements in the given buffer');
+ ReadableByteStreamControllerError(controller, e);
+ throw e;
+ }
+ }
+ ReadableByteStreamControllerClearAlgorithms(controller);
+ ReadableStreamClose(stream);
+ }
+ function ReadableByteStreamControllerEnqueue(controller, chunk) {
+ const stream = controller._controlledReadableByteStream;
+ if (controller._closeRequested || stream._state !== 'readable') {
+ return;
+ }
+ const buffer = chunk.buffer;
+ const byteOffset = chunk.byteOffset;
+ const byteLength = chunk.byteLength;
+ const transferredBuffer = TransferArrayBuffer(buffer);
+ if (controller._pendingPullIntos.length > 0) {
+ const firstPendingPullInto = controller._pendingPullIntos.peek();
+ if (IsDetachedBuffer(firstPendingPullInto.buffer)) ;
+ firstPendingPullInto.buffer = TransferArrayBuffer(firstPendingPullInto.buffer);
+ }
+ ReadableByteStreamControllerInvalidateBYOBRequest(controller);
+ if (ReadableStreamHasDefaultReader(stream)) {
+ if (ReadableStreamGetNumReadRequests(stream) === 0) {
+ ReadableByteStreamControllerEnqueueChunkToQueue(controller, transferredBuffer, byteOffset, byteLength);
+ }
+ else {
+ if (controller._pendingPullIntos.length > 0) {
+ ReadableByteStreamControllerShiftPendingPullInto(controller);
+ }
+ const transferredView = new Uint8Array(transferredBuffer, byteOffset, byteLength);
+ ReadableStreamFulfillReadRequest(stream, transferredView, false);
+ }
+ }
+ else if (ReadableStreamHasBYOBReader(stream)) {
+ // TODO: Ideally in this branch detaching should happen only if the buffer is not consumed fully.
+ ReadableByteStreamControllerEnqueueChunkToQueue(controller, transferredBuffer, byteOffset, byteLength);
+ ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller);
+ }
+ else {
+ ReadableByteStreamControllerEnqueueChunkToQueue(controller, transferredBuffer, byteOffset, byteLength);
+ }
+ ReadableByteStreamControllerCallPullIfNeeded(controller);
+ }
+ function ReadableByteStreamControllerError(controller, e) {
+ const stream = controller._controlledReadableByteStream;
+ if (stream._state !== 'readable') {
+ return;
+ }
+ ReadableByteStreamControllerClearPendingPullIntos(controller);
+ ResetQueue(controller);
+ ReadableByteStreamControllerClearAlgorithms(controller);
+ ReadableStreamError(stream, e);
+ }
+ function ReadableByteStreamControllerGetBYOBRequest(controller) {
+ if (controller._byobRequest === null && controller._pendingPullIntos.length > 0) {
+ const firstDescriptor = controller._pendingPullIntos.peek();
+ const view = new Uint8Array(firstDescriptor.buffer, firstDescriptor.byteOffset + firstDescriptor.bytesFilled, firstDescriptor.byteLength - firstDescriptor.bytesFilled);
+ const byobRequest = Object.create(ReadableStreamBYOBRequest.prototype);
+ SetUpReadableStreamBYOBRequest(byobRequest, controller, view);
+ controller._byobRequest = byobRequest;
+ }
+ return controller._byobRequest;
+ }
+ function ReadableByteStreamControllerGetDesiredSize(controller) {
+ const state = controller._controlledReadableByteStream._state;
+ if (state === 'errored') {
+ return null;
+ }
+ if (state === 'closed') {
+ return 0;
+ }
+ return controller._strategyHWM - controller._queueTotalSize;
+ }
+ function ReadableByteStreamControllerRespond(controller, bytesWritten) {
+ const firstDescriptor = controller._pendingPullIntos.peek();
+ const state = controller._controlledReadableByteStream._state;
+ if (state === 'closed') {
+ if (bytesWritten !== 0) {
+ throw new TypeError('bytesWritten must be 0 when calling respond() on a closed stream');
+ }
+ }
+ else {
+ if (bytesWritten === 0) {
+ throw new TypeError('bytesWritten must be greater than 0 when calling respond() on a readable stream');
+ }
+ if (firstDescriptor.bytesFilled + bytesWritten > firstDescriptor.byteLength) {
+ throw new RangeError('bytesWritten out of range');
+ }
+ }
+ firstDescriptor.buffer = TransferArrayBuffer(firstDescriptor.buffer);
+ ReadableByteStreamControllerRespondInternal(controller, bytesWritten);
+ }
+ function ReadableByteStreamControllerRespondWithNewView(controller, view) {
+ const firstDescriptor = controller._pendingPullIntos.peek();
+ const state = controller._controlledReadableByteStream._state;
+ if (state === 'closed') {
+ if (view.byteLength !== 0) {
+ throw new TypeError('The view\'s length must be 0 when calling respondWithNewView() on a closed stream');
+ }
+ }
+ else {
+ if (view.byteLength === 0) {
+ throw new TypeError('The view\'s length must be greater than 0 when calling respondWithNewView() on a readable stream');
+ }
+ }
+ if (firstDescriptor.byteOffset + firstDescriptor.bytesFilled !== view.byteOffset) {
+ throw new RangeError('The region specified by view does not match byobRequest');
+ }
+ if (firstDescriptor.bufferByteLength !== view.buffer.byteLength) {
+ throw new RangeError('The buffer of view has different capacity than byobRequest');
+ }
+ if (firstDescriptor.bytesFilled + view.byteLength > firstDescriptor.byteLength) {
+ throw new RangeError('The region specified by view is larger than byobRequest');
+ }
+ const viewByteLength = view.byteLength;
+ firstDescriptor.buffer = TransferArrayBuffer(view.buffer);
+ ReadableByteStreamControllerRespondInternal(controller, viewByteLength);
+ }
+ function SetUpReadableByteStreamController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, autoAllocateChunkSize) {
+ controller._controlledReadableByteStream = stream;
+ controller._pullAgain = false;
+ controller._pulling = false;
+ controller._byobRequest = null;
+ // Need to set the slots so that the assert doesn't fire. In the spec the slots already exist implicitly.
+ controller._queue = controller._queueTotalSize = undefined;
+ ResetQueue(controller);
+ controller._closeRequested = false;
+ controller._started = false;
+ controller._strategyHWM = highWaterMark;
+ controller._pullAlgorithm = pullAlgorithm;
+ controller._cancelAlgorithm = cancelAlgorithm;
+ controller._autoAllocateChunkSize = autoAllocateChunkSize;
+ controller._pendingPullIntos = new SimpleQueue();
+ stream._readableStreamController = controller;
+ const startResult = startAlgorithm();
+ uponPromise(promiseResolvedWith(startResult), () => {
+ controller._started = true;
+ ReadableByteStreamControllerCallPullIfNeeded(controller);
+ }, r => {
+ ReadableByteStreamControllerError(controller, r);
+ });
+ }
+ function SetUpReadableByteStreamControllerFromUnderlyingSource(stream, underlyingByteSource, highWaterMark) {
+ const controller = Object.create(ReadableByteStreamController.prototype);
+ let startAlgorithm = () => undefined;
+ let pullAlgorithm = () => promiseResolvedWith(undefined);
+ let cancelAlgorithm = () => promiseResolvedWith(undefined);
+ if (underlyingByteSource.start !== undefined) {
+ startAlgorithm = () => underlyingByteSource.start(controller);
+ }
+ if (underlyingByteSource.pull !== undefined) {
+ pullAlgorithm = () => underlyingByteSource.pull(controller);
+ }
+ if (underlyingByteSource.cancel !== undefined) {
+ cancelAlgorithm = reason => underlyingByteSource.cancel(reason);
+ }
+ const autoAllocateChunkSize = underlyingByteSource.autoAllocateChunkSize;
+ if (autoAllocateChunkSize === 0) {
+ throw new TypeError('autoAllocateChunkSize must be greater than 0');
+ }
+ SetUpReadableByteStreamController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, autoAllocateChunkSize);
+ }
+ function SetUpReadableStreamBYOBRequest(request, controller, view) {
+ request._associatedReadableByteStreamController = controller;
+ request._view = view;
+ }
+ // Helper functions for the ReadableStreamBYOBRequest.
+ function byobRequestBrandCheckException(name) {
+ return new TypeError(`ReadableStreamBYOBRequest.prototype.${name} can only be used on a ReadableStreamBYOBRequest`);
+ }
+ // Helper functions for the ReadableByteStreamController.
+ function byteStreamControllerBrandCheckException(name) {
+ return new TypeError(`ReadableByteStreamController.prototype.${name} can only be used on a ReadableByteStreamController`);
+ }
+
+ // Abstract operations for the ReadableStream.
+ function AcquireReadableStreamBYOBReader(stream) {
+ return new ReadableStreamBYOBReader(stream);
+ }
+ // ReadableStream API exposed for controllers.
+ function ReadableStreamAddReadIntoRequest(stream, readIntoRequest) {
+ stream._reader._readIntoRequests.push(readIntoRequest);
+ }
+ function ReadableStreamFulfillReadIntoRequest(stream, chunk, done) {
+ const reader = stream._reader;
+ const readIntoRequest = reader._readIntoRequests.shift();
+ if (done) {
+ readIntoRequest._closeSteps(chunk);
+ }
+ else {
+ readIntoRequest._chunkSteps(chunk);
+ }
+ }
+ function ReadableStreamGetNumReadIntoRequests(stream) {
+ return stream._reader._readIntoRequests.length;
+ }
+ function ReadableStreamHasBYOBReader(stream) {
+ const reader = stream._reader;
+ if (reader === undefined) {
+ return false;
+ }
+ if (!IsReadableStreamBYOBReader(reader)) {
+ return false;
+ }
+ return true;
+ }
+ /**
+ * A BYOB reader vended by a {@link ReadableStream}.
+ *
+ * @public
+ */
+ class ReadableStreamBYOBReader {
+ constructor(stream) {
+ assertRequiredArgument(stream, 1, 'ReadableStreamBYOBReader');
+ assertReadableStream(stream, 'First parameter');
+ if (IsReadableStreamLocked(stream)) {
+ throw new TypeError('This stream has already been locked for exclusive reading by another reader');
+ }
+ if (!IsReadableByteStreamController(stream._readableStreamController)) {
+ throw new TypeError('Cannot construct a ReadableStreamBYOBReader for a stream not constructed with a byte ' +
+ 'source');
+ }
+ ReadableStreamReaderGenericInitialize(this, stream);
+ this._readIntoRequests = new SimpleQueue();
+ }
+ /**
+ * Returns a promise that will be fulfilled when the stream becomes closed, or rejected if the stream ever errors or
+ * the reader's lock is released before the stream finishes closing.
+ */
+ get closed() {
+ if (!IsReadableStreamBYOBReader(this)) {
+ return promiseRejectedWith(byobReaderBrandCheckException('closed'));
+ }
+ return this._closedPromise;
+ }
+ /**
+ * If the reader is active, behaves the same as {@link ReadableStream.cancel | stream.cancel(reason)}.
+ */
+ cancel(reason = undefined) {
+ if (!IsReadableStreamBYOBReader(this)) {
+ return promiseRejectedWith(byobReaderBrandCheckException('cancel'));
+ }
+ if (this._ownerReadableStream === undefined) {
+ return promiseRejectedWith(readerLockException('cancel'));
+ }
+ return ReadableStreamReaderGenericCancel(this, reason);
+ }
+ /**
+ * Attempts to reads bytes into view, and returns a promise resolved with the result.
+ *
+ * If reading a chunk causes the queue to become empty, more data will be pulled from the underlying source.
+ */
+ read(view) {
+ if (!IsReadableStreamBYOBReader(this)) {
+ return promiseRejectedWith(byobReaderBrandCheckException('read'));
+ }
+ if (!ArrayBuffer.isView(view)) {
+ return promiseRejectedWith(new TypeError('view must be an array buffer view'));
+ }
+ if (view.byteLength === 0) {
+ return promiseRejectedWith(new TypeError('view must have non-zero byteLength'));
+ }
+ if (view.buffer.byteLength === 0) {
+ return promiseRejectedWith(new TypeError(`view's buffer must have non-zero byteLength`));
+ }
+ if (IsDetachedBuffer(view.buffer)) ;
+ if (this._ownerReadableStream === undefined) {
+ return promiseRejectedWith(readerLockException('read from'));
+ }
+ let resolvePromise;
+ let rejectPromise;
+ const promise = newPromise((resolve, reject) => {
+ resolvePromise = resolve;
+ rejectPromise = reject;
+ });
+ const readIntoRequest = {
+ _chunkSteps: chunk => resolvePromise({ value: chunk, done: false }),
+ _closeSteps: chunk => resolvePromise({ value: chunk, done: true }),
+ _errorSteps: e => rejectPromise(e)
+ };
+ ReadableStreamBYOBReaderRead(this, view, readIntoRequest);
+ return promise;
+ }
+ /**
+ * Releases the reader's lock on the corresponding stream. After the lock is released, the reader is no longer active.
+ * If the associated stream is errored when the lock is released, the reader will appear errored in the same way
+ * from now on; otherwise, the reader will appear closed.
+ *
+ * A reader's lock cannot be released while it still has a pending read request, i.e., if a promise returned by
+ * the reader's {@link ReadableStreamBYOBReader.read | read()} method has not yet been settled. Attempting to
+ * do so will throw a `TypeError` and leave the reader locked to the stream.
+ */
+ releaseLock() {
+ if (!IsReadableStreamBYOBReader(this)) {
+ throw byobReaderBrandCheckException('releaseLock');
+ }
+ if (this._ownerReadableStream === undefined) {
+ return;
+ }
+ if (this._readIntoRequests.length > 0) {
+ throw new TypeError('Tried to release a reader lock when that reader has pending read() calls un-settled');
+ }
+ ReadableStreamReaderGenericRelease(this);
+ }
+ }
+ Object.defineProperties(ReadableStreamBYOBReader.prototype, {
+ cancel: { enumerable: true },
+ read: { enumerable: true },
+ releaseLock: { enumerable: true },
+ closed: { enumerable: true }
+ });
+ if (typeof SymbolPolyfill.toStringTag === 'symbol') {
+ Object.defineProperty(ReadableStreamBYOBReader.prototype, SymbolPolyfill.toStringTag, {
+ value: 'ReadableStreamBYOBReader',
+ configurable: true
+ });
+ }
+ // Abstract operations for the readers.
+ function IsReadableStreamBYOBReader(x) {
+ if (!typeIsObject(x)) {
+ return false;
+ }
+ if (!Object.prototype.hasOwnProperty.call(x, '_readIntoRequests')) {
+ return false;
+ }
+ return x instanceof ReadableStreamBYOBReader;
+ }
+ function ReadableStreamBYOBReaderRead(reader, view, readIntoRequest) {
+ const stream = reader._ownerReadableStream;
+ stream._disturbed = true;
+ if (stream._state === 'errored') {
+ readIntoRequest._errorSteps(stream._storedError);
+ }
+ else {
+ ReadableByteStreamControllerPullInto(stream._readableStreamController, view, readIntoRequest);
+ }
+ }
+ // Helper functions for the ReadableStreamBYOBReader.
+ function byobReaderBrandCheckException(name) {
+ return new TypeError(`ReadableStreamBYOBReader.prototype.${name} can only be used on a ReadableStreamBYOBReader`);
+ }
+
+ function ExtractHighWaterMark(strategy, defaultHWM) {
+ const { highWaterMark } = strategy;
+ if (highWaterMark === undefined) {
+ return defaultHWM;
+ }
+ if (NumberIsNaN(highWaterMark) || highWaterMark < 0) {
+ throw new RangeError('Invalid highWaterMark');
+ }
+ return highWaterMark;
+ }
+ function ExtractSizeAlgorithm(strategy) {
+ const { size } = strategy;
+ if (!size) {
+ return () => 1;
+ }
+ return size;
+ }
+
+ function convertQueuingStrategy(init, context) {
+ assertDictionary(init, context);
+ const highWaterMark = init === null || init === void 0 ? void 0 : init.highWaterMark;
+ const size = init === null || init === void 0 ? void 0 : init.size;
+ return {
+ highWaterMark: highWaterMark === undefined ? undefined : convertUnrestrictedDouble(highWaterMark),
+ size: size === undefined ? undefined : convertQueuingStrategySize(size, `${context} has member 'size' that`)
+ };
+ }
+ function convertQueuingStrategySize(fn, context) {
+ assertFunction(fn, context);
+ return chunk => convertUnrestrictedDouble(fn(chunk));
+ }
+
+ function convertUnderlyingSink(original, context) {
+ assertDictionary(original, context);
+ const abort = original === null || original === void 0 ? void 0 : original.abort;
+ const close = original === null || original === void 0 ? void 0 : original.close;
+ const start = original === null || original === void 0 ? void 0 : original.start;
+ const type = original === null || original === void 0 ? void 0 : original.type;
+ const write = original === null || original === void 0 ? void 0 : original.write;
+ return {
+ abort: abort === undefined ?
+ undefined :
+ convertUnderlyingSinkAbortCallback(abort, original, `${context} has member 'abort' that`),
+ close: close === undefined ?
+ undefined :
+ convertUnderlyingSinkCloseCallback(close, original, `${context} has member 'close' that`),
+ start: start === undefined ?
+ undefined :
+ convertUnderlyingSinkStartCallback(start, original, `${context} has member 'start' that`),
+ write: write === undefined ?
+ undefined :
+ convertUnderlyingSinkWriteCallback(write, original, `${context} has member 'write' that`),
+ type
+ };
+ }
+ function convertUnderlyingSinkAbortCallback(fn, original, context) {
+ assertFunction(fn, context);
+ return (reason) => promiseCall(fn, original, [reason]);
+ }
+ function convertUnderlyingSinkCloseCallback(fn, original, context) {
+ assertFunction(fn, context);
+ return () => promiseCall(fn, original, []);
+ }
+ function convertUnderlyingSinkStartCallback(fn, original, context) {
+ assertFunction(fn, context);
+ return (controller) => reflectCall(fn, original, [controller]);
+ }
+ function convertUnderlyingSinkWriteCallback(fn, original, context) {
+ assertFunction(fn, context);
+ return (chunk, controller) => promiseCall(fn, original, [chunk, controller]);
+ }
+
+ function assertWritableStream(x, context) {
+ if (!IsWritableStream(x)) {
+ throw new TypeError(`${context} is not a WritableStream.`);
+ }
+ }
+
+ function isAbortSignal(value) {
+ if (typeof value !== 'object' || value === null) {
+ return false;
+ }
+ try {
+ return typeof value.aborted === 'boolean';
+ }
+ catch (_a) {
+ // AbortSignal.prototype.aborted throws if its brand check fails
+ return false;
+ }
+ }
+ const supportsAbortController = typeof AbortController === 'function';
+ /**
+ * Construct a new AbortController, if supported by the platform.
+ *
+ * @internal
+ */
+ function createAbortController() {
+ if (supportsAbortController) {
+ return new AbortController();
+ }
+ return undefined;
+ }
+
+ /**
+ * A writable stream represents a destination for data, into which you can write.
+ *
+ * @public
+ */
+ class WritableStream {
+ constructor(rawUnderlyingSink = {}, rawStrategy = {}) {
+ if (rawUnderlyingSink === undefined) {
+ rawUnderlyingSink = null;
+ }
+ else {
+ assertObject(rawUnderlyingSink, 'First parameter');
+ }
+ const strategy = convertQueuingStrategy(rawStrategy, 'Second parameter');
+ const underlyingSink = convertUnderlyingSink(rawUnderlyingSink, 'First parameter');
+ InitializeWritableStream(this);
+ const type = underlyingSink.type;
+ if (type !== undefined) {
+ throw new RangeError('Invalid type is specified');
+ }
+ const sizeAlgorithm = ExtractSizeAlgorithm(strategy);
+ const highWaterMark = ExtractHighWaterMark(strategy, 1);
+ SetUpWritableStreamDefaultControllerFromUnderlyingSink(this, underlyingSink, highWaterMark, sizeAlgorithm);
+ }
+ /**
+ * Returns whether or not the writable stream is locked to a writer.
+ */
+ get locked() {
+ if (!IsWritableStream(this)) {
+ throw streamBrandCheckException$2('locked');
+ }
+ return IsWritableStreamLocked(this);
+ }
+ /**
+ * Aborts the stream, signaling that the producer can no longer successfully write to the stream and it is to be
+ * immediately moved to an errored state, with any queued-up writes discarded. This will also execute any abort
+ * mechanism of the underlying sink.
+ *
+ * The returned promise will fulfill if the stream shuts down successfully, or reject if the underlying sink signaled
+ * that there was an error doing so. Additionally, it will reject with a `TypeError` (without attempting to cancel
+ * the stream) if the stream is currently locked.
+ */
+ abort(reason = undefined) {
+ if (!IsWritableStream(this)) {
+ return promiseRejectedWith(streamBrandCheckException$2('abort'));
+ }
+ if (IsWritableStreamLocked(this)) {
+ return promiseRejectedWith(new TypeError('Cannot abort a stream that already has a writer'));
+ }
+ return WritableStreamAbort(this, reason);
+ }
+ /**
+ * Closes the stream. The underlying sink will finish processing any previously-written chunks, before invoking its
+ * close behavior. During this time any further attempts to write will fail (without erroring the stream).
+ *
+ * The method returns a promise that will fulfill if all remaining chunks are successfully written and the stream
+ * successfully closes, or rejects if an error is encountered during this process. Additionally, it will reject with
+ * a `TypeError` (without attempting to cancel the stream) if the stream is currently locked.
+ */
+ close() {
+ if (!IsWritableStream(this)) {
+ return promiseRejectedWith(streamBrandCheckException$2('close'));
+ }
+ if (IsWritableStreamLocked(this)) {
+ return promiseRejectedWith(new TypeError('Cannot close a stream that already has a writer'));
+ }
+ if (WritableStreamCloseQueuedOrInFlight(this)) {
+ return promiseRejectedWith(new TypeError('Cannot close an already-closing stream'));
+ }
+ return WritableStreamClose(this);
+ }
+ /**
+ * Creates a {@link WritableStreamDefaultWriter | writer} and locks the stream to the new writer. While the stream
+ * is locked, no other writer can be acquired until this one is released.
+ *
+ * This functionality is especially useful for creating abstractions that desire the ability to write to a stream
+ * without interruption or interleaving. By getting a writer for the stream, you can ensure nobody else can write at
+ * the same time, which would cause the resulting written data to be unpredictable and probably useless.
+ */
+ getWriter() {
+ if (!IsWritableStream(this)) {
+ throw streamBrandCheckException$2('getWriter');
+ }
+ return AcquireWritableStreamDefaultWriter(this);
+ }
+ }
+ Object.defineProperties(WritableStream.prototype, {
+ abort: { enumerable: true },
+ close: { enumerable: true },
+ getWriter: { enumerable: true },
+ locked: { enumerable: true }
+ });
+ if (typeof SymbolPolyfill.toStringTag === 'symbol') {
+ Object.defineProperty(WritableStream.prototype, SymbolPolyfill.toStringTag, {
+ value: 'WritableStream',
+ configurable: true
+ });
+ }
+ // Abstract operations for the WritableStream.
+ function AcquireWritableStreamDefaultWriter(stream) {
+ return new WritableStreamDefaultWriter(stream);
+ }
+ // Throws if and only if startAlgorithm throws.
+ function CreateWritableStream(startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark = 1, sizeAlgorithm = () => 1) {
+ const stream = Object.create(WritableStream.prototype);
+ InitializeWritableStream(stream);
+ const controller = Object.create(WritableStreamDefaultController.prototype);
+ SetUpWritableStreamDefaultController(stream, controller, startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark, sizeAlgorithm);
+ return stream;
+ }
+ function InitializeWritableStream(stream) {
+ stream._state = 'writable';
+ // The error that will be reported by new method calls once the state becomes errored. Only set when [[state]] is
+ // 'erroring' or 'errored'. May be set to an undefined value.
+ stream._storedError = undefined;
+ stream._writer = undefined;
+ // Initialize to undefined first because the constructor of the controller checks this
+ // variable to validate the caller.
+ stream._writableStreamController = undefined;
+ // This queue is placed here instead of the writer class in order to allow for passing a writer to the next data
+ // producer without waiting for the queued writes to finish.
+ stream._writeRequests = new SimpleQueue();
+ // Write requests are removed from _writeRequests when write() is called on the underlying sink. This prevents
+ // them from being erroneously rejected on error. If a write() call is in-flight, the request is stored here.
+ stream._inFlightWriteRequest = undefined;
+ // The promise that was returned from writer.close(). Stored here because it may be fulfilled after the writer
+ // has been detached.
+ stream._closeRequest = undefined;
+ // Close request is removed from _closeRequest when close() is called on the underlying sink. This prevents it
+ // from being erroneously rejected on error. If a close() call is in-flight, the request is stored here.
+ stream._inFlightCloseRequest = undefined;
+ // The promise that was returned from writer.abort(). This may also be fulfilled after the writer has detached.
+ stream._pendingAbortRequest = undefined;
+ // The backpressure signal set by the controller.
+ stream._backpressure = false;
+ }
+ function IsWritableStream(x) {
+ if (!typeIsObject(x)) {
+ return false;
+ }
+ if (!Object.prototype.hasOwnProperty.call(x, '_writableStreamController')) {
+ return false;
+ }
+ return x instanceof WritableStream;
+ }
+ function IsWritableStreamLocked(stream) {
+ if (stream._writer === undefined) {
+ return false;
+ }
+ return true;
+ }
+ function WritableStreamAbort(stream, reason) {
+ var _a;
+ if (stream._state === 'closed' || stream._state === 'errored') {
+ return promiseResolvedWith(undefined);
+ }
+ stream._writableStreamController._abortReason = reason;
+ (_a = stream._writableStreamController._abortController) === null || _a === void 0 ? void 0 : _a.abort();
+ // TypeScript narrows the type of `stream._state` down to 'writable' | 'erroring',
+ // but it doesn't know that signaling abort runs author code that might have changed the state.
+ // Widen the type again by casting to WritableStreamState.
+ const state = stream._state;
+ if (state === 'closed' || state === 'errored') {
+ return promiseResolvedWith(undefined);
+ }
+ if (stream._pendingAbortRequest !== undefined) {
+ return stream._pendingAbortRequest._promise;
+ }
+ let wasAlreadyErroring = false;
+ if (state === 'erroring') {
+ wasAlreadyErroring = true;
+ // reason will not be used, so don't keep a reference to it.
+ reason = undefined;
+ }
+ const promise = newPromise((resolve, reject) => {
+ stream._pendingAbortRequest = {
+ _promise: undefined,
+ _resolve: resolve,
+ _reject: reject,
+ _reason: reason,
+ _wasAlreadyErroring: wasAlreadyErroring
+ };
+ });
+ stream._pendingAbortRequest._promise = promise;
+ if (!wasAlreadyErroring) {
+ WritableStreamStartErroring(stream, reason);
+ }
+ return promise;
+ }
+ function WritableStreamClose(stream) {
+ const state = stream._state;
+ if (state === 'closed' || state === 'errored') {
+ return promiseRejectedWith(new TypeError(`The stream (in ${state} state) is not in the writable state and cannot be closed`));
+ }
+ const promise = newPromise((resolve, reject) => {
+ const closeRequest = {
+ _resolve: resolve,
+ _reject: reject
+ };
+ stream._closeRequest = closeRequest;
+ });
+ const writer = stream._writer;
+ if (writer !== undefined && stream._backpressure && state === 'writable') {
+ defaultWriterReadyPromiseResolve(writer);
+ }
+ WritableStreamDefaultControllerClose(stream._writableStreamController);
+ return promise;
+ }
+ // WritableStream API exposed for controllers.
+ function WritableStreamAddWriteRequest(stream) {
+ const promise = newPromise((resolve, reject) => {
+ const writeRequest = {
+ _resolve: resolve,
+ _reject: reject
+ };
+ stream._writeRequests.push(writeRequest);
+ });
+ return promise;
+ }
+ function WritableStreamDealWithRejection(stream, error) {
+ const state = stream._state;
+ if (state === 'writable') {
+ WritableStreamStartErroring(stream, error);
+ return;
+ }
+ WritableStreamFinishErroring(stream);
+ }
+ function WritableStreamStartErroring(stream, reason) {
+ const controller = stream._writableStreamController;
+ stream._state = 'erroring';
+ stream._storedError = reason;
+ const writer = stream._writer;
+ if (writer !== undefined) {
+ WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer, reason);
+ }
+ if (!WritableStreamHasOperationMarkedInFlight(stream) && controller._started) {
+ WritableStreamFinishErroring(stream);
+ }
+ }
+ function WritableStreamFinishErroring(stream) {
+ stream._state = 'errored';
+ stream._writableStreamController[ErrorSteps]();
+ const storedError = stream._storedError;
+ stream._writeRequests.forEach(writeRequest => {
+ writeRequest._reject(storedError);
+ });
+ stream._writeRequests = new SimpleQueue();
+ if (stream._pendingAbortRequest === undefined) {
+ WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream);
+ return;
+ }
+ const abortRequest = stream._pendingAbortRequest;
+ stream._pendingAbortRequest = undefined;
+ if (abortRequest._wasAlreadyErroring) {
+ abortRequest._reject(storedError);
+ WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream);
+ return;
+ }
+ const promise = stream._writableStreamController[AbortSteps](abortRequest._reason);
+ uponPromise(promise, () => {
+ abortRequest._resolve();
+ WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream);
+ }, (reason) => {
+ abortRequest._reject(reason);
+ WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream);
+ });
+ }
+ function WritableStreamFinishInFlightWrite(stream) {
+ stream._inFlightWriteRequest._resolve(undefined);
+ stream._inFlightWriteRequest = undefined;
+ }
+ function WritableStreamFinishInFlightWriteWithError(stream, error) {
+ stream._inFlightWriteRequest._reject(error);
+ stream._inFlightWriteRequest = undefined;
+ WritableStreamDealWithRejection(stream, error);
+ }
+ function WritableStreamFinishInFlightClose(stream) {
+ stream._inFlightCloseRequest._resolve(undefined);
+ stream._inFlightCloseRequest = undefined;
+ const state = stream._state;
+ if (state === 'erroring') {
+ // The error was too late to do anything, so it is ignored.
+ stream._storedError = undefined;
+ if (stream._pendingAbortRequest !== undefined) {
+ stream._pendingAbortRequest._resolve();
+ stream._pendingAbortRequest = undefined;
+ }
+ }
+ stream._state = 'closed';
+ const writer = stream._writer;
+ if (writer !== undefined) {
+ defaultWriterClosedPromiseResolve(writer);
+ }
+ }
+ function WritableStreamFinishInFlightCloseWithError(stream, error) {
+ stream._inFlightCloseRequest._reject(error);
+ stream._inFlightCloseRequest = undefined;
+ // Never execute sink abort() after sink close().
+ if (stream._pendingAbortRequest !== undefined) {
+ stream._pendingAbortRequest._reject(error);
+ stream._pendingAbortRequest = undefined;
+ }
+ WritableStreamDealWithRejection(stream, error);
+ }
+ // TODO(ricea): Fix alphabetical order.
+ function WritableStreamCloseQueuedOrInFlight(stream) {
+ if (stream._closeRequest === undefined && stream._inFlightCloseRequest === undefined) {
+ return false;
+ }
+ return true;
+ }
+ function WritableStreamHasOperationMarkedInFlight(stream) {
+ if (stream._inFlightWriteRequest === undefined && stream._inFlightCloseRequest === undefined) {
+ return false;
+ }
+ return true;
+ }
+ function WritableStreamMarkCloseRequestInFlight(stream) {
+ stream._inFlightCloseRequest = stream._closeRequest;
+ stream._closeRequest = undefined;
+ }
+ function WritableStreamMarkFirstWriteRequestInFlight(stream) {
+ stream._inFlightWriteRequest = stream._writeRequests.shift();
+ }
+ function WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream) {
+ if (stream._closeRequest !== undefined) {
+ stream._closeRequest._reject(stream._storedError);
+ stream._closeRequest = undefined;
+ }
+ const writer = stream._writer;
+ if (writer !== undefined) {
+ defaultWriterClosedPromiseReject(writer, stream._storedError);
+ }
+ }
+ function WritableStreamUpdateBackpressure(stream, backpressure) {
+ const writer = stream._writer;
+ if (writer !== undefined && backpressure !== stream._backpressure) {
+ if (backpressure) {
+ defaultWriterReadyPromiseReset(writer);
+ }
+ else {
+ defaultWriterReadyPromiseResolve(writer);
+ }
+ }
+ stream._backpressure = backpressure;
+ }
+ /**
+ * A default writer vended by a {@link WritableStream}.
+ *
+ * @public
+ */
+ class WritableStreamDefaultWriter {
+ constructor(stream) {
+ assertRequiredArgument(stream, 1, 'WritableStreamDefaultWriter');
+ assertWritableStream(stream, 'First parameter');
+ if (IsWritableStreamLocked(stream)) {
+ throw new TypeError('This stream has already been locked for exclusive writing by another writer');
+ }
+ this._ownerWritableStream = stream;
+ stream._writer = this;
+ const state = stream._state;
+ if (state === 'writable') {
+ if (!WritableStreamCloseQueuedOrInFlight(stream) && stream._backpressure) {
+ defaultWriterReadyPromiseInitialize(this);
+ }
+ else {
+ defaultWriterReadyPromiseInitializeAsResolved(this);
+ }
+ defaultWriterClosedPromiseInitialize(this);
+ }
+ else if (state === 'erroring') {
+ defaultWriterReadyPromiseInitializeAsRejected(this, stream._storedError);
+ defaultWriterClosedPromiseInitialize(this);
+ }
+ else if (state === 'closed') {
+ defaultWriterReadyPromiseInitializeAsResolved(this);
+ defaultWriterClosedPromiseInitializeAsResolved(this);
+ }
+ else {
+ const storedError = stream._storedError;
+ defaultWriterReadyPromiseInitializeAsRejected(this, storedError);
+ defaultWriterClosedPromiseInitializeAsRejected(this, storedError);
+ }
+ }
+ /**
+ * Returns a promise that will be fulfilled when the stream becomes closed, or rejected if the stream ever errors or
+ * the writer’s lock is released before the stream finishes closing.
+ */
+ get closed() {
+ if (!IsWritableStreamDefaultWriter(this)) {
+ return promiseRejectedWith(defaultWriterBrandCheckException('closed'));
+ }
+ return this._closedPromise;
+ }
+ /**
+ * Returns the desired size to fill the stream’s internal queue. It can be negative, if the queue is over-full.
+ * A producer can use this information to determine the right amount of data to write.
+ *
+ * It will be `null` if the stream cannot be successfully written to (due to either being errored, or having an abort
+ * queued up). It will return zero if the stream is closed. And the getter will throw an exception if invoked when
+ * the writer’s lock is released.
+ */
+ get desiredSize() {
+ if (!IsWritableStreamDefaultWriter(this)) {
+ throw defaultWriterBrandCheckException('desiredSize');
+ }
+ if (this._ownerWritableStream === undefined) {
+ throw defaultWriterLockException('desiredSize');
+ }
+ return WritableStreamDefaultWriterGetDesiredSize(this);
+ }
+ /**
+ * Returns a promise that will be fulfilled when the desired size to fill the stream’s internal queue transitions
+ * from non-positive to positive, signaling that it is no longer applying backpressure. Once the desired size dips
+ * back to zero or below, the getter will return a new promise that stays pending until the next transition.
+ *
+ * If the stream becomes errored or aborted, or the writer’s lock is released, the returned promise will become
+ * rejected.
+ */
+ get ready() {
+ if (!IsWritableStreamDefaultWriter(this)) {
+ return promiseRejectedWith(defaultWriterBrandCheckException('ready'));
+ }
+ return this._readyPromise;
+ }
+ /**
+ * If the reader is active, behaves the same as {@link WritableStream.abort | stream.abort(reason)}.
+ */
+ abort(reason = undefined) {
+ if (!IsWritableStreamDefaultWriter(this)) {
+ return promiseRejectedWith(defaultWriterBrandCheckException('abort'));
+ }
+ if (this._ownerWritableStream === undefined) {
+ return promiseRejectedWith(defaultWriterLockException('abort'));
+ }
+ return WritableStreamDefaultWriterAbort(this, reason);
+ }
+ /**
+ * If the reader is active, behaves the same as {@link WritableStream.close | stream.close()}.
+ */
+ close() {
+ if (!IsWritableStreamDefaultWriter(this)) {
+ return promiseRejectedWith(defaultWriterBrandCheckException('close'));
+ }
+ const stream = this._ownerWritableStream;
+ if (stream === undefined) {
+ return promiseRejectedWith(defaultWriterLockException('close'));
+ }
+ if (WritableStreamCloseQueuedOrInFlight(stream)) {
+ return promiseRejectedWith(new TypeError('Cannot close an already-closing stream'));
+ }
+ return WritableStreamDefaultWriterClose(this);
+ }
+ /**
+ * Releases the writer’s lock on the corresponding stream. After the lock is released, the writer is no longer active.
+ * If the associated stream is errored when the lock is released, the writer will appear errored in the same way from
+ * now on; otherwise, the writer will appear closed.
+ *
+ * Note that the lock can still be released even if some ongoing writes have not yet finished (i.e. even if the
+ * promises returned from previous calls to {@link WritableStreamDefaultWriter.write | write()} have not yet settled).
+ * It’s not necessary to hold the lock on the writer for the duration of the write; the lock instead simply prevents
+ * other producers from writing in an interleaved manner.
+ */
+ releaseLock() {
+ if (!IsWritableStreamDefaultWriter(this)) {
+ throw defaultWriterBrandCheckException('releaseLock');
+ }
+ const stream = this._ownerWritableStream;
+ if (stream === undefined) {
+ return;
+ }
+ WritableStreamDefaultWriterRelease(this);
+ }
+ write(chunk = undefined) {
+ if (!IsWritableStreamDefaultWriter(this)) {
+ return promiseRejectedWith(defaultWriterBrandCheckException('write'));
+ }
+ if (this._ownerWritableStream === undefined) {
+ return promiseRejectedWith(defaultWriterLockException('write to'));
+ }
+ return WritableStreamDefaultWriterWrite(this, chunk);
+ }
+ }
+ Object.defineProperties(WritableStreamDefaultWriter.prototype, {
+ abort: { enumerable: true },
+ close: { enumerable: true },
+ releaseLock: { enumerable: true },
+ write: { enumerable: true },
+ closed: { enumerable: true },
+ desiredSize: { enumerable: true },
+ ready: { enumerable: true }
+ });
+ if (typeof SymbolPolyfill.toStringTag === 'symbol') {
+ Object.defineProperty(WritableStreamDefaultWriter.prototype, SymbolPolyfill.toStringTag, {
+ value: 'WritableStreamDefaultWriter',
+ configurable: true
+ });
+ }
+ // Abstract operations for the WritableStreamDefaultWriter.
+ function IsWritableStreamDefaultWriter(x) {
+ if (!typeIsObject(x)) {
+ return false;
+ }
+ if (!Object.prototype.hasOwnProperty.call(x, '_ownerWritableStream')) {
+ return false;
+ }
+ return x instanceof WritableStreamDefaultWriter;
+ }
+ // A client of WritableStreamDefaultWriter may use these functions directly to bypass state check.
+ function WritableStreamDefaultWriterAbort(writer, reason) {
+ const stream = writer._ownerWritableStream;
+ return WritableStreamAbort(stream, reason);
+ }
+ function WritableStreamDefaultWriterClose(writer) {
+ const stream = writer._ownerWritableStream;
+ return WritableStreamClose(stream);
+ }
+ function WritableStreamDefaultWriterCloseWithErrorPropagation(writer) {
+ const stream = writer._ownerWritableStream;
+ const state = stream._state;
+ if (WritableStreamCloseQueuedOrInFlight(stream) || state === 'closed') {
+ return promiseResolvedWith(undefined);
+ }
+ if (state === 'errored') {
+ return promiseRejectedWith(stream._storedError);
+ }
+ return WritableStreamDefaultWriterClose(writer);
+ }
+ function WritableStreamDefaultWriterEnsureClosedPromiseRejected(writer, error) {
+ if (writer._closedPromiseState === 'pending') {
+ defaultWriterClosedPromiseReject(writer, error);
+ }
+ else {
+ defaultWriterClosedPromiseResetToRejected(writer, error);
+ }
+ }
+ function WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer, error) {
+ if (writer._readyPromiseState === 'pending') {
+ defaultWriterReadyPromiseReject(writer, error);
+ }
+ else {
+ defaultWriterReadyPromiseResetToRejected(writer, error);
+ }
+ }
+ function WritableStreamDefaultWriterGetDesiredSize(writer) {
+ const stream = writer._ownerWritableStream;
+ const state = stream._state;
+ if (state === 'errored' || state === 'erroring') {
+ return null;
+ }
+ if (state === 'closed') {
+ return 0;
+ }
+ return WritableStreamDefaultControllerGetDesiredSize(stream._writableStreamController);
+ }
+ function WritableStreamDefaultWriterRelease(writer) {
+ const stream = writer._ownerWritableStream;
+ const releasedError = new TypeError(`Writer was released and can no longer be used to monitor the stream's closedness`);
+ WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer, releasedError);
+ // The state transitions to "errored" before the sink abort() method runs, but the writer.closed promise is not
+ // rejected until afterwards. This means that simply testing state will not work.
+ WritableStreamDefaultWriterEnsureClosedPromiseRejected(writer, releasedError);
+ stream._writer = undefined;
+ writer._ownerWritableStream = undefined;
+ }
+ function WritableStreamDefaultWriterWrite(writer, chunk) {
+ const stream = writer._ownerWritableStream;
+ const controller = stream._writableStreamController;
+ const chunkSize = WritableStreamDefaultControllerGetChunkSize(controller, chunk);
+ if (stream !== writer._ownerWritableStream) {
+ return promiseRejectedWith(defaultWriterLockException('write to'));
+ }
+ const state = stream._state;
+ if (state === 'errored') {
+ return promiseRejectedWith(stream._storedError);
+ }
+ if (WritableStreamCloseQueuedOrInFlight(stream) || state === 'closed') {
+ return promiseRejectedWith(new TypeError('The stream is closing or closed and cannot be written to'));
+ }
+ if (state === 'erroring') {
+ return promiseRejectedWith(stream._storedError);
+ }
+ const promise = WritableStreamAddWriteRequest(stream);
+ WritableStreamDefaultControllerWrite(controller, chunk, chunkSize);
+ return promise;
+ }
+ const closeSentinel = {};
+ /**
+ * Allows control of a {@link WritableStream | writable stream}'s state and internal queue.
+ *
+ * @public
+ */
+ class WritableStreamDefaultController {
+ constructor() {
+ throw new TypeError('Illegal constructor');
+ }
+ /**
+ * The reason which was passed to `WritableStream.abort(reason)` when the stream was aborted.
+ *
+ * @deprecated
+ * This property has been removed from the specification, see https://github.com/whatwg/streams/pull/1177.
+ * Use {@link WritableStreamDefaultController.signal}'s `reason` instead.
+ */
+ get abortReason() {
+ if (!IsWritableStreamDefaultController(this)) {
+ throw defaultControllerBrandCheckException$2('abortReason');
+ }
+ return this._abortReason;
+ }
+ /**
+ * An `AbortSignal` that can be used to abort the pending write or close operation when the stream is aborted.
+ */
+ get signal() {
+ if (!IsWritableStreamDefaultController(this)) {
+ throw defaultControllerBrandCheckException$2('signal');
+ }
+ if (this._abortController === undefined) {
+ // Older browsers or older Node versions may not support `AbortController` or `AbortSignal`.
+ // We don't want to bundle and ship an `AbortController` polyfill together with our polyfill,
+ // so instead we only implement support for `signal` if we find a global `AbortController` constructor.
+ throw new TypeError('WritableStreamDefaultController.prototype.signal is not supported');
+ }
+ return this._abortController.signal;
+ }
+ /**
+ * Closes the controlled writable stream, making all future interactions with it fail with the given error `e`.
+ *
+ * This method is rarely used, since usually it suffices to return a rejected promise from one of the underlying
+ * sink's methods. However, it can be useful for suddenly shutting down a stream in response to an event outside the
+ * normal lifecycle of interactions with the underlying sink.
+ */
+ error(e = undefined) {
+ if (!IsWritableStreamDefaultController(this)) {
+ throw defaultControllerBrandCheckException$2('error');
+ }
+ const state = this._controlledWritableStream._state;
+ if (state !== 'writable') {
+ // The stream is closed, errored or will be soon. The sink can't do anything useful if it gets an error here, so
+ // just treat it as a no-op.
+ return;
+ }
+ WritableStreamDefaultControllerError(this, e);
+ }
+ /** @internal */
+ [AbortSteps](reason) {
+ const result = this._abortAlgorithm(reason);
+ WritableStreamDefaultControllerClearAlgorithms(this);
+ return result;
+ }
+ /** @internal */
+ [ErrorSteps]() {
+ ResetQueue(this);
+ }
+ }
+ Object.defineProperties(WritableStreamDefaultController.prototype, {
+ abortReason: { enumerable: true },
+ signal: { enumerable: true },
+ error: { enumerable: true }
+ });
+ if (typeof SymbolPolyfill.toStringTag === 'symbol') {
+ Object.defineProperty(WritableStreamDefaultController.prototype, SymbolPolyfill.toStringTag, {
+ value: 'WritableStreamDefaultController',
+ configurable: true
+ });
+ }
+ // Abstract operations implementing interface required by the WritableStream.
+ function IsWritableStreamDefaultController(x) {
+ if (!typeIsObject(x)) {
+ return false;
+ }
+ if (!Object.prototype.hasOwnProperty.call(x, '_controlledWritableStream')) {
+ return false;
+ }
+ return x instanceof WritableStreamDefaultController;
+ }
+ function SetUpWritableStreamDefaultController(stream, controller, startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark, sizeAlgorithm) {
+ controller._controlledWritableStream = stream;
+ stream._writableStreamController = controller;
+ // Need to set the slots so that the assert doesn't fire. In the spec the slots already exist implicitly.
+ controller._queue = undefined;
+ controller._queueTotalSize = undefined;
+ ResetQueue(controller);
+ controller._abortReason = undefined;
+ controller._abortController = createAbortController();
+ controller._started = false;
+ controller._strategySizeAlgorithm = sizeAlgorithm;
+ controller._strategyHWM = highWaterMark;
+ controller._writeAlgorithm = writeAlgorithm;
+ controller._closeAlgorithm = closeAlgorithm;
+ controller._abortAlgorithm = abortAlgorithm;
+ const backpressure = WritableStreamDefaultControllerGetBackpressure(controller);
+ WritableStreamUpdateBackpressure(stream, backpressure);
+ const startResult = startAlgorithm();
+ const startPromise = promiseResolvedWith(startResult);
+ uponPromise(startPromise, () => {
+ controller._started = true;
+ WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller);
+ }, r => {
+ controller._started = true;
+ WritableStreamDealWithRejection(stream, r);
+ });
+ }
+ function SetUpWritableStreamDefaultControllerFromUnderlyingSink(stream, underlyingSink, highWaterMark, sizeAlgorithm) {
+ const controller = Object.create(WritableStreamDefaultController.prototype);
+ let startAlgorithm = () => undefined;
+ let writeAlgorithm = () => promiseResolvedWith(undefined);
+ let closeAlgorithm = () => promiseResolvedWith(undefined);
+ let abortAlgorithm = () => promiseResolvedWith(undefined);
+ if (underlyingSink.start !== undefined) {
+ startAlgorithm = () => underlyingSink.start(controller);
+ }
+ if (underlyingSink.write !== undefined) {
+ writeAlgorithm = chunk => underlyingSink.write(chunk, controller);
+ }
+ if (underlyingSink.close !== undefined) {
+ closeAlgorithm = () => underlyingSink.close();
+ }
+ if (underlyingSink.abort !== undefined) {
+ abortAlgorithm = reason => underlyingSink.abort(reason);
+ }
+ SetUpWritableStreamDefaultController(stream, controller, startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark, sizeAlgorithm);
+ }
+ // ClearAlgorithms may be called twice. Erroring the same stream in multiple ways will often result in redundant calls.
+ function WritableStreamDefaultControllerClearAlgorithms(controller) {
+ controller._writeAlgorithm = undefined;
+ controller._closeAlgorithm = undefined;
+ controller._abortAlgorithm = undefined;
+ controller._strategySizeAlgorithm = undefined;
+ }
+ function WritableStreamDefaultControllerClose(controller) {
+ EnqueueValueWithSize(controller, closeSentinel, 0);
+ WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller);
+ }
+ function WritableStreamDefaultControllerGetChunkSize(controller, chunk) {
+ try {
+ return controller._strategySizeAlgorithm(chunk);
+ }
+ catch (chunkSizeE) {
+ WritableStreamDefaultControllerErrorIfNeeded(controller, chunkSizeE);
+ return 1;
+ }
+ }
+ function WritableStreamDefaultControllerGetDesiredSize(controller) {
+ return controller._strategyHWM - controller._queueTotalSize;
+ }
+ function WritableStreamDefaultControllerWrite(controller, chunk, chunkSize) {
+ try {
+ EnqueueValueWithSize(controller, chunk, chunkSize);
+ }
+ catch (enqueueE) {
+ WritableStreamDefaultControllerErrorIfNeeded(controller, enqueueE);
+ return;
+ }
+ const stream = controller._controlledWritableStream;
+ if (!WritableStreamCloseQueuedOrInFlight(stream) && stream._state === 'writable') {
+ const backpressure = WritableStreamDefaultControllerGetBackpressure(controller);
+ WritableStreamUpdateBackpressure(stream, backpressure);
+ }
+ WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller);
+ }
+ // Abstract operations for the WritableStreamDefaultController.
+ function WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller) {
+ const stream = controller._controlledWritableStream;
+ if (!controller._started) {
+ return;
+ }
+ if (stream._inFlightWriteRequest !== undefined) {
+ return;
+ }
+ const state = stream._state;
+ if (state === 'erroring') {
+ WritableStreamFinishErroring(stream);
+ return;
+ }
+ if (controller._queue.length === 0) {
+ return;
+ }
+ const value = PeekQueueValue(controller);
+ if (value === closeSentinel) {
+ WritableStreamDefaultControllerProcessClose(controller);
+ }
+ else {
+ WritableStreamDefaultControllerProcessWrite(controller, value);
+ }
+ }
+ function WritableStreamDefaultControllerErrorIfNeeded(controller, error) {
+ if (controller._controlledWritableStream._state === 'writable') {
+ WritableStreamDefaultControllerError(controller, error);
+ }
+ }
+ function WritableStreamDefaultControllerProcessClose(controller) {
+ const stream = controller._controlledWritableStream;
+ WritableStreamMarkCloseRequestInFlight(stream);
+ DequeueValue(controller);
+ const sinkClosePromise = controller._closeAlgorithm();
+ WritableStreamDefaultControllerClearAlgorithms(controller);
+ uponPromise(sinkClosePromise, () => {
+ WritableStreamFinishInFlightClose(stream);
+ }, reason => {
+ WritableStreamFinishInFlightCloseWithError(stream, reason);
+ });
+ }
+ function WritableStreamDefaultControllerProcessWrite(controller, chunk) {
+ const stream = controller._controlledWritableStream;
+ WritableStreamMarkFirstWriteRequestInFlight(stream);
+ const sinkWritePromise = controller._writeAlgorithm(chunk);
+ uponPromise(sinkWritePromise, () => {
+ WritableStreamFinishInFlightWrite(stream);
+ const state = stream._state;
+ DequeueValue(controller);
+ if (!WritableStreamCloseQueuedOrInFlight(stream) && state === 'writable') {
+ const backpressure = WritableStreamDefaultControllerGetBackpressure(controller);
+ WritableStreamUpdateBackpressure(stream, backpressure);
+ }
+ WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller);
+ }, reason => {
+ if (stream._state === 'writable') {
+ WritableStreamDefaultControllerClearAlgorithms(controller);
+ }
+ WritableStreamFinishInFlightWriteWithError(stream, reason);
+ });
+ }
+ function WritableStreamDefaultControllerGetBackpressure(controller) {
+ const desiredSize = WritableStreamDefaultControllerGetDesiredSize(controller);
+ return desiredSize <= 0;
+ }
+ // A client of WritableStreamDefaultController may use these functions directly to bypass state check.
+ function WritableStreamDefaultControllerError(controller, error) {
+ const stream = controller._controlledWritableStream;
+ WritableStreamDefaultControllerClearAlgorithms(controller);
+ WritableStreamStartErroring(stream, error);
+ }
+ // Helper functions for the WritableStream.
+ function streamBrandCheckException$2(name) {
+ return new TypeError(`WritableStream.prototype.${name} can only be used on a WritableStream`);
+ }
+ // Helper functions for the WritableStreamDefaultController.
+ function defaultControllerBrandCheckException$2(name) {
+ return new TypeError(`WritableStreamDefaultController.prototype.${name} can only be used on a WritableStreamDefaultController`);
+ }
+ // Helper functions for the WritableStreamDefaultWriter.
+ function defaultWriterBrandCheckException(name) {
+ return new TypeError(`WritableStreamDefaultWriter.prototype.${name} can only be used on a WritableStreamDefaultWriter`);
+ }
+ function defaultWriterLockException(name) {
+ return new TypeError('Cannot ' + name + ' a stream using a released writer');
+ }
+ function defaultWriterClosedPromiseInitialize(writer) {
+ writer._closedPromise = newPromise((resolve, reject) => {
+ writer._closedPromise_resolve = resolve;
+ writer._closedPromise_reject = reject;
+ writer._closedPromiseState = 'pending';
+ });
+ }
+ function defaultWriterClosedPromiseInitializeAsRejected(writer, reason) {
+ defaultWriterClosedPromiseInitialize(writer);
+ defaultWriterClosedPromiseReject(writer, reason);
+ }
+ function defaultWriterClosedPromiseInitializeAsResolved(writer) {
+ defaultWriterClosedPromiseInitialize(writer);
+ defaultWriterClosedPromiseResolve(writer);
+ }
+ function defaultWriterClosedPromiseReject(writer, reason) {
+ if (writer._closedPromise_reject === undefined) {
+ return;
+ }
+ setPromiseIsHandledToTrue(writer._closedPromise);
+ writer._closedPromise_reject(reason);
+ writer._closedPromise_resolve = undefined;
+ writer._closedPromise_reject = undefined;
+ writer._closedPromiseState = 'rejected';
+ }
+ function defaultWriterClosedPromiseResetToRejected(writer, reason) {
+ defaultWriterClosedPromiseInitializeAsRejected(writer, reason);
+ }
+ function defaultWriterClosedPromiseResolve(writer) {
+ if (writer._closedPromise_resolve === undefined) {
+ return;
+ }
+ writer._closedPromise_resolve(undefined);
+ writer._closedPromise_resolve = undefined;
+ writer._closedPromise_reject = undefined;
+ writer._closedPromiseState = 'resolved';
+ }
+ function defaultWriterReadyPromiseInitialize(writer) {
+ writer._readyPromise = newPromise((resolve, reject) => {
+ writer._readyPromise_resolve = resolve;
+ writer._readyPromise_reject = reject;
+ });
+ writer._readyPromiseState = 'pending';
+ }
+ function defaultWriterReadyPromiseInitializeAsRejected(writer, reason) {
+ defaultWriterReadyPromiseInitialize(writer);
+ defaultWriterReadyPromiseReject(writer, reason);
+ }
+ function defaultWriterReadyPromiseInitializeAsResolved(writer) {
+ defaultWriterReadyPromiseInitialize(writer);
+ defaultWriterReadyPromiseResolve(writer);
+ }
+ function defaultWriterReadyPromiseReject(writer, reason) {
+ if (writer._readyPromise_reject === undefined) {
+ return;
+ }
+ setPromiseIsHandledToTrue(writer._readyPromise);
+ writer._readyPromise_reject(reason);
+ writer._readyPromise_resolve = undefined;
+ writer._readyPromise_reject = undefined;
+ writer._readyPromiseState = 'rejected';
+ }
+ function defaultWriterReadyPromiseReset(writer) {
+ defaultWriterReadyPromiseInitialize(writer);
+ }
+ function defaultWriterReadyPromiseResetToRejected(writer, reason) {
+ defaultWriterReadyPromiseInitializeAsRejected(writer, reason);
+ }
+ function defaultWriterReadyPromiseResolve(writer) {
+ if (writer._readyPromise_resolve === undefined) {
+ return;
+ }
+ writer._readyPromise_resolve(undefined);
+ writer._readyPromise_resolve = undefined;
+ writer._readyPromise_reject = undefined;
+ writer._readyPromiseState = 'fulfilled';
+ }
+
+ ///
+ const NativeDOMException = typeof DOMException !== 'undefined' ? DOMException : undefined;
+
+ ///
+ function isDOMExceptionConstructor(ctor) {
+ if (!(typeof ctor === 'function' || typeof ctor === 'object')) {
+ return false;
+ }
+ try {
+ new ctor();
+ return true;
+ }
+ catch (_a) {
+ return false;
+ }
+ }
+ function createDOMExceptionPolyfill() {
+ // eslint-disable-next-line no-shadow
+ const ctor = function DOMException(message, name) {
+ this.message = message || '';
+ this.name = name || 'Error';
+ if (Error.captureStackTrace) {
+ Error.captureStackTrace(this, this.constructor);
+ }
+ };
+ ctor.prototype = Object.create(Error.prototype);
+ Object.defineProperty(ctor.prototype, 'constructor', { value: ctor, writable: true, configurable: true });
+ return ctor;
+ }
+ // eslint-disable-next-line no-redeclare
+ const DOMException$1 = isDOMExceptionConstructor(NativeDOMException) ? NativeDOMException : createDOMExceptionPolyfill();
+
+ function ReadableStreamPipeTo(source, dest, preventClose, preventAbort, preventCancel, signal) {
+ const reader = AcquireReadableStreamDefaultReader(source);
+ const writer = AcquireWritableStreamDefaultWriter(dest);
+ source._disturbed = true;
+ let shuttingDown = false;
+ // This is used to keep track of the spec's requirement that we wait for ongoing writes during shutdown.
+ let currentWrite = promiseResolvedWith(undefined);
+ return newPromise((resolve, reject) => {
+ let abortAlgorithm;
+ if (signal !== undefined) {
+ abortAlgorithm = () => {
+ const error = new DOMException$1('Aborted', 'AbortError');
+ const actions = [];
+ if (!preventAbort) {
+ actions.push(() => {
+ if (dest._state === 'writable') {
+ return WritableStreamAbort(dest, error);
+ }
+ return promiseResolvedWith(undefined);
+ });
+ }
+ if (!preventCancel) {
+ actions.push(() => {
+ if (source._state === 'readable') {
+ return ReadableStreamCancel(source, error);
+ }
+ return promiseResolvedWith(undefined);
+ });
+ }
+ shutdownWithAction(() => Promise.all(actions.map(action => action())), true, error);
+ };
+ if (signal.aborted) {
+ abortAlgorithm();
+ return;
+ }
+ signal.addEventListener('abort', abortAlgorithm);
+ }
+ // Using reader and writer, read all chunks from this and write them to dest
+ // - Backpressure must be enforced
+ // - Shutdown must stop all activity
+ function pipeLoop() {
+ return newPromise((resolveLoop, rejectLoop) => {
+ function next(done) {
+ if (done) {
+ resolveLoop();
+ }
+ else {
+ // Use `PerformPromiseThen` instead of `uponPromise` to avoid
+ // adding unnecessary `.catch(rethrowAssertionErrorRejection)` handlers
+ PerformPromiseThen(pipeStep(), next, rejectLoop);
+ }
+ }
+ next(false);
+ });
+ }
+ function pipeStep() {
+ if (shuttingDown) {
+ return promiseResolvedWith(true);
+ }
+ return PerformPromiseThen(writer._readyPromise, () => {
+ return newPromise((resolveRead, rejectRead) => {
+ ReadableStreamDefaultReaderRead(reader, {
+ _chunkSteps: chunk => {
+ currentWrite = PerformPromiseThen(WritableStreamDefaultWriterWrite(writer, chunk), undefined, noop);
+ resolveRead(false);
+ },
+ _closeSteps: () => resolveRead(true),
+ _errorSteps: rejectRead
+ });
+ });
+ });
+ }
+ // Errors must be propagated forward
+ isOrBecomesErrored(source, reader._closedPromise, storedError => {
+ if (!preventAbort) {
+ shutdownWithAction(() => WritableStreamAbort(dest, storedError), true, storedError);
+ }
+ else {
+ shutdown(true, storedError);
+ }
+ });
+ // Errors must be propagated backward
+ isOrBecomesErrored(dest, writer._closedPromise, storedError => {
+ if (!preventCancel) {
+ shutdownWithAction(() => ReadableStreamCancel(source, storedError), true, storedError);
+ }
+ else {
+ shutdown(true, storedError);
+ }
+ });
+ // Closing must be propagated forward
+ isOrBecomesClosed(source, reader._closedPromise, () => {
+ if (!preventClose) {
+ shutdownWithAction(() => WritableStreamDefaultWriterCloseWithErrorPropagation(writer));
+ }
+ else {
+ shutdown();
+ }
+ });
+ // Closing must be propagated backward
+ if (WritableStreamCloseQueuedOrInFlight(dest) || dest._state === 'closed') {
+ const destClosed = new TypeError('the destination writable stream closed before all data could be piped to it');
+ if (!preventCancel) {
+ shutdownWithAction(() => ReadableStreamCancel(source, destClosed), true, destClosed);
+ }
+ else {
+ shutdown(true, destClosed);
+ }
+ }
+ setPromiseIsHandledToTrue(pipeLoop());
+ function waitForWritesToFinish() {
+ // Another write may have started while we were waiting on this currentWrite, so we have to be sure to wait
+ // for that too.
+ const oldCurrentWrite = currentWrite;
+ return PerformPromiseThen(currentWrite, () => oldCurrentWrite !== currentWrite ? waitForWritesToFinish() : undefined);
+ }
+ function isOrBecomesErrored(stream, promise, action) {
+ if (stream._state === 'errored') {
+ action(stream._storedError);
+ }
+ else {
+ uponRejection(promise, action);
+ }
+ }
+ function isOrBecomesClosed(stream, promise, action) {
+ if (stream._state === 'closed') {
+ action();
+ }
+ else {
+ uponFulfillment(promise, action);
+ }
+ }
+ function shutdownWithAction(action, originalIsError, originalError) {
+ if (shuttingDown) {
+ return;
+ }
+ shuttingDown = true;
+ if (dest._state === 'writable' && !WritableStreamCloseQueuedOrInFlight(dest)) {
+ uponFulfillment(waitForWritesToFinish(), doTheRest);
+ }
+ else {
+ doTheRest();
+ }
+ function doTheRest() {
+ uponPromise(action(), () => finalize(originalIsError, originalError), newError => finalize(true, newError));
+ }
+ }
+ function shutdown(isError, error) {
+ if (shuttingDown) {
+ return;
+ }
+ shuttingDown = true;
+ if (dest._state === 'writable' && !WritableStreamCloseQueuedOrInFlight(dest)) {
+ uponFulfillment(waitForWritesToFinish(), () => finalize(isError, error));
+ }
+ else {
+ finalize(isError, error);
+ }
+ }
+ function finalize(isError, error) {
+ WritableStreamDefaultWriterRelease(writer);
+ ReadableStreamReaderGenericRelease(reader);
+ if (signal !== undefined) {
+ signal.removeEventListener('abort', abortAlgorithm);
+ }
+ if (isError) {
+ reject(error);
+ }
+ else {
+ resolve(undefined);
+ }
+ }
+ });
+ }
+
+ /**
+ * Allows control of a {@link ReadableStream | readable stream}'s state and internal queue.
+ *
+ * @public
+ */
+ class ReadableStreamDefaultController {
+ constructor() {
+ throw new TypeError('Illegal constructor');
+ }
+ /**
+ * Returns the desired size to fill the controlled stream's internal queue. It can be negative, if the queue is
+ * over-full. An underlying source ought to use this information to determine when and how to apply backpressure.
+ */
+ get desiredSize() {
+ if (!IsReadableStreamDefaultController(this)) {
+ throw defaultControllerBrandCheckException$1('desiredSize');
+ }
+ return ReadableStreamDefaultControllerGetDesiredSize(this);
+ }
+ /**
+ * Closes the controlled readable stream. Consumers will still be able to read any previously-enqueued chunks from
+ * the stream, but once those are read, the stream will become closed.
+ */
+ close() {
+ if (!IsReadableStreamDefaultController(this)) {
+ throw defaultControllerBrandCheckException$1('close');
+ }
+ if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(this)) {
+ throw new TypeError('The stream is not in a state that permits close');
+ }
+ ReadableStreamDefaultControllerClose(this);
+ }
+ enqueue(chunk = undefined) {
+ if (!IsReadableStreamDefaultController(this)) {
+ throw defaultControllerBrandCheckException$1('enqueue');
+ }
+ if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(this)) {
+ throw new TypeError('The stream is not in a state that permits enqueue');
+ }
+ return ReadableStreamDefaultControllerEnqueue(this, chunk);
+ }
+ /**
+ * Errors the controlled readable stream, making all future interactions with it fail with the given error `e`.
+ */
+ error(e = undefined) {
+ if (!IsReadableStreamDefaultController(this)) {
+ throw defaultControllerBrandCheckException$1('error');
+ }
+ ReadableStreamDefaultControllerError(this, e);
+ }
+ /** @internal */
+ [CancelSteps](reason) {
+ ResetQueue(this);
+ const result = this._cancelAlgorithm(reason);
+ ReadableStreamDefaultControllerClearAlgorithms(this);
+ return result;
+ }
+ /** @internal */
+ [PullSteps](readRequest) {
+ const stream = this._controlledReadableStream;
+ if (this._queue.length > 0) {
+ const chunk = DequeueValue(this);
+ if (this._closeRequested && this._queue.length === 0) {
+ ReadableStreamDefaultControllerClearAlgorithms(this);
+ ReadableStreamClose(stream);
+ }
+ else {
+ ReadableStreamDefaultControllerCallPullIfNeeded(this);
+ }
+ readRequest._chunkSteps(chunk);
+ }
+ else {
+ ReadableStreamAddReadRequest(stream, readRequest);
+ ReadableStreamDefaultControllerCallPullIfNeeded(this);
+ }
+ }
+ }
+ Object.defineProperties(ReadableStreamDefaultController.prototype, {
+ close: { enumerable: true },
+ enqueue: { enumerable: true },
+ error: { enumerable: true },
+ desiredSize: { enumerable: true }
+ });
+ if (typeof SymbolPolyfill.toStringTag === 'symbol') {
+ Object.defineProperty(ReadableStreamDefaultController.prototype, SymbolPolyfill.toStringTag, {
+ value: 'ReadableStreamDefaultController',
+ configurable: true
+ });
+ }
+ // Abstract operations for the ReadableStreamDefaultController.
+ function IsReadableStreamDefaultController(x) {
+ if (!typeIsObject(x)) {
+ return false;
+ }
+ if (!Object.prototype.hasOwnProperty.call(x, '_controlledReadableStream')) {
+ return false;
+ }
+ return x instanceof ReadableStreamDefaultController;
+ }
+ function ReadableStreamDefaultControllerCallPullIfNeeded(controller) {
+ const shouldPull = ReadableStreamDefaultControllerShouldCallPull(controller);
+ if (!shouldPull) {
+ return;
+ }
+ if (controller._pulling) {
+ controller._pullAgain = true;
+ return;
+ }
+ controller._pulling = true;
+ const pullPromise = controller._pullAlgorithm();
+ uponPromise(pullPromise, () => {
+ controller._pulling = false;
+ if (controller._pullAgain) {
+ controller._pullAgain = false;
+ ReadableStreamDefaultControllerCallPullIfNeeded(controller);
+ }
+ }, e => {
+ ReadableStreamDefaultControllerError(controller, e);
+ });
+ }
+ function ReadableStreamDefaultControllerShouldCallPull(controller) {
+ const stream = controller._controlledReadableStream;
+ if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(controller)) {
+ return false;
+ }
+ if (!controller._started) {
+ return false;
+ }
+ if (IsReadableStreamLocked(stream) && ReadableStreamGetNumReadRequests(stream) > 0) {
+ return true;
+ }
+ const desiredSize = ReadableStreamDefaultControllerGetDesiredSize(controller);
+ if (desiredSize > 0) {
+ return true;
+ }
+ return false;
+ }
+ function ReadableStreamDefaultControllerClearAlgorithms(controller) {
+ controller._pullAlgorithm = undefined;
+ controller._cancelAlgorithm = undefined;
+ controller._strategySizeAlgorithm = undefined;
+ }
+ // A client of ReadableStreamDefaultController may use these functions directly to bypass state check.
+ function ReadableStreamDefaultControllerClose(controller) {
+ if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(controller)) {
+ return;
+ }
+ const stream = controller._controlledReadableStream;
+ controller._closeRequested = true;
+ if (controller._queue.length === 0) {
+ ReadableStreamDefaultControllerClearAlgorithms(controller);
+ ReadableStreamClose(stream);
+ }
+ }
+ function ReadableStreamDefaultControllerEnqueue(controller, chunk) {
+ if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(controller)) {
+ return;
+ }
+ const stream = controller._controlledReadableStream;
+ if (IsReadableStreamLocked(stream) && ReadableStreamGetNumReadRequests(stream) > 0) {
+ ReadableStreamFulfillReadRequest(stream, chunk, false);
+ }
+ else {
+ let chunkSize;
+ try {
+ chunkSize = controller._strategySizeAlgorithm(chunk);
+ }
+ catch (chunkSizeE) {
+ ReadableStreamDefaultControllerError(controller, chunkSizeE);
+ throw chunkSizeE;
+ }
+ try {
+ EnqueueValueWithSize(controller, chunk, chunkSize);
+ }
+ catch (enqueueE) {
+ ReadableStreamDefaultControllerError(controller, enqueueE);
+ throw enqueueE;
+ }
+ }
+ ReadableStreamDefaultControllerCallPullIfNeeded(controller);
+ }
+ function ReadableStreamDefaultControllerError(controller, e) {
+ const stream = controller._controlledReadableStream;
+ if (stream._state !== 'readable') {
+ return;
+ }
+ ResetQueue(controller);
+ ReadableStreamDefaultControllerClearAlgorithms(controller);
+ ReadableStreamError(stream, e);
+ }
+ function ReadableStreamDefaultControllerGetDesiredSize(controller) {
+ const state = controller._controlledReadableStream._state;
+ if (state === 'errored') {
+ return null;
+ }
+ if (state === 'closed') {
+ return 0;
+ }
+ return controller._strategyHWM - controller._queueTotalSize;
+ }
+ // This is used in the implementation of TransformStream.
+ function ReadableStreamDefaultControllerHasBackpressure(controller) {
+ if (ReadableStreamDefaultControllerShouldCallPull(controller)) {
+ return false;
+ }
+ return true;
+ }
+ function ReadableStreamDefaultControllerCanCloseOrEnqueue(controller) {
+ const state = controller._controlledReadableStream._state;
+ if (!controller._closeRequested && state === 'readable') {
+ return true;
+ }
+ return false;
+ }
+ function SetUpReadableStreamDefaultController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, sizeAlgorithm) {
+ controller._controlledReadableStream = stream;
+ controller._queue = undefined;
+ controller._queueTotalSize = undefined;
+ ResetQueue(controller);
+ controller._started = false;
+ controller._closeRequested = false;
+ controller._pullAgain = false;
+ controller._pulling = false;
+ controller._strategySizeAlgorithm = sizeAlgorithm;
+ controller._strategyHWM = highWaterMark;
+ controller._pullAlgorithm = pullAlgorithm;
+ controller._cancelAlgorithm = cancelAlgorithm;
+ stream._readableStreamController = controller;
+ const startResult = startAlgorithm();
+ uponPromise(promiseResolvedWith(startResult), () => {
+ controller._started = true;
+ ReadableStreamDefaultControllerCallPullIfNeeded(controller);
+ }, r => {
+ ReadableStreamDefaultControllerError(controller, r);
+ });
+ }
+ function SetUpReadableStreamDefaultControllerFromUnderlyingSource(stream, underlyingSource, highWaterMark, sizeAlgorithm) {
+ const controller = Object.create(ReadableStreamDefaultController.prototype);
+ let startAlgorithm = () => undefined;
+ let pullAlgorithm = () => promiseResolvedWith(undefined);
+ let cancelAlgorithm = () => promiseResolvedWith(undefined);
+ if (underlyingSource.start !== undefined) {
+ startAlgorithm = () => underlyingSource.start(controller);
+ }
+ if (underlyingSource.pull !== undefined) {
+ pullAlgorithm = () => underlyingSource.pull(controller);
+ }
+ if (underlyingSource.cancel !== undefined) {
+ cancelAlgorithm = reason => underlyingSource.cancel(reason);
+ }
+ SetUpReadableStreamDefaultController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, sizeAlgorithm);
+ }
+ // Helper functions for the ReadableStreamDefaultController.
+ function defaultControllerBrandCheckException$1(name) {
+ return new TypeError(`ReadableStreamDefaultController.prototype.${name} can only be used on a ReadableStreamDefaultController`);
+ }
+
+ function ReadableStreamTee(stream, cloneForBranch2) {
+ if (IsReadableByteStreamController(stream._readableStreamController)) {
+ return ReadableByteStreamTee(stream);
+ }
+ return ReadableStreamDefaultTee(stream);
+ }
+ function ReadableStreamDefaultTee(stream, cloneForBranch2) {
+ const reader = AcquireReadableStreamDefaultReader(stream);
+ let reading = false;
+ let readAgain = false;
+ let canceled1 = false;
+ let canceled2 = false;
+ let reason1;
+ let reason2;
+ let branch1;
+ let branch2;
+ let resolveCancelPromise;
+ const cancelPromise = newPromise(resolve => {
+ resolveCancelPromise = resolve;
+ });
+ function pullAlgorithm() {
+ if (reading) {
+ readAgain = true;
+ return promiseResolvedWith(undefined);
+ }
+ reading = true;
+ const readRequest = {
+ _chunkSteps: chunk => {
+ // This needs to be delayed a microtask because it takes at least a microtask to detect errors (using
+ // reader._closedPromise below), and we want errors in stream to error both branches immediately. We cannot let
+ // successful synchronously-available reads get ahead of asynchronously-available errors.
+ queueMicrotask(() => {
+ readAgain = false;
+ const chunk1 = chunk;
+ const chunk2 = chunk;
+ // There is no way to access the cloning code right now in the reference implementation.
+ // If we add one then we'll need an implementation for serializable objects.
+ // if (!canceled2 && cloneForBranch2) {
+ // chunk2 = StructuredDeserialize(StructuredSerialize(chunk2));
+ // }
+ if (!canceled1) {
+ ReadableStreamDefaultControllerEnqueue(branch1._readableStreamController, chunk1);
+ }
+ if (!canceled2) {
+ ReadableStreamDefaultControllerEnqueue(branch2._readableStreamController, chunk2);
+ }
+ reading = false;
+ if (readAgain) {
+ pullAlgorithm();
+ }
+ });
+ },
+ _closeSteps: () => {
+ reading = false;
+ if (!canceled1) {
+ ReadableStreamDefaultControllerClose(branch1._readableStreamController);
+ }
+ if (!canceled2) {
+ ReadableStreamDefaultControllerClose(branch2._readableStreamController);
+ }
+ if (!canceled1 || !canceled2) {
+ resolveCancelPromise(undefined);
+ }
+ },
+ _errorSteps: () => {
+ reading = false;
+ }
+ };
+ ReadableStreamDefaultReaderRead(reader, readRequest);
+ return promiseResolvedWith(undefined);
+ }
+ function cancel1Algorithm(reason) {
+ canceled1 = true;
+ reason1 = reason;
+ if (canceled2) {
+ const compositeReason = CreateArrayFromList([reason1, reason2]);
+ const cancelResult = ReadableStreamCancel(stream, compositeReason);
+ resolveCancelPromise(cancelResult);
+ }
+ return cancelPromise;
+ }
+ function cancel2Algorithm(reason) {
+ canceled2 = true;
+ reason2 = reason;
+ if (canceled1) {
+ const compositeReason = CreateArrayFromList([reason1, reason2]);
+ const cancelResult = ReadableStreamCancel(stream, compositeReason);
+ resolveCancelPromise(cancelResult);
+ }
+ return cancelPromise;
+ }
+ function startAlgorithm() {
+ // do nothing
+ }
+ branch1 = CreateReadableStream(startAlgorithm, pullAlgorithm, cancel1Algorithm);
+ branch2 = CreateReadableStream(startAlgorithm, pullAlgorithm, cancel2Algorithm);
+ uponRejection(reader._closedPromise, (r) => {
+ ReadableStreamDefaultControllerError(branch1._readableStreamController, r);
+ ReadableStreamDefaultControllerError(branch2._readableStreamController, r);
+ if (!canceled1 || !canceled2) {
+ resolveCancelPromise(undefined);
+ }
+ });
+ return [branch1, branch2];
+ }
+ function ReadableByteStreamTee(stream) {
+ let reader = AcquireReadableStreamDefaultReader(stream);
+ let reading = false;
+ let readAgainForBranch1 = false;
+ let readAgainForBranch2 = false;
+ let canceled1 = false;
+ let canceled2 = false;
+ let reason1;
+ let reason2;
+ let branch1;
+ let branch2;
+ let resolveCancelPromise;
+ const cancelPromise = newPromise(resolve => {
+ resolveCancelPromise = resolve;
+ });
+ function forwardReaderError(thisReader) {
+ uponRejection(thisReader._closedPromise, r => {
+ if (thisReader !== reader) {
+ return;
+ }
+ ReadableByteStreamControllerError(branch1._readableStreamController, r);
+ ReadableByteStreamControllerError(branch2._readableStreamController, r);
+ if (!canceled1 || !canceled2) {
+ resolveCancelPromise(undefined);
+ }
+ });
+ }
+ function pullWithDefaultReader() {
+ if (IsReadableStreamBYOBReader(reader)) {
+ ReadableStreamReaderGenericRelease(reader);
+ reader = AcquireReadableStreamDefaultReader(stream);
+ forwardReaderError(reader);
+ }
+ const readRequest = {
+ _chunkSteps: chunk => {
+ // This needs to be delayed a microtask because it takes at least a microtask to detect errors (using
+ // reader._closedPromise below), and we want errors in stream to error both branches immediately. We cannot let
+ // successful synchronously-available reads get ahead of asynchronously-available errors.
+ queueMicrotask(() => {
+ readAgainForBranch1 = false;
+ readAgainForBranch2 = false;
+ const chunk1 = chunk;
+ let chunk2 = chunk;
+ if (!canceled1 && !canceled2) {
+ try {
+ chunk2 = CloneAsUint8Array(chunk);
+ }
+ catch (cloneE) {
+ ReadableByteStreamControllerError(branch1._readableStreamController, cloneE);
+ ReadableByteStreamControllerError(branch2._readableStreamController, cloneE);
+ resolveCancelPromise(ReadableStreamCancel(stream, cloneE));
+ return;
+ }
+ }
+ if (!canceled1) {
+ ReadableByteStreamControllerEnqueue(branch1._readableStreamController, chunk1);
+ }
+ if (!canceled2) {
+ ReadableByteStreamControllerEnqueue(branch2._readableStreamController, chunk2);
+ }
+ reading = false;
+ if (readAgainForBranch1) {
+ pull1Algorithm();
+ }
+ else if (readAgainForBranch2) {
+ pull2Algorithm();
+ }
+ });
+ },
+ _closeSteps: () => {
+ reading = false;
+ if (!canceled1) {
+ ReadableByteStreamControllerClose(branch1._readableStreamController);
+ }
+ if (!canceled2) {
+ ReadableByteStreamControllerClose(branch2._readableStreamController);
+ }
+ if (branch1._readableStreamController._pendingPullIntos.length > 0) {
+ ReadableByteStreamControllerRespond(branch1._readableStreamController, 0);
+ }
+ if (branch2._readableStreamController._pendingPullIntos.length > 0) {
+ ReadableByteStreamControllerRespond(branch2._readableStreamController, 0);
+ }
+ if (!canceled1 || !canceled2) {
+ resolveCancelPromise(undefined);
+ }
+ },
+ _errorSteps: () => {
+ reading = false;
+ }
+ };
+ ReadableStreamDefaultReaderRead(reader, readRequest);
+ }
+ function pullWithBYOBReader(view, forBranch2) {
+ if (IsReadableStreamDefaultReader(reader)) {
+ ReadableStreamReaderGenericRelease(reader);
+ reader = AcquireReadableStreamBYOBReader(stream);
+ forwardReaderError(reader);
+ }
+ const byobBranch = forBranch2 ? branch2 : branch1;
+ const otherBranch = forBranch2 ? branch1 : branch2;
+ const readIntoRequest = {
+ _chunkSteps: chunk => {
+ // This needs to be delayed a microtask because it takes at least a microtask to detect errors (using
+ // reader._closedPromise below), and we want errors in stream to error both branches immediately. We cannot let
+ // successful synchronously-available reads get ahead of asynchronously-available errors.
+ queueMicrotask(() => {
+ readAgainForBranch1 = false;
+ readAgainForBranch2 = false;
+ const byobCanceled = forBranch2 ? canceled2 : canceled1;
+ const otherCanceled = forBranch2 ? canceled1 : canceled2;
+ if (!otherCanceled) {
+ let clonedChunk;
+ try {
+ clonedChunk = CloneAsUint8Array(chunk);
+ }
+ catch (cloneE) {
+ ReadableByteStreamControllerError(byobBranch._readableStreamController, cloneE);
+ ReadableByteStreamControllerError(otherBranch._readableStreamController, cloneE);
+ resolveCancelPromise(ReadableStreamCancel(stream, cloneE));
+ return;
+ }
+ if (!byobCanceled) {
+ ReadableByteStreamControllerRespondWithNewView(byobBranch._readableStreamController, chunk);
+ }
+ ReadableByteStreamControllerEnqueue(otherBranch._readableStreamController, clonedChunk);
+ }
+ else if (!byobCanceled) {
+ ReadableByteStreamControllerRespondWithNewView(byobBranch._readableStreamController, chunk);
+ }
+ reading = false;
+ if (readAgainForBranch1) {
+ pull1Algorithm();
+ }
+ else if (readAgainForBranch2) {
+ pull2Algorithm();
+ }
+ });
+ },
+ _closeSteps: chunk => {
+ reading = false;
+ const byobCanceled = forBranch2 ? canceled2 : canceled1;
+ const otherCanceled = forBranch2 ? canceled1 : canceled2;
+ if (!byobCanceled) {
+ ReadableByteStreamControllerClose(byobBranch._readableStreamController);
+ }
+ if (!otherCanceled) {
+ ReadableByteStreamControllerClose(otherBranch._readableStreamController);
+ }
+ if (chunk !== undefined) {
+ if (!byobCanceled) {
+ ReadableByteStreamControllerRespondWithNewView(byobBranch._readableStreamController, chunk);
+ }
+ if (!otherCanceled && otherBranch._readableStreamController._pendingPullIntos.length > 0) {
+ ReadableByteStreamControllerRespond(otherBranch._readableStreamController, 0);
+ }
+ }
+ if (!byobCanceled || !otherCanceled) {
+ resolveCancelPromise(undefined);
+ }
+ },
+ _errorSteps: () => {
+ reading = false;
+ }
+ };
+ ReadableStreamBYOBReaderRead(reader, view, readIntoRequest);
+ }
+ function pull1Algorithm() {
+ if (reading) {
+ readAgainForBranch1 = true;
+ return promiseResolvedWith(undefined);
+ }
+ reading = true;
+ const byobRequest = ReadableByteStreamControllerGetBYOBRequest(branch1._readableStreamController);
+ if (byobRequest === null) {
+ pullWithDefaultReader();
+ }
+ else {
+ pullWithBYOBReader(byobRequest._view, false);
+ }
+ return promiseResolvedWith(undefined);
+ }
+ function pull2Algorithm() {
+ if (reading) {
+ readAgainForBranch2 = true;
+ return promiseResolvedWith(undefined);
+ }
+ reading = true;
+ const byobRequest = ReadableByteStreamControllerGetBYOBRequest(branch2._readableStreamController);
+ if (byobRequest === null) {
+ pullWithDefaultReader();
+ }
+ else {
+ pullWithBYOBReader(byobRequest._view, true);
+ }
+ return promiseResolvedWith(undefined);
+ }
+ function cancel1Algorithm(reason) {
+ canceled1 = true;
+ reason1 = reason;
+ if (canceled2) {
+ const compositeReason = CreateArrayFromList([reason1, reason2]);
+ const cancelResult = ReadableStreamCancel(stream, compositeReason);
+ resolveCancelPromise(cancelResult);
+ }
+ return cancelPromise;
+ }
+ function cancel2Algorithm(reason) {
+ canceled2 = true;
+ reason2 = reason;
+ if (canceled1) {
+ const compositeReason = CreateArrayFromList([reason1, reason2]);
+ const cancelResult = ReadableStreamCancel(stream, compositeReason);
+ resolveCancelPromise(cancelResult);
+ }
+ return cancelPromise;
+ }
+ function startAlgorithm() {
+ return;
+ }
+ branch1 = CreateReadableByteStream(startAlgorithm, pull1Algorithm, cancel1Algorithm);
+ branch2 = CreateReadableByteStream(startAlgorithm, pull2Algorithm, cancel2Algorithm);
+ forwardReaderError(reader);
+ return [branch1, branch2];
+ }
+
+ function convertUnderlyingDefaultOrByteSource(source, context) {
+ assertDictionary(source, context);
+ const original = source;
+ const autoAllocateChunkSize = original === null || original === void 0 ? void 0 : original.autoAllocateChunkSize;
+ const cancel = original === null || original === void 0 ? void 0 : original.cancel;
+ const pull = original === null || original === void 0 ? void 0 : original.pull;
+ const start = original === null || original === void 0 ? void 0 : original.start;
+ const type = original === null || original === void 0 ? void 0 : original.type;
+ return {
+ autoAllocateChunkSize: autoAllocateChunkSize === undefined ?
+ undefined :
+ convertUnsignedLongLongWithEnforceRange(autoAllocateChunkSize, `${context} has member 'autoAllocateChunkSize' that`),
+ cancel: cancel === undefined ?
+ undefined :
+ convertUnderlyingSourceCancelCallback(cancel, original, `${context} has member 'cancel' that`),
+ pull: pull === undefined ?
+ undefined :
+ convertUnderlyingSourcePullCallback(pull, original, `${context} has member 'pull' that`),
+ start: start === undefined ?
+ undefined :
+ convertUnderlyingSourceStartCallback(start, original, `${context} has member 'start' that`),
+ type: type === undefined ? undefined : convertReadableStreamType(type, `${context} has member 'type' that`)
+ };
+ }
+ function convertUnderlyingSourceCancelCallback(fn, original, context) {
+ assertFunction(fn, context);
+ return (reason) => promiseCall(fn, original, [reason]);
+ }
+ function convertUnderlyingSourcePullCallback(fn, original, context) {
+ assertFunction(fn, context);
+ return (controller) => promiseCall(fn, original, [controller]);
+ }
+ function convertUnderlyingSourceStartCallback(fn, original, context) {
+ assertFunction(fn, context);
+ return (controller) => reflectCall(fn, original, [controller]);
+ }
+ function convertReadableStreamType(type, context) {
+ type = `${type}`;
+ if (type !== 'bytes') {
+ throw new TypeError(`${context} '${type}' is not a valid enumeration value for ReadableStreamType`);
+ }
+ return type;
+ }
+
+ function convertReaderOptions(options, context) {
+ assertDictionary(options, context);
+ const mode = options === null || options === void 0 ? void 0 : options.mode;
+ return {
+ mode: mode === undefined ? undefined : convertReadableStreamReaderMode(mode, `${context} has member 'mode' that`)
+ };
+ }
+ function convertReadableStreamReaderMode(mode, context) {
+ mode = `${mode}`;
+ if (mode !== 'byob') {
+ throw new TypeError(`${context} '${mode}' is not a valid enumeration value for ReadableStreamReaderMode`);
+ }
+ return mode;
+ }
+
+ function convertIteratorOptions(options, context) {
+ assertDictionary(options, context);
+ const preventCancel = options === null || options === void 0 ? void 0 : options.preventCancel;
+ return { preventCancel: Boolean(preventCancel) };
+ }
+
+ function convertPipeOptions(options, context) {
+ assertDictionary(options, context);
+ const preventAbort = options === null || options === void 0 ? void 0 : options.preventAbort;
+ const preventCancel = options === null || options === void 0 ? void 0 : options.preventCancel;
+ const preventClose = options === null || options === void 0 ? void 0 : options.preventClose;
+ const signal = options === null || options === void 0 ? void 0 : options.signal;
+ if (signal !== undefined) {
+ assertAbortSignal(signal, `${context} has member 'signal' that`);
+ }
+ return {
+ preventAbort: Boolean(preventAbort),
+ preventCancel: Boolean(preventCancel),
+ preventClose: Boolean(preventClose),
+ signal
+ };
+ }
+ function assertAbortSignal(signal, context) {
+ if (!isAbortSignal(signal)) {
+ throw new TypeError(`${context} is not an AbortSignal.`);
+ }
+ }
+
+ function convertReadableWritablePair(pair, context) {
+ assertDictionary(pair, context);
+ const readable = pair === null || pair === void 0 ? void 0 : pair.readable;
+ assertRequiredField(readable, 'readable', 'ReadableWritablePair');
+ assertReadableStream(readable, `${context} has member 'readable' that`);
+ const writable = pair === null || pair === void 0 ? void 0 : pair.writable;
+ assertRequiredField(writable, 'writable', 'ReadableWritablePair');
+ assertWritableStream(writable, `${context} has member 'writable' that`);
+ return { readable, writable };
+ }
+
+ /**
+ * A readable stream represents a source of data, from which you can read.
+ *
+ * @public
+ */
+ class ReadableStream {
+ constructor(rawUnderlyingSource = {}, rawStrategy = {}) {
+ if (rawUnderlyingSource === undefined) {
+ rawUnderlyingSource = null;
+ }
+ else {
+ assertObject(rawUnderlyingSource, 'First parameter');
+ }
+ const strategy = convertQueuingStrategy(rawStrategy, 'Second parameter');
+ const underlyingSource = convertUnderlyingDefaultOrByteSource(rawUnderlyingSource, 'First parameter');
+ InitializeReadableStream(this);
+ if (underlyingSource.type === 'bytes') {
+ if (strategy.size !== undefined) {
+ throw new RangeError('The strategy for a byte stream cannot have a size function');
+ }
+ const highWaterMark = ExtractHighWaterMark(strategy, 0);
+ SetUpReadableByteStreamControllerFromUnderlyingSource(this, underlyingSource, highWaterMark);
+ }
+ else {
+ const sizeAlgorithm = ExtractSizeAlgorithm(strategy);
+ const highWaterMark = ExtractHighWaterMark(strategy, 1);
+ SetUpReadableStreamDefaultControllerFromUnderlyingSource(this, underlyingSource, highWaterMark, sizeAlgorithm);
+ }
+ }
+ /**
+ * Whether or not the readable stream is locked to a {@link ReadableStreamDefaultReader | reader}.
+ */
+ get locked() {
+ if (!IsReadableStream(this)) {
+ throw streamBrandCheckException$1('locked');
+ }
+ return IsReadableStreamLocked(this);
+ }
+ /**
+ * Cancels the stream, signaling a loss of interest in the stream by a consumer.
+ *
+ * The supplied `reason` argument will be given to the underlying source's {@link UnderlyingSource.cancel | cancel()}
+ * method, which might or might not use it.
+ */
+ cancel(reason = undefined) {
+ if (!IsReadableStream(this)) {
+ return promiseRejectedWith(streamBrandCheckException$1('cancel'));
+ }
+ if (IsReadableStreamLocked(this)) {
+ return promiseRejectedWith(new TypeError('Cannot cancel a stream that already has a reader'));
+ }
+ return ReadableStreamCancel(this, reason);
+ }
+ getReader(rawOptions = undefined) {
+ if (!IsReadableStream(this)) {
+ throw streamBrandCheckException$1('getReader');
+ }
+ const options = convertReaderOptions(rawOptions, 'First parameter');
+ if (options.mode === undefined) {
+ return AcquireReadableStreamDefaultReader(this);
+ }
+ return AcquireReadableStreamBYOBReader(this);
+ }
+ pipeThrough(rawTransform, rawOptions = {}) {
+ if (!IsReadableStream(this)) {
+ throw streamBrandCheckException$1('pipeThrough');
+ }
+ assertRequiredArgument(rawTransform, 1, 'pipeThrough');
+ const transform = convertReadableWritablePair(rawTransform, 'First parameter');
+ const options = convertPipeOptions(rawOptions, 'Second parameter');
+ if (IsReadableStreamLocked(this)) {
+ throw new TypeError('ReadableStream.prototype.pipeThrough cannot be used on a locked ReadableStream');
+ }
+ if (IsWritableStreamLocked(transform.writable)) {
+ throw new TypeError('ReadableStream.prototype.pipeThrough cannot be used on a locked WritableStream');
+ }
+ const promise = ReadableStreamPipeTo(this, transform.writable, options.preventClose, options.preventAbort, options.preventCancel, options.signal);
+ setPromiseIsHandledToTrue(promise);
+ return transform.readable;
+ }
+ pipeTo(destination, rawOptions = {}) {
+ if (!IsReadableStream(this)) {
+ return promiseRejectedWith(streamBrandCheckException$1('pipeTo'));
+ }
+ if (destination === undefined) {
+ return promiseRejectedWith(`Parameter 1 is required in 'pipeTo'.`);
+ }
+ if (!IsWritableStream(destination)) {
+ return promiseRejectedWith(new TypeError(`ReadableStream.prototype.pipeTo's first argument must be a WritableStream`));
+ }
+ let options;
+ try {
+ options = convertPipeOptions(rawOptions, 'Second parameter');
+ }
+ catch (e) {
+ return promiseRejectedWith(e);
+ }
+ if (IsReadableStreamLocked(this)) {
+ return promiseRejectedWith(new TypeError('ReadableStream.prototype.pipeTo cannot be used on a locked ReadableStream'));
+ }
+ if (IsWritableStreamLocked(destination)) {
+ return promiseRejectedWith(new TypeError('ReadableStream.prototype.pipeTo cannot be used on a locked WritableStream'));
+ }
+ return ReadableStreamPipeTo(this, destination, options.preventClose, options.preventAbort, options.preventCancel, options.signal);
+ }
+ /**
+ * Tees this readable stream, returning a two-element array containing the two resulting branches as
+ * new {@link ReadableStream} instances.
+ *
+ * Teeing a stream will lock it, preventing any other consumer from acquiring a reader.
+ * To cancel the stream, cancel both of the resulting branches; a composite cancellation reason will then be
+ * propagated to the stream's underlying source.
+ *
+ * Note that the chunks seen in each branch will be the same object. If the chunks are not immutable,
+ * this could allow interference between the two branches.
+ */
+ tee() {
+ if (!IsReadableStream(this)) {
+ throw streamBrandCheckException$1('tee');
+ }
+ const branches = ReadableStreamTee(this);
+ return CreateArrayFromList(branches);
+ }
+ values(rawOptions = undefined) {
+ if (!IsReadableStream(this)) {
+ throw streamBrandCheckException$1('values');
+ }
+ const options = convertIteratorOptions(rawOptions, 'First parameter');
+ return AcquireReadableStreamAsyncIterator(this, options.preventCancel);
+ }
+ }
+ Object.defineProperties(ReadableStream.prototype, {
+ cancel: { enumerable: true },
+ getReader: { enumerable: true },
+ pipeThrough: { enumerable: true },
+ pipeTo: { enumerable: true },
+ tee: { enumerable: true },
+ values: { enumerable: true },
+ locked: { enumerable: true }
+ });
+ if (typeof SymbolPolyfill.toStringTag === 'symbol') {
+ Object.defineProperty(ReadableStream.prototype, SymbolPolyfill.toStringTag, {
+ value: 'ReadableStream',
+ configurable: true
+ });
+ }
+ if (typeof SymbolPolyfill.asyncIterator === 'symbol') {
+ Object.defineProperty(ReadableStream.prototype, SymbolPolyfill.asyncIterator, {
+ value: ReadableStream.prototype.values,
+ writable: true,
+ configurable: true
+ });
+ }
+ // Abstract operations for the ReadableStream.
+ // Throws if and only if startAlgorithm throws.
+ function CreateReadableStream(startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark = 1, sizeAlgorithm = () => 1) {
+ const stream = Object.create(ReadableStream.prototype);
+ InitializeReadableStream(stream);
+ const controller = Object.create(ReadableStreamDefaultController.prototype);
+ SetUpReadableStreamDefaultController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, sizeAlgorithm);
+ return stream;
+ }
+ // Throws if and only if startAlgorithm throws.
+ function CreateReadableByteStream(startAlgorithm, pullAlgorithm, cancelAlgorithm) {
+ const stream = Object.create(ReadableStream.prototype);
+ InitializeReadableStream(stream);
+ const controller = Object.create(ReadableByteStreamController.prototype);
+ SetUpReadableByteStreamController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, 0, undefined);
+ return stream;
+ }
+ function InitializeReadableStream(stream) {
+ stream._state = 'readable';
+ stream._reader = undefined;
+ stream._storedError = undefined;
+ stream._disturbed = false;
+ }
+ function IsReadableStream(x) {
+ if (!typeIsObject(x)) {
+ return false;
+ }
+ if (!Object.prototype.hasOwnProperty.call(x, '_readableStreamController')) {
+ return false;
+ }
+ return x instanceof ReadableStream;
+ }
+ function IsReadableStreamLocked(stream) {
+ if (stream._reader === undefined) {
+ return false;
+ }
+ return true;
+ }
+ // ReadableStream API exposed for controllers.
+ function ReadableStreamCancel(stream, reason) {
+ stream._disturbed = true;
+ if (stream._state === 'closed') {
+ return promiseResolvedWith(undefined);
+ }
+ if (stream._state === 'errored') {
+ return promiseRejectedWith(stream._storedError);
+ }
+ ReadableStreamClose(stream);
+ const reader = stream._reader;
+ if (reader !== undefined && IsReadableStreamBYOBReader(reader)) {
+ reader._readIntoRequests.forEach(readIntoRequest => {
+ readIntoRequest._closeSteps(undefined);
+ });
+ reader._readIntoRequests = new SimpleQueue();
+ }
+ const sourceCancelPromise = stream._readableStreamController[CancelSteps](reason);
+ return transformPromiseWith(sourceCancelPromise, noop);
+ }
+ function ReadableStreamClose(stream) {
+ stream._state = 'closed';
+ const reader = stream._reader;
+ if (reader === undefined) {
+ return;
+ }
+ defaultReaderClosedPromiseResolve(reader);
+ if (IsReadableStreamDefaultReader(reader)) {
+ reader._readRequests.forEach(readRequest => {
+ readRequest._closeSteps();
+ });
+ reader._readRequests = new SimpleQueue();
+ }
+ }
+ function ReadableStreamError(stream, e) {
+ stream._state = 'errored';
+ stream._storedError = e;
+ const reader = stream._reader;
+ if (reader === undefined) {
+ return;
+ }
+ defaultReaderClosedPromiseReject(reader, e);
+ if (IsReadableStreamDefaultReader(reader)) {
+ reader._readRequests.forEach(readRequest => {
+ readRequest._errorSteps(e);
+ });
+ reader._readRequests = new SimpleQueue();
+ }
+ else {
+ reader._readIntoRequests.forEach(readIntoRequest => {
+ readIntoRequest._errorSteps(e);
+ });
+ reader._readIntoRequests = new SimpleQueue();
+ }
+ }
+ // Helper functions for the ReadableStream.
+ function streamBrandCheckException$1(name) {
+ return new TypeError(`ReadableStream.prototype.${name} can only be used on a ReadableStream`);
+ }
+
+ function convertQueuingStrategyInit(init, context) {
+ assertDictionary(init, context);
+ const highWaterMark = init === null || init === void 0 ? void 0 : init.highWaterMark;
+ assertRequiredField(highWaterMark, 'highWaterMark', 'QueuingStrategyInit');
+ return {
+ highWaterMark: convertUnrestrictedDouble(highWaterMark)
+ };
+ }
+
+ // The size function must not have a prototype property nor be a constructor
+ const byteLengthSizeFunction = (chunk) => {
+ return chunk.byteLength;
+ };
+ try {
+ Object.defineProperty(byteLengthSizeFunction, 'name', {
+ value: 'size',
+ configurable: true
+ });
+ }
+ catch (_a) {
+ // This property is non-configurable in older browsers, so ignore if this throws.
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#browser_compatibility
+ }
+ /**
+ * A queuing strategy that counts the number of bytes in each chunk.
+ *
+ * @public
+ */
+ class ByteLengthQueuingStrategy {
+ constructor(options) {
+ assertRequiredArgument(options, 1, 'ByteLengthQueuingStrategy');
+ options = convertQueuingStrategyInit(options, 'First parameter');
+ this._byteLengthQueuingStrategyHighWaterMark = options.highWaterMark;
+ }
+ /**
+ * Returns the high water mark provided to the constructor.
+ */
+ get highWaterMark() {
+ if (!IsByteLengthQueuingStrategy(this)) {
+ throw byteLengthBrandCheckException('highWaterMark');
+ }
+ return this._byteLengthQueuingStrategyHighWaterMark;
+ }
+ /**
+ * Measures the size of `chunk` by returning the value of its `byteLength` property.
+ */
+ get size() {
+ if (!IsByteLengthQueuingStrategy(this)) {
+ throw byteLengthBrandCheckException('size');
+ }
+ return byteLengthSizeFunction;
+ }
+ }
+ Object.defineProperties(ByteLengthQueuingStrategy.prototype, {
+ highWaterMark: { enumerable: true },
+ size: { enumerable: true }
+ });
+ if (typeof SymbolPolyfill.toStringTag === 'symbol') {
+ Object.defineProperty(ByteLengthQueuingStrategy.prototype, SymbolPolyfill.toStringTag, {
+ value: 'ByteLengthQueuingStrategy',
+ configurable: true
+ });
+ }
+ // Helper functions for the ByteLengthQueuingStrategy.
+ function byteLengthBrandCheckException(name) {
+ return new TypeError(`ByteLengthQueuingStrategy.prototype.${name} can only be used on a ByteLengthQueuingStrategy`);
+ }
+ function IsByteLengthQueuingStrategy(x) {
+ if (!typeIsObject(x)) {
+ return false;
+ }
+ if (!Object.prototype.hasOwnProperty.call(x, '_byteLengthQueuingStrategyHighWaterMark')) {
+ return false;
+ }
+ return x instanceof ByteLengthQueuingStrategy;
+ }
+
+ // The size function must not have a prototype property nor be a constructor
+ const countSizeFunction = () => {
+ return 1;
+ };
+ try {
+ Object.defineProperty(countSizeFunction, 'name', {
+ value: 'size',
+ configurable: true
+ });
+ }
+ catch (_a) {
+ // This property is non-configurable in older browsers, so ignore if this throws.
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#browser_compatibility
+ }
+ /**
+ * A queuing strategy that counts the number of chunks.
+ *
+ * @public
+ */
+ class CountQueuingStrategy {
+ constructor(options) {
+ assertRequiredArgument(options, 1, 'CountQueuingStrategy');
+ options = convertQueuingStrategyInit(options, 'First parameter');
+ this._countQueuingStrategyHighWaterMark = options.highWaterMark;
+ }
+ /**
+ * Returns the high water mark provided to the constructor.
+ */
+ get highWaterMark() {
+ if (!IsCountQueuingStrategy(this)) {
+ throw countBrandCheckException('highWaterMark');
+ }
+ return this._countQueuingStrategyHighWaterMark;
+ }
+ /**
+ * Measures the size of `chunk` by always returning 1.
+ * This ensures that the total queue size is a count of the number of chunks in the queue.
+ */
+ get size() {
+ if (!IsCountQueuingStrategy(this)) {
+ throw countBrandCheckException('size');
+ }
+ return countSizeFunction;
+ }
+ }
+ Object.defineProperties(CountQueuingStrategy.prototype, {
+ highWaterMark: { enumerable: true },
+ size: { enumerable: true }
+ });
+ if (typeof SymbolPolyfill.toStringTag === 'symbol') {
+ Object.defineProperty(CountQueuingStrategy.prototype, SymbolPolyfill.toStringTag, {
+ value: 'CountQueuingStrategy',
+ configurable: true
+ });
+ }
+ // Helper functions for the CountQueuingStrategy.
+ function countBrandCheckException(name) {
+ return new TypeError(`CountQueuingStrategy.prototype.${name} can only be used on a CountQueuingStrategy`);
+ }
+ function IsCountQueuingStrategy(x) {
+ if (!typeIsObject(x)) {
+ return false;
+ }
+ if (!Object.prototype.hasOwnProperty.call(x, '_countQueuingStrategyHighWaterMark')) {
+ return false;
+ }
+ return x instanceof CountQueuingStrategy;
+ }
+
+ function convertTransformer(original, context) {
+ assertDictionary(original, context);
+ const flush = original === null || original === void 0 ? void 0 : original.flush;
+ const readableType = original === null || original === void 0 ? void 0 : original.readableType;
+ const start = original === null || original === void 0 ? void 0 : original.start;
+ const transform = original === null || original === void 0 ? void 0 : original.transform;
+ const writableType = original === null || original === void 0 ? void 0 : original.writableType;
+ return {
+ flush: flush === undefined ?
+ undefined :
+ convertTransformerFlushCallback(flush, original, `${context} has member 'flush' that`),
+ readableType,
+ start: start === undefined ?
+ undefined :
+ convertTransformerStartCallback(start, original, `${context} has member 'start' that`),
+ transform: transform === undefined ?
+ undefined :
+ convertTransformerTransformCallback(transform, original, `${context} has member 'transform' that`),
+ writableType
+ };
+ }
+ function convertTransformerFlushCallback(fn, original, context) {
+ assertFunction(fn, context);
+ return (controller) => promiseCall(fn, original, [controller]);
+ }
+ function convertTransformerStartCallback(fn, original, context) {
+ assertFunction(fn, context);
+ return (controller) => reflectCall(fn, original, [controller]);
+ }
+ function convertTransformerTransformCallback(fn, original, context) {
+ assertFunction(fn, context);
+ return (chunk, controller) => promiseCall(fn, original, [chunk, controller]);
+ }
+
+ // Class TransformStream
+ /**
+ * A transform stream consists of a pair of streams: a {@link WritableStream | writable stream},
+ * known as its writable side, and a {@link ReadableStream | readable stream}, known as its readable side.
+ * In a manner specific to the transform stream in question, writes to the writable side result in new data being
+ * made available for reading from the readable side.
+ *
+ * @public
+ */
+ class TransformStream {
+ constructor(rawTransformer = {}, rawWritableStrategy = {}, rawReadableStrategy = {}) {
+ if (rawTransformer === undefined) {
+ rawTransformer = null;
+ }
+ const writableStrategy = convertQueuingStrategy(rawWritableStrategy, 'Second parameter');
+ const readableStrategy = convertQueuingStrategy(rawReadableStrategy, 'Third parameter');
+ const transformer = convertTransformer(rawTransformer, 'First parameter');
+ if (transformer.readableType !== undefined) {
+ throw new RangeError('Invalid readableType specified');
+ }
+ if (transformer.writableType !== undefined) {
+ throw new RangeError('Invalid writableType specified');
+ }
+ const readableHighWaterMark = ExtractHighWaterMark(readableStrategy, 0);
+ const readableSizeAlgorithm = ExtractSizeAlgorithm(readableStrategy);
+ const writableHighWaterMark = ExtractHighWaterMark(writableStrategy, 1);
+ const writableSizeAlgorithm = ExtractSizeAlgorithm(writableStrategy);
+ let startPromise_resolve;
+ const startPromise = newPromise(resolve => {
+ startPromise_resolve = resolve;
+ });
+ InitializeTransformStream(this, startPromise, writableHighWaterMark, writableSizeAlgorithm, readableHighWaterMark, readableSizeAlgorithm);
+ SetUpTransformStreamDefaultControllerFromTransformer(this, transformer);
+ if (transformer.start !== undefined) {
+ startPromise_resolve(transformer.start(this._transformStreamController));
+ }
+ else {
+ startPromise_resolve(undefined);
+ }
+ }
+ /**
+ * The readable side of the transform stream.
+ */
+ get readable() {
+ if (!IsTransformStream(this)) {
+ throw streamBrandCheckException('readable');
+ }
+ return this._readable;
+ }
+ /**
+ * The writable side of the transform stream.
+ */
+ get writable() {
+ if (!IsTransformStream(this)) {
+ throw streamBrandCheckException('writable');
+ }
+ return this._writable;
+ }
+ }
+ Object.defineProperties(TransformStream.prototype, {
+ readable: { enumerable: true },
+ writable: { enumerable: true }
+ });
+ if (typeof SymbolPolyfill.toStringTag === 'symbol') {
+ Object.defineProperty(TransformStream.prototype, SymbolPolyfill.toStringTag, {
+ value: 'TransformStream',
+ configurable: true
+ });
+ }
+ function InitializeTransformStream(stream, startPromise, writableHighWaterMark, writableSizeAlgorithm, readableHighWaterMark, readableSizeAlgorithm) {
+ function startAlgorithm() {
+ return startPromise;
+ }
+ function writeAlgorithm(chunk) {
+ return TransformStreamDefaultSinkWriteAlgorithm(stream, chunk);
+ }
+ function abortAlgorithm(reason) {
+ return TransformStreamDefaultSinkAbortAlgorithm(stream, reason);
+ }
+ function closeAlgorithm() {
+ return TransformStreamDefaultSinkCloseAlgorithm(stream);
+ }
+ stream._writable = CreateWritableStream(startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, writableHighWaterMark, writableSizeAlgorithm);
+ function pullAlgorithm() {
+ return TransformStreamDefaultSourcePullAlgorithm(stream);
+ }
+ function cancelAlgorithm(reason) {
+ TransformStreamErrorWritableAndUnblockWrite(stream, reason);
+ return promiseResolvedWith(undefined);
+ }
+ stream._readable = CreateReadableStream(startAlgorithm, pullAlgorithm, cancelAlgorithm, readableHighWaterMark, readableSizeAlgorithm);
+ // The [[backpressure]] slot is set to undefined so that it can be initialised by TransformStreamSetBackpressure.
+ stream._backpressure = undefined;
+ stream._backpressureChangePromise = undefined;
+ stream._backpressureChangePromise_resolve = undefined;
+ TransformStreamSetBackpressure(stream, true);
+ stream._transformStreamController = undefined;
+ }
+ function IsTransformStream(x) {
+ if (!typeIsObject(x)) {
+ return false;
+ }
+ if (!Object.prototype.hasOwnProperty.call(x, '_transformStreamController')) {
+ return false;
+ }
+ return x instanceof TransformStream;
+ }
+ // This is a no-op if both sides are already errored.
+ function TransformStreamError(stream, e) {
+ ReadableStreamDefaultControllerError(stream._readable._readableStreamController, e);
+ TransformStreamErrorWritableAndUnblockWrite(stream, e);
+ }
+ function TransformStreamErrorWritableAndUnblockWrite(stream, e) {
+ TransformStreamDefaultControllerClearAlgorithms(stream._transformStreamController);
+ WritableStreamDefaultControllerErrorIfNeeded(stream._writable._writableStreamController, e);
+ if (stream._backpressure) {
+ // Pretend that pull() was called to permit any pending write() calls to complete. TransformStreamSetBackpressure()
+ // cannot be called from enqueue() or pull() once the ReadableStream is errored, so this will will be the final time
+ // _backpressure is set.
+ TransformStreamSetBackpressure(stream, false);
+ }
+ }
+ function TransformStreamSetBackpressure(stream, backpressure) {
+ // Passes also when called during construction.
+ if (stream._backpressureChangePromise !== undefined) {
+ stream._backpressureChangePromise_resolve();
+ }
+ stream._backpressureChangePromise = newPromise(resolve => {
+ stream._backpressureChangePromise_resolve = resolve;
+ });
+ stream._backpressure = backpressure;
+ }
+ // Class TransformStreamDefaultController
+ /**
+ * Allows control of the {@link ReadableStream} and {@link WritableStream} of the associated {@link TransformStream}.
+ *
+ * @public
+ */
+ class TransformStreamDefaultController {
+ constructor() {
+ throw new TypeError('Illegal constructor');
+ }
+ /**
+ * Returns the desired size to fill the readable side’s internal queue. It can be negative, if the queue is over-full.
+ */
+ get desiredSize() {
+ if (!IsTransformStreamDefaultController(this)) {
+ throw defaultControllerBrandCheckException('desiredSize');
+ }
+ const readableController = this._controlledTransformStream._readable._readableStreamController;
+ return ReadableStreamDefaultControllerGetDesiredSize(readableController);
+ }
+ enqueue(chunk = undefined) {
+ if (!IsTransformStreamDefaultController(this)) {
+ throw defaultControllerBrandCheckException('enqueue');
+ }
+ TransformStreamDefaultControllerEnqueue(this, chunk);
+ }
+ /**
+ * Errors both the readable side and the writable side of the controlled transform stream, making all future
+ * interactions with it fail with the given error `e`. Any chunks queued for transformation will be discarded.
+ */
+ error(reason = undefined) {
+ if (!IsTransformStreamDefaultController(this)) {
+ throw defaultControllerBrandCheckException('error');
+ }
+ TransformStreamDefaultControllerError(this, reason);
+ }
+ /**
+ * Closes the readable side and errors the writable side of the controlled transform stream. This is useful when the
+ * transformer only needs to consume a portion of the chunks written to the writable side.
+ */
+ terminate() {
+ if (!IsTransformStreamDefaultController(this)) {
+ throw defaultControllerBrandCheckException('terminate');
+ }
+ TransformStreamDefaultControllerTerminate(this);
+ }
+ }
+ Object.defineProperties(TransformStreamDefaultController.prototype, {
+ enqueue: { enumerable: true },
+ error: { enumerable: true },
+ terminate: { enumerable: true },
+ desiredSize: { enumerable: true }
+ });
+ if (typeof SymbolPolyfill.toStringTag === 'symbol') {
+ Object.defineProperty(TransformStreamDefaultController.prototype, SymbolPolyfill.toStringTag, {
+ value: 'TransformStreamDefaultController',
+ configurable: true
+ });
+ }
+ // Transform Stream Default Controller Abstract Operations
+ function IsTransformStreamDefaultController(x) {
+ if (!typeIsObject(x)) {
+ return false;
+ }
+ if (!Object.prototype.hasOwnProperty.call(x, '_controlledTransformStream')) {
+ return false;
+ }
+ return x instanceof TransformStreamDefaultController;
+ }
+ function SetUpTransformStreamDefaultController(stream, controller, transformAlgorithm, flushAlgorithm) {
+ controller._controlledTransformStream = stream;
+ stream._transformStreamController = controller;
+ controller._transformAlgorithm = transformAlgorithm;
+ controller._flushAlgorithm = flushAlgorithm;
+ }
+ function SetUpTransformStreamDefaultControllerFromTransformer(stream, transformer) {
+ const controller = Object.create(TransformStreamDefaultController.prototype);
+ let transformAlgorithm = (chunk) => {
+ try {
+ TransformStreamDefaultControllerEnqueue(controller, chunk);
+ return promiseResolvedWith(undefined);
+ }
+ catch (transformResultE) {
+ return promiseRejectedWith(transformResultE);
+ }
+ };
+ let flushAlgorithm = () => promiseResolvedWith(undefined);
+ if (transformer.transform !== undefined) {
+ transformAlgorithm = chunk => transformer.transform(chunk, controller);
+ }
+ if (transformer.flush !== undefined) {
+ flushAlgorithm = () => transformer.flush(controller);
+ }
+ SetUpTransformStreamDefaultController(stream, controller, transformAlgorithm, flushAlgorithm);
+ }
+ function TransformStreamDefaultControllerClearAlgorithms(controller) {
+ controller._transformAlgorithm = undefined;
+ controller._flushAlgorithm = undefined;
+ }
+ function TransformStreamDefaultControllerEnqueue(controller, chunk) {
+ const stream = controller._controlledTransformStream;
+ const readableController = stream._readable._readableStreamController;
+ if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(readableController)) {
+ throw new TypeError('Readable side is not in a state that permits enqueue');
+ }
+ // We throttle transform invocations based on the backpressure of the ReadableStream, but we still
+ // accept TransformStreamDefaultControllerEnqueue() calls.
+ try {
+ ReadableStreamDefaultControllerEnqueue(readableController, chunk);
+ }
+ catch (e) {
+ // This happens when readableStrategy.size() throws.
+ TransformStreamErrorWritableAndUnblockWrite(stream, e);
+ throw stream._readable._storedError;
+ }
+ const backpressure = ReadableStreamDefaultControllerHasBackpressure(readableController);
+ if (backpressure !== stream._backpressure) {
+ TransformStreamSetBackpressure(stream, true);
+ }
+ }
+ function TransformStreamDefaultControllerError(controller, e) {
+ TransformStreamError(controller._controlledTransformStream, e);
+ }
+ function TransformStreamDefaultControllerPerformTransform(controller, chunk) {
+ const transformPromise = controller._transformAlgorithm(chunk);
+ return transformPromiseWith(transformPromise, undefined, r => {
+ TransformStreamError(controller._controlledTransformStream, r);
+ throw r;
+ });
+ }
+ function TransformStreamDefaultControllerTerminate(controller) {
+ const stream = controller._controlledTransformStream;
+ const readableController = stream._readable._readableStreamController;
+ ReadableStreamDefaultControllerClose(readableController);
+ const error = new TypeError('TransformStream terminated');
+ TransformStreamErrorWritableAndUnblockWrite(stream, error);
+ }
+ // TransformStreamDefaultSink Algorithms
+ function TransformStreamDefaultSinkWriteAlgorithm(stream, chunk) {
+ const controller = stream._transformStreamController;
+ if (stream._backpressure) {
+ const backpressureChangePromise = stream._backpressureChangePromise;
+ return transformPromiseWith(backpressureChangePromise, () => {
+ const writable = stream._writable;
+ const state = writable._state;
+ if (state === 'erroring') {
+ throw writable._storedError;
+ }
+ return TransformStreamDefaultControllerPerformTransform(controller, chunk);
+ });
+ }
+ return TransformStreamDefaultControllerPerformTransform(controller, chunk);
+ }
+ function TransformStreamDefaultSinkAbortAlgorithm(stream, reason) {
+ // abort() is not called synchronously, so it is possible for abort() to be called when the stream is already
+ // errored.
+ TransformStreamError(stream, reason);
+ return promiseResolvedWith(undefined);
+ }
+ function TransformStreamDefaultSinkCloseAlgorithm(stream) {
+ // stream._readable cannot change after construction, so caching it across a call to user code is safe.
+ const readable = stream._readable;
+ const controller = stream._transformStreamController;
+ const flushPromise = controller._flushAlgorithm();
+ TransformStreamDefaultControllerClearAlgorithms(controller);
+ // Return a promise that is fulfilled with undefined on success.
+ return transformPromiseWith(flushPromise, () => {
+ if (readable._state === 'errored') {
+ throw readable._storedError;
+ }
+ ReadableStreamDefaultControllerClose(readable._readableStreamController);
+ }, r => {
+ TransformStreamError(stream, r);
+ throw readable._storedError;
+ });
+ }
+ // TransformStreamDefaultSource Algorithms
+ function TransformStreamDefaultSourcePullAlgorithm(stream) {
+ // Invariant. Enforced by the promises returned by start() and pull().
+ TransformStreamSetBackpressure(stream, false);
+ // Prevent the next pull() call until there is backpressure.
+ return stream._backpressureChangePromise;
+ }
+ // Helper functions for the TransformStreamDefaultController.
+ function defaultControllerBrandCheckException(name) {
+ return new TypeError(`TransformStreamDefaultController.prototype.${name} can only be used on a TransformStreamDefaultController`);
+ }
+ // Helper functions for the TransformStream.
+ function streamBrandCheckException(name) {
+ return new TypeError(`TransformStream.prototype.${name} can only be used on a TransformStream`);
+ }
+
+ const exports$1 = {
+ ReadableStream,
+ ReadableStreamDefaultController,
+ ReadableByteStreamController,
+ ReadableStreamBYOBRequest,
+ ReadableStreamDefaultReader,
+ ReadableStreamBYOBReader,
+ WritableStream,
+ WritableStreamDefaultController,
+ WritableStreamDefaultWriter,
+ ByteLengthQueuingStrategy,
+ CountQueuingStrategy,
+ TransformStream,
+ TransformStreamDefaultController
+ };
+ // Add classes to global scope
+ if (typeof globals !== 'undefined') {
+ for (const prop in exports$1) {
+ if (Object.prototype.hasOwnProperty.call(exports$1, prop)) {
+ Object.defineProperty(globals, prop, {
+ value: exports$1[prop],
+ writable: true,
+ configurable: true
+ });
+ }
+ }
+ }
+
+ exports.ByteLengthQueuingStrategy = ByteLengthQueuingStrategy;
+ exports.CountQueuingStrategy = CountQueuingStrategy;
+ exports.ReadableByteStreamController = ReadableByteStreamController;
+ exports.ReadableStream = ReadableStream;
+ exports.ReadableStreamBYOBReader = ReadableStreamBYOBReader;
+ exports.ReadableStreamBYOBRequest = ReadableStreamBYOBRequest;
+ exports.ReadableStreamDefaultController = ReadableStreamDefaultController;
+ exports.ReadableStreamDefaultReader = ReadableStreamDefaultReader;
+ exports.TransformStream = TransformStream;
+ exports.TransformStreamDefaultController = TransformStreamDefaultController;
+ exports.WritableStream = WritableStream;
+ exports.WritableStreamDefaultController = WritableStreamDefaultController;
+ exports.WritableStreamDefaultWriter = WritableStreamDefaultWriter;
+
+ Object.defineProperty(exports, '__esModule', { value: true });
+
+})));
+//# sourceMappingURL=polyfill.es2018.js.map
diff --git a/node_modules/web-streams-polyfill/dist/polyfill.es2018.js.map b/node_modules/web-streams-polyfill/dist/polyfill.es2018.js.map
new file mode 100644
index 0000000..1f9d92a
--- /dev/null
+++ b/node_modules/web-streams-polyfill/dist/polyfill.es2018.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"polyfill.es2018.js","sources":["../src/stub/symbol.ts","../src/utils.ts","../src/lib/helpers/miscellaneous.ts","../src/lib/helpers/webidl.ts","../src/lib/simple-queue.ts","../src/lib/readable-stream/generic-reader.ts","../src/lib/abstract-ops/internal-methods.ts","../src/stub/number-isfinite.ts","../src/stub/math-trunc.ts","../src/lib/validators/basic.ts","../src/lib/validators/readable-stream.ts","../src/lib/readable-stream/default-reader.ts","../src/target/es2018/stub/async-iterator-prototype.ts","../src/lib/readable-stream/async-iterator.ts","../src/stub/number-isnan.ts","../src/lib/abstract-ops/ecmascript.ts","../src/lib/abstract-ops/miscellaneous.ts","../src/lib/abstract-ops/queue-with-sizes.ts","../src/lib/readable-stream/byte-stream-controller.ts","../src/lib/readable-stream/byob-reader.ts","../src/lib/abstract-ops/queuing-strategy.ts","../src/lib/validators/queuing-strategy.ts","../src/lib/validators/underlying-sink.ts","../src/lib/validators/writable-stream.ts","../src/lib/abort-signal.ts","../src/lib/writable-stream.ts","../src/stub/native.ts","../src/stub/dom-exception.ts","../src/lib/readable-stream/pipe.ts","../src/lib/readable-stream/default-controller.ts","../src/lib/readable-stream/tee.ts","../src/lib/validators/underlying-source.ts","../src/lib/validators/reader-options.ts","../src/lib/validators/iterator-options.ts","../src/lib/validators/pipe-options.ts","../src/lib/validators/readable-writable-pair.ts","../src/lib/readable-stream.ts","../src/lib/validators/queuing-strategy-init.ts","../src/lib/byte-length-queuing-strategy.ts","../src/lib/count-queuing-strategy.ts","../src/lib/validators/transformer.ts","../src/lib/transform-stream.ts","../src/polyfill.ts"],"sourcesContent":["/// \n\nconst SymbolPolyfill: (description?: string) => symbol =\n typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ?\n Symbol :\n description => `Symbol(${description})` as any as symbol;\n\nexport default SymbolPolyfill;\n","/// \n\nexport function noop(): undefined {\n return undefined;\n}\n\nfunction getGlobals() {\n if (typeof self !== 'undefined') {\n return self;\n } else if (typeof window !== 'undefined') {\n return window;\n } else if (typeof global !== 'undefined') {\n return global;\n }\n return undefined;\n}\n\nexport const globals = getGlobals();\n","import { noop } from '../../utils';\nimport { AssertionError } from '../../stub/assert';\n\nexport function typeIsObject(x: any): x is object {\n return (typeof x === 'object' && x !== null) || typeof x === 'function';\n}\n\nexport const rethrowAssertionErrorRejection: (e: any) => void =\n DEBUG ? e => {\n // Used throughout the reference implementation, as `.catch(rethrowAssertionErrorRejection)`, to ensure any errors\n // get shown. There are places in the spec where we do promise transformations and purposefully ignore or don't\n // expect any errors, but assertion errors are always problematic.\n if (e && e instanceof AssertionError) {\n setTimeout(() => {\n throw e;\n }, 0);\n }\n } : noop;\n","import { globals } from '../../utils';\nimport { rethrowAssertionErrorRejection } from './miscellaneous';\nimport assert from '../../stub/assert';\n\nconst originalPromise = Promise;\nconst originalPromiseThen = Promise.prototype.then;\nconst originalPromiseResolve = Promise.resolve.bind(originalPromise);\nconst originalPromiseReject = Promise.reject.bind(originalPromise);\n\nexport function newPromise(executor: (\n resolve: (value: T | PromiseLike) => void,\n reject: (reason?: any) => void\n) => void): Promise {\n return new originalPromise(executor);\n}\n\nexport function promiseResolvedWith(value: T | PromiseLike): Promise {\n return originalPromiseResolve(value);\n}\n\nexport function promiseRejectedWith(reason: any): Promise {\n return originalPromiseReject(reason);\n}\n\nexport function PerformPromiseThen(\n promise: Promise,\n onFulfilled?: (value: T) => TResult1 | PromiseLike,\n onRejected?: (reason: any) => TResult2 | PromiseLike): Promise {\n // There doesn't appear to be any way to correctly emulate the behaviour from JavaScript, so this is just an\n // approximation.\n return originalPromiseThen.call(promise, onFulfilled, onRejected) as Promise;\n}\n\nexport function uponPromise(\n promise: Promise,\n onFulfilled?: (value: T) => void | PromiseLike,\n onRejected?: (reason: any) => void | PromiseLike): void {\n PerformPromiseThen(\n PerformPromiseThen(promise, onFulfilled, onRejected),\n undefined,\n rethrowAssertionErrorRejection\n );\n}\n\nexport function uponFulfillment(promise: Promise, onFulfilled: (value: T) => void | PromiseLike): void {\n uponPromise(promise, onFulfilled);\n}\n\nexport function uponRejection(promise: Promise, onRejected: (reason: any) => void | PromiseLike): void {\n uponPromise(promise, undefined, onRejected);\n}\n\nexport function transformPromiseWith(\n promise: Promise,\n fulfillmentHandler?: (value: T) => TResult1 | PromiseLike,\n rejectionHandler?: (reason: any) => TResult2 | PromiseLike): Promise