@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.cjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { FetchHAROptions, RequestInitWithDuplex } from './types.js';\nimport type { DataURL as npmDataURL } from '@readme/data-urls';\nimport type { Har } from 'har-format';\n\nimport { parse as parseDataUrl } from '@readme/data-urls';\n\ntype DataURL = npmDataURL & {\n // `parse-data-url` doesn't explicitly support `name` in data URLs but if it's there it'll be\n // returned back to us.\n name?: string;\n};\n\nfunction isBrowser() {\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n\nfunction isBuffer(value: unknown): value is Buffer {\n return typeof Buffer !== 'undefined' && Buffer.isBuffer(value);\n}\n\nfunction isFile(value: unknown): value is File {\n if (value instanceof File) {\n /**\n * The `Blob` polyfill on Node comes back as being an instanceof `File`. Because passing a Blob\n * into a File will end up with a corrupted file we want to prevent this.\n *\n * This object identity crisis does not happen in the browser.\n */\n return value.constructor.name === 'File';\n }\n\n return false;\n}\n\nfunction getFileFromSuppliedFiles(filename: string, files: FetchHAROptions['files']) {\n if (files && filename in files) {\n return files[filename];\n } else if (files && decodeURIComponent(filename) in files) {\n return files[decodeURIComponent(filename)];\n }\n\n return false;\n}\n\nexport default async function fetchHAR(har: Har, opts: FetchHAROptions = {}): Promise<Response> {\n if (!har) throw new Error('Missing HAR definition');\n if (!har.log?.entries?.length) throw new Error('Missing log.entries array');\n\n if (!globalThis.Blob) {\n try {\n const NodeBlob = (await import('buffer')).Blob;\n // @ts-expect-error the types don't match exactly, which is expected!\n globalThis.Blob = NodeBlob;\n } catch {\n throw new Error(\n 'The Blob API is required for this library. https://developer.mozilla.org/en-US/docs/Web/API/Blob',\n );\n }\n }\n\n if (!globalThis.File) {\n try {\n const NodeFile = (await import('buffer')).File;\n // @ts-expect-error the types don't match exactly, which is expected!\n globalThis.File = NodeFile;\n } catch {\n throw new Error(\n 'The File API is required for this library. https://developer.mozilla.org/en-US/docs/Web/API/File',\n );\n }\n }\n\n const { request } = har.log.entries[0];\n const { url } = request;\n let querystring = '';\n let shouldSetDuplex = false;\n\n const options: RequestInitWithDuplex = {\n // If we have custom options for the `Request` API we need to add them in here now before we\n // fill it in with everything we need from the HAR.\n ...(opts.init ? opts.init : {}),\n method: request.method,\n };\n\n if (!options.headers) {\n options.headers = new Headers();\n } else if (typeof options.headers === 'object' && !(options.headers instanceof Headers) && options.headers !== null) {\n options.headers = new Headers(options.headers);\n }\n\n const headers: Headers = options.headers;\n if ('headers' in request && request.headers.length) {\n request.headers.forEach(header => {\n try {\n headers.append(header.name, header.value);\n } catch {\n /**\n * `Headers.append()` will throw errors if the header name is not a legal HTTP header name,\n * like `X-API-KEY (Header)`. If that happens instead of tossing the error back out, we\n * should silently just ignore\n * it.\n */\n }\n });\n }\n\n if ('cookies' in request && request.cookies.length) {\n /**\n * As the browser fetch API can't set custom cookies for requests, they instead need to be\n * defined on the document and passed into the request via `credentials: include`. Since this\n * is a browser-specific quirk, that should only\n * happen in browsers!\n */\n if (isBrowser()) {\n request.cookies.forEach(cookie => {\n document.cookie = `${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`;\n });\n\n options.credentials = 'include';\n } else {\n headers.append(\n 'cookie',\n request.cookies\n .map(cookie => `${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`)\n .join('; '),\n );\n }\n }\n\n if ('postData' in request) {\n if (request.postData && 'params' in request.postData) {\n if (!('mimeType' in request.postData)) {\n // @ts-expect-error HAR spec requires that `mimeType` is always present but it might not be.\n request.postData.mimeType = 'application/octet-stream';\n }\n\n switch (request.postData.mimeType) {\n case 'application/x-www-form-urlencoded': {\n /**\n * Since the content we're handling here is to be encoded as\n * `application/x-www-form-urlencoded`, this should override any other `Content-Type`\n * headers that are present in the HAR. This is how Postman handles this case when\n * building code snippets!\n *\n * @see {@link https://github.com/github/fetch/issues/263#issuecomment-209530977}\n */\n headers.set('Content-Type', request.postData.mimeType);\n\n const encodedParams = new URLSearchParams();\n request.postData.params?.forEach(param => {\n if (param.value) encodedParams.set(param.name, param.value);\n });\n\n options.body = encodedParams.toString();\n break;\n }\n\n case 'multipart/alternative':\n case 'multipart/form-data':\n case 'multipart/mixed':\n case 'multipart/related': {\n /**\n * If there's a `Content-Type` header set we need to remove it. We're doing this because\n * when we pass the form data object into `fetch` that'll set a proper `Content-Type`\n * header for this request that also includes the boundary used on the content.\n *\n * If we don't do this, then consumers won't be able to parse out the payload because\n * they won't know what the boundary to split on it.\n */\n if (headers.has('Content-Type')) {\n headers.delete('Content-Type');\n }\n\n const form = new FormData();\n\n request.postData.params?.forEach(param => {\n if ('fileName' in param && param.fileName) {\n if (opts.files) {\n const fileContents = getFileFromSuppliedFiles(param.fileName, opts.files);\n if (fileContents) {\n // If the file we've got available to us is a Buffer then we need to convert it so\n // that the FormData API can use it.\n if (isBuffer(fileContents)) {\n form.append(\n param.name,\n new File([new Uint8Array(fileContents)], param.fileName, {\n type: param.contentType || undefined,\n }),\n param.fileName,\n );\n\n return;\n } else if (isFile(fileContents)) {\n form.append(param.name, fileContents as Blob, param.fileName);\n return;\n }\n\n throw new TypeError(\n 'An unknown object has been supplied into the `files` config for use. We only support instances of the File API and Node Buffer objects.',\n );\n }\n }\n\n if ('value' in param && param.value) {\n let paramBlob: Blob;\n const parsed = parseDataUrl(param.value);\n if (parsed) {\n // If we were able to parse out this data URL we don't need to transform its data\n // into a buffer for `Blob` because that supports data URLs already.\n paramBlob = new Blob([param.value], { type: parsed.contentType || param.contentType || undefined });\n } else {\n paramBlob = new Blob([param.value], { type: param.contentType || undefined });\n }\n\n form.append(param.name, paramBlob, param.fileName);\n return;\n }\n\n throw new Error(\n \"The supplied HAR has a postData parameter with `fileName`, but neither `value` content within the HAR or any file buffers were supplied with the `files` option. Since this library doesn't have access to the filesystem, it can't fetch that file.\",\n );\n }\n\n if (param.value) form.append(param.name, param.value);\n });\n\n options.body = form;\n break;\n }\n\n default: {\n const formBody: Record<string, unknown> = {};\n request.postData.params?.map(param => {\n try {\n formBody[param.name] = JSON.parse(param.value || '');\n } catch {\n formBody[param.name] = param.value;\n }\n\n return true;\n });\n }\n }\n } else if (request.postData?.text?.length) {\n // If we've got `files` map content present, and this post data content contains a valid data\n // URL then we can substitute the payload with that file instead of the using data URL.\n if (opts.files) {\n const parsed = parseDataUrl(request.postData.text) as DataURL;\n if (parsed) {\n if (parsed?.name) {\n const fileContents = getFileFromSuppliedFiles(parsed.name, opts.files);\n if (fileContents) {\n if (isBuffer(fileContents)) {\n options.body = new Uint8Array(fileContents);\n } else if (isFile(fileContents)) {\n // `Readable.from` isn't available in browsers but the browser `Request` object can\n // handle `File` objects just fine without us having to mold it into shape.\n if (isBrowser()) {\n options.body = fileContents;\n } else {\n options.body = (fileContents as File).stream();\n shouldSetDuplex = true;\n\n // Supplying a polyfilled `File` stream into `Request.body` doesn't automatically\n // add `Content-Length`.\n if (!headers.has('content-length')) {\n headers.set('content-length', String((fileContents as File).size));\n }\n }\n }\n }\n }\n }\n }\n\n if (typeof options.body === 'undefined') {\n options.body = request.postData.text;\n }\n }\n\n /**\n * The fetch spec, which Node 18+ strictly abides by, now requires that `duplex` be sent with\n * requests that have payloads.\n *\n * As `RequestInit#duplex` isn't supported by any browsers, or even mentioned on MDN, we aren't\n * sending it in browser environments. This work is purely to support Node 18+ and `undici`\n * environments.\n *\n * @see {@link https://github.com/nodejs/node/issues/46221}\n * @see {@link https://github.com/whatwg/fetch/pull/1457}\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Request/Request}\n */\n if (shouldSetDuplex && !isBrowser()) {\n options.duplex = 'half';\n }\n }\n\n // We automaticaly assume that the HAR that we have already has query parameters encoded within\n // it so we do **not** use the `URLSearchParams` API here for composing the query string.\n let requestURL = url;\n if ('queryString' in request && request.queryString.length) {\n const urlObj = new URL(requestURL);\n\n const queryParams = Array.from(urlObj.searchParams).map(([k, v]) => `${k}=${v}`);\n request.queryString.forEach(q => {\n queryParams.push(`${q.name}=${q.value}`);\n });\n\n querystring = queryParams.join('&');\n\n // Because anchor hashes before query strings will prevent query strings from being delivered\n // we need to pop them off and re-add them after.\n if (urlObj.hash) {\n const urlWithoutHashes = requestURL.replace(urlObj.hash, '');\n requestURL = `${urlWithoutHashes.split('?')[0]}${querystring ? `?${querystring}` : ''}`;\n requestURL += urlObj.hash;\n } else {\n requestURL = `${requestURL.split('?')[0]}${querystring ? `?${querystring}` : ''}`;\n }\n }\n\n if (opts.userAgent) {\n headers.append('User-Agent', opts.userAgent);\n }\n\n options.headers = headers;\n\n return fetch(requestURL, options);\n}\n"],"mappings":";;;AAYA,SAAS,YAAY;AACnB,QAAO,OAAO,WAAW,eAAe,OAAO,aAAa;;AAG9D,SAAS,SAAS,OAAiC;AACjD,QAAO,OAAO,WAAW,eAAe,OAAO,SAAS,MAAM;;AAGhE,SAAS,OAAO,OAA+B;AAC7C,KAAI,iBAAiB;;;;;;;AAOnB,QAAO,MAAM,YAAY,SAAS;AAGpC,QAAO;;AAGT,SAAS,yBAAyB,UAAkB,OAAiC;AACnF,KAAI,SAAS,YAAY,MACvB,QAAO,MAAM;UACJ,SAAS,mBAAmB,SAAS,IAAI,MAClD,QAAO,MAAM,mBAAmB,SAAS;AAG3C,QAAO;;AAGT,eAA8B,SAAS,KAAU,OAAwB,EAAE,EAAqB;AAC9F,KAAI,CAAC,IAAK,OAAM,IAAI,MAAM,yBAAyB;AACnD,KAAI,CAAC,IAAI,KAAK,SAAS,OAAQ,OAAM,IAAI,MAAM,4BAA4B;AAE3E,KAAI,CAAC,WAAW,KACd,KAAI;EACF,MAAM,YAAY,MAAM,OAAO,WAAW;AAE1C,aAAW,OAAO;SACZ;AACN,QAAM,IAAI,MACR,mGACD;;AAIL,KAAI,CAAC,WAAW,KACd,KAAI;EACF,MAAM,YAAY,MAAM,OAAO,WAAW;AAE1C,aAAW,OAAO;SACZ;AACN,QAAM,IAAI,MACR,mGACD;;CAIL,MAAM,EAAE,YAAY,IAAI,IAAI,QAAQ;CACpC,MAAM,EAAE,QAAQ;CAChB,IAAI,cAAc;CAClB,IAAI,kBAAkB;CAEtB,MAAM,UAAiC;EAGrC,GAAI,KAAK,OAAO,KAAK,OAAO,EAAE;EAC9B,QAAQ,QAAQ;EACjB;AAED,KAAI,CAAC,QAAQ,QACX,SAAQ,UAAU,IAAI,SAAS;UACtB,OAAO,QAAQ,YAAY,YAAY,EAAE,QAAQ,mBAAmB,YAAY,QAAQ,YAAY,KAC7G,SAAQ,UAAU,IAAI,QAAQ,QAAQ,QAAQ;CAGhD,MAAM,UAAmB,QAAQ;AACjC,KAAI,aAAa,WAAW,QAAQ,QAAQ,OAC1C,SAAQ,QAAQ,SAAQ,WAAU;AAChC,MAAI;AACF,WAAQ,OAAO,OAAO,MAAM,OAAO,MAAM;UACnC;GAQR;AAGJ,KAAI,aAAa,WAAW,QAAQ,QAAQ;;;;;;;AAO1C,KAAI,WAAW,EAAE;AACf,UAAQ,QAAQ,SAAQ,WAAU;AAChC,YAAS,SAAS,GAAG,mBAAmB,OAAO,KAAK,CAAC,GAAG,mBAAmB,OAAO,MAAM;IACxF;AAEF,UAAQ,cAAc;OAEtB,SAAQ,OACN,UACA,QAAQ,QACL,KAAI,WAAU,GAAG,mBAAmB,OAAO,KAAK,CAAC,GAAG,mBAAmB,OAAO,MAAM,GAAG,CACvF,KAAK,KAAK,CACd;AAIL,KAAI,cAAc,SAAS;AACzB,MAAI,QAAQ,YAAY,YAAY,QAAQ,UAAU;AACpD,OAAI,EAAE,cAAc,QAAQ,UAE1B,SAAQ,SAAS,WAAW;AAG9B,WAAQ,QAAQ,SAAS,UAAzB;IACE,KAAK,qCAAqC;;;;;;;;;AASxC,aAAQ,IAAI,gBAAgB,QAAQ,SAAS,SAAS;KAEtD,MAAM,gBAAgB,IAAI,iBAAiB;AAC3C,aAAQ,SAAS,QAAQ,SAAQ,UAAS;AACxC,UAAI,MAAM,MAAO,eAAc,IAAI,MAAM,MAAM,MAAM,MAAM;OAC3D;AAEF,aAAQ,OAAO,cAAc,UAAU;AACvC;;IAGF,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK,qBAAqB;;;;;;;;;AASxB,SAAI,QAAQ,IAAI,eAAe,CAC7B,SAAQ,OAAO,eAAe;KAGhC,MAAM,OAAO,IAAI,UAAU;AAE3B,aAAQ,SAAS,QAAQ,SAAQ,UAAS;AACxC,UAAI,cAAc,SAAS,MAAM,UAAU;AACzC,WAAI,KAAK,OAAO;QACd,MAAM,eAAe,yBAAyB,MAAM,UAAU,KAAK,MAAM;AACzE,YAAI,cAAc;AAGhB,aAAI,SAAS,aAAa,EAAE;AAC1B,eAAK,OACH,MAAM,MACN,IAAI,KAAK,CAAC,IAAI,WAAW,aAAa,CAAC,EAAE,MAAM,UAAU,EACvD,MAAM,MAAM,eAAe,QAC5B,CAAC,EACF,MAAM,SACP;AAED;oBACS,OAAO,aAAa,EAAE;AAC/B,eAAK,OAAO,MAAM,MAAM,cAAsB,MAAM,SAAS;AAC7D;;AAGF,eAAM,IAAI,UACR,0IACD;;;AAIL,WAAI,WAAW,SAAS,MAAM,OAAO;QACnC,IAAI;QACJ,MAAM,sCAAsB,MAAM,MAAM;AACxC,YAAI,OAGF,aAAY,IAAI,KAAK,CAAC,MAAM,MAAM,EAAE,EAAE,MAAM,OAAO,eAAe,MAAM,eAAe,QAAW,CAAC;YAEnG,aAAY,IAAI,KAAK,CAAC,MAAM,MAAM,EAAE,EAAE,MAAM,MAAM,eAAe,QAAW,CAAC;AAG/E,aAAK,OAAO,MAAM,MAAM,WAAW,MAAM,SAAS;AAClD;;AAGF,aAAM,IAAI,MACR,uPACD;;AAGH,UAAI,MAAM,MAAO,MAAK,OAAO,MAAM,MAAM,MAAM,MAAM;OACrD;AAEF,aAAQ,OAAO;AACf;;IAGF,SAAS;KACP,MAAM,WAAoC,EAAE;AAC5C,aAAQ,SAAS,QAAQ,KAAI,UAAS;AACpC,UAAI;AACF,gBAAS,MAAM,QAAQ,KAAK,MAAM,MAAM,SAAS,GAAG;cAC9C;AACN,gBAAS,MAAM,QAAQ,MAAM;;AAG/B,aAAO;OACP;;;aAGG,QAAQ,UAAU,MAAM,QAAQ;AAGzC,OAAI,KAAK,OAAO;IACd,MAAM,sCAAsB,QAAQ,SAAS,KAAK;AAClD,QAAI,QACF;SAAI,QAAQ,MAAM;MAChB,MAAM,eAAe,yBAAyB,OAAO,MAAM,KAAK,MAAM;AACtE,UAAI,cACF;WAAI,SAAS,aAAa,CACxB,SAAQ,OAAO,IAAI,WAAW,aAAa;gBAClC,OAAO,aAAa,CAG7B,KAAI,WAAW,CACb,SAAQ,OAAO;YACV;AACL,gBAAQ,OAAQ,aAAsB,QAAQ;AAC9C,0BAAkB;AAIlB,YAAI,CAAC,QAAQ,IAAI,iBAAiB,CAChC,SAAQ,IAAI,kBAAkB,OAAQ,aAAsB,KAAK,CAAC;;;;;;AAShF,OAAI,OAAO,QAAQ,SAAS,YAC1B,SAAQ,OAAO,QAAQ,SAAS;;;;;;;;;;;;;;AAgBpC,MAAI,mBAAmB,CAAC,WAAW,CACjC,SAAQ,SAAS;;CAMrB,IAAI,aAAa;AACjB,KAAI,iBAAiB,WAAW,QAAQ,YAAY,QAAQ;EAC1D,MAAM,SAAS,IAAI,IAAI,WAAW;EAElC,MAAM,cAAc,MAAM,KAAK,OAAO,aAAa,CAAC,KAAK,CAAC,GAAG,OAAO,GAAG,EAAE,GAAG,IAAI;AAChF,UAAQ,YAAY,SAAQ,MAAK;AAC/B,eAAY,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,QAAQ;IACxC;AAEF,gBAAc,YAAY,KAAK,IAAI;AAInC,MAAI,OAAO,MAAM;AAEf,gBAAa,GADY,WAAW,QAAQ,OAAO,MAAM,GAAG,CAC3B,MAAM,IAAI,CAAC,KAAK,cAAc,IAAI,gBAAgB;AACnF,iBAAc,OAAO;QAErB,cAAa,GAAG,WAAW,MAAM,IAAI,CAAC,KAAK,cAAc,IAAI,gBAAgB;;AAIjF,KAAI,KAAK,UACP,SAAQ,OAAO,cAAc,KAAK,UAAU;AAG9C,SAAQ,UAAU;AAElB,QAAO,MAAM,YAAY,QAAQ"} | ||
| {"version":3,"file":"index.cjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { FetchHAROptions, RequestInitWithDuplex } from './types.js';\nimport type { DataURL as npmDataURL } from '@readme/data-urls';\nimport type { Har } from 'har-format';\n\nimport { parse as parseDataUrl } from '@readme/data-urls';\n\ntype DataURL = npmDataURL & {\n // `parse-data-url` doesn't explicitly support `name` in data URLs but if it's there it'll be\n // returned back to us.\n name?: string;\n};\n\nfunction isBrowser() {\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n\nfunction isBuffer(value: unknown): value is Buffer {\n return typeof Buffer !== 'undefined' && Buffer.isBuffer(value);\n}\n\nfunction isFile(value: unknown): value is File {\n if (value instanceof File) {\n /**\n * The `Blob` polyfill on Node comes back as being an instanceof `File`. Because passing a Blob\n * into a File will end up with a corrupted file we want to prevent this.\n *\n * This object identity crisis does not happen in the browser.\n */\n return value.constructor.name === 'File';\n }\n\n return false;\n}\n\nfunction getFileFromSuppliedFiles(filename: string, files: FetchHAROptions['files']) {\n if (files && filename in files) {\n return files[filename];\n } else if (files && decodeURIComponent(filename) in files) {\n return files[decodeURIComponent(filename)];\n }\n\n return false;\n}\n\nexport default async function fetchHAR(har: Har, opts: FetchHAROptions = {}): Promise<Response> {\n if (!har) throw new Error('Missing HAR definition');\n if (!har.log?.entries?.length) throw new Error('Missing log.entries array');\n\n if (!globalThis.Blob) {\n try {\n const NodeBlob = (await import('buffer')).Blob;\n // @ts-expect-error the types don't match exactly, which is expected!\n globalThis.Blob = NodeBlob;\n } catch {\n throw new Error(\n 'The Blob API is required for this library. https://developer.mozilla.org/en-US/docs/Web/API/Blob',\n );\n }\n }\n\n if (!globalThis.File) {\n try {\n const NodeFile = (await import('buffer')).File;\n // @ts-expect-error the types don't match exactly, which is expected!\n globalThis.File = NodeFile;\n } catch {\n throw new Error(\n 'The File API is required for this library. https://developer.mozilla.org/en-US/docs/Web/API/File',\n );\n }\n }\n\n const { request } = har.log.entries[0];\n const { url } = request;\n let querystring = '';\n let shouldSetDuplex = false;\n\n const options: RequestInitWithDuplex = {\n // If we have custom options for the `Request` API we need to add them in here now before we\n // fill it in with everything we need from the HAR.\n ...(opts.init ? opts.init : {}),\n method: request.method,\n };\n\n if (!options.headers) {\n options.headers = new Headers();\n } else if (typeof options.headers === 'object' && !(options.headers instanceof Headers) && options.headers !== null) {\n options.headers = new Headers(options.headers);\n }\n\n const headers: Headers = options.headers;\n if ('headers' in request && request.headers.length) {\n request.headers.forEach(header => {\n try {\n headers.append(header.name, header.value);\n } catch {\n /**\n * `Headers.append()` will throw errors if the header name is not a legal HTTP header name,\n * like `X-API-KEY (Header)`. If that happens instead of tossing the error back out, we\n * should silently just ignore\n * it.\n */\n }\n });\n }\n\n if ('cookies' in request && request.cookies.length) {\n /**\n * As the browser fetch API can't set custom cookies for requests, they instead need to be\n * defined on the document and passed into the request via `credentials: include`. Since this\n * is a browser-specific quirk, that should only\n * happen in browsers!\n */\n if (isBrowser()) {\n request.cookies.forEach(cookie => {\n document.cookie = `${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`;\n });\n\n options.credentials = 'include';\n } else {\n headers.append(\n 'cookie',\n request.cookies\n .map(cookie => `${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`)\n .join('; '),\n );\n }\n }\n\n if ('postData' in request) {\n if (request.postData && 'params' in request.postData) {\n if (!('mimeType' in request.postData)) {\n // @ts-expect-error HAR spec requires that `mimeType` is always present but it might not be.\n request.postData.mimeType = 'application/octet-stream';\n }\n\n switch (request.postData.mimeType) {\n case 'application/x-www-form-urlencoded': {\n /**\n * Since the content we're handling here is to be encoded as\n * `application/x-www-form-urlencoded`, this should override any other `Content-Type`\n * headers that are present in the HAR. This is how Postman handles this case when\n * building code snippets!\n *\n * @see {@link https://github.com/github/fetch/issues/263#issuecomment-209530977}\n */\n headers.set('Content-Type', request.postData.mimeType);\n\n const encodedParams = new URLSearchParams();\n request.postData.params?.forEach(param => {\n if (param.value) encodedParams.set(param.name, param.value);\n });\n\n options.body = encodedParams.toString();\n break;\n }\n\n case 'multipart/alternative':\n case 'multipart/form-data':\n case 'multipart/mixed':\n case 'multipart/related': {\n /**\n * If there's a `Content-Type` header set we need to remove it. We're doing this because\n * when we pass the form data object into `fetch` that'll set a proper `Content-Type`\n * header for this request that also includes the boundary used on the content.\n *\n * If we don't do this, then consumers won't be able to parse out the payload because\n * they won't know what the boundary to split on it.\n */\n if (headers.has('Content-Type')) {\n headers.delete('Content-Type');\n }\n\n const form = new FormData();\n\n request.postData.params?.forEach(param => {\n if ('fileName' in param && param.fileName) {\n if (opts.files) {\n const fileContents = getFileFromSuppliedFiles(param.fileName, opts.files);\n if (fileContents) {\n // If the file we've got available to us is a Buffer then we need to convert it so\n // that the FormData API can use it.\n if (isBuffer(fileContents)) {\n form.append(\n param.name,\n new File([new Uint8Array(fileContents)], param.fileName, {\n type: param.contentType || undefined,\n }),\n param.fileName,\n );\n\n return;\n } else if (isFile(fileContents)) {\n form.append(param.name, fileContents as Blob, param.fileName);\n return;\n }\n\n throw new TypeError(\n 'An unknown object has been supplied into the `files` config for use. We only support instances of the File API and Node Buffer objects.',\n );\n }\n }\n\n if ('value' in param && param.value) {\n let paramBlob: Blob;\n const parsed = parseDataUrl(param.value);\n if (parsed) {\n // If we were able to parse out this data URL we don't need to transform its data\n // into a buffer for `Blob` because that supports data URLs already.\n paramBlob = new Blob([param.value], { type: parsed.contentType || param.contentType || undefined });\n } else {\n paramBlob = new Blob([param.value], { type: param.contentType || undefined });\n }\n\n form.append(param.name, paramBlob, param.fileName);\n return;\n }\n\n throw new Error(\n \"The supplied HAR has a postData parameter with `fileName`, but neither `value` content within the HAR or any file buffers were supplied with the `files` option. Since this library doesn't have access to the filesystem, it can't fetch that file.\",\n );\n }\n\n if (param.value) form.append(param.name, param.value);\n });\n\n options.body = form;\n break;\n }\n\n default: {\n const formBody: Record<string, unknown> = {};\n request.postData.params?.map(param => {\n try {\n formBody[param.name] = JSON.parse(param.value || '');\n } catch {\n formBody[param.name] = param.value;\n }\n\n return true;\n });\n }\n }\n } else if (request.postData?.text?.length) {\n // If we've got `files` map content present, and this post data content contains a valid data\n // URL then we can substitute the payload with that file instead of the using data URL.\n if (opts.files) {\n const parsed = parseDataUrl(request.postData.text) as DataURL;\n if (parsed) {\n if (parsed?.name) {\n const fileContents = getFileFromSuppliedFiles(parsed.name, opts.files);\n if (fileContents) {\n if (isBuffer(fileContents)) {\n options.body = new Uint8Array(fileContents);\n } else if (isFile(fileContents)) {\n // `Readable.from` isn't available in browsers but the browser `Request` object can\n // handle `File` objects just fine without us having to mold it into shape.\n if (isBrowser()) {\n options.body = fileContents;\n } else {\n options.body = (fileContents as File).stream();\n shouldSetDuplex = true;\n\n // Supplying a polyfilled `File` stream into `Request.body` doesn't automatically\n // add `Content-Length`.\n if (!headers.has('content-length')) {\n headers.set('content-length', String((fileContents as File).size));\n }\n }\n }\n }\n }\n }\n }\n\n if (typeof options.body === 'undefined') {\n options.body = request.postData.text;\n }\n }\n\n /**\n * The fetch spec, which Node 18+ strictly abides by, now requires that `duplex` be sent with\n * requests that have payloads.\n *\n * As `RequestInit#duplex` isn't supported by any browsers, or even mentioned on MDN, we aren't\n * sending it in browser environments. This work is purely to support Node 18+ and `undici`\n * environments.\n *\n * @see {@link https://github.com/nodejs/node/issues/46221}\n * @see {@link https://github.com/whatwg/fetch/pull/1457}\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Request/Request}\n */\n if (shouldSetDuplex && !isBrowser()) {\n options.duplex = 'half';\n }\n }\n\n // We automaticaly assume that the HAR that we have already has query parameters encoded within\n // it so we do **not** use the `URLSearchParams` API here for composing the query string.\n let requestURL = url;\n if ('queryString' in request && request.queryString.length) {\n const urlObj = new URL(requestURL);\n\n const queryParams = Array.from(urlObj.searchParams).map(([k, v]) => `${k}=${v}`);\n request.queryString.forEach(q => {\n queryParams.push(`${q.name}=${q.value}`);\n });\n\n querystring = queryParams.join('&');\n\n // Because anchor hashes before query strings will prevent query strings from being delivered\n // we need to pop them off and re-add them after.\n if (urlObj.hash) {\n const urlWithoutHashes = requestURL.replace(urlObj.hash, '');\n requestURL = `${urlWithoutHashes.split('?')[0]}${querystring ? `?${querystring}` : ''}`;\n requestURL += urlObj.hash;\n } else {\n requestURL = `${requestURL.split('?')[0]}${querystring ? `?${querystring}` : ''}`;\n }\n }\n\n if (opts.userAgent) {\n headers.append('User-Agent', opts.userAgent);\n }\n\n options.headers = headers;\n\n return fetch(requestURL, options);\n}\n"],"mappings":"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"} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.mjs","names":["parseDataUrl"],"sources":["../src/index.ts"],"sourcesContent":["import type { FetchHAROptions, RequestInitWithDuplex } from './types.js';\nimport type { DataURL as npmDataURL } from '@readme/data-urls';\nimport type { Har } from 'har-format';\n\nimport { parse as parseDataUrl } from '@readme/data-urls';\n\ntype DataURL = npmDataURL & {\n // `parse-data-url` doesn't explicitly support `name` in data URLs but if it's there it'll be\n // returned back to us.\n name?: string;\n};\n\nfunction isBrowser() {\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n\nfunction isBuffer(value: unknown): value is Buffer {\n return typeof Buffer !== 'undefined' && Buffer.isBuffer(value);\n}\n\nfunction isFile(value: unknown): value is File {\n if (value instanceof File) {\n /**\n * The `Blob` polyfill on Node comes back as being an instanceof `File`. Because passing a Blob\n * into a File will end up with a corrupted file we want to prevent this.\n *\n * This object identity crisis does not happen in the browser.\n */\n return value.constructor.name === 'File';\n }\n\n return false;\n}\n\nfunction getFileFromSuppliedFiles(filename: string, files: FetchHAROptions['files']) {\n if (files && filename in files) {\n return files[filename];\n } else if (files && decodeURIComponent(filename) in files) {\n return files[decodeURIComponent(filename)];\n }\n\n return false;\n}\n\nexport default async function fetchHAR(har: Har, opts: FetchHAROptions = {}): Promise<Response> {\n if (!har) throw new Error('Missing HAR definition');\n if (!har.log?.entries?.length) throw new Error('Missing log.entries array');\n\n if (!globalThis.Blob) {\n try {\n const NodeBlob = (await import('buffer')).Blob;\n // @ts-expect-error the types don't match exactly, which is expected!\n globalThis.Blob = NodeBlob;\n } catch {\n throw new Error(\n 'The Blob API is required for this library. https://developer.mozilla.org/en-US/docs/Web/API/Blob',\n );\n }\n }\n\n if (!globalThis.File) {\n try {\n const NodeFile = (await import('buffer')).File;\n // @ts-expect-error the types don't match exactly, which is expected!\n globalThis.File = NodeFile;\n } catch {\n throw new Error(\n 'The File API is required for this library. https://developer.mozilla.org/en-US/docs/Web/API/File',\n );\n }\n }\n\n const { request } = har.log.entries[0];\n const { url } = request;\n let querystring = '';\n let shouldSetDuplex = false;\n\n const options: RequestInitWithDuplex = {\n // If we have custom options for the `Request` API we need to add them in here now before we\n // fill it in with everything we need from the HAR.\n ...(opts.init ? opts.init : {}),\n method: request.method,\n };\n\n if (!options.headers) {\n options.headers = new Headers();\n } else if (typeof options.headers === 'object' && !(options.headers instanceof Headers) && options.headers !== null) {\n options.headers = new Headers(options.headers);\n }\n\n const headers: Headers = options.headers;\n if ('headers' in request && request.headers.length) {\n request.headers.forEach(header => {\n try {\n headers.append(header.name, header.value);\n } catch {\n /**\n * `Headers.append()` will throw errors if the header name is not a legal HTTP header name,\n * like `X-API-KEY (Header)`. If that happens instead of tossing the error back out, we\n * should silently just ignore\n * it.\n */\n }\n });\n }\n\n if ('cookies' in request && request.cookies.length) {\n /**\n * As the browser fetch API can't set custom cookies for requests, they instead need to be\n * defined on the document and passed into the request via `credentials: include`. Since this\n * is a browser-specific quirk, that should only\n * happen in browsers!\n */\n if (isBrowser()) {\n request.cookies.forEach(cookie => {\n document.cookie = `${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`;\n });\n\n options.credentials = 'include';\n } else {\n headers.append(\n 'cookie',\n request.cookies\n .map(cookie => `${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`)\n .join('; '),\n );\n }\n }\n\n if ('postData' in request) {\n if (request.postData && 'params' in request.postData) {\n if (!('mimeType' in request.postData)) {\n // @ts-expect-error HAR spec requires that `mimeType` is always present but it might not be.\n request.postData.mimeType = 'application/octet-stream';\n }\n\n switch (request.postData.mimeType) {\n case 'application/x-www-form-urlencoded': {\n /**\n * Since the content we're handling here is to be encoded as\n * `application/x-www-form-urlencoded`, this should override any other `Content-Type`\n * headers that are present in the HAR. This is how Postman handles this case when\n * building code snippets!\n *\n * @see {@link https://github.com/github/fetch/issues/263#issuecomment-209530977}\n */\n headers.set('Content-Type', request.postData.mimeType);\n\n const encodedParams = new URLSearchParams();\n request.postData.params?.forEach(param => {\n if (param.value) encodedParams.set(param.name, param.value);\n });\n\n options.body = encodedParams.toString();\n break;\n }\n\n case 'multipart/alternative':\n case 'multipart/form-data':\n case 'multipart/mixed':\n case 'multipart/related': {\n /**\n * If there's a `Content-Type` header set we need to remove it. We're doing this because\n * when we pass the form data object into `fetch` that'll set a proper `Content-Type`\n * header for this request that also includes the boundary used on the content.\n *\n * If we don't do this, then consumers won't be able to parse out the payload because\n * they won't know what the boundary to split on it.\n */\n if (headers.has('Content-Type')) {\n headers.delete('Content-Type');\n }\n\n const form = new FormData();\n\n request.postData.params?.forEach(param => {\n if ('fileName' in param && param.fileName) {\n if (opts.files) {\n const fileContents = getFileFromSuppliedFiles(param.fileName, opts.files);\n if (fileContents) {\n // If the file we've got available to us is a Buffer then we need to convert it so\n // that the FormData API can use it.\n if (isBuffer(fileContents)) {\n form.append(\n param.name,\n new File([new Uint8Array(fileContents)], param.fileName, {\n type: param.contentType || undefined,\n }),\n param.fileName,\n );\n\n return;\n } else if (isFile(fileContents)) {\n form.append(param.name, fileContents as Blob, param.fileName);\n return;\n }\n\n throw new TypeError(\n 'An unknown object has been supplied into the `files` config for use. We only support instances of the File API and Node Buffer objects.',\n );\n }\n }\n\n if ('value' in param && param.value) {\n let paramBlob: Blob;\n const parsed = parseDataUrl(param.value);\n if (parsed) {\n // If we were able to parse out this data URL we don't need to transform its data\n // into a buffer for `Blob` because that supports data URLs already.\n paramBlob = new Blob([param.value], { type: parsed.contentType || param.contentType || undefined });\n } else {\n paramBlob = new Blob([param.value], { type: param.contentType || undefined });\n }\n\n form.append(param.name, paramBlob, param.fileName);\n return;\n }\n\n throw new Error(\n \"The supplied HAR has a postData parameter with `fileName`, but neither `value` content within the HAR or any file buffers were supplied with the `files` option. Since this library doesn't have access to the filesystem, it can't fetch that file.\",\n );\n }\n\n if (param.value) form.append(param.name, param.value);\n });\n\n options.body = form;\n break;\n }\n\n default: {\n const formBody: Record<string, unknown> = {};\n request.postData.params?.map(param => {\n try {\n formBody[param.name] = JSON.parse(param.value || '');\n } catch {\n formBody[param.name] = param.value;\n }\n\n return true;\n });\n }\n }\n } else if (request.postData?.text?.length) {\n // If we've got `files` map content present, and this post data content contains a valid data\n // URL then we can substitute the payload with that file instead of the using data URL.\n if (opts.files) {\n const parsed = parseDataUrl(request.postData.text) as DataURL;\n if (parsed) {\n if (parsed?.name) {\n const fileContents = getFileFromSuppliedFiles(parsed.name, opts.files);\n if (fileContents) {\n if (isBuffer(fileContents)) {\n options.body = new Uint8Array(fileContents);\n } else if (isFile(fileContents)) {\n // `Readable.from` isn't available in browsers but the browser `Request` object can\n // handle `File` objects just fine without us having to mold it into shape.\n if (isBrowser()) {\n options.body = fileContents;\n } else {\n options.body = (fileContents as File).stream();\n shouldSetDuplex = true;\n\n // Supplying a polyfilled `File` stream into `Request.body` doesn't automatically\n // add `Content-Length`.\n if (!headers.has('content-length')) {\n headers.set('content-length', String((fileContents as File).size));\n }\n }\n }\n }\n }\n }\n }\n\n if (typeof options.body === 'undefined') {\n options.body = request.postData.text;\n }\n }\n\n /**\n * The fetch spec, which Node 18+ strictly abides by, now requires that `duplex` be sent with\n * requests that have payloads.\n *\n * As `RequestInit#duplex` isn't supported by any browsers, or even mentioned on MDN, we aren't\n * sending it in browser environments. This work is purely to support Node 18+ and `undici`\n * environments.\n *\n * @see {@link https://github.com/nodejs/node/issues/46221}\n * @see {@link https://github.com/whatwg/fetch/pull/1457}\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Request/Request}\n */\n if (shouldSetDuplex && !isBrowser()) {\n options.duplex = 'half';\n }\n }\n\n // We automaticaly assume that the HAR that we have already has query parameters encoded within\n // it so we do **not** use the `URLSearchParams` API here for composing the query string.\n let requestURL = url;\n if ('queryString' in request && request.queryString.length) {\n const urlObj = new URL(requestURL);\n\n const queryParams = Array.from(urlObj.searchParams).map(([k, v]) => `${k}=${v}`);\n request.queryString.forEach(q => {\n queryParams.push(`${q.name}=${q.value}`);\n });\n\n querystring = queryParams.join('&');\n\n // Because anchor hashes before query strings will prevent query strings from being delivered\n // we need to pop them off and re-add them after.\n if (urlObj.hash) {\n const urlWithoutHashes = requestURL.replace(urlObj.hash, '');\n requestURL = `${urlWithoutHashes.split('?')[0]}${querystring ? `?${querystring}` : ''}`;\n requestURL += urlObj.hash;\n } else {\n requestURL = `${requestURL.split('?')[0]}${querystring ? `?${querystring}` : ''}`;\n }\n }\n\n if (opts.userAgent) {\n headers.append('User-Agent', opts.userAgent);\n }\n\n options.headers = headers;\n\n return fetch(requestURL, options);\n}\n"],"mappings":"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"} | ||
| {"version":3,"file":"index.mjs","names":["parseDataUrl"],"sources":["../src/index.ts"],"sourcesContent":["import type { FetchHAROptions, RequestInitWithDuplex } from './types.js';\nimport type { DataURL as npmDataURL } from '@readme/data-urls';\nimport type { Har } from 'har-format';\n\nimport { parse as parseDataUrl } from '@readme/data-urls';\n\ntype DataURL = npmDataURL & {\n // `parse-data-url` doesn't explicitly support `name` in data URLs but if it's there it'll be\n // returned back to us.\n name?: string;\n};\n\nfunction isBrowser() {\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n\nfunction isBuffer(value: unknown): value is Buffer {\n return typeof Buffer !== 'undefined' && Buffer.isBuffer(value);\n}\n\nfunction isFile(value: unknown): value is File {\n if (value instanceof File) {\n /**\n * The `Blob` polyfill on Node comes back as being an instanceof `File`. Because passing a Blob\n * into a File will end up with a corrupted file we want to prevent this.\n *\n * This object identity crisis does not happen in the browser.\n */\n return value.constructor.name === 'File';\n }\n\n return false;\n}\n\nfunction getFileFromSuppliedFiles(filename: string, files: FetchHAROptions['files']) {\n if (files && filename in files) {\n return files[filename];\n } else if (files && decodeURIComponent(filename) in files) {\n return files[decodeURIComponent(filename)];\n }\n\n return false;\n}\n\nexport default async function fetchHAR(har: Har, opts: FetchHAROptions = {}): Promise<Response> {\n if (!har) throw new Error('Missing HAR definition');\n if (!har.log?.entries?.length) throw new Error('Missing log.entries array');\n\n if (!globalThis.Blob) {\n try {\n const NodeBlob = (await import('buffer')).Blob;\n // @ts-expect-error the types don't match exactly, which is expected!\n globalThis.Blob = NodeBlob;\n } catch {\n throw new Error(\n 'The Blob API is required for this library. https://developer.mozilla.org/en-US/docs/Web/API/Blob',\n );\n }\n }\n\n if (!globalThis.File) {\n try {\n const NodeFile = (await import('buffer')).File;\n // @ts-expect-error the types don't match exactly, which is expected!\n globalThis.File = NodeFile;\n } catch {\n throw new Error(\n 'The File API is required for this library. https://developer.mozilla.org/en-US/docs/Web/API/File',\n );\n }\n }\n\n const { request } = har.log.entries[0];\n const { url } = request;\n let querystring = '';\n let shouldSetDuplex = false;\n\n const options: RequestInitWithDuplex = {\n // If we have custom options for the `Request` API we need to add them in here now before we\n // fill it in with everything we need from the HAR.\n ...(opts.init ? opts.init : {}),\n method: request.method,\n };\n\n if (!options.headers) {\n options.headers = new Headers();\n } else if (typeof options.headers === 'object' && !(options.headers instanceof Headers) && options.headers !== null) {\n options.headers = new Headers(options.headers);\n }\n\n const headers: Headers = options.headers;\n if ('headers' in request && request.headers.length) {\n request.headers.forEach(header => {\n try {\n headers.append(header.name, header.value);\n } catch {\n /**\n * `Headers.append()` will throw errors if the header name is not a legal HTTP header name,\n * like `X-API-KEY (Header)`. If that happens instead of tossing the error back out, we\n * should silently just ignore\n * it.\n */\n }\n });\n }\n\n if ('cookies' in request && request.cookies.length) {\n /**\n * As the browser fetch API can't set custom cookies for requests, they instead need to be\n * defined on the document and passed into the request via `credentials: include`. Since this\n * is a browser-specific quirk, that should only\n * happen in browsers!\n */\n if (isBrowser()) {\n request.cookies.forEach(cookie => {\n document.cookie = `${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`;\n });\n\n options.credentials = 'include';\n } else {\n headers.append(\n 'cookie',\n request.cookies\n .map(cookie => `${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`)\n .join('; '),\n );\n }\n }\n\n if ('postData' in request) {\n if (request.postData && 'params' in request.postData) {\n if (!('mimeType' in request.postData)) {\n // @ts-expect-error HAR spec requires that `mimeType` is always present but it might not be.\n request.postData.mimeType = 'application/octet-stream';\n }\n\n switch (request.postData.mimeType) {\n case 'application/x-www-form-urlencoded': {\n /**\n * Since the content we're handling here is to be encoded as\n * `application/x-www-form-urlencoded`, this should override any other `Content-Type`\n * headers that are present in the HAR. This is how Postman handles this case when\n * building code snippets!\n *\n * @see {@link https://github.com/github/fetch/issues/263#issuecomment-209530977}\n */\n headers.set('Content-Type', request.postData.mimeType);\n\n const encodedParams = new URLSearchParams();\n request.postData.params?.forEach(param => {\n if (param.value) encodedParams.set(param.name, param.value);\n });\n\n options.body = encodedParams.toString();\n break;\n }\n\n case 'multipart/alternative':\n case 'multipart/form-data':\n case 'multipart/mixed':\n case 'multipart/related': {\n /**\n * If there's a `Content-Type` header set we need to remove it. We're doing this because\n * when we pass the form data object into `fetch` that'll set a proper `Content-Type`\n * header for this request that also includes the boundary used on the content.\n *\n * If we don't do this, then consumers won't be able to parse out the payload because\n * they won't know what the boundary to split on it.\n */\n if (headers.has('Content-Type')) {\n headers.delete('Content-Type');\n }\n\n const form = new FormData();\n\n request.postData.params?.forEach(param => {\n if ('fileName' in param && param.fileName) {\n if (opts.files) {\n const fileContents = getFileFromSuppliedFiles(param.fileName, opts.files);\n if (fileContents) {\n // If the file we've got available to us is a Buffer then we need to convert it so\n // that the FormData API can use it.\n if (isBuffer(fileContents)) {\n form.append(\n param.name,\n new File([new Uint8Array(fileContents)], param.fileName, {\n type: param.contentType || undefined,\n }),\n param.fileName,\n );\n\n return;\n } else if (isFile(fileContents)) {\n form.append(param.name, fileContents as Blob, param.fileName);\n return;\n }\n\n throw new TypeError(\n 'An unknown object has been supplied into the `files` config for use. We only support instances of the File API and Node Buffer objects.',\n );\n }\n }\n\n if ('value' in param && param.value) {\n let paramBlob: Blob;\n const parsed = parseDataUrl(param.value);\n if (parsed) {\n // If we were able to parse out this data URL we don't need to transform its data\n // into a buffer for `Blob` because that supports data URLs already.\n paramBlob = new Blob([param.value], { type: parsed.contentType || param.contentType || undefined });\n } else {\n paramBlob = new Blob([param.value], { type: param.contentType || undefined });\n }\n\n form.append(param.name, paramBlob, param.fileName);\n return;\n }\n\n throw new Error(\n \"The supplied HAR has a postData parameter with `fileName`, but neither `value` content within the HAR or any file buffers were supplied with the `files` option. Since this library doesn't have access to the filesystem, it can't fetch that file.\",\n );\n }\n\n if (param.value) form.append(param.name, param.value);\n });\n\n options.body = form;\n break;\n }\n\n default: {\n const formBody: Record<string, unknown> = {};\n request.postData.params?.map(param => {\n try {\n formBody[param.name] = JSON.parse(param.value || '');\n } catch {\n formBody[param.name] = param.value;\n }\n\n return true;\n });\n }\n }\n } else if (request.postData?.text?.length) {\n // If we've got `files` map content present, and this post data content contains a valid data\n // URL then we can substitute the payload with that file instead of the using data URL.\n if (opts.files) {\n const parsed = parseDataUrl(request.postData.text) as DataURL;\n if (parsed) {\n if (parsed?.name) {\n const fileContents = getFileFromSuppliedFiles(parsed.name, opts.files);\n if (fileContents) {\n if (isBuffer(fileContents)) {\n options.body = new Uint8Array(fileContents);\n } else if (isFile(fileContents)) {\n // `Readable.from` isn't available in browsers but the browser `Request` object can\n // handle `File` objects just fine without us having to mold it into shape.\n if (isBrowser()) {\n options.body = fileContents;\n } else {\n options.body = (fileContents as File).stream();\n shouldSetDuplex = true;\n\n // Supplying a polyfilled `File` stream into `Request.body` doesn't automatically\n // add `Content-Length`.\n if (!headers.has('content-length')) {\n headers.set('content-length', String((fileContents as File).size));\n }\n }\n }\n }\n }\n }\n }\n\n if (typeof options.body === 'undefined') {\n options.body = request.postData.text;\n }\n }\n\n /**\n * The fetch spec, which Node 18+ strictly abides by, now requires that `duplex` be sent with\n * requests that have payloads.\n *\n * As `RequestInit#duplex` isn't supported by any browsers, or even mentioned on MDN, we aren't\n * sending it in browser environments. This work is purely to support Node 18+ and `undici`\n * environments.\n *\n * @see {@link https://github.com/nodejs/node/issues/46221}\n * @see {@link https://github.com/whatwg/fetch/pull/1457}\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Request/Request}\n */\n if (shouldSetDuplex && !isBrowser()) {\n options.duplex = 'half';\n }\n }\n\n // We automaticaly assume that the HAR that we have already has query parameters encoded within\n // it so we do **not** use the `URLSearchParams` API here for composing the query string.\n let requestURL = url;\n if ('queryString' in request && request.queryString.length) {\n const urlObj = new URL(requestURL);\n\n const queryParams = Array.from(urlObj.searchParams).map(([k, v]) => `${k}=${v}`);\n request.queryString.forEach(q => {\n queryParams.push(`${q.name}=${q.value}`);\n });\n\n querystring = queryParams.join('&');\n\n // Because anchor hashes before query strings will prevent query strings from being delivered\n // we need to pop them off and re-add them after.\n if (urlObj.hash) {\n const urlWithoutHashes = requestURL.replace(urlObj.hash, '');\n requestURL = `${urlWithoutHashes.split('?')[0]}${querystring ? `?${querystring}` : ''}`;\n requestURL += urlObj.hash;\n } else {\n requestURL = `${requestURL.split('?')[0]}${querystring ? `?${querystring}` : ''}`;\n }\n }\n\n if (opts.userAgent) {\n headers.append('User-Agent', opts.userAgent);\n }\n\n options.headers = headers;\n\n return fetch(requestURL, options);\n}\n"],"mappings":";;;AAYA,SAAS,YAAY;AACnB,QAAO,OAAO,WAAW,eAAe,OAAO,aAAa;;AAG9D,SAAS,SAAS,OAAiC;AACjD,QAAO,OAAO,WAAW,eAAe,OAAO,SAAS,MAAM;;AAGhE,SAAS,OAAO,OAA+B;AAC7C,KAAI,iBAAiB;;;;;;;AAOnB,QAAO,MAAM,YAAY,SAAS;AAGpC,QAAO;;AAGT,SAAS,yBAAyB,UAAkB,OAAiC;AACnF,KAAI,SAAS,YAAY,MACvB,QAAO,MAAM;UACJ,SAAS,mBAAmB,SAAS,IAAI,MAClD,QAAO,MAAM,mBAAmB,SAAS;AAG3C,QAAO;;AAGT,eAA8B,SAAS,KAAU,OAAwB,EAAE,EAAqB;AAC9F,KAAI,CAAC,IAAK,OAAM,IAAI,MAAM,yBAAyB;AACnD,KAAI,CAAC,IAAI,KAAK,SAAS,OAAQ,OAAM,IAAI,MAAM,4BAA4B;AAE3E,KAAI,CAAC,WAAW,KACd,KAAI;EACF,MAAM,YAAY,MAAM,OAAO,WAAW;AAE1C,aAAW,OAAO;SACZ;AACN,QAAM,IAAI,MACR,mGACD;;AAIL,KAAI,CAAC,WAAW,KACd,KAAI;EACF,MAAM,YAAY,MAAM,OAAO,WAAW;AAE1C,aAAW,OAAO;SACZ;AACN,QAAM,IAAI,MACR,mGACD;;CAIL,MAAM,EAAE,YAAY,IAAI,IAAI,QAAQ;CACpC,MAAM,EAAE,QAAQ;CAChB,IAAI,cAAc;CAClB,IAAI,kBAAkB;CAEtB,MAAM,UAAiC;EAGrC,GAAI,KAAK,OAAO,KAAK,OAAO,EAAE;EAC9B,QAAQ,QAAQ;EACjB;AAED,KAAI,CAAC,QAAQ,QACX,SAAQ,UAAU,IAAI,SAAS;UACtB,OAAO,QAAQ,YAAY,YAAY,EAAE,QAAQ,mBAAmB,YAAY,QAAQ,YAAY,KAC7G,SAAQ,UAAU,IAAI,QAAQ,QAAQ,QAAQ;CAGhD,MAAM,UAAmB,QAAQ;AACjC,KAAI,aAAa,WAAW,QAAQ,QAAQ,OAC1C,SAAQ,QAAQ,SAAQ,WAAU;AAChC,MAAI;AACF,WAAQ,OAAO,OAAO,MAAM,OAAO,MAAM;UACnC;GAQR;AAGJ,KAAI,aAAa,WAAW,QAAQ,QAAQ;;;;;;;AAO1C,KAAI,WAAW,EAAE;AACf,UAAQ,QAAQ,SAAQ,WAAU;AAChC,YAAS,SAAS,GAAG,mBAAmB,OAAO,KAAK,CAAC,GAAG,mBAAmB,OAAO,MAAM;IACxF;AAEF,UAAQ,cAAc;OAEtB,SAAQ,OACN,UACA,QAAQ,QACL,KAAI,WAAU,GAAG,mBAAmB,OAAO,KAAK,CAAC,GAAG,mBAAmB,OAAO,MAAM,GAAG,CACvF,KAAK,KAAK,CACd;AAIL,KAAI,cAAc,SAAS;AACzB,MAAI,QAAQ,YAAY,YAAY,QAAQ,UAAU;AACpD,OAAI,EAAE,cAAc,QAAQ,UAE1B,SAAQ,SAAS,WAAW;AAG9B,WAAQ,QAAQ,SAAS,UAAzB;IACE,KAAK,qCAAqC;;;;;;;;;AASxC,aAAQ,IAAI,gBAAgB,QAAQ,SAAS,SAAS;KAEtD,MAAM,gBAAgB,IAAI,iBAAiB;AAC3C,aAAQ,SAAS,QAAQ,SAAQ,UAAS;AACxC,UAAI,MAAM,MAAO,eAAc,IAAI,MAAM,MAAM,MAAM,MAAM;OAC3D;AAEF,aAAQ,OAAO,cAAc,UAAU;AACvC;;IAGF,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK,qBAAqB;;;;;;;;;AASxB,SAAI,QAAQ,IAAI,eAAe,CAC7B,SAAQ,OAAO,eAAe;KAGhC,MAAM,OAAO,IAAI,UAAU;AAE3B,aAAQ,SAAS,QAAQ,SAAQ,UAAS;AACxC,UAAI,cAAc,SAAS,MAAM,UAAU;AACzC,WAAI,KAAK,OAAO;QACd,MAAM,eAAe,yBAAyB,MAAM,UAAU,KAAK,MAAM;AACzE,YAAI,cAAc;AAGhB,aAAI,SAAS,aAAa,EAAE;AAC1B,eAAK,OACH,MAAM,MACN,IAAI,KAAK,CAAC,IAAI,WAAW,aAAa,CAAC,EAAE,MAAM,UAAU,EACvD,MAAM,MAAM,eAAe,QAC5B,CAAC,EACF,MAAM,SACP;AAED;oBACS,OAAO,aAAa,EAAE;AAC/B,eAAK,OAAO,MAAM,MAAM,cAAsB,MAAM,SAAS;AAC7D;;AAGF,eAAM,IAAI,UACR,0IACD;;;AAIL,WAAI,WAAW,SAAS,MAAM,OAAO;QACnC,IAAI;QACJ,MAAM,SAASA,MAAa,MAAM,MAAM;AACxC,YAAI,OAGF,aAAY,IAAI,KAAK,CAAC,MAAM,MAAM,EAAE,EAAE,MAAM,OAAO,eAAe,MAAM,eAAe,QAAW,CAAC;YAEnG,aAAY,IAAI,KAAK,CAAC,MAAM,MAAM,EAAE,EAAE,MAAM,MAAM,eAAe,QAAW,CAAC;AAG/E,aAAK,OAAO,MAAM,MAAM,WAAW,MAAM,SAAS;AAClD;;AAGF,aAAM,IAAI,MACR,uPACD;;AAGH,UAAI,MAAM,MAAO,MAAK,OAAO,MAAM,MAAM,MAAM,MAAM;OACrD;AAEF,aAAQ,OAAO;AACf;;IAGF,SAAS;KACP,MAAM,WAAoC,EAAE;AAC5C,aAAQ,SAAS,QAAQ,KAAI,UAAS;AACpC,UAAI;AACF,gBAAS,MAAM,QAAQ,KAAK,MAAM,MAAM,SAAS,GAAG;cAC9C;AACN,gBAAS,MAAM,QAAQ,MAAM;;AAG/B,aAAO;OACP;;;aAGG,QAAQ,UAAU,MAAM,QAAQ;AAGzC,OAAI,KAAK,OAAO;IACd,MAAM,SAASA,MAAa,QAAQ,SAAS,KAAK;AAClD,QAAI,QACF;SAAI,QAAQ,MAAM;MAChB,MAAM,eAAe,yBAAyB,OAAO,MAAM,KAAK,MAAM;AACtE,UAAI,cACF;WAAI,SAAS,aAAa,CACxB,SAAQ,OAAO,IAAI,WAAW,aAAa;gBAClC,OAAO,aAAa,CAG7B,KAAI,WAAW,CACb,SAAQ,OAAO;YACV;AACL,gBAAQ,OAAQ,aAAsB,QAAQ;AAC9C,0BAAkB;AAIlB,YAAI,CAAC,QAAQ,IAAI,iBAAiB,CAChC,SAAQ,IAAI,kBAAkB,OAAQ,aAAsB,KAAK,CAAC;;;;;;AAShF,OAAI,OAAO,QAAQ,SAAS,YAC1B,SAAQ,OAAO,QAAQ,SAAS;;;;;;;;;;;;;;AAgBpC,MAAI,mBAAmB,CAAC,WAAW,CACjC,SAAQ,SAAS;;CAMrB,IAAI,aAAa;AACjB,KAAI,iBAAiB,WAAW,QAAQ,YAAY,QAAQ;EAC1D,MAAM,SAAS,IAAI,IAAI,WAAW;EAElC,MAAM,cAAc,MAAM,KAAK,OAAO,aAAa,CAAC,KAAK,CAAC,GAAG,OAAO,GAAG,EAAE,GAAG,IAAI;AAChF,UAAQ,YAAY,SAAQ,MAAK;AAC/B,eAAY,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,QAAQ;IACxC;AAEF,gBAAc,YAAY,KAAK,IAAI;AAInC,MAAI,OAAO,MAAM;AAEf,gBAAa,GADY,WAAW,QAAQ,OAAO,MAAM,GACzB,CAAC,MAAM,IAAI,CAAC,KAAK,cAAc,IAAI,gBAAgB;AACnF,iBAAc,OAAO;QAErB,cAAa,GAAG,WAAW,MAAM,IAAI,CAAC,KAAK,cAAc,IAAI,gBAAgB;;AAIjF,KAAI,KAAK,UACP,SAAQ,OAAO,cAAc,KAAK,UAAU;AAG9C,SAAQ,UAAU;AAElB,QAAO,MAAM,YAAY,QAAQ"} |
+1
-1
| { | ||
| "name": "fetch-har", | ||
| "version": "12.0.2", | ||
| "version": "12.0.3", | ||
| "description": "Make a fetch request from a HAR definition", | ||
@@ -5,0 +5,0 @@ "homepage": "https://github.com/readmeio/fetch-har#readme", |
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package