CoolFace
Apppublic

canal007/voice-bot

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
lib.node.cjs2105 linesDownload Raw Back to dist
1'use strict';2 3const http = require('http');4const https = require('https');5const zlib = require('zlib');6const fs = require('fs');7const mime = require('mrmime');8const dataUriToBuffer = require('data-uri-to-buffer');9const buffer = require('buffer');10const Stream = require('stream');11const util = require('util');12const blob = require('@web-std/blob');13const file = require('@web-std/file');14const formData = require('@web-std/form-data');15const crypto = require('crypto');16const multipartParser = require('@web3-storage/multipart-parser');17const url = require('url');18const abortController = require('abort-controller');19 20class FetchBaseError extends Error {21	/**22	 * @param {string} message 23	 * @param {string} type 24	 */25	constructor(message, type) {26		super(message);27		// Hide custom error implementation details from end-users28		Error.captureStackTrace(this, this.constructor);29 30		this.type = type;31	}32 33	get name() {34		return this.constructor.name;35	}36 37	get [Symbol.toStringTag]() {38		return this.constructor.name;39	}40}41 42/**43 * @typedef {{44 * address?: string45 * code: string46 * dest?: string47 * errno: number48 * info?: object49 * message: string50 * path?: string51 * port?: number52 * syscall: string53 * }} SystemError54*/55 56/**57 * FetchError interface for operational errors58 */59class FetchError extends FetchBaseError {60	/**61	 * @param  {string} message -      Error message for human62	 * @param  {string} type -        Error type for machine63	 * @param  {SystemError} [systemError] - For Node.js system error64	 */65	constructor(message, type, systemError) {66		super(message, type);67		// When err.type is `system`, err.erroredSysCall contains system error and err.code contains system error code68		if (systemError) {69			// eslint-disable-next-line no-multi-assign70			this.code = this.errno = systemError.code;71			this.erroredSysCall = systemError.syscall;72		}73	}74}75 76/**77 * Is.js78 *79 * Object type checks.80 */81 82const NAME = Symbol.toStringTag;83 84/**85 * Check if `obj` is a URLSearchParams object86 * ref: https://github.com/node-fetch/node-fetch/issues/296#issuecomment-30759814387 *88 * @param  {any} object89 * @return {obj is URLSearchParams}90 */91const isURLSearchParameters = (object) => {92	return (93		typeof object === "object" &&94		typeof object.append === "function" &&95		typeof object.delete === "function" &&96		typeof object.get === "function" &&97		typeof object.getAll === "function" &&98		typeof object.has === "function" &&99		typeof object.set === "function" &&100		typeof object.sort === "function" &&101		object[NAME] === "URLSearchParams"102	);103};104 105/**106 * Check if `object` is a W3C `Blob` object (which `File` inherits from)107 *108 * @param  {*} object109 * @return {object is Blob}110 */111const isBlob = (object) => {112	return (113		typeof object === "object" &&114		typeof object.arrayBuffer === "function" &&115		typeof object.type === "string" &&116		typeof object.stream === "function" &&117		typeof object.constructor === "function" &&118		/^(Blob|File)$/.test(object[NAME])119	);120};121 122/**123 * Check if `obj` is a spec-compliant `FormData` object124 *125 * @param {*} object126 * @return {object is FormData}127 */128function isFormData(object) {129	return (130		typeof object === "object" &&131		typeof object.append === "function" &&132		typeof object.set === "function" &&133		typeof object.get === "function" &&134		typeof object.getAll === "function" &&135		typeof object.delete === "function" &&136		typeof object.keys === "function" &&137		typeof object.values === "function" &&138		typeof object.entries === "function" &&139		typeof object.constructor === "function" &&140		object[NAME] === "FormData"141	);142}143 144/**145 * Detect form data input from form-data module146 *147 * @param {any} value148 * @returns {value is Stream & {getBoundary():string, hasKnownLength():boolean, getLengthSync():number|null}}149 */150const isMultipartFormDataStream = (value) => {151	return (152		value instanceof Stream === true &&153		typeof value.getBoundary === "function" &&154		typeof value.hasKnownLength === "function" &&155		typeof value.getLengthSync === "function"156	);157};158 159/**160 * Check if `obj` is an instance of AbortSignal.161 *162 * @param  {any} object163 * @return {obj is AbortSignal}164 */165const isAbortSignal = (object) => {166	return (167		typeof object === "object" &&168		(object[NAME] === "AbortSignal" || object[NAME] === "EventTarget")169	);170};171 172/**173 * Check if `value` is a ReadableStream.174 *175 * @param {*} value176 * @returns {value is ReadableStream}177 */178const isReadableStream = (value) => {179	return (180		typeof value === "object" &&181		typeof value.getReader === "function" &&182		typeof value.cancel === "function" &&183		typeof value.tee === "function"184	);185};186 187/**188 *189 * @param {any} value190 * @returns {value is Iterable<unknown>}191 */192const isIterable = (value) => value && Symbol.iterator in value;193 194const carriage = '\r\n';195const dashes = '-'.repeat(2);196const carriageLength = Buffer.byteLength(carriage);197 198/**199 * @param {string} boundary200 */201const getFooter = boundary => `${dashes}${boundary}${dashes}${carriage.repeat(2)}`;202 203/**204 * @param {string} boundary205 * @param {string} name206 * @param {*} field207 *208 * @return {string}209 */210function getHeader(boundary, name, field) {211	let header = '';212 213	header += `${dashes}${boundary}${carriage}`;214	header += `Content-Disposition: form-data; name="${name}"`;215 216	if (isBlob(field)) {217		const { name = 'blob', type } = /** @type {Blob & {name?:string}} */ (field);218		header += `; filename="${name}"${carriage}`;219		header += `Content-Type: ${type || 'application/octet-stream'}`;220	}221 222	return `${header}${carriage.repeat(2)}`;223}224 225/**226 * @return {string}227 */228const getBoundary = () => crypto.randomBytes(8).toString('hex');229 230/**231 * @param {FormData} form232 * @param {string} boundary233 */234async function * formDataIterator(form, boundary) {235	const encoder = new TextEncoder();236	for (const [name, value] of form) {237		yield encoder.encode(getHeader(boundary, name, value));238 239		if (isBlob(value)) {240			// @ts-ignore - we know our streams implement aysnc iteration241			yield * value.stream();242		} else {243			yield encoder.encode(value);244		}245 246		yield encoder.encode(carriage);247	}248 249	yield encoder.encode(getFooter(boundary));250}251 252/**253 * @param {FormData} form254 * @param {string} boundary255 */256function getFormDataLength(form, boundary) {257	let length = 0;258 259	for (const [name, value] of form) {260		length += Buffer.byteLength(getHeader(boundary, name, value));261 262		if (isBlob(value)) {263			length += value.size;264		} else {265			length += Buffer.byteLength(String(value));266		}267 268		length += carriageLength;269	}270 271	length += Buffer.byteLength(getFooter(boundary));272 273	return length;274}275 276/**277 * @param {Body & {headers?:Headers}} source278 */279const toFormData = async (source) => {280  let { body, headers } = source;281  const contentType = headers?.get('Content-Type') || '';282 283  if (contentType.startsWith('application/x-www-form-urlencoded') && body != null) {284	const form = new formData.FormData();285	let bodyText = await source.text();286	new URLSearchParams(bodyText).forEach((v, k) => form.append(k, v));287	return form;288  }289 290  const [type, boundary] = contentType.split(/\s*;\s*boundary=/);291  if (type === 'multipart/form-data' && boundary != null && body != null) {292    const form = new formData.FormData();293    const parts = multipartParser.iterateMultipart(body, boundary);294    for await (const { name, data, filename, contentType } of parts) {295      if (typeof filename === 'string') {296        form.append(name, new file.File([data], filename, { type: contentType }));297      } else if (typeof filename !== 'undefined') {298        form.append(name, new file.File([], '', { type: contentType }));299      } else {300        form.append(name, new TextDecoder().decode(data), filename);301      }302    }303    return form304  } else {305    throw new TypeError('Could not parse content as FormData.')306  }307};308 309const encoder = new util.TextEncoder();310const decoder = new util.TextDecoder();311 312/**313 * @param {string} text314 */315const encode = text => encoder.encode(text);316 317/**318 * @param {Uint8Array} bytes319 */320const decode = bytes => decoder.decode(bytes);321 322// @ts-check323const {readableHighWaterMark} = new Stream.Readable();324 325const INTERNALS$2 = Symbol('Body internals');326 327/**328 * Body mixin329 *330 * Ref: https://fetch.spec.whatwg.org/#body331 * @implements {globalThis.Body}332 */333 334class Body {335	/**336	 * @param {BodyInit|Stream|null} body337	 * @param {{size?:number}} options338	 */339	constructor(body, {340		size = 0341	} = {}) {342		const state = {343			/** @type {null|ReadableStream<Uint8Array>} */344			body: null,345			/** @type {string|null} */346			type: null,347			/** @type {number|null} */348			size: null,349			/** @type {null|string} */350			boundary: null,351			disturbed: false,352			/** @type {null|Error} */353			error: null354		};355		/** @private */356		this[INTERNALS$2] = state;357 358		if (body === null) {359			// Body is undefined or null360			state.body = null;361			state.size = 0;362		} else if (isURLSearchParameters(body)) {363		// Body is a URLSearchParams364			const bytes = encode(body.toString());365			state.body = fromBytes(bytes);366			state.size = bytes.byteLength;367			state.type = 'application/x-www-form-urlencoded;charset=UTF-8';368		} else if (isBlob(body)) {369			// Body is blob370			state.size = body.size;371			state.type = body.type || null;372			state.body = body.stream();373		} else if (body instanceof Uint8Array) {374			// Body is Buffer375			state.body = fromBytes(body);376			state.size = body.byteLength;377		} else if (util.types.isAnyArrayBuffer(body)) {378			// Body is ArrayBuffer379			const bytes = new Uint8Array(body);380			state.body = fromBytes(bytes);381			state.size = bytes.byteLength;382		} else if (ArrayBuffer.isView(body)) {383			// Body is ArrayBufferView384			const bytes = new Uint8Array(body.buffer, body.byteOffset, body.byteLength);385			state.body = fromBytes(bytes);386			state.size = bytes.byteLength;387		} else if (isReadableStream(body)) {388			// Body is stream389			state.body = body;390		} else if (isFormData(body)) {391			// Body is an instance of formdata-node392			const boundary = `NodeFetchFormDataBoundary${getBoundary()}`;393			state.type = `multipart/form-data; boundary=${boundary}`;394			state.size = getFormDataLength(body, boundary);395			state.body = fromAsyncIterable(formDataIterator(body, boundary));396		} else if (isMultipartFormDataStream(body)) {397			state.type = `multipart/form-data; boundary=${body.getBoundary()}`;398			state.size = body.hasKnownLength() ? body.getLengthSync() : null;399			state.body = fromStream(body);400		} else if (body instanceof Stream) {401			state.body = fromStream(body);402		} else {403			// None of the above404			// coerce to string then buffer405			const bytes = encode(String(body));406			state.type = 'text/plain;charset=UTF-8';407			state.size = bytes.byteLength;408			state.body = fromBytes(bytes);409		}410 411		this.size = size;412 413		// if (body instanceof Stream) {414		// 	body.on('error', err => {415		// 		const error = err instanceof FetchBaseError ?416		// 			err :417		// 			new FetchError(`Invalid response body while trying to fetch ${this.url}: ${err.message}`, 'system', err);418		// 		this[INTERNALS].error = error;419		// 	});420		// }421	}422 423	/** @type {Headers} */424	/* c8 ignore next 3 */425	get headers() {426		throw new TypeError(`'get headers' called on an object that does not implements interface.`)427	}428 429	get body() {430		return this[INTERNALS$2].body;431	}432 433	get bodyUsed() {434		return this[INTERNALS$2].disturbed;435	}436 437	/**438	 * Decode response as ArrayBuffer439	 *440	 * @return {Promise<ArrayBuffer>}441	 */442	async arrayBuffer() {443		const {buffer, byteOffset, byteLength} = await consumeBody(this);444		return buffer.slice(byteOffset, byteOffset + byteLength);445	}446 447	/**448	 * Return raw response as Blob449	 *450	 * @return Promise451	 */452	async blob() {453		const ct = (this.headers && this.headers.get('content-type')) || (this[INTERNALS$2].body && this[INTERNALS$2].type) || '';454		const buf = await consumeBody(this);455 456		return new blob.Blob([buf], {457			type: ct458		});459	}460 461	/**462	 * Decode response as json463	 *464	 * @return  Promise465	 */466	async json() {467		return JSON.parse(await this.text());468	}469 470	/**471	 * Decode response as text472	 *473	 * @return  Promise474	 */475	async text() {476		const buffer = await consumeBody(this);477		return decode(buffer);478	}479 480	/**481	 * @returns {Promise<FormData>}482	 */483 484	async formData() {485		return toFormData(this)486	}487}488 489// In browsers, all properties are enumerable.490Object.defineProperties(Body.prototype, {491	body: {enumerable: true},492	bodyUsed: {enumerable: true},493	arrayBuffer: {enumerable: true},494	blob: {enumerable: true},495	json: {enumerable: true},496	text: {enumerable: true},497	formData: {enumerable: true}498});499 500/**501 * Consume and convert an entire Body to a Buffer.502 *503 * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body504 *505 * @param {Body & {url?:string}} data506 * @return {Promise<Uint8Array>}507 */508async function consumeBody(data) {509	const state = data[INTERNALS$2];510	if (state.disturbed) {511		throw new TypeError(`body used already for: ${data.url}`);512	}513 514	state.disturbed = true;515 516	if (state.error) {517		throw state.error;518	}519 520	const {body} = state;521 522	// Body is null523	if (body === null) {524		return new Uint8Array(0);525	}526 527	// Body is stream528	// get ready to actually consume the body529	/** @type {[Uint8Array|null, Uint8Array[], number]} */530	const [buffer, chunks, limit] = data.size > 0 ?531		[new Uint8Array(data.size), [], data.size] :532		[null, [], Infinity];533	let offset = 0;534 535	const source = streamIterator(body);536	try {537		for await (const chunk of source) {538			const bytes = chunk instanceof Uint8Array ?539				chunk :540				Buffer.from(chunk);541 542			if (offset + bytes.byteLength > limit) {543				const error = new FetchError(`content size at ${data.url} over limit: ${limit}`, 'max-size');544				source.throw(error);545				throw error;546			} else if (buffer) {547				buffer.set(bytes, offset);548			} else {549				chunks.push(bytes);550			}551 552			offset += bytes.byteLength;553		}554 555		if (buffer) {556			if (offset < buffer.byteLength) {557				throw new FetchError(`Premature close of server response while trying to fetch ${data.url}`, 'premature-close');558			} else {559				return buffer;560			}561		} else {562			return writeBytes(new Uint8Array(offset), chunks);563		}564	} catch (error) {565		if (error instanceof FetchBaseError) {566			throw error;567		// @ts-expect-error - we know it will have a name568		} else if (error && error.name === 'AbortError') {569			throw error;570		} else {571			const e = /** @type {import('./errors/fetch-error').SystemError} */(error);572			// Other errors, such as incorrect content-encoding573			throw new FetchError(`Invalid response body while trying to fetch ${data.url}: ${e.message}`, 'system', e);574		}575	}576}577 578/**579 * Clone body given Res/Req instance580 *581 * @param {Body} instance       Response or Request instance582 * @return {ReadableStream<Uint8Array> | null}583 */584const clone = instance => {585	const {body} = instance;586 587	// Don't allow cloning a used body588	if (instance.bodyUsed) {589		throw new Error('cannot clone body after it is used');590	}591 592	if (!body) {593		return null;594	}595 596	const [left, right] = body.tee();597	instance[INTERNALS$2].body = left;598	return right;599};600 601/**602 * Performs the operation "extract a `Content-Type` value from |object|" as603 * specified in the specification:604 * https://fetch.spec.whatwg.org/#concept-bodyinit-extract605 *606 * This function assumes that instance.body is present.607 *608 * @param {Body} source Any options.body input609 * @returns {string | null}610 */611const extractContentType = source => source[INTERNALS$2].type;612 613/**614 * The Fetch Standard treats this as if "total bytes" is a property on the body.615 * For us, we have to explicitly get it with a function.616 *617 * ref: https://fetch.spec.whatwg.org/#concept-body-total-bytes618 *619 * @param {Body} source - Body object from the Body instance.620 * @returns {number | null}621 */622const getTotalBytes = source => source[INTERNALS$2].size;623 624/**625 * Write a Body to a Node.js WritableStream (e.g. http.Request) object.626 *627 * @param {Stream.Writable} dest - The stream to write to.628 * @param {Body} source - Body object from the Body instance.629 * @returns {void}630 */631const writeToStream = (dest, {body}) => {632	if (body === null) {633		// Body is null634		dest.end();635	} else {636		Stream.Readable.from(streamIterator(body)).pipe(dest);637	}638};639 640/**641 * @template T642 * @implements {AsyncGenerator<T, void, void>}643 */644class StreamIterableIterator {645	/**646	 * @param {ReadableStream<T>} stream647	 */648	constructor(stream) {649		this.stream = stream;650		this.reader = null;651	}652 653	/**654	 * @returns {AsyncGenerator<T, void, void>}655	 */656	[Symbol.asyncIterator]() {657		return this;658	}659 660	getReader() {661		if (this.reader) {662			return this.reader;663		}664 665		const reader = this.stream.getReader();666		this.reader = reader;667		return reader;668	}669 670	/**671	 * @returns {Promise<IteratorResult<T, void>>}672	 */673	next() {674		return /** @type {Promise<IteratorResult<T, void>>} */ (this.getReader().read());675	}676 677	/**678	 * @returns {Promise<IteratorResult<T, void>>}679	 */680	async return() {681		if (this.reader) {682			await this.reader.cancel();683		}684 685		return {done: true, value: undefined};686	}687 688	/**689	 * 690	 * @param {any} error 691	 * @returns {Promise<IteratorResult<T, void>>}692	 */693	async throw(error) {694		await this.getReader().cancel(error);695		return {done: true, value: undefined};696	}697}698 699/**700 * @template T701 * @param {ReadableStream<T>} stream702 */703const streamIterator = stream => new StreamIterableIterator(stream);704 705/**706 * @param {Uint8Array} buffer707 * @param {Uint8Array[]} chunks708 */709const writeBytes = (buffer, chunks) => {710	let offset = 0;711	for (const chunk of chunks) {712		buffer.set(chunk, offset);713		offset += chunk.byteLength;714	}715 716	return buffer;717};718 719/**720 * @param {Uint8Array} bytes721 * @returns {ReadableStream<Uint8Array>}722 */723// @ts-ignore724const fromBytes = bytes => new blob.ReadableStream({725	start(controller) {726		controller.enqueue(bytes);727		controller.close();728	}729});730 731/**732 * @param {AsyncIterable<Uint8Array>} content733 * @returns {ReadableStream<Uint8Array>}734 */735const fromAsyncIterable = content =>736	// @ts-ignore737	new blob.ReadableStream(new AsyncIterablePump(content));738 739/**740 * @implements {UnderlyingSource<Uint8Array>}741 */742class AsyncIterablePump {743	/**744	 * @param {AsyncIterable<Uint8Array>} source745	 */746	constructor(source) {747		this.source = source[Symbol.asyncIterator]();748	}749 750	/**751	 * @param {ReadableStreamController<Uint8Array>} controller752	 */753	async pull(controller) {754		try {755			while (controller.desiredSize || 0 > 0) {756				// eslint-disable-next-line no-await-in-loop757				const next = await this.source.next();758				if (next.done) {759					controller.close();760					break;761				} else {762					controller.enqueue(next.value);763				}764			}765		} catch (error) {766			controller.error(error);767		}768	}769 770	/**771	 * @param {any} [reason]772	 */773	cancel(reason) {774		if (reason) {775			if (typeof this.source.throw === 'function') {776				this.source.throw(reason);777			} else if (typeof this.source.return === 'function') {778				this.source.return();779			}780		} else if (typeof this.source.return === 'function') {781			this.source.return();782		}783	}784}785 786/**787 * @param {Stream & {readableHighWaterMark?:number}} source788 * @returns {ReadableStream<Uint8Array>}789 */790const fromStream = source => {791	const pump = new StreamPump(source);792	const stream = new blob.ReadableStream(pump, pump);793	return stream;794};795 796/**797 * @implements {UnderlyingSource<Uint8Array>}798 * @implements {QueuingStrategy<Uint8Array>}799 */800class StreamPump {801	/**802	 * @param {Stream & {803	 * 	readableHighWaterMark?: number804	 * 	readable?:boolean,805	 * 	resume?: () => void,806	 * 	pause?: () => void807	 * 	destroy?: (error?:Error) => void808	 * }} stream809	 */810	constructor(stream) {811		this.highWaterMark = stream.readableHighWaterMark || readableHighWaterMark;812		this.accumalatedSize = 0;813		this.stream = stream;814		this.enqueue = this.enqueue.bind(this);815		this.error = this.error.bind(this);816		this.close = this.close.bind(this);817	}818 819	/**820	 * @param {Uint8Array} [chunk]821	 */822	size(chunk) {823		return chunk?.byteLength || 0;824	}825 826	/**827	 * @param {ReadableStreamController<Uint8Array>} controller828	 */829	start(controller) {830		this.controller = controller;831		this.stream.on('data', this.enqueue);832		this.stream.once('error', this.error);833		this.stream.once('end', this.close);834		this.stream.once('close', this.close);835	}836 837	pull() {838		this.resume();839	}840 841	/**842	 * @param {any} [reason]843	 */844	cancel(reason) {845		if (this.stream.destroy) {846			this.stream.destroy(reason);847		}848 849		this.stream.off('data', this.enqueue);850		this.stream.off('error', this.error);851		this.stream.off('end', this.close);852		this.stream.off('close', this.close);853	}854 855	/**856	 * @param {Uint8Array|string} chunk857	 */858	enqueue(chunk) {859		if (this.controller) {860			try {861				const bytes = chunk instanceof Uint8Array ?862					chunk :863					Buffer.from(chunk);864 865				const available = (this.controller.desiredSize || 0) - bytes.byteLength;866				this.controller.enqueue(bytes);867				if (available <= 0) {868					this.pause();869				}870			} catch {871				this.controller.error(new Error('Could not create Buffer, chunk must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object'));872				this.cancel();873			}874		}875	}876 877	pause() {878		if (this.stream.pause) {879			this.stream.pause();880		}881	}882 883	resume() {884		if (this.stream.readable && this.stream.resume) {885			this.stream.resume();886		}887	}888 889	close() {890		if (this.controller) {891			this.controller.close();892			delete this.controller;893		}894	}895 896	/**897	 * @param {Error} error 898	 */899	error(error) {900		if (this.controller) {901			this.controller.error(error);902			delete this.controller;903		}904	}905}906 907/**908 * Headers.js909 *910 * Headers class offers convenient helpers911 */912 913const validators = /** @type {{validateHeaderName?:(name:string) => any, validateHeaderValue?:(name:string, value:string) => any}} */914(http);915 916const validateHeaderName = typeof validators.validateHeaderName === 'function' ?917	validators.validateHeaderName :918	/**919	 * @param {string} name 920	 */921	name => {922		if (!/^[\^`\-\w!#$%&'*+.|~]+$/.test(name)) {923			const err = new TypeError(`Header name must be a valid HTTP token [${name}]`);924			Object.defineProperty(err, 'code', {value: 'ERR_INVALID_HTTP_TOKEN'});925			throw err;926		}927	};928 929const validateHeaderValue = typeof validators.validateHeaderValue === 'function' ?930	validators.validateHeaderValue :931	/**932	 * @param {string} name 933	 * @param {string} value 934	 */935	(name, value) => {936		if (/[^\t\u0020-\u007E\u0080-\u00FF]/.test(value)) {937			const err = new TypeError(`Invalid character in header content ["${name}"]`);938			Object.defineProperty(err, 'code', {value: 'ERR_INVALID_CHAR'});939			throw err;940		}941	};942 943/**944 * @typedef {Headers | Record<string, string> | Iterable<readonly [string, string]> | Iterable<Iterable<string>>} HeadersInit945 */946 947/**948 * This Fetch API interface allows you to perform various actions on HTTP request and response headers.949 * These actions include retrieving, setting, adding to, and removing.950 * A Headers object has an associated header list, which is initially empty and consists of zero or more name and value pairs.951 * You can add to this using methods like append() (see Examples.)952 * In all methods of this interface, header names are matched by case-insensitive byte sequence.953 *954 * @implements {globalThis.Headers}955 */956class Headers$1 extends URLSearchParams {957	/**958	 * Headers class959	 *960	 * @constructor961	 * @param {HeadersInit} [init] - Response headers962	 */963	constructor(init) {964		// Validate and normalize init object in [name, value(s)][]965		/** @type {string[][]} */966		let result = [];967		if (init instanceof Headers$1) {968			const raw = init.raw();969			for (const [name, values] of Object.entries(raw)) {970				result.push(...values.map(value => [name, value]));971			}972		} else if (init == null) ; else if (isIterable(init)) {973			// Sequence<sequence<ByteString>>974			// Note: per spec we have to first exhaust the lists then process them975			result = [...init]976				.map(pair => {977					if (978						typeof pair !== 'object' || util.types.isBoxedPrimitive(pair)979					) {980						throw new TypeError('Each header pair must be an iterable object');981					}982 983					return [...pair];984				}).map(pair => {985					if (pair.length !== 2) {986						throw new TypeError('Each header pair must be a name/value tuple');987					}988 989					return [...pair];990				});991		} else if (typeof init === "object" && init !== null) {992			// Record<ByteString, ByteString>993			result.push(...Object.entries(init));994		} else {995			throw new TypeError('Failed to construct \'Headers\': The provided value is not of type \'(sequence<sequence<ByteString>> or record<ByteString, ByteString>)');996		}997 998		// Validate and lowercase999		result =1000			result.length > 0 ?1001				result.map(([name, value]) => {1002					validateHeaderName(name);1003					validateHeaderValue(name, String(value));1004					return [String(name).toLowerCase(), String(value)];1005				}) :1006				[];1007 1008		super(result);1009 1010		// Returning a Proxy that will lowercase key names, validate parameters and sort keys1011		// eslint-disable-next-line no-constructor-return1012		return new Proxy(this, {1013			get(target, p, receiver) {1014				switch (p) {1015					case 'append':1016					case 'set':1017						/**1018						 * @param {string} name1019						 * @param {string} value1020						 */1021						return (name, value) => {1022							validateHeaderName(name);1023							validateHeaderValue(name, String(value));1024							return URLSearchParams.prototype[p].call(1025								receiver,1026								String(name).toLowerCase(),1027								String(value)1028							);1029						};1030 1031					case 'delete':1032					case 'has':1033					case 'getAll':1034						/**1035						 * @param {string} name1036						 */1037						return name => {1038							validateHeaderName(name);1039							// @ts-ignore1040							return URLSearchParams.prototype[p].call(1041								receiver,1042								String(name).toLowerCase()1043							);1044						};1045 1046					case 'keys':1047						return () => {1048							target.sort();1049							return new Set(URLSearchParams.prototype.keys.call(target)).keys();1050						};1051 1052					default:1053						return Reflect.get(target, p, receiver);1054				}1055			}1056			/* c8 ignore next */1057		});1058	}1059 1060	get [Symbol.toStringTag]() {1061		return this.constructor.name;1062	}1063 1064	toString() {1065		return Object.prototype.toString.call(this);1066	}1067 1068	/**1069	 * 1070	 * @param {string} name 1071	 */1072	get(name) {1073		const values = this.getAll(name);1074		if (values.length === 0) {1075			return null;1076		}1077 1078		let value = values.join(', ');1079		if (/^content-encoding$/i.test(name)) {1080			value = value.toLowerCase();1081		}1082 1083		return value;1084	}1085 1086	/**1087	 * @param {(value: string, key: string, parent: this) => void} callback 1088	 * @param {any} thisArg 1089	 * @returns {void}1090	 */1091	forEach(callback, thisArg = undefined) {1092		for (const name of this.keys()) {1093			if (name.toLowerCase() === 'set-cookie') {1094				let cookies = this.getAll(name);1095				while (cookies.length > 0) {1096					Reflect.apply(callback, thisArg, [cookies.shift(), name, this]);1097				}1098			} else {1099				Reflect.apply(callback, thisArg, [this.get(name), name, this]);1100			}1101		}1102	}1103 1104	/**1105	 * @returns {IterableIterator<string>}1106	 */1107	* values() {1108		for (const name of this.keys()) {1109			if (name.toLowerCase() === 'set-cookie') {1110				let cookies = this.getAll(name);1111				while (cookies.length > 0) {1112					yield /** @type {string} */(cookies.shift());1113				}1114			} else {1115				yield /** @type {string} */(this.get(name));1116			}1117		}1118	}1119 1120	/**1121	 * @returns {IterableIterator<[string, string]>}1122	 */1123	* entries() {1124		for (const name of this.keys()) {1125			if (name.toLowerCase() === 'set-cookie') {1126				let cookies = this.getAll(name);1127				while (cookies.length > 0) {1128					yield [name, /** @type {string} */(cookies.shift())];1129				}1130			} else {1131				yield [name, /** @type {string} */(this.get(name))];1132			}1133		}1134	}1135 1136	[Symbol.iterator]() {1137		return this.entries();1138	}1139 1140	/**1141	 * Node-fetch non-spec method1142	 * returning all headers and their values as array1143	 * @returns {Record<string, string[]>}1144	 */1145	raw() {1146		return [...this.keys()].reduce((result, key) => {1147			result[key] = this.getAll(key);1148			return result;1149		}, /** @type {Record<string, string[]>} */({}));1150	}1151 1152	/**1153	 * For better console.log(headers) and also to convert Headers into Node.js Request compatible format1154	 */1155	[Symbol.for('nodejs.util.inspect.custom')]() {1156		return [...this.keys()].reduce((result, key) => {1157			const values = this.getAll(key);1158			// Http.request() only supports string as Host header.1159			// This hack makes specifying custom Host header possible.1160			if (key === 'host') {1161				result[key] = values[0];1162			} else {1163				result[key] = values.length > 1 ? values : values[0];1164			}1165 1166			return result;1167		}, /** @type {Record<string, string|string[]>} */({}));1168	}1169}1170 1171/**1172 * Re-shaping object for Web IDL tests1173 * Only need to do it for overridden methods1174 */1175Object.defineProperties(1176	Headers$1.prototype,1177	['get', 'entries', 'forEach', 'values'].reduce((result, property) => {1178		result[property] = {enumerable: true};1179		return result;1180	}, /** @type {Record<string, {enumerable:true}>} */ ({}))1181);1182 1183/**1184 * Create a Headers object from an http.IncomingMessage.rawHeaders, ignoring those that do1185 * not conform to HTTP grammar productions.1186 * @param {import('http').IncomingMessage['rawHeaders']} headers1187 */1188function fromRawHeaders(headers = []) {1189	return new Headers$1(1190		headers1191			// Split into pairs1192			.reduce((result, value, index, array) => {1193				if (index % 2 === 0) {1194					result.push(array.slice(index, index + 2));1195				}1196 1197				return result;1198			}, /** @type {string[][]} */([]))1199			.filter(([name, value]) => {1200				try {

Showing the first 1,200 of 2105 lines. Download the file for the rest.