forked from waja/action-debian-package
		
	node_modules: update
This commit is contained in:
		
							parent
							
								
									63ec4f26a7
								
							
						
					
					
						commit
						d33a5e2307
					
				
					 193 changed files with 30796 additions and 147 deletions
				
			
		
							
								
								
									
										21
									
								
								node_modules/undici/lib/fetch/LICENSE
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								node_modules/undici/lib/fetch/LICENSE
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,21 @@
 | 
			
		|||
MIT License
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2020 Ethan Arrowood
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
							
								
								
									
										605
									
								
								node_modules/undici/lib/fetch/body.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										605
									
								
								node_modules/undici/lib/fetch/body.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,605 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
const Busboy = require('@fastify/busboy')
 | 
			
		||||
const util = require('../core/util')
 | 
			
		||||
const {
 | 
			
		||||
  ReadableStreamFrom,
 | 
			
		||||
  isBlobLike,
 | 
			
		||||
  isReadableStreamLike,
 | 
			
		||||
  readableStreamClose,
 | 
			
		||||
  createDeferredPromise,
 | 
			
		||||
  fullyReadBody
 | 
			
		||||
} = require('./util')
 | 
			
		||||
const { FormData } = require('./formdata')
 | 
			
		||||
const { kState } = require('./symbols')
 | 
			
		||||
const { webidl } = require('./webidl')
 | 
			
		||||
const { DOMException, structuredClone } = require('./constants')
 | 
			
		||||
const { Blob, File: NativeFile } = require('buffer')
 | 
			
		||||
const { kBodyUsed } = require('../core/symbols')
 | 
			
		||||
const assert = require('assert')
 | 
			
		||||
const { isErrored } = require('../core/util')
 | 
			
		||||
const { isUint8Array, isArrayBuffer } = require('util/types')
 | 
			
		||||
const { File: UndiciFile } = require('./file')
 | 
			
		||||
const { parseMIMEType, serializeAMimeType } = require('./dataURL')
 | 
			
		||||
 | 
			
		||||
let ReadableStream = globalThis.ReadableStream
 | 
			
		||||
 | 
			
		||||
/** @type {globalThis['File']} */
 | 
			
		||||
const File = NativeFile ?? UndiciFile
 | 
			
		||||
const textEncoder = new TextEncoder()
 | 
			
		||||
const textDecoder = new TextDecoder()
 | 
			
		||||
 | 
			
		||||
// https://fetch.spec.whatwg.org/#concept-bodyinit-extract
 | 
			
		||||
function extractBody (object, keepalive = false) {
 | 
			
		||||
  if (!ReadableStream) {
 | 
			
		||||
    ReadableStream = require('stream/web').ReadableStream
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // 1. Let stream be null.
 | 
			
		||||
  let stream = null
 | 
			
		||||
 | 
			
		||||
  // 2. If object is a ReadableStream object, then set stream to object.
 | 
			
		||||
  if (object instanceof ReadableStream) {
 | 
			
		||||
    stream = object
 | 
			
		||||
  } else if (isBlobLike(object)) {
 | 
			
		||||
    // 3. Otherwise, if object is a Blob object, set stream to the
 | 
			
		||||
    //    result of running object’s get stream.
 | 
			
		||||
    stream = object.stream()
 | 
			
		||||
  } else {
 | 
			
		||||
    // 4. Otherwise, set stream to a new ReadableStream object, and set
 | 
			
		||||
    //    up stream.
 | 
			
		||||
    stream = new ReadableStream({
 | 
			
		||||
      async pull (controller) {
 | 
			
		||||
        controller.enqueue(
 | 
			
		||||
          typeof source === 'string' ? textEncoder.encode(source) : source
 | 
			
		||||
        )
 | 
			
		||||
        queueMicrotask(() => readableStreamClose(controller))
 | 
			
		||||
      },
 | 
			
		||||
      start () {},
 | 
			
		||||
      type: undefined
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // 5. Assert: stream is a ReadableStream object.
 | 
			
		||||
  assert(isReadableStreamLike(stream))
 | 
			
		||||
 | 
			
		||||
  // 6. Let action be null.
 | 
			
		||||
  let action = null
 | 
			
		||||
 | 
			
		||||
  // 7. Let source be null.
 | 
			
		||||
  let source = null
 | 
			
		||||
 | 
			
		||||
  // 8. Let length be null.
 | 
			
		||||
  let length = null
 | 
			
		||||
 | 
			
		||||
  // 9. Let type be null.
 | 
			
		||||
  let type = null
 | 
			
		||||
 | 
			
		||||
  // 10. Switch on object:
 | 
			
		||||
  if (typeof object === 'string') {
 | 
			
		||||
    // Set source to the UTF-8 encoding of object.
 | 
			
		||||
    // Note: setting source to a Uint8Array here breaks some mocking assumptions.
 | 
			
		||||
    source = object
 | 
			
		||||
 | 
			
		||||
    // Set type to `text/plain;charset=UTF-8`.
 | 
			
		||||
    type = 'text/plain;charset=UTF-8'
 | 
			
		||||
  } 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 type to `application/x-www-form-urlencoded;charset=UTF-8`.
 | 
			
		||||
    type = 'application/x-www-form-urlencoded;charset=UTF-8'
 | 
			
		||||
  } else if (isArrayBuffer(object)) {
 | 
			
		||||
    // BufferSource/ArrayBuffer
 | 
			
		||||
 | 
			
		||||
    // Set source to a copy of the bytes held by object.
 | 
			
		||||
    source = new Uint8Array(object.slice())
 | 
			
		||||
  } else if (ArrayBuffer.isView(object)) {
 | 
			
		||||
    // BufferSource/ArrayBufferView
 | 
			
		||||
 | 
			
		||||
    // Set source to a copy of the bytes held by object.
 | 
			
		||||
    source = new Uint8Array(object.buffer.slice(object.byteOffset, object.byteOffset + object.byteLength))
 | 
			
		||||
  } else if (util.isFormDataLike(object)) {
 | 
			
		||||
    const boundary = `----formdata-undici-0${`${Math.floor(Math.random() * 1e11)}`.padStart(11, '0')}`
 | 
			
		||||
    const prefix = `--${boundary}\r\nContent-Disposition: form-data`
 | 
			
		||||
 | 
			
		||||
    /*! formdata-polyfill. MIT License. Jimmy Wärting <https://jimmy.warting.se/opensource> */
 | 
			
		||||
    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.
 | 
			
		||||
    // - This ensures that the body is immutable and can't be changed afterwords
 | 
			
		||||
    // - That the content-length is calculated in advance.
 | 
			
		||||
    // - And that all parts are pre-encoded and ready to be sent.
 | 
			
		||||
 | 
			
		||||
    const blobParts = []
 | 
			
		||||
    const rn = new Uint8Array([13, 10]) // '\r\n'
 | 
			
		||||
    length = 0
 | 
			
		||||
    let hasUnknownSizeValue = false
 | 
			
		||||
 | 
			
		||||
    for (const [name, value] of object) {
 | 
			
		||||
      if (typeof value === 'string') {
 | 
			
		||||
        const chunk = textEncoder.encode(prefix +
 | 
			
		||||
          `; name="${escape(normalizeLinefeeds(name))}"` +
 | 
			
		||||
          `\r\n\r\n${normalizeLinefeeds(value)}\r\n`)
 | 
			
		||||
        blobParts.push(chunk)
 | 
			
		||||
        length += chunk.byteLength
 | 
			
		||||
      } else {
 | 
			
		||||
        const chunk = textEncoder.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`)
 | 
			
		||||
        blobParts.push(chunk, value, rn)
 | 
			
		||||
        if (typeof value.size === 'number') {
 | 
			
		||||
          length += chunk.byteLength + value.size + rn.byteLength
 | 
			
		||||
        } else {
 | 
			
		||||
          hasUnknownSizeValue = true
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const chunk = textEncoder.encode(`--${boundary}--`)
 | 
			
		||||
    blobParts.push(chunk)
 | 
			
		||||
    length += chunk.byteLength
 | 
			
		||||
    if (hasUnknownSizeValue) {
 | 
			
		||||
      length = null
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Set source to object.
 | 
			
		||||
    source = object
 | 
			
		||||
 | 
			
		||||
    action = async function * () {
 | 
			
		||||
      for (const part of blobParts) {
 | 
			
		||||
        if (part.stream) {
 | 
			
		||||
          yield * part.stream()
 | 
			
		||||
        } else {
 | 
			
		||||
          yield part
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Set type to `multipart/form-data; boundary=`,
 | 
			
		||||
    // followed by the multipart/form-data boundary string generated
 | 
			
		||||
    // by the multipart/form-data encoding algorithm.
 | 
			
		||||
    type = 'multipart/form-data; boundary=' + boundary
 | 
			
		||||
  } else if (isBlobLike(object)) {
 | 
			
		||||
    // Blob
 | 
			
		||||
 | 
			
		||||
    // 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
 | 
			
		||||
    // type to its value.
 | 
			
		||||
    if (object.type) {
 | 
			
		||||
      type = 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)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // 11. If source is a byte sequence, then set action to a
 | 
			
		||||
  // step that returns source and length to source’s length.
 | 
			
		||||
  if (typeof source === 'string' || util.isBuffer(source)) {
 | 
			
		||||
    length = Buffer.byteLength(source)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // 12. 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()
 | 
			
		||||
      },
 | 
			
		||||
      type: undefined
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // 13. Let body be a body whose stream is stream, source is source,
 | 
			
		||||
  // and length is length.
 | 
			
		||||
  const body = { stream, source, length }
 | 
			
		||||
 | 
			
		||||
  // 14. Return (body, type).
 | 
			
		||||
  return [body, type]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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), 'The body has already been consumed.')
 | 
			
		||||
    // istanbul ignore next
 | 
			
		||||
    assert(!object.locked, 'The stream is 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()
 | 
			
		||||
  const out2Clone = structuredClone(out2, { transfer: [out2] })
 | 
			
		||||
  // This, for whatever reasons, unrefs out2Clone which allows
 | 
			
		||||
  // the process to exit by itself.
 | 
			
		||||
  const [, finalClone] = out2Clone.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: finalClone,
 | 
			
		||||
    length: body.length,
 | 
			
		||||
    source: body.source
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function * consumeBody (body) {
 | 
			
		||||
  if (body) {
 | 
			
		||||
    if (isUint8Array(body)) {
 | 
			
		||||
      yield body
 | 
			
		||||
    } else {
 | 
			
		||||
      const stream = body.stream
 | 
			
		||||
 | 
			
		||||
      if (util.isDisturbed(stream)) {
 | 
			
		||||
        throw new TypeError('The body has already been consumed.')
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (stream.locked) {
 | 
			
		||||
        throw new TypeError('The stream is locked.')
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Compat.
 | 
			
		||||
      stream[kBodyUsed] = true
 | 
			
		||||
 | 
			
		||||
      yield * stream
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function throwIfAborted (state) {
 | 
			
		||||
  if (state.aborted) {
 | 
			
		||||
    throw new DOMException('The operation was aborted.', 'AbortError')
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function bodyMixinMethods (instance) {
 | 
			
		||||
  const methods = {
 | 
			
		||||
    blob () {
 | 
			
		||||
      // The blob() method steps are to return the result of
 | 
			
		||||
      // running consume body with this and the following step
 | 
			
		||||
      // given a byte sequence bytes: return a Blob whose
 | 
			
		||||
      // contents are bytes and whose type attribute is this’s
 | 
			
		||||
      // MIME type.
 | 
			
		||||
      return specConsumeBody(this, (bytes) => {
 | 
			
		||||
        let mimeType = bodyMimeType(this)
 | 
			
		||||
 | 
			
		||||
        if (mimeType === 'failure') {
 | 
			
		||||
          mimeType = ''
 | 
			
		||||
        } else if (mimeType) {
 | 
			
		||||
          mimeType = serializeAMimeType(mimeType)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Return a Blob whose contents are bytes and type attribute
 | 
			
		||||
        // is mimeType.
 | 
			
		||||
        return new Blob([bytes], { type: mimeType })
 | 
			
		||||
      }, instance)
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    arrayBuffer () {
 | 
			
		||||
      // The arrayBuffer() method steps are to return the result
 | 
			
		||||
      // of running consume body with this and the following step
 | 
			
		||||
      // given a byte sequence bytes: return a new ArrayBuffer
 | 
			
		||||
      // whose contents are bytes.
 | 
			
		||||
      return specConsumeBody(this, (bytes) => {
 | 
			
		||||
        return new Uint8Array(bytes).buffer
 | 
			
		||||
      }, instance)
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    text () {
 | 
			
		||||
      // The text() method steps are to return the result of running
 | 
			
		||||
      // consume body with this and UTF-8 decode.
 | 
			
		||||
      return specConsumeBody(this, utf8DecodeBytes, instance)
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    json () {
 | 
			
		||||
      // The json() method steps are to return the result of running
 | 
			
		||||
      // consume body with this and parse JSON from bytes.
 | 
			
		||||
      return specConsumeBody(this, parseJSONFromBytes, instance)
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    async formData () {
 | 
			
		||||
      webidl.brandCheck(this, instance)
 | 
			
		||||
 | 
			
		||||
      throwIfAborted(this[kState])
 | 
			
		||||
 | 
			
		||||
      const contentType = this.headers.get('Content-Type')
 | 
			
		||||
 | 
			
		||||
      // If mimeType’s essence is "multipart/form-data", then:
 | 
			
		||||
      if (/multipart\/form-data/.test(contentType)) {
 | 
			
		||||
        const headers = {}
 | 
			
		||||
        for (const [key, value] of this.headers) headers[key.toLowerCase()] = value
 | 
			
		||||
 | 
			
		||||
        const responseFormData = new FormData()
 | 
			
		||||
 | 
			
		||||
        let busboy
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
          busboy = new Busboy({
 | 
			
		||||
            headers,
 | 
			
		||||
            preservePath: true
 | 
			
		||||
          })
 | 
			
		||||
        } catch (err) {
 | 
			
		||||
          throw new DOMException(`${err}`, 'AbortError')
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        busboy.on('field', (name, value) => {
 | 
			
		||||
          responseFormData.append(name, value)
 | 
			
		||||
        })
 | 
			
		||||
        busboy.on('file', (name, value, filename, encoding, mimeType) => {
 | 
			
		||||
          const chunks = []
 | 
			
		||||
 | 
			
		||||
          if (encoding === 'base64' || encoding.toLowerCase() === 'base64') {
 | 
			
		||||
            let base64chunk = ''
 | 
			
		||||
 | 
			
		||||
            value.on('data', (chunk) => {
 | 
			
		||||
              base64chunk += chunk.toString().replace(/[\r\n]/gm, '')
 | 
			
		||||
 | 
			
		||||
              const end = base64chunk.length - base64chunk.length % 4
 | 
			
		||||
              chunks.push(Buffer.from(base64chunk.slice(0, end), 'base64'))
 | 
			
		||||
 | 
			
		||||
              base64chunk = base64chunk.slice(end)
 | 
			
		||||
            })
 | 
			
		||||
            value.on('end', () => {
 | 
			
		||||
              chunks.push(Buffer.from(base64chunk, 'base64'))
 | 
			
		||||
              responseFormData.append(name, new File(chunks, filename, { type: mimeType }))
 | 
			
		||||
            })
 | 
			
		||||
          } else {
 | 
			
		||||
            value.on('data', (chunk) => {
 | 
			
		||||
              chunks.push(chunk)
 | 
			
		||||
            })
 | 
			
		||||
            value.on('end', () => {
 | 
			
		||||
              responseFormData.append(name, new File(chunks, filename, { type: mimeType }))
 | 
			
		||||
            })
 | 
			
		||||
          }
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
        const busboyResolve = new Promise((resolve, reject) => {
 | 
			
		||||
          busboy.on('finish', resolve)
 | 
			
		||||
          busboy.on('error', (err) => reject(new TypeError(err)))
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
        if (this.body !== null) for await (const chunk of consumeBody(this[kState].body)) busboy.write(chunk)
 | 
			
		||||
        busboy.end()
 | 
			
		||||
        await busboyResolve
 | 
			
		||||
 | 
			
		||||
        return responseFormData
 | 
			
		||||
      } 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 {
 | 
			
		||||
          let text = ''
 | 
			
		||||
          // application/x-www-form-urlencoded parser will keep the BOM.
 | 
			
		||||
          // https://url.spec.whatwg.org/#concept-urlencoded-parser
 | 
			
		||||
          // Note that streaming decoder is stateful and cannot be reused
 | 
			
		||||
          const streamingDecoder = new TextDecoder('utf-8', { ignoreBOM: true })
 | 
			
		||||
 | 
			
		||||
          for await (const chunk of consumeBody(this[kState].body)) {
 | 
			
		||||
            if (!isUint8Array(chunk)) {
 | 
			
		||||
              throw new TypeError('Expected Uint8Array chunk')
 | 
			
		||||
            }
 | 
			
		||||
            text += streamingDecoder.decode(chunk, { stream: true })
 | 
			
		||||
          }
 | 
			
		||||
          text += streamingDecoder.decode()
 | 
			
		||||
          entries = new URLSearchParams(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 {
 | 
			
		||||
        // Wait a tick before checking if the request has been aborted.
 | 
			
		||||
        // Otherwise, a TypeError can be thrown when an AbortError should.
 | 
			
		||||
        await Promise.resolve()
 | 
			
		||||
 | 
			
		||||
        throwIfAborted(this[kState])
 | 
			
		||||
 | 
			
		||||
        // Otherwise, throw a TypeError.
 | 
			
		||||
        throw webidl.errors.exception({
 | 
			
		||||
          header: `${instance.name}.formData`,
 | 
			
		||||
          message: 'Could not parse content as FormData.'
 | 
			
		||||
        })
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return methods
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function mixinBody (prototype) {
 | 
			
		||||
  Object.assign(prototype.prototype, bodyMixinMethods(prototype))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @see https://fetch.spec.whatwg.org/#concept-body-consume-body
 | 
			
		||||
 * @param {Response|Request} object
 | 
			
		||||
 * @param {(value: unknown) => unknown} convertBytesToJSValue
 | 
			
		||||
 * @param {Response|Request} instance
 | 
			
		||||
 */
 | 
			
		||||
async function specConsumeBody (object, convertBytesToJSValue, instance) {
 | 
			
		||||
  webidl.brandCheck(object, instance)
 | 
			
		||||
 | 
			
		||||
  throwIfAborted(object[kState])
 | 
			
		||||
 | 
			
		||||
  // 1. If object is unusable, then return a promise rejected
 | 
			
		||||
  //    with a TypeError.
 | 
			
		||||
  if (bodyUnusable(object[kState].body)) {
 | 
			
		||||
    throw new TypeError('Body is unusable')
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // 2. Let promise be a new promise.
 | 
			
		||||
  const promise = createDeferredPromise()
 | 
			
		||||
 | 
			
		||||
  // 3. Let errorSteps given error be to reject promise with error.
 | 
			
		||||
  const errorSteps = (error) => promise.reject(error)
 | 
			
		||||
 | 
			
		||||
  // 4. Let successSteps given a byte sequence data be to resolve
 | 
			
		||||
  //    promise with the result of running convertBytesToJSValue
 | 
			
		||||
  //    with data. If that threw an exception, then run errorSteps
 | 
			
		||||
  //    with that exception.
 | 
			
		||||
  const successSteps = (data) => {
 | 
			
		||||
    try {
 | 
			
		||||
      promise.resolve(convertBytesToJSValue(data))
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      errorSteps(e)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // 5. If object’s body is null, then run successSteps with an
 | 
			
		||||
  //    empty byte sequence.
 | 
			
		||||
  if (object[kState].body == null) {
 | 
			
		||||
    successSteps(new Uint8Array())
 | 
			
		||||
    return promise.promise
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // 6. Otherwise, fully read object’s body given successSteps,
 | 
			
		||||
  //    errorSteps, and object’s relevant global object.
 | 
			
		||||
  await fullyReadBody(object[kState].body, successSteps, errorSteps)
 | 
			
		||||
 | 
			
		||||
  // 7. Return promise.
 | 
			
		||||
  return promise.promise
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// https://fetch.spec.whatwg.org/#body-unusable
 | 
			
		||||
function bodyUnusable (body) {
 | 
			
		||||
  // An object including the Body interface mixin is
 | 
			
		||||
  // said to be unusable if its body is non-null and
 | 
			
		||||
  // its body’s stream is disturbed or locked.
 | 
			
		||||
  return body != null && (body.stream.locked || util.isDisturbed(body.stream))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @see https://encoding.spec.whatwg.org/#utf-8-decode
 | 
			
		||||
 * @param {Buffer} buffer
 | 
			
		||||
 */
 | 
			
		||||
function utf8DecodeBytes (buffer) {
 | 
			
		||||
  if (buffer.length === 0) {
 | 
			
		||||
    return ''
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // 1. Let buffer be the result of peeking three bytes from
 | 
			
		||||
  //    ioQueue, converted to a byte sequence.
 | 
			
		||||
 | 
			
		||||
  // 2. If buffer is 0xEF 0xBB 0xBF, then read three
 | 
			
		||||
  //    bytes from ioQueue. (Do nothing with those bytes.)
 | 
			
		||||
  if (buffer[0] === 0xEF && buffer[1] === 0xBB && buffer[2] === 0xBF) {
 | 
			
		||||
    buffer = buffer.subarray(3)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // 3. Process a queue with an instance of UTF-8’s
 | 
			
		||||
  //    decoder, ioQueue, output, and "replacement".
 | 
			
		||||
  const output = textDecoder.decode(buffer)
 | 
			
		||||
 | 
			
		||||
  // 4. Return output.
 | 
			
		||||
  return output
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @see https://infra.spec.whatwg.org/#parse-json-bytes-to-a-javascript-value
 | 
			
		||||
 * @param {Uint8Array} bytes
 | 
			
		||||
 */
 | 
			
		||||
function parseJSONFromBytes (bytes) {
 | 
			
		||||
  return JSON.parse(utf8DecodeBytes(bytes))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @see https://fetch.spec.whatwg.org/#concept-body-mime-type
 | 
			
		||||
 * @param {import('./response').Response|import('./request').Request} object
 | 
			
		||||
 */
 | 
			
		||||
function bodyMimeType (object) {
 | 
			
		||||
  const { headersList } = object[kState]
 | 
			
		||||
  const contentType = headersList.get('content-type')
 | 
			
		||||
 | 
			
		||||
  if (contentType === null) {
 | 
			
		||||
    return 'failure'
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return parseMIMEType(contentType)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
  extractBody,
 | 
			
		||||
  safelyExtractBody,
 | 
			
		||||
  cloneBody,
 | 
			
		||||
  mixinBody
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										151
									
								
								node_modules/undici/lib/fetch/constants.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								node_modules/undici/lib/fetch/constants.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,151 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
const { MessageChannel, receiveMessageOnPort } = require('worker_threads')
 | 
			
		||||
 | 
			
		||||
const corsSafeListedMethods = ['GET', 'HEAD', 'POST']
 | 
			
		||||
const corsSafeListedMethodsSet = new Set(corsSafeListedMethods)
 | 
			
		||||
 | 
			
		||||
const nullBodyStatus = [101, 204, 205, 304]
 | 
			
		||||
 | 
			
		||||
const redirectStatus = [301, 302, 303, 307, 308]
 | 
			
		||||
const redirectStatusSet = new Set(redirectStatus)
 | 
			
		||||
 | 
			
		||||
// 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'
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
const badPortsSet = new Set(badPorts)
 | 
			
		||||
 | 
			
		||||
// https://w3c.github.io/webappsec-referrer-policy/#referrer-policies
 | 
			
		||||
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 referrerPolicySet = new Set(referrerPolicy)
 | 
			
		||||
 | 
			
		||||
const requestRedirect = ['follow', 'manual', 'error']
 | 
			
		||||
 | 
			
		||||
const safeMethods = ['GET', 'HEAD', 'OPTIONS', 'TRACE']
 | 
			
		||||
const safeMethodsSet = new Set(safeMethods)
 | 
			
		||||
 | 
			
		||||
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'
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
// https://fetch.spec.whatwg.org/#request-body-header-name
 | 
			
		||||
const requestBodyHeader = [
 | 
			
		||||
  'content-encoding',
 | 
			
		||||
  'content-language',
 | 
			
		||||
  'content-location',
 | 
			
		||||
  'content-type',
 | 
			
		||||
  // See https://github.com/nodejs/undici/issues/2021
 | 
			
		||||
  // 'Content-Length' is a forbidden header name, which is typically
 | 
			
		||||
  // removed in the Headers implementation. However, undici doesn't
 | 
			
		||||
  // filter out headers, so we add it here.
 | 
			
		||||
  'content-length'
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
// https://fetch.spec.whatwg.org/#enumdef-requestduplex
 | 
			
		||||
const requestDuplex = [
 | 
			
		||||
  'half'
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
// http://fetch.spec.whatwg.org/#forbidden-method
 | 
			
		||||
const forbiddenMethods = ['CONNECT', 'TRACE', 'TRACK']
 | 
			
		||||
const forbiddenMethodsSet = new Set(forbiddenMethods)
 | 
			
		||||
 | 
			
		||||
const subresource = [
 | 
			
		||||
  'audio',
 | 
			
		||||
  'audioworklet',
 | 
			
		||||
  'font',
 | 
			
		||||
  'image',
 | 
			
		||||
  'manifest',
 | 
			
		||||
  'paintworklet',
 | 
			
		||||
  'script',
 | 
			
		||||
  'style',
 | 
			
		||||
  'track',
 | 
			
		||||
  'video',
 | 
			
		||||
  'xslt',
 | 
			
		||||
  ''
 | 
			
		||||
]
 | 
			
		||||
const subresourceSet = new Set(subresource)
 | 
			
		||||
 | 
			
		||||
/** @type {globalThis['DOMException']} */
 | 
			
		||||
const DOMException = globalThis.DOMException ?? (() => {
 | 
			
		||||
  // DOMException was only made a global in Node v17.0.0,
 | 
			
		||||
  // but fetch supports >= v16.8.
 | 
			
		||||
  try {
 | 
			
		||||
    atob('~')
 | 
			
		||||
  } catch (err) {
 | 
			
		||||
    return Object.getPrototypeOf(err).constructor
 | 
			
		||||
  }
 | 
			
		||||
})()
 | 
			
		||||
 | 
			
		||||
let channel
 | 
			
		||||
 | 
			
		||||
/** @type {globalThis['structuredClone']} */
 | 
			
		||||
const structuredClone =
 | 
			
		||||
  globalThis.structuredClone ??
 | 
			
		||||
  // https://github.com/nodejs/node/blob/b27ae24dcc4251bad726d9d84baf678d1f707fed/lib/internal/structured_clone.js
 | 
			
		||||
  // structuredClone was added in v17.0.0, but fetch supports v16.8
 | 
			
		||||
  function structuredClone (value, options = undefined) {
 | 
			
		||||
    if (arguments.length === 0) {
 | 
			
		||||
      throw new TypeError('missing argument')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!channel) {
 | 
			
		||||
      channel = new MessageChannel()
 | 
			
		||||
    }
 | 
			
		||||
    channel.port1.unref()
 | 
			
		||||
    channel.port2.unref()
 | 
			
		||||
    channel.port1.postMessage(value, options?.transfer)
 | 
			
		||||
    return receiveMessageOnPort(channel.port2).message
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
  DOMException,
 | 
			
		||||
  structuredClone,
 | 
			
		||||
  subresource,
 | 
			
		||||
  forbiddenMethods,
 | 
			
		||||
  requestBodyHeader,
 | 
			
		||||
  referrerPolicy,
 | 
			
		||||
  requestRedirect,
 | 
			
		||||
  requestMode,
 | 
			
		||||
  requestCredentials,
 | 
			
		||||
  requestCache,
 | 
			
		||||
  redirectStatus,
 | 
			
		||||
  corsSafeListedMethods,
 | 
			
		||||
  nullBodyStatus,
 | 
			
		||||
  safeMethods,
 | 
			
		||||
  badPorts,
 | 
			
		||||
  requestDuplex,
 | 
			
		||||
  subresourceSet,
 | 
			
		||||
  badPortsSet,
 | 
			
		||||
  redirectStatusSet,
 | 
			
		||||
  corsSafeListedMethodsSet,
 | 
			
		||||
  safeMethodsSet,
 | 
			
		||||
  forbiddenMethodsSet,
 | 
			
		||||
  referrerPolicySet
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										627
									
								
								node_modules/undici/lib/fetch/dataURL.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										627
									
								
								node_modules/undici/lib/fetch/dataURL.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,627 @@
 | 
			
		|||
const assert = require('assert')
 | 
			
		||||
const { atob } = require('buffer')
 | 
			
		||||
const { isomorphicDecode } = require('./util')
 | 
			
		||||
 | 
			
		||||
const encoder = new TextEncoder()
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @see https://mimesniff.spec.whatwg.org/#http-token-code-point
 | 
			
		||||
 */
 | 
			
		||||
const HTTP_TOKEN_CODEPOINTS = /^[!#$%&'*+-.^_|~A-Za-z0-9]+$/
 | 
			
		||||
const HTTP_WHITESPACE_REGEX = /(\u000A|\u000D|\u0009|\u0020)/ // eslint-disable-line
 | 
			
		||||
/**
 | 
			
		||||
 * @see https://mimesniff.spec.whatwg.org/#http-quoted-string-token-code-point
 | 
			
		||||
 */
 | 
			
		||||
const HTTP_QUOTED_STRING_TOKENS = /[\u0009|\u0020-\u007E|\u0080-\u00FF]/ // eslint-disable-line
 | 
			
		||||
 | 
			
		||||
// 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 = collectASequenceOfCodePointsFast(
 | 
			
		||||
    ',',
 | 
			
		||||
    input,
 | 
			
		||||
    position
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
  // 6. Strip leading and trailing ASCII whitespace
 | 
			
		||||
  // from mimeType.
 | 
			
		||||
  // 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 = removeASCIIWhitespace(mimeType, true, true)
 | 
			
		||||
 | 
			
		||||
  // 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.
 | 
			
		||||
  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 = isomorphicDecode(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) {
 | 
			
		||||
  if (!excludeFragment) {
 | 
			
		||||
    return url.href
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const href = url.href
 | 
			
		||||
  const hashLength = url.hash.length
 | 
			
		||||
 | 
			
		||||
  return hashLength === 0 ? href : href.substring(0, href.length - hashLength)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A faster collectASequenceOfCodePoints that only works when comparing a single character.
 | 
			
		||||
 * @param {string} char
 | 
			
		||||
 * @param {string} input
 | 
			
		||||
 * @param {{ position: number }} position
 | 
			
		||||
 */
 | 
			
		||||
function collectASequenceOfCodePointsFast (char, input, position) {
 | 
			
		||||
  const idx = input.indexOf(char, position.position)
 | 
			
		||||
  const start = position.position
 | 
			
		||||
 | 
			
		||||
  if (idx === -1) {
 | 
			
		||||
    position.position = input.length
 | 
			
		||||
    return input.slice(start)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  position.position = idx
 | 
			
		||||
  return input.slice(start, position.position)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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.from(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 = removeHTTPWhitespace(input, true, true)
 | 
			
		||||
 | 
			
		||||
  // 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 = collectASequenceOfCodePointsFast(
 | 
			
		||||
    '/',
 | 
			
		||||
    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 || !HTTP_TOKEN_CODEPOINTS.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 = collectASequenceOfCodePointsFast(
 | 
			
		||||
    ';',
 | 
			
		||||
    input,
 | 
			
		||||
    position
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
  // 8. Remove any trailing HTTP whitespace from subtype.
 | 
			
		||||
  subtype = removeHTTPWhitespace(subtype, false, true)
 | 
			
		||||
 | 
			
		||||
  // 9. If subtype is the empty string or does not solely
 | 
			
		||||
  // contain HTTP token code points, then return failure.
 | 
			
		||||
  if (subtype.length === 0 || !HTTP_TOKEN_CODEPOINTS.test(subtype)) {
 | 
			
		||||
    return 'failure'
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const typeLowercase = type.toLowerCase()
 | 
			
		||||
  const subtypeLowercase = subtype.toLowerCase()
 | 
			
		||||
 | 
			
		||||
  // 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: typeLowercase,
 | 
			
		||||
    subtype: subtypeLowercase,
 | 
			
		||||
    /** @type {Map<string, string>} */
 | 
			
		||||
    parameters: new Map(),
 | 
			
		||||
    // https://mimesniff.spec.whatwg.org/#mime-type-essence
 | 
			
		||||
    essence: `${typeLowercase}/${subtypeLowercase}`
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // 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 => HTTP_WHITESPACE_REGEX.test(char),
 | 
			
		||||
      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.
 | 
			
		||||
      parameterValue = collectAnHTTPQuotedString(input, position, true)
 | 
			
		||||
 | 
			
		||||
      // 2. Collect a sequence of code points that are not
 | 
			
		||||
      // U+003B (;) from input, given position.
 | 
			
		||||
      collectASequenceOfCodePointsFast(
 | 
			
		||||
        ';',
 | 
			
		||||
        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 = collectASequenceOfCodePointsFast(
 | 
			
		||||
        ';',
 | 
			
		||||
        input,
 | 
			
		||||
        position
 | 
			
		||||
      )
 | 
			
		||||
 | 
			
		||||
      // 2. Remove any trailing HTTP whitespace from parameterValue.
 | 
			
		||||
      parameterValue = removeHTTPWhitespace(parameterValue, false, true)
 | 
			
		||||
 | 
			
		||||
      // 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 &&
 | 
			
		||||
      HTTP_TOKEN_CODEPOINTS.test(parameterName) &&
 | 
			
		||||
      (parameterValue.length === 0 || HTTP_QUOTED_STRING_TOKENS.test(parameterValue)) &&
 | 
			
		||||
      !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)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @see https://mimesniff.spec.whatwg.org/#serialize-a-mime-type
 | 
			
		||||
 */
 | 
			
		||||
function serializeAMimeType (mimeType) {
 | 
			
		||||
  assert(mimeType !== 'failure')
 | 
			
		||||
  const { parameters, essence } = mimeType
 | 
			
		||||
 | 
			
		||||
  // 1. Let serialization be the concatenation of mimeType’s
 | 
			
		||||
  //    type, U+002F (/), and mimeType’s subtype.
 | 
			
		||||
  let serialization = essence
 | 
			
		||||
 | 
			
		||||
  // 2. For each name → value of mimeType’s parameters:
 | 
			
		||||
  for (let [name, value] of parameters.entries()) {
 | 
			
		||||
    // 1. Append U+003B (;) to serialization.
 | 
			
		||||
    serialization += ';'
 | 
			
		||||
 | 
			
		||||
    // 2. Append name to serialization.
 | 
			
		||||
    serialization += name
 | 
			
		||||
 | 
			
		||||
    // 3. Append U+003D (=) to serialization.
 | 
			
		||||
    serialization += '='
 | 
			
		||||
 | 
			
		||||
    // 4. If value does not solely contain HTTP token code
 | 
			
		||||
    //    points or value is the empty string, then:
 | 
			
		||||
    if (!HTTP_TOKEN_CODEPOINTS.test(value)) {
 | 
			
		||||
      // 1. Precede each occurence of U+0022 (") or
 | 
			
		||||
      //    U+005C (\) in value with U+005C (\).
 | 
			
		||||
      value = value.replace(/(\\|")/g, '\\$1')
 | 
			
		||||
 | 
			
		||||
      // 2. Prepend U+0022 (") to value.
 | 
			
		||||
      value = '"' + value
 | 
			
		||||
 | 
			
		||||
      // 3. Append U+0022 (") to value.
 | 
			
		||||
      value += '"'
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 5. Append value to serialization.
 | 
			
		||||
    serialization += value
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // 3. Return serialization.
 | 
			
		||||
  return serialization
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @see https://fetch.spec.whatwg.org/#http-whitespace
 | 
			
		||||
 * @param {string} char
 | 
			
		||||
 */
 | 
			
		||||
function isHTTPWhiteSpace (char) {
 | 
			
		||||
  return char === '\r' || char === '\n' || char === '\t' || char === ' '
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @see https://fetch.spec.whatwg.org/#http-whitespace
 | 
			
		||||
 * @param {string} str
 | 
			
		||||
 */
 | 
			
		||||
function removeHTTPWhitespace (str, leading = true, trailing = true) {
 | 
			
		||||
  let lead = 0
 | 
			
		||||
  let trail = str.length - 1
 | 
			
		||||
 | 
			
		||||
  if (leading) {
 | 
			
		||||
    for (; lead < str.length && isHTTPWhiteSpace(str[lead]); lead++);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (trailing) {
 | 
			
		||||
    for (; trail > 0 && isHTTPWhiteSpace(str[trail]); trail--);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return str.slice(lead, trail + 1)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @see https://infra.spec.whatwg.org/#ascii-whitespace
 | 
			
		||||
 * @param {string} char
 | 
			
		||||
 */
 | 
			
		||||
function isASCIIWhitespace (char) {
 | 
			
		||||
  return char === '\r' || char === '\n' || char === '\t' || char === '\f' || char === ' '
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @see https://infra.spec.whatwg.org/#strip-leading-and-trailing-ascii-whitespace
 | 
			
		||||
 */
 | 
			
		||||
function removeASCIIWhitespace (str, leading = true, trailing = true) {
 | 
			
		||||
  let lead = 0
 | 
			
		||||
  let trail = str.length - 1
 | 
			
		||||
 | 
			
		||||
  if (leading) {
 | 
			
		||||
    for (; lead < str.length && isASCIIWhitespace(str[lead]); lead++);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (trailing) {
 | 
			
		||||
    for (; trail > 0 && isASCIIWhitespace(str[trail]); trail--);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return str.slice(lead, trail + 1)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
  dataURLProcessor,
 | 
			
		||||
  URLSerializer,
 | 
			
		||||
  collectASequenceOfCodePoints,
 | 
			
		||||
  collectASequenceOfCodePointsFast,
 | 
			
		||||
  stringPercentDecode,
 | 
			
		||||
  parseMIMEType,
 | 
			
		||||
  collectAnHTTPQuotedString,
 | 
			
		||||
  serializeAMimeType
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										344
									
								
								node_modules/undici/lib/fetch/file.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										344
									
								
								node_modules/undici/lib/fetch/file.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,344 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
const { Blob, File: NativeFile } = require('buffer')
 | 
			
		||||
const { types } = require('util')
 | 
			
		||||
const { kState } = require('./symbols')
 | 
			
		||||
const { isBlobLike } = require('./util')
 | 
			
		||||
const { webidl } = require('./webidl')
 | 
			
		||||
const { parseMIMEType, serializeAMimeType } = require('./dataURL')
 | 
			
		||||
const { kEnumerableProperty } = require('../core/util')
 | 
			
		||||
const encoder = new TextEncoder()
 | 
			
		||||
 | 
			
		||||
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:
 | 
			
		||||
    webidl.argumentLengthCheck(arguments, 2, { header: 'File constructor' })
 | 
			
		||||
 | 
			
		||||
    fileBits = webidl.converters['sequence<BlobPart>'](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.
 | 
			
		||||
    let t = options.type
 | 
			
		||||
    let d
 | 
			
		||||
 | 
			
		||||
    // eslint-disable-next-line no-labels
 | 
			
		||||
    substep: {
 | 
			
		||||
      if (t) {
 | 
			
		||||
        t = parseMIMEType(t)
 | 
			
		||||
 | 
			
		||||
        if (t === 'failure') {
 | 
			
		||||
          t = ''
 | 
			
		||||
          // eslint-disable-next-line no-labels
 | 
			
		||||
          break substep
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        t = serializeAMimeType(t).toLowerCase()
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      //    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]).
 | 
			
		||||
      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: t })
 | 
			
		||||
    this[kState] = {
 | 
			
		||||
      name: n,
 | 
			
		||||
      lastModified: d,
 | 
			
		||||
      type: t
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get name () {
 | 
			
		||||
    webidl.brandCheck(this, File)
 | 
			
		||||
 | 
			
		||||
    return this[kState].name
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get lastModified () {
 | 
			
		||||
    webidl.brandCheck(this, File)
 | 
			
		||||
 | 
			
		||||
    return this[kState].lastModified
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get type () {
 | 
			
		||||
    webidl.brandCheck(this, File)
 | 
			
		||||
 | 
			
		||||
    return this[kState].type
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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) {
 | 
			
		||||
    webidl.brandCheck(this, FileLike)
 | 
			
		||||
 | 
			
		||||
    return this[kState].blobLike.stream(...args)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  arrayBuffer (...args) {
 | 
			
		||||
    webidl.brandCheck(this, FileLike)
 | 
			
		||||
 | 
			
		||||
    return this[kState].blobLike.arrayBuffer(...args)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  slice (...args) {
 | 
			
		||||
    webidl.brandCheck(this, FileLike)
 | 
			
		||||
 | 
			
		||||
    return this[kState].blobLike.slice(...args)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  text (...args) {
 | 
			
		||||
    webidl.brandCheck(this, FileLike)
 | 
			
		||||
 | 
			
		||||
    return this[kState].blobLike.text(...args)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get size () {
 | 
			
		||||
    webidl.brandCheck(this, FileLike)
 | 
			
		||||
 | 
			
		||||
    return this[kState].blobLike.size
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get type () {
 | 
			
		||||
    webidl.brandCheck(this, FileLike)
 | 
			
		||||
 | 
			
		||||
    return this[kState].blobLike.type
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get name () {
 | 
			
		||||
    webidl.brandCheck(this, FileLike)
 | 
			
		||||
 | 
			
		||||
    return this[kState].name
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get lastModified () {
 | 
			
		||||
    webidl.brandCheck(this, FileLike)
 | 
			
		||||
 | 
			
		||||
    return this[kState].lastModified
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get [Symbol.toStringTag] () {
 | 
			
		||||
    return 'File'
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Object.defineProperties(File.prototype, {
 | 
			
		||||
  [Symbol.toStringTag]: {
 | 
			
		||||
    value: 'File',
 | 
			
		||||
    configurable: true
 | 
			
		||||
  },
 | 
			
		||||
  name: kEnumerableProperty,
 | 
			
		||||
  lastModified: kEnumerableProperty
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
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 })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (
 | 
			
		||||
      ArrayBuffer.isView(V) ||
 | 
			
		||||
      types.isAnyArrayBuffer(V)
 | 
			
		||||
    ) {
 | 
			
		||||
      return webidl.converters.BufferSource(V, opts)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return webidl.converters.USVString(V, opts)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
webidl.converters['sequence<BlobPart>'] = 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(encoder.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(
 | 
			
		||||
          new Uint8Array(element.buffer, element.byteOffset, element.byteLength)
 | 
			
		||||
        )
 | 
			
		||||
      }
 | 
			
		||||
    } 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)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// If this function is moved to ./util.js, some tools (such as
 | 
			
		||||
// rollup) will warn about circular dependencies. See:
 | 
			
		||||
// https://github.com/nodejs/undici/issues/1629
 | 
			
		||||
function isFileLike (object) {
 | 
			
		||||
  return (
 | 
			
		||||
    (NativeFile && object instanceof NativeFile) ||
 | 
			
		||||
    object instanceof File || (
 | 
			
		||||
      object &&
 | 
			
		||||
      (typeof object.stream === 'function' ||
 | 
			
		||||
      typeof object.arrayBuffer === 'function') &&
 | 
			
		||||
      object[Symbol.toStringTag] === 'File'
 | 
			
		||||
    )
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = { File, FileLike, isFileLike }
 | 
			
		||||
							
								
								
									
										265
									
								
								node_modules/undici/lib/fetch/formdata.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										265
									
								
								node_modules/undici/lib/fetch/formdata.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,265 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
const { isBlobLike, toUSVString, makeIterator } = require('./util')
 | 
			
		||||
const { kState } = require('./symbols')
 | 
			
		||||
const { File: UndiciFile, FileLike, isFileLike } = require('./file')
 | 
			
		||||
const { webidl } = require('./webidl')
 | 
			
		||||
const { Blob, File: NativeFile } = require('buffer')
 | 
			
		||||
 | 
			
		||||
/** @type {globalThis['File']} */
 | 
			
		||||
const File = NativeFile ?? UndiciFile
 | 
			
		||||
 | 
			
		||||
// https://xhr.spec.whatwg.org/#formdata
 | 
			
		||||
class FormData {
 | 
			
		||||
  constructor (form) {
 | 
			
		||||
    if (form !== undefined) {
 | 
			
		||||
      throw webidl.errors.conversionFailed({
 | 
			
		||||
        prefix: 'FormData constructor',
 | 
			
		||||
        argument: 'Argument 1',
 | 
			
		||||
        types: ['undefined']
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this[kState] = []
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  append (name, value, filename = undefined) {
 | 
			
		||||
    webidl.brandCheck(this, FormData)
 | 
			
		||||
 | 
			
		||||
    webidl.argumentLengthCheck(arguments, 2, { header: 'FormData.append' })
 | 
			
		||||
 | 
			
		||||
    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) {
 | 
			
		||||
    webidl.brandCheck(this, FormData)
 | 
			
		||||
 | 
			
		||||
    webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.delete' })
 | 
			
		||||
 | 
			
		||||
    name = webidl.converters.USVString(name)
 | 
			
		||||
 | 
			
		||||
    // The delete(name) method steps are to remove all entries whose name
 | 
			
		||||
    // is name from this’s entry list.
 | 
			
		||||
    this[kState] = this[kState].filter(entry => entry.name !== name)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get (name) {
 | 
			
		||||
    webidl.brandCheck(this, FormData)
 | 
			
		||||
 | 
			
		||||
    webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.get' })
 | 
			
		||||
 | 
			
		||||
    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) {
 | 
			
		||||
    webidl.brandCheck(this, FormData)
 | 
			
		||||
 | 
			
		||||
    webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.getAll' })
 | 
			
		||||
 | 
			
		||||
    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) {
 | 
			
		||||
    webidl.brandCheck(this, FormData)
 | 
			
		||||
 | 
			
		||||
    webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.has' })
 | 
			
		||||
 | 
			
		||||
    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) {
 | 
			
		||||
    webidl.brandCheck(this, FormData)
 | 
			
		||||
 | 
			
		||||
    webidl.argumentLengthCheck(arguments, 2, { header: 'FormData.set' })
 | 
			
		||||
 | 
			
		||||
    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)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  entries () {
 | 
			
		||||
    webidl.brandCheck(this, FormData)
 | 
			
		||||
 | 
			
		||||
    return makeIterator(
 | 
			
		||||
      () => this[kState].map(pair => [pair.name, pair.value]),
 | 
			
		||||
      'FormData',
 | 
			
		||||
      'key+value'
 | 
			
		||||
    )
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  keys () {
 | 
			
		||||
    webidl.brandCheck(this, FormData)
 | 
			
		||||
 | 
			
		||||
    return makeIterator(
 | 
			
		||||
      () => this[kState].map(pair => [pair.name, pair.value]),
 | 
			
		||||
      'FormData',
 | 
			
		||||
      'key'
 | 
			
		||||
    )
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  values () {
 | 
			
		||||
    webidl.brandCheck(this, FormData)
 | 
			
		||||
 | 
			
		||||
    return makeIterator(
 | 
			
		||||
      () => this[kState].map(pair => [pair.name, pair.value]),
 | 
			
		||||
      'FormData',
 | 
			
		||||
      'value'
 | 
			
		||||
    )
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @param {(value: string, key: string, self: FormData) => void} callbackFn
 | 
			
		||||
   * @param {unknown} thisArg
 | 
			
		||||
   */
 | 
			
		||||
  forEach (callbackFn, thisArg = globalThis) {
 | 
			
		||||
    webidl.brandCheck(this, FormData)
 | 
			
		||||
 | 
			
		||||
    webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.forEach' })
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
Object.defineProperties(FormData.prototype, {
 | 
			
		||||
  [Symbol.toStringTag]: {
 | 
			
		||||
    value: 'FormData',
 | 
			
		||||
    configurable: true
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @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) {
 | 
			
		||||
      /** @type {FilePropertyBag} */
 | 
			
		||||
      const options = {
 | 
			
		||||
        type: value.type,
 | 
			
		||||
        lastModified: value.lastModified
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      value = (NativeFile && value instanceof NativeFile) || value instanceof UndiciFile
 | 
			
		||||
        ? new File([value], filename, options)
 | 
			
		||||
        : new FileLike(value, filename, options)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // 4. Return an entry whose name is name and whose value is value.
 | 
			
		||||
  return { name, value }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = { FormData }
 | 
			
		||||
							
								
								
									
										40
									
								
								node_modules/undici/lib/fetch/global.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								node_modules/undici/lib/fetch/global.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,40 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
// In case of breaking changes, increase the version
 | 
			
		||||
// number to avoid conflicts.
 | 
			
		||||
const globalOrigin = Symbol.for('undici.globalOrigin.1')
 | 
			
		||||
 | 
			
		||||
function getGlobalOrigin () {
 | 
			
		||||
  return globalThis[globalOrigin]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function setGlobalOrigin (newOrigin) {
 | 
			
		||||
  if (newOrigin === undefined) {
 | 
			
		||||
    Object.defineProperty(globalThis, globalOrigin, {
 | 
			
		||||
      value: undefined,
 | 
			
		||||
      writable: true,
 | 
			
		||||
      enumerable: false,
 | 
			
		||||
      configurable: false
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    return
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const parsedURL = new URL(newOrigin)
 | 
			
		||||
 | 
			
		||||
  if (parsedURL.protocol !== 'http:' && parsedURL.protocol !== 'https:') {
 | 
			
		||||
    throw new TypeError(`Only http & https urls are allowed, received ${parsedURL.protocol}`)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Object.defineProperty(globalThis, globalOrigin, {
 | 
			
		||||
    value: parsedURL,
 | 
			
		||||
    writable: true,
 | 
			
		||||
    enumerable: false,
 | 
			
		||||
    configurable: false
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
  getGlobalOrigin,
 | 
			
		||||
  setGlobalOrigin
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										589
									
								
								node_modules/undici/lib/fetch/headers.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										589
									
								
								node_modules/undici/lib/fetch/headers.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,589 @@
 | 
			
		|||
// https://github.com/Ethan-Arrowood/undici-fetch
 | 
			
		||||
 | 
			
		||||
'use strict'
 | 
			
		||||
 | 
			
		||||
const { kHeadersList, kConstruct } = require('../core/symbols')
 | 
			
		||||
const { kGuard } = require('./symbols')
 | 
			
		||||
const { kEnumerableProperty } = require('../core/util')
 | 
			
		||||
const {
 | 
			
		||||
  makeIterator,
 | 
			
		||||
  isValidHeaderName,
 | 
			
		||||
  isValidHeaderValue
 | 
			
		||||
} = require('./util')
 | 
			
		||||
const { webidl } = require('./webidl')
 | 
			
		||||
const assert = require('assert')
 | 
			
		||||
 | 
			
		||||
const kHeadersMap = Symbol('headers map')
 | 
			
		||||
const kHeadersSortedMap = Symbol('headers map sorted')
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @param {number} code
 | 
			
		||||
 */
 | 
			
		||||
function isHTTPWhiteSpaceCharCode (code) {
 | 
			
		||||
  return code === 0x00a || code === 0x00d || code === 0x009 || code === 0x020
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @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.
 | 
			
		||||
  let i = 0; let j = potentialValue.length
 | 
			
		||||
 | 
			
		||||
  while (j > i && isHTTPWhiteSpaceCharCode(potentialValue.charCodeAt(j - 1))) --j
 | 
			
		||||
  while (j > i && isHTTPWhiteSpaceCharCode(potentialValue.charCodeAt(i))) ++i
 | 
			
		||||
 | 
			
		||||
  return i === 0 && j === potentialValue.length ? potentialValue : potentialValue.substring(i, j)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 (let i = 0; i < object.length; ++i) {
 | 
			
		||||
      const header = object[i]
 | 
			
		||||
      // 1. If header does not contain exactly two items, then throw a TypeError.
 | 
			
		||||
      if (header.length !== 2) {
 | 
			
		||||
        throw 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.
 | 
			
		||||
      appendHeader(headers, 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
 | 
			
		||||
    const keys = Object.keys(object)
 | 
			
		||||
    for (let i = 0; i < keys.length; ++i) {
 | 
			
		||||
      appendHeader(headers, keys[i], object[keys[i]])
 | 
			
		||||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
    throw webidl.errors.conversionFailed({
 | 
			
		||||
      prefix: 'Headers constructor',
 | 
			
		||||
      argument: 'Argument 1',
 | 
			
		||||
      types: ['sequence<sequence<ByteString>>', 'record<ByteString, ByteString>']
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @see https://fetch.spec.whatwg.org/#concept-headers-append
 | 
			
		||||
 */
 | 
			
		||||
function appendHeader (headers, name, 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)) {
 | 
			
		||||
    throw webidl.errors.invalidArgument({
 | 
			
		||||
      prefix: 'Headers.append',
 | 
			
		||||
      value: name,
 | 
			
		||||
      type: 'header name'
 | 
			
		||||
    })
 | 
			
		||||
  } else if (!isValidHeaderValue(value)) {
 | 
			
		||||
    throw 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 (headers[kGuard] === 'immutable') {
 | 
			
		||||
    throw new TypeError('immutable')
 | 
			
		||||
  } else if (headers[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.
 | 
			
		||||
  return headers[kHeadersList].append(name, value)
 | 
			
		||||
 | 
			
		||||
  // 8. If headers’s guard is "request-no-cors", then remove
 | 
			
		||||
  //    privileged no-CORS request headers from headers
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class HeadersList {
 | 
			
		||||
  /** @type {[string, string][]|null} */
 | 
			
		||||
  cookies = null
 | 
			
		||||
 | 
			
		||||
  constructor (init) {
 | 
			
		||||
    if (init instanceof HeadersList) {
 | 
			
		||||
      this[kHeadersMap] = new Map(init[kHeadersMap])
 | 
			
		||||
      this[kHeadersSortedMap] = init[kHeadersSortedMap]
 | 
			
		||||
      this.cookies = init.cookies === null ? null : [...init.cookies]
 | 
			
		||||
    } 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
 | 
			
		||||
    this.cookies = 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.
 | 
			
		||||
    const lowercaseName = name.toLowerCase()
 | 
			
		||||
    const exists = this[kHeadersMap].get(lowercaseName)
 | 
			
		||||
 | 
			
		||||
    // 2. Append (name, value) to list.
 | 
			
		||||
    if (exists) {
 | 
			
		||||
      const delimiter = lowercaseName === 'cookie' ? '; ' : ', '
 | 
			
		||||
      this[kHeadersMap].set(lowercaseName, {
 | 
			
		||||
        name: exists.name,
 | 
			
		||||
        value: `${exists.value}${delimiter}${value}`
 | 
			
		||||
      })
 | 
			
		||||
    } else {
 | 
			
		||||
      this[kHeadersMap].set(lowercaseName, { name, value })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (lowercaseName === 'set-cookie') {
 | 
			
		||||
      this.cookies ??= []
 | 
			
		||||
      this.cookies.push(value)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // https://fetch.spec.whatwg.org/#concept-header-list-set
 | 
			
		||||
  set (name, value) {
 | 
			
		||||
    this[kHeadersSortedMap] = null
 | 
			
		||||
    const lowercaseName = name.toLowerCase()
 | 
			
		||||
 | 
			
		||||
    if (lowercaseName === 'set-cookie') {
 | 
			
		||||
      this.cookies = [value]
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 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.
 | 
			
		||||
    this[kHeadersMap].set(lowercaseName, { name, value })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // https://fetch.spec.whatwg.org/#concept-header-list-delete
 | 
			
		||||
  delete (name) {
 | 
			
		||||
    this[kHeadersSortedMap] = null
 | 
			
		||||
 | 
			
		||||
    name = name.toLowerCase()
 | 
			
		||||
 | 
			
		||||
    if (name === 'set-cookie') {
 | 
			
		||||
      this.cookies = null
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this[kHeadersMap].delete(name)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // https://fetch.spec.whatwg.org/#concept-header-list-get
 | 
			
		||||
  get (name) {
 | 
			
		||||
    const value = this[kHeadersMap].get(name.toLowerCase())
 | 
			
		||||
 | 
			
		||||
    // 1. If list does not contain name, then 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 value === undefined ? null : value.value
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  * [Symbol.iterator] () {
 | 
			
		||||
    // use the lowercased name
 | 
			
		||||
    for (const [name, { value }] of this[kHeadersMap]) {
 | 
			
		||||
      yield [name, value]
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get entries () {
 | 
			
		||||
    const headers = {}
 | 
			
		||||
 | 
			
		||||
    if (this[kHeadersMap].size) {
 | 
			
		||||
      for (const { name, value } of this[kHeadersMap].values()) {
 | 
			
		||||
        headers[name] = value
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return headers
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// https://fetch.spec.whatwg.org/#headers-class
 | 
			
		||||
class Headers {
 | 
			
		||||
  constructor (init = undefined) {
 | 
			
		||||
    if (init === kConstruct) {
 | 
			
		||||
      return
 | 
			
		||||
    }
 | 
			
		||||
    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)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // https://fetch.spec.whatwg.org/#dom-headers-append
 | 
			
		||||
  append (name, value) {
 | 
			
		||||
    webidl.brandCheck(this, Headers)
 | 
			
		||||
 | 
			
		||||
    webidl.argumentLengthCheck(arguments, 2, { header: 'Headers.append' })
 | 
			
		||||
 | 
			
		||||
    name = webidl.converters.ByteString(name)
 | 
			
		||||
    value = webidl.converters.ByteString(value)
 | 
			
		||||
 | 
			
		||||
    return appendHeader(this, name, value)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // https://fetch.spec.whatwg.org/#dom-headers-delete
 | 
			
		||||
  delete (name) {
 | 
			
		||||
    webidl.brandCheck(this, Headers)
 | 
			
		||||
 | 
			
		||||
    webidl.argumentLengthCheck(arguments, 1, { header: 'Headers.delete' })
 | 
			
		||||
 | 
			
		||||
    name = webidl.converters.ByteString(name)
 | 
			
		||||
 | 
			
		||||
    // 1. If name is not a header name, then throw a TypeError.
 | 
			
		||||
    if (!isValidHeaderName(name)) {
 | 
			
		||||
      throw 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.
 | 
			
		||||
    this[kHeadersList].delete(name)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // https://fetch.spec.whatwg.org/#dom-headers-get
 | 
			
		||||
  get (name) {
 | 
			
		||||
    webidl.brandCheck(this, Headers)
 | 
			
		||||
 | 
			
		||||
    webidl.argumentLengthCheck(arguments, 1, { header: 'Headers.get' })
 | 
			
		||||
 | 
			
		||||
    name = webidl.converters.ByteString(name)
 | 
			
		||||
 | 
			
		||||
    // 1. If name is not a header name, then throw a TypeError.
 | 
			
		||||
    if (!isValidHeaderName(name)) {
 | 
			
		||||
      throw 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) {
 | 
			
		||||
    webidl.brandCheck(this, Headers)
 | 
			
		||||
 | 
			
		||||
    webidl.argumentLengthCheck(arguments, 1, { header: 'Headers.has' })
 | 
			
		||||
 | 
			
		||||
    name = webidl.converters.ByteString(name)
 | 
			
		||||
 | 
			
		||||
    // 1. If name is not a header name, then throw a TypeError.
 | 
			
		||||
    if (!isValidHeaderName(name)) {
 | 
			
		||||
      throw 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) {
 | 
			
		||||
    webidl.brandCheck(this, Headers)
 | 
			
		||||
 | 
			
		||||
    webidl.argumentLengthCheck(arguments, 2, { header: 'Headers.set' })
 | 
			
		||||
 | 
			
		||||
    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)) {
 | 
			
		||||
      throw webidl.errors.invalidArgument({
 | 
			
		||||
        prefix: 'Headers.set',
 | 
			
		||||
        value: name,
 | 
			
		||||
        type: 'header name'
 | 
			
		||||
      })
 | 
			
		||||
    } else if (!isValidHeaderValue(value)) {
 | 
			
		||||
      throw 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
 | 
			
		||||
    this[kHeadersList].set(name, value)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // https://fetch.spec.whatwg.org/#dom-headers-getsetcookie
 | 
			
		||||
  getSetCookie () {
 | 
			
		||||
    webidl.brandCheck(this, Headers)
 | 
			
		||||
 | 
			
		||||
    // 1. If this’s header list does not contain `Set-Cookie`, then return « ».
 | 
			
		||||
    // 2. Return the values of all headers in this’s header list whose name is
 | 
			
		||||
    //    a byte-case-insensitive match for `Set-Cookie`, in order.
 | 
			
		||||
 | 
			
		||||
    const list = this[kHeadersList].cookies
 | 
			
		||||
 | 
			
		||||
    if (list) {
 | 
			
		||||
      return [...list]
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return []
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // https://fetch.spec.whatwg.org/#concept-header-list-sort-and-combine
 | 
			
		||||
  get [kHeadersSortedMap] () {
 | 
			
		||||
    if (this[kHeadersList][kHeadersSortedMap]) {
 | 
			
		||||
      return this[kHeadersList][kHeadersSortedMap]
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 1. Let headers be an empty list of headers with the key being the name
 | 
			
		||||
    //    and value the value.
 | 
			
		||||
    const headers = []
 | 
			
		||||
 | 
			
		||||
    // 2. Let names be the result of convert header names to a sorted-lowercase
 | 
			
		||||
    //    set with all the names of the headers in list.
 | 
			
		||||
    const names = [...this[kHeadersList]].sort((a, b) => a[0] < b[0] ? -1 : 1)
 | 
			
		||||
    const cookies = this[kHeadersList].cookies
 | 
			
		||||
 | 
			
		||||
    // 3. For each name of names:
 | 
			
		||||
    for (let i = 0; i < names.length; ++i) {
 | 
			
		||||
      const [name, value] = names[i]
 | 
			
		||||
      // 1. If name is `set-cookie`, then:
 | 
			
		||||
      if (name === 'set-cookie') {
 | 
			
		||||
        // 1. Let values be a list of all values of headers in list whose name
 | 
			
		||||
        //    is a byte-case-insensitive match for name, in order.
 | 
			
		||||
 | 
			
		||||
        // 2. For each value of values:
 | 
			
		||||
        // 1. Append (name, value) to headers.
 | 
			
		||||
        for (let j = 0; j < cookies.length; ++j) {
 | 
			
		||||
          headers.push([name, cookies[j]])
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        // 2. Otherwise:
 | 
			
		||||
 | 
			
		||||
        // 1. Let value be the result of getting name from list.
 | 
			
		||||
 | 
			
		||||
        // 2. Assert: value is non-null.
 | 
			
		||||
        assert(value !== null)
 | 
			
		||||
 | 
			
		||||
        // 3. Append (name, value) to headers.
 | 
			
		||||
        headers.push([name, value])
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this[kHeadersList][kHeadersSortedMap] = headers
 | 
			
		||||
 | 
			
		||||
    // 4. Return headers.
 | 
			
		||||
    return headers
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  keys () {
 | 
			
		||||
    webidl.brandCheck(this, Headers)
 | 
			
		||||
 | 
			
		||||
    if (this[kGuard] === 'immutable') {
 | 
			
		||||
      const value = this[kHeadersSortedMap]
 | 
			
		||||
      return makeIterator(() => value, 'Headers',
 | 
			
		||||
        'key')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return makeIterator(
 | 
			
		||||
      () => [...this[kHeadersSortedMap].values()],
 | 
			
		||||
      'Headers',
 | 
			
		||||
      'key'
 | 
			
		||||
    )
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  values () {
 | 
			
		||||
    webidl.brandCheck(this, Headers)
 | 
			
		||||
 | 
			
		||||
    if (this[kGuard] === 'immutable') {
 | 
			
		||||
      const value = this[kHeadersSortedMap]
 | 
			
		||||
      return makeIterator(() => value, 'Headers',
 | 
			
		||||
        'value')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return makeIterator(
 | 
			
		||||
      () => [...this[kHeadersSortedMap].values()],
 | 
			
		||||
      'Headers',
 | 
			
		||||
      'value'
 | 
			
		||||
    )
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  entries () {
 | 
			
		||||
    webidl.brandCheck(this, Headers)
 | 
			
		||||
 | 
			
		||||
    if (this[kGuard] === 'immutable') {
 | 
			
		||||
      const value = this[kHeadersSortedMap]
 | 
			
		||||
      return makeIterator(() => value, 'Headers',
 | 
			
		||||
        'key+value')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return makeIterator(
 | 
			
		||||
      () => [...this[kHeadersSortedMap].values()],
 | 
			
		||||
      'Headers',
 | 
			
		||||
      'key+value'
 | 
			
		||||
    )
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @param {(value: string, key: string, self: Headers) => void} callbackFn
 | 
			
		||||
   * @param {unknown} thisArg
 | 
			
		||||
   */
 | 
			
		||||
  forEach (callbackFn, thisArg = globalThis) {
 | 
			
		||||
    webidl.brandCheck(this, Headers)
 | 
			
		||||
 | 
			
		||||
    webidl.argumentLengthCheck(arguments, 1, { header: 'Headers.forEach' })
 | 
			
		||||
 | 
			
		||||
    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')] () {
 | 
			
		||||
    webidl.brandCheck(this, Headers)
 | 
			
		||||
 | 
			
		||||
    return this[kHeadersList]
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Headers.prototype[Symbol.iterator] = Headers.prototype.entries
 | 
			
		||||
 | 
			
		||||
Object.defineProperties(Headers.prototype, {
 | 
			
		||||
  append: kEnumerableProperty,
 | 
			
		||||
  delete: kEnumerableProperty,
 | 
			
		||||
  get: kEnumerableProperty,
 | 
			
		||||
  has: kEnumerableProperty,
 | 
			
		||||
  set: kEnumerableProperty,
 | 
			
		||||
  getSetCookie: kEnumerableProperty,
 | 
			
		||||
  keys: kEnumerableProperty,
 | 
			
		||||
  values: kEnumerableProperty,
 | 
			
		||||
  entries: kEnumerableProperty,
 | 
			
		||||
  forEach: kEnumerableProperty,
 | 
			
		||||
  [Symbol.iterator]: { enumerable: false },
 | 
			
		||||
  [Symbol.toStringTag]: {
 | 
			
		||||
    value: 'Headers',
 | 
			
		||||
    configurable: true
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
webidl.converters.HeadersInit = function (V) {
 | 
			
		||||
  if (webidl.util.Type(V) === 'Object') {
 | 
			
		||||
    if (V[Symbol.iterator]) {
 | 
			
		||||
      return webidl.converters['sequence<sequence<ByteString>>'](V)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return webidl.converters['record<ByteString, ByteString>'](V)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  throw webidl.errors.conversionFailed({
 | 
			
		||||
    prefix: 'Headers constructor',
 | 
			
		||||
    argument: 'Argument 1',
 | 
			
		||||
    types: ['sequence<sequence<ByteString>>', 'record<ByteString, ByteString>']
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
  fill,
 | 
			
		||||
  Headers,
 | 
			
		||||
  HeadersList
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										2145
									
								
								node_modules/undici/lib/fetch/index.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2145
									
								
								node_modules/undici/lib/fetch/index.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										946
									
								
								node_modules/undici/lib/fetch/request.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										946
									
								
								node_modules/undici/lib/fetch/request.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,946 @@
 | 
			
		|||
/* globals AbortController */
 | 
			
		||||
 | 
			
		||||
'use strict'
 | 
			
		||||
 | 
			
		||||
const { extractBody, mixinBody, cloneBody } = require('./body')
 | 
			
		||||
const { Headers, fill: fillHeaders, HeadersList } = require('./headers')
 | 
			
		||||
const { FinalizationRegistry } = require('../compat/dispatcher-weakref')()
 | 
			
		||||
const util = require('../core/util')
 | 
			
		||||
const {
 | 
			
		||||
  isValidHTTPToken,
 | 
			
		||||
  sameOrigin,
 | 
			
		||||
  normalizeMethod,
 | 
			
		||||
  makePolicyContainer,
 | 
			
		||||
  normalizeMethodRecord
 | 
			
		||||
} = require('./util')
 | 
			
		||||
const {
 | 
			
		||||
  forbiddenMethodsSet,
 | 
			
		||||
  corsSafeListedMethodsSet,
 | 
			
		||||
  referrerPolicy,
 | 
			
		||||
  requestRedirect,
 | 
			
		||||
  requestMode,
 | 
			
		||||
  requestCredentials,
 | 
			
		||||
  requestCache,
 | 
			
		||||
  requestDuplex
 | 
			
		||||
} = require('./constants')
 | 
			
		||||
const { kEnumerableProperty } = util
 | 
			
		||||
const { kHeaders, kSignal, kState, kGuard, kRealm } = require('./symbols')
 | 
			
		||||
const { webidl } = require('./webidl')
 | 
			
		||||
const { getGlobalOrigin } = require('./global')
 | 
			
		||||
const { URLSerializer } = require('./dataURL')
 | 
			
		||||
const { kHeadersList, kConstruct } = require('../core/symbols')
 | 
			
		||||
const assert = require('assert')
 | 
			
		||||
const { getMaxListeners, setMaxListeners, getEventListeners, defaultMaxListeners } = require('events')
 | 
			
		||||
 | 
			
		||||
let TransformStream = globalThis.TransformStream
 | 
			
		||||
 | 
			
		||||
const kAbortController = Symbol('abortController')
 | 
			
		||||
 | 
			
		||||
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 === kConstruct) {
 | 
			
		||||
      return
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    webidl.argumentLengthCheck(arguments, 1, { header: 'Request constructor' })
 | 
			
		||||
 | 
			
		||||
    input = webidl.converters.RequestInfo(input)
 | 
			
		||||
    init = webidl.converters.RequestInit(init)
 | 
			
		||||
 | 
			
		||||
    // https://html.spec.whatwg.org/multipage/webappapis.html#environment-settings-object
 | 
			
		||||
    this[kRealm] = {
 | 
			
		||||
      settingsObject: {
 | 
			
		||||
        baseUrl: getGlobalOrigin(),
 | 
			
		||||
        get origin () {
 | 
			
		||||
          return this.baseUrl?.origin
 | 
			
		||||
        },
 | 
			
		||||
        policyContainer: makePolicyContainer()
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 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 != null) {
 | 
			
		||||
      throw new TypeError(`'window' option '${window}' must be null`)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 11. If init["window"] exists, then set window to "no-window".
 | 
			
		||||
    if ('window' in init) {
 | 
			
		||||
      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]
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    const initHasKey = Object.keys(init).length !== 0
 | 
			
		||||
 | 
			
		||||
    // 13. If init is not empty, then:
 | 
			
		||||
    if (initHasKey) {
 | 
			
		||||
      // 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 scheme is "about" and path is the string "client"
 | 
			
		||||
        // - parsedReferrer’s origin is not same origin with origin
 | 
			
		||||
        // then set request’s referrer to "client".
 | 
			
		||||
        if (
 | 
			
		||||
          (parsedReferrer.protocol === 'about:' && parsedReferrer.hostname === 'client') ||
 | 
			
		||||
          (origin && !sameOrigin(parsedReferrer, this[kRealm].settingsObject.baseUrl))
 | 
			
		||||
        ) {
 | 
			
		||||
          request.referrer = 'client'
 | 
			
		||||
        } else {
 | 
			
		||||
          // 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
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 16. Let mode be init["mode"] if it exists, and fallbackMode otherwise.
 | 
			
		||||
    let mode
 | 
			
		||||
    if (init.mode !== undefined) {
 | 
			
		||||
      mode = init.mode
 | 
			
		||||
    } else {
 | 
			
		||||
      mode = fallbackMode
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 17. If mode is "navigate", then throw a TypeError.
 | 
			
		||||
    if (mode === 'navigate') {
 | 
			
		||||
      throw 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
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 18. If init["cache"] exists, then set request’s cache mode to it.
 | 
			
		||||
    if (init.cache !== undefined) {
 | 
			
		||||
      request.cache = init.cache
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 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
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 23. If init["integrity"] exists, then set request’s integrity metadata to it.
 | 
			
		||||
    if (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(method)) {
 | 
			
		||||
        throw new TypeError(`'${method}' is not a valid HTTP method.`)
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (forbiddenMethodsSet.has(method.toUpperCase())) {
 | 
			
		||||
        throw new TypeError(`'${method}' HTTP method is unsupported.`)
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // 3. Normalize method.
 | 
			
		||||
      method = normalizeMethodRecord[method] ?? normalizeMethod(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.
 | 
			
		||||
    // TODO: could this be simplified with AbortSignal.any
 | 
			
		||||
    // (https://dom.spec.whatwg.org/#dom-abortsignal-any)
 | 
			
		||||
    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(signal.reason)
 | 
			
		||||
      } else {
 | 
			
		||||
        // Keep a strong ref to ac while request object
 | 
			
		||||
        // is alive. This is needed to prevent AbortController
 | 
			
		||||
        // from being prematurely garbage collected.
 | 
			
		||||
        // See, https://github.com/nodejs/undici/issues/1926.
 | 
			
		||||
        this[kAbortController] = ac
 | 
			
		||||
 | 
			
		||||
        const acRef = new WeakRef(ac)
 | 
			
		||||
        const abort = function () {
 | 
			
		||||
          const ac = acRef.deref()
 | 
			
		||||
          if (ac !== undefined) {
 | 
			
		||||
            ac.abort(this.reason)
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Third-party AbortControllers may not work with these.
 | 
			
		||||
        // See, https://github.com/nodejs/undici/pull/1910#issuecomment-1464495619.
 | 
			
		||||
        try {
 | 
			
		||||
          // If the max amount of listeners is equal to the default, increase it
 | 
			
		||||
          // This is only available in node >= v19.9.0
 | 
			
		||||
          if (typeof getMaxListeners === 'function' && getMaxListeners(signal) === defaultMaxListeners) {
 | 
			
		||||
            setMaxListeners(100, signal)
 | 
			
		||||
          } else if (getEventListeners(signal, 'abort').length >= defaultMaxListeners) {
 | 
			
		||||
            setMaxListeners(100, signal)
 | 
			
		||||
          }
 | 
			
		||||
        } catch {}
 | 
			
		||||
 | 
			
		||||
        util.addAbortListener(signal, abort)
 | 
			
		||||
        requestFinalizer.register(ac, { 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(kConstruct)
 | 
			
		||||
    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 (!corsSafeListedMethodsSet.has(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 (initHasKey) {
 | 
			
		||||
      /** @type {HeadersList} */
 | 
			
		||||
      const headersList = this[kHeaders][kHeadersList]
 | 
			
		||||
      // 1. Let headers be a copy of this’s headers and its associated header
 | 
			
		||||
      // list.
 | 
			
		||||
      // 2. If init["headers"] exists, then set headers to init["headers"].
 | 
			
		||||
      const headers = init.headers !== undefined ? init.headers : new HeadersList(headersList)
 | 
			
		||||
 | 
			
		||||
      // 3. Empty this’s headers’s header list.
 | 
			
		||||
      headersList.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 instanceof HeadersList) {
 | 
			
		||||
        for (const [key, val] of headers) {
 | 
			
		||||
          headersList.append(key, val)
 | 
			
		||||
        }
 | 
			
		||||
        // Note: Copy the `set-cookie` meta-data.
 | 
			
		||||
        headersList.cookies = headers.cookies
 | 
			
		||||
      } 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 != 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 != 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][kHeadersList].contains('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 initBody is non-null and init["duplex"] does not exist,
 | 
			
		||||
      //    then throw a TypeError.
 | 
			
		||||
      if (initBody != null && init.duplex == null) {
 | 
			
		||||
        throw new TypeError('RequestInit: duplex option is required when sending a body.')
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // 2. 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"'
 | 
			
		||||
        )
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // 3. 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
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Returns request’s HTTP method, which is "GET" by default.
 | 
			
		||||
  get method () {
 | 
			
		||||
    webidl.brandCheck(this, Request)
 | 
			
		||||
 | 
			
		||||
    // 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 () {
 | 
			
		||||
    webidl.brandCheck(this, Request)
 | 
			
		||||
 | 
			
		||||
    // The url getter steps are to return this’s request’s URL, serialized.
 | 
			
		||||
    return URLSerializer(this[kState].url)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // 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 () {
 | 
			
		||||
    webidl.brandCheck(this, Request)
 | 
			
		||||
 | 
			
		||||
    // 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 () {
 | 
			
		||||
    webidl.brandCheck(this, Request)
 | 
			
		||||
 | 
			
		||||
    // 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 () {
 | 
			
		||||
    webidl.brandCheck(this, Request)
 | 
			
		||||
 | 
			
		||||
    // 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 () {
 | 
			
		||||
    webidl.brandCheck(this, Request)
 | 
			
		||||
 | 
			
		||||
    // 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 () {
 | 
			
		||||
    webidl.brandCheck(this, Request)
 | 
			
		||||
 | 
			
		||||
    // 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 () {
 | 
			
		||||
    webidl.brandCheck(this, Request)
 | 
			
		||||
 | 
			
		||||
    // 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 () {
 | 
			
		||||
    webidl.brandCheck(this, Request)
 | 
			
		||||
 | 
			
		||||
    // 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 () {
 | 
			
		||||
    webidl.brandCheck(this, Request)
 | 
			
		||||
 | 
			
		||||
    // 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 () {
 | 
			
		||||
    webidl.brandCheck(this, Request)
 | 
			
		||||
 | 
			
		||||
    // 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 () {
 | 
			
		||||
    webidl.brandCheck(this, Request)
 | 
			
		||||
 | 
			
		||||
    // 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 () {
 | 
			
		||||
    webidl.brandCheck(this, Request)
 | 
			
		||||
 | 
			
		||||
    // 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 () {
 | 
			
		||||
    webidl.brandCheck(this, Request)
 | 
			
		||||
 | 
			
		||||
    // The signal getter steps are to return this’s signal.
 | 
			
		||||
    return this[kSignal]
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get body () {
 | 
			
		||||
    webidl.brandCheck(this, Request)
 | 
			
		||||
 | 
			
		||||
    return this[kState].body ? this[kState].body.stream : null
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get bodyUsed () {
 | 
			
		||||
    webidl.brandCheck(this, Request)
 | 
			
		||||
 | 
			
		||||
    return !!this[kState].body && util.isDisturbed(this[kState].body.stream)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get duplex () {
 | 
			
		||||
    webidl.brandCheck(this, Request)
 | 
			
		||||
 | 
			
		||||
    return 'half'
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Returns a clone of request.
 | 
			
		||||
  clone () {
 | 
			
		||||
    webidl.brandCheck(this, Request)
 | 
			
		||||
 | 
			
		||||
    // 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(kConstruct)
 | 
			
		||||
    clonedRequestObject[kState] = clonedRequest
 | 
			
		||||
    clonedRequestObject[kRealm] = this[kRealm]
 | 
			
		||||
    clonedRequestObject[kHeaders] = new Headers(kConstruct)
 | 
			
		||||
    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(this.signal.reason)
 | 
			
		||||
    } else {
 | 
			
		||||
      util.addAbortListener(
 | 
			
		||||
        this.signal,
 | 
			
		||||
        () => {
 | 
			
		||||
          ac.abort(this.signal.reason)
 | 
			
		||||
        }
 | 
			
		||||
      )
 | 
			
		||||
    }
 | 
			
		||||
    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,
 | 
			
		||||
  duplex: kEnumerableProperty,
 | 
			
		||||
  destination: kEnumerableProperty,
 | 
			
		||||
  body: kEnumerableProperty,
 | 
			
		||||
  bodyUsed: kEnumerableProperty,
 | 
			
		||||
  isHistoryNavigation: kEnumerableProperty,
 | 
			
		||||
  isReloadNavigation: kEnumerableProperty,
 | 
			
		||||
  keepalive: kEnumerableProperty,
 | 
			
		||||
  integrity: kEnumerableProperty,
 | 
			
		||||
  cache: kEnumerableProperty,
 | 
			
		||||
  credentials: kEnumerableProperty,
 | 
			
		||||
  attribute: kEnumerableProperty,
 | 
			
		||||
  referrerPolicy: kEnumerableProperty,
 | 
			
		||||
  referrer: kEnumerableProperty,
 | 
			
		||||
  mode: kEnumerableProperty,
 | 
			
		||||
  [Symbol.toStringTag]: {
 | 
			
		||||
    value: 'Request',
 | 
			
		||||
    configurable: true
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
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: referrerPolicy
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    key: 'mode',
 | 
			
		||||
    converter: webidl.converters.DOMString,
 | 
			
		||||
    // https://fetch.spec.whatwg.org/#concept-request-mode
 | 
			
		||||
    allowedValues: requestMode
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    key: 'credentials',
 | 
			
		||||
    converter: webidl.converters.DOMString,
 | 
			
		||||
    // https://fetch.spec.whatwg.org/#requestcredentials
 | 
			
		||||
    allowedValues: requestCredentials
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    key: 'cache',
 | 
			
		||||
    converter: webidl.converters.DOMString,
 | 
			
		||||
    // https://fetch.spec.whatwg.org/#requestcache
 | 
			
		||||
    allowedValues: requestCache
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    key: 'redirect',
 | 
			
		||||
    converter: webidl.converters.DOMString,
 | 
			
		||||
    // https://fetch.spec.whatwg.org/#requestredirect
 | 
			
		||||
    allowedValues: requestRedirect
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    key: 'integrity',
 | 
			
		||||
    converter: webidl.converters.DOMString
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    key: 'keepalive',
 | 
			
		||||
    converter: webidl.converters.boolean
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    key: 'signal',
 | 
			
		||||
    converter: webidl.nullableConverter(
 | 
			
		||||
      (signal) => webidl.converters.AbortSignal(
 | 
			
		||||
        signal,
 | 
			
		||||
        { strict: false }
 | 
			
		||||
      )
 | 
			
		||||
    )
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    key: 'window',
 | 
			
		||||
    converter: webidl.converters.any
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    key: 'duplex',
 | 
			
		||||
    converter: webidl.converters.DOMString,
 | 
			
		||||
    allowedValues: requestDuplex
 | 
			
		||||
  }
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
module.exports = { Request, makeRequest }
 | 
			
		||||
							
								
								
									
										571
									
								
								node_modules/undici/lib/fetch/response.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										571
									
								
								node_modules/undici/lib/fetch/response.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,571 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
const { Headers, HeadersList, fill } = require('./headers')
 | 
			
		||||
const { extractBody, cloneBody, mixinBody } = require('./body')
 | 
			
		||||
const util = require('../core/util')
 | 
			
		||||
const { kEnumerableProperty } = util
 | 
			
		||||
const {
 | 
			
		||||
  isValidReasonPhrase,
 | 
			
		||||
  isCancelled,
 | 
			
		||||
  isAborted,
 | 
			
		||||
  isBlobLike,
 | 
			
		||||
  serializeJavascriptValueToJSONString,
 | 
			
		||||
  isErrorLike,
 | 
			
		||||
  isomorphicEncode
 | 
			
		||||
} = require('./util')
 | 
			
		||||
const {
 | 
			
		||||
  redirectStatusSet,
 | 
			
		||||
  nullBodyStatus,
 | 
			
		||||
  DOMException
 | 
			
		||||
} = require('./constants')
 | 
			
		||||
const { kState, kHeaders, kGuard, kRealm } = require('./symbols')
 | 
			
		||||
const { webidl } = require('./webidl')
 | 
			
		||||
const { FormData } = require('./formdata')
 | 
			
		||||
const { getGlobalOrigin } = require('./global')
 | 
			
		||||
const { URLSerializer } = require('./dataURL')
 | 
			
		||||
const { kHeadersList, kConstruct } = require('../core/symbols')
 | 
			
		||||
const assert = require('assert')
 | 
			
		||||
const { types } = require('util')
 | 
			
		||||
 | 
			
		||||
const ReadableStream = globalThis.ReadableStream || require('stream/web').ReadableStream
 | 
			
		||||
const textEncoder = new TextEncoder('utf-8')
 | 
			
		||||
 | 
			
		||||
// 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 = {}) {
 | 
			
		||||
    webidl.argumentLengthCheck(arguments, 1, { header: 'Response.json' })
 | 
			
		||||
 | 
			
		||||
    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 = textEncoder.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: {} }
 | 
			
		||||
 | 
			
		||||
    webidl.argumentLengthCheck(arguments, 1, { header: 'Response.redirect' })
 | 
			
		||||
 | 
			
		||||
    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, getGlobalOrigin())
 | 
			
		||||
    } 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 (!redirectStatusSet.has(status)) {
 | 
			
		||||
      throw new RangeError('Invalid status code ' + status)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 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.
 | 
			
		||||
    const value = isomorphicEncode(URLSerializer(parsedURL))
 | 
			
		||||
 | 
			
		||||
    // 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(kConstruct)
 | 
			
		||||
    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)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Returns response’s type, e.g., "cors".
 | 
			
		||||
  get type () {
 | 
			
		||||
    webidl.brandCheck(this, Response)
 | 
			
		||||
 | 
			
		||||
    // 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 () {
 | 
			
		||||
    webidl.brandCheck(this, Response)
 | 
			
		||||
 | 
			
		||||
    const urlList = this[kState].urlList
 | 
			
		||||
 | 
			
		||||
    // 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.
 | 
			
		||||
    const url = urlList[urlList.length - 1] ?? null
 | 
			
		||||
 | 
			
		||||
    if (url === null) {
 | 
			
		||||
      return ''
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return URLSerializer(url, true)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Returns whether response was obtained through a redirect.
 | 
			
		||||
  get redirected () {
 | 
			
		||||
    webidl.brandCheck(this, Response)
 | 
			
		||||
 | 
			
		||||
    // 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 () {
 | 
			
		||||
    webidl.brandCheck(this, Response)
 | 
			
		||||
 | 
			
		||||
    // 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 () {
 | 
			
		||||
    webidl.brandCheck(this, Response)
 | 
			
		||||
 | 
			
		||||
    // 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 () {
 | 
			
		||||
    webidl.brandCheck(this, Response)
 | 
			
		||||
 | 
			
		||||
    // 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 () {
 | 
			
		||||
    webidl.brandCheck(this, Response)
 | 
			
		||||
 | 
			
		||||
    // The headers getter steps are to return this’s headers.
 | 
			
		||||
    return this[kHeaders]
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get body () {
 | 
			
		||||
    webidl.brandCheck(this, Response)
 | 
			
		||||
 | 
			
		||||
    return this[kState].body ? this[kState].body.stream : null
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get bodyUsed () {
 | 
			
		||||
    webidl.brandCheck(this, Response)
 | 
			
		||||
 | 
			
		||||
    return !!this[kState].body && util.isDisturbed(this[kState].body.stream)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Returns a clone of response.
 | 
			
		||||
  clone () {
 | 
			
		||||
    webidl.brandCheck(this, Response)
 | 
			
		||||
 | 
			
		||||
    // 1. If this is unusable, then throw a TypeError.
 | 
			
		||||
    if (this.bodyUsed || (this.body && this.body.locked)) {
 | 
			
		||||
      throw 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,
 | 
			
		||||
  body: kEnumerableProperty,
 | 
			
		||||
  bodyUsed: kEnumerableProperty,
 | 
			
		||||
  [Symbol.toStringTag]: {
 | 
			
		||||
    value: 'Response',
 | 
			
		||||
    configurable: true
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
Object.defineProperties(Response, {
 | 
			
		||||
  json: kEnumerableProperty,
 | 
			
		||||
  redirect: kEnumerableProperty,
 | 
			
		||||
  error: 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) {
 | 
			
		||||
  const isError = isErrorLike(reason)
 | 
			
		||||
  return makeResponse({
 | 
			
		||||
    type: 'error',
 | 
			
		||||
    status: 0,
 | 
			
		||||
    error: isError
 | 
			
		||||
      ? reason
 | 
			
		||||
      : new Error(reason ? String(reason) : reason),
 | 
			
		||||
    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, err = null) {
 | 
			
		||||
  // 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(Object.assign(new DOMException('The operation was aborted.', 'AbortError'), { cause: err }))
 | 
			
		||||
    : makeNetworkError(Object.assign(new DOMException('Request was cancelled.'), { cause: err }))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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[kHeaders], 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)) {
 | 
			
		||||
      throw webidl.errors.exception({
 | 
			
		||||
        header: 'Response constructor',
 | 
			
		||||
        message: 'Invalid response status code ' + response.status
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 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.contains('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, { strict: false })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (types.isArrayBuffer(V) || types.isTypedArray(V) || types.isDataView(V)) {
 | 
			
		||||
    return webidl.converters.BufferSource(V)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (util.isFormDataLike(V)) {
 | 
			
		||||
    return webidl.converters.FormData(V, { strict: false })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  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,
 | 
			
		||||
  cloneResponse
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										10
									
								
								node_modules/undici/lib/fetch/symbols.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								node_modules/undici/lib/fetch/symbols.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,10 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
  kUrl: Symbol('url'),
 | 
			
		||||
  kHeaders: Symbol('headers'),
 | 
			
		||||
  kSignal: Symbol('signal'),
 | 
			
		||||
  kState: Symbol('state'),
 | 
			
		||||
  kGuard: Symbol('guard'),
 | 
			
		||||
  kRealm: Symbol('realm')
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1071
									
								
								node_modules/undici/lib/fetch/util.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1071
									
								
								node_modules/undici/lib/fetch/util.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										646
									
								
								node_modules/undici/lib/fetch/webidl.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										646
									
								
								node_modules/undici/lib/fetch/webidl.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,646 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
const { types } = require('util')
 | 
			
		||||
const { hasOwn, toUSVString } = require('./util')
 | 
			
		||||
 | 
			
		||||
/** @type {import('../../types/webidl').Webidl} */
 | 
			
		||||
const webidl = {}
 | 
			
		||||
webidl.converters = {}
 | 
			
		||||
webidl.util = {}
 | 
			
		||||
webidl.errors = {}
 | 
			
		||||
 | 
			
		||||
webidl.errors.exception = function (message) {
 | 
			
		||||
  return new TypeError(`${message.header}: ${message.message}`)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
webidl.errors.invalidArgument = function (context) {
 | 
			
		||||
  return webidl.errors.exception({
 | 
			
		||||
    header: context.prefix,
 | 
			
		||||
    message: `"${context.value}" is an invalid ${context.type}.`
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// https://webidl.spec.whatwg.org/#implements
 | 
			
		||||
webidl.brandCheck = function (V, I, opts = undefined) {
 | 
			
		||||
  if (opts?.strict !== false && !(V instanceof I)) {
 | 
			
		||||
    throw new TypeError('Illegal invocation')
 | 
			
		||||
  } else {
 | 
			
		||||
    return V?.[Symbol.toStringTag] === I.prototype[Symbol.toStringTag]
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
webidl.argumentLengthCheck = function ({ length }, min, ctx) {
 | 
			
		||||
  if (length < min) {
 | 
			
		||||
    throw webidl.errors.exception({
 | 
			
		||||
      message: `${min} argument${min !== 1 ? 's' : ''} required, ` +
 | 
			
		||||
               `but${length ? ' only' : ''} ${length} found.`,
 | 
			
		||||
      ...ctx
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
webidl.illegalConstructor = function () {
 | 
			
		||||
  throw webidl.errors.exception({
 | 
			
		||||
    header: 'TypeError',
 | 
			
		||||
    message: 'Illegal constructor'
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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 (x === 0) {
 | 
			
		||||
    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
 | 
			
		||||
    ) {
 | 
			
		||||
      throw 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) {
 | 
			
		||||
      throw 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) ||
 | 
			
		||||
    (x === 0 && 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') {
 | 
			
		||||
      throw 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'
 | 
			
		||||
    ) {
 | 
			
		||||
      throw 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
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// https://webidl.spec.whatwg.org/#es-to-record
 | 
			
		||||
webidl.recordConverter = function (keyConverter, valueConverter) {
 | 
			
		||||
  return (O) => {
 | 
			
		||||
    // 1. If Type(O) is not Object, throw a TypeError.
 | 
			
		||||
    if (webidl.util.Type(O) !== 'Object') {
 | 
			
		||||
      throw webidl.errors.exception({
 | 
			
		||||
        header: 'Record',
 | 
			
		||||
        message: `Value of type ${webidl.util.Type(O)} is not an Object.`
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 2. Let result be a new empty instance of record<K, V>.
 | 
			
		||||
    const result = {}
 | 
			
		||||
 | 
			
		||||
    if (!types.isProxy(O)) {
 | 
			
		||||
      // Object.keys only returns enumerable properties
 | 
			
		||||
      const keys = Object.keys(O)
 | 
			
		||||
 | 
			
		||||
      for (const key of keys) {
 | 
			
		||||
        // 1. Let typedKey be key converted to an IDL value of type K.
 | 
			
		||||
        const typedKey = keyConverter(key)
 | 
			
		||||
 | 
			
		||||
        // 2. Let value be ? Get(O, key).
 | 
			
		||||
        // 3. Let typedValue be value converted to an IDL value of type V.
 | 
			
		||||
        const typedValue = valueConverter(O[key])
 | 
			
		||||
 | 
			
		||||
        // 4. Set result[typedKey] to typedValue.
 | 
			
		||||
        result[typedKey] = typedValue
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // 5. Return result.
 | 
			
		||||
      return result
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 3. Let keys be ? O.[[OwnPropertyKeys]]().
 | 
			
		||||
    const keys = Reflect.ownKeys(O)
 | 
			
		||||
 | 
			
		||||
    // 4. For each key of keys.
 | 
			
		||||
    for (const key of keys) {
 | 
			
		||||
      // 1. Let desc be ? O.[[GetOwnProperty]](key).
 | 
			
		||||
      const desc = Reflect.getOwnPropertyDescriptor(O, key)
 | 
			
		||||
 | 
			
		||||
      // 2. If desc is not undefined and desc.[[Enumerable]] is true:
 | 
			
		||||
      if (desc?.enumerable) {
 | 
			
		||||
        // 1. Let typedKey be key converted to an IDL value of type K.
 | 
			
		||||
        const typedKey = keyConverter(key)
 | 
			
		||||
 | 
			
		||||
        // 2. Let value be ? Get(O, key).
 | 
			
		||||
        // 3. Let typedValue be value converted to an IDL value of type V.
 | 
			
		||||
        const typedValue = valueConverter(O[key])
 | 
			
		||||
 | 
			
		||||
        // 4. Set result[typedKey] to typedValue.
 | 
			
		||||
        result[typedKey] = typedValue
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 5. Return result.
 | 
			
		||||
    return result
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
webidl.interfaceConverter = function (i) {
 | 
			
		||||
  return (V, opts = {}) => {
 | 
			
		||||
    if (opts.strict !== false && !(V instanceof i)) {
 | 
			
		||||
      throw webidl.errors.exception({
 | 
			
		||||
        header: i.name,
 | 
			
		||||
        message: `Expected ${V} to be an instance of ${i.name}.`
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return V
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
webidl.dictionaryConverter = function (converters) {
 | 
			
		||||
  return (dictionary) => {
 | 
			
		||||
    const type = webidl.util.Type(dictionary)
 | 
			
		||||
    const dict = {}
 | 
			
		||||
 | 
			
		||||
    if (type === 'Null' || type === 'Undefined') {
 | 
			
		||||
      return dict
 | 
			
		||||
    } else if (type !== 'Object') {
 | 
			
		||||
      throw 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 (!hasOwn(dictionary, key)) {
 | 
			
		||||
          throw webidl.errors.exception({
 | 
			
		||||
            header: 'Dictionary',
 | 
			
		||||
            message: `Missing required key "${key}".`
 | 
			
		||||
          })
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      let value = dictionary[key]
 | 
			
		||||
      const hasDefault = 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)
 | 
			
		||||
        ) {
 | 
			
		||||
          throw 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)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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.
 | 
			
		||||
  for (let index = 0; index < x.length; index++) {
 | 
			
		||||
    if (x.charCodeAt(index) > 255) {
 | 
			
		||||
      throw new TypeError(
 | 
			
		||||
        'Cannot convert argument to a ByteString because the character at ' +
 | 
			
		||||
        `index ${index} has a value of ${x.charCodeAt(index)} which is greater than 255.`
 | 
			
		||||
      )
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // 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
 | 
			
		||||
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) {
 | 
			
		||||
  // 1. Let x be ? ConvertToInt(V, 64, "signed").
 | 
			
		||||
  const x = webidl.util.ConvertToInt(V, 64, 'signed')
 | 
			
		||||
 | 
			
		||||
  // 2. Return the IDL long long value that represents
 | 
			
		||||
  //    the same numeric value as x.
 | 
			
		||||
  return x
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// https://webidl.spec.whatwg.org/#es-unsigned-long-long
 | 
			
		||||
webidl.converters['unsigned long long'] = function (V) {
 | 
			
		||||
  // 1. Let x be ? ConvertToInt(V, 64, "unsigned").
 | 
			
		||||
  const x = webidl.util.ConvertToInt(V, 64, 'unsigned')
 | 
			
		||||
 | 
			
		||||
  // 2. Return the IDL unsigned long long value that
 | 
			
		||||
  //    represents the same numeric value as x.
 | 
			
		||||
  return x
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// https://webidl.spec.whatwg.org/#es-unsigned-long
 | 
			
		||||
webidl.converters['unsigned long'] = function (V) {
 | 
			
		||||
  // 1. Let x be ? ConvertToInt(V, 32, "unsigned").
 | 
			
		||||
  const x = webidl.util.ConvertToInt(V, 32, 'unsigned')
 | 
			
		||||
 | 
			
		||||
  // 2. Return the IDL unsigned 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, opts) {
 | 
			
		||||
  // 1. Let x be ? ConvertToInt(V, 16, "unsigned").
 | 
			
		||||
  const x = webidl.util.ConvertToInt(V, 16, 'unsigned', opts)
 | 
			
		||||
 | 
			
		||||
  // 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)
 | 
			
		||||
  ) {
 | 
			
		||||
    throw 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)) {
 | 
			
		||||
    throw 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
 | 
			
		||||
  ) {
 | 
			
		||||
    throw 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)) {
 | 
			
		||||
    throw 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)) {
 | 
			
		||||
    throw 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)) {
 | 
			
		||||
    throw 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<ByteString>'] = webidl.sequenceConverter(
 | 
			
		||||
  webidl.converters.ByteString
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
webidl.converters['sequence<sequence<ByteString>>'] = webidl.sequenceConverter(
 | 
			
		||||
  webidl.converters['sequence<ByteString>']
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
webidl.converters['record<ByteString, ByteString>'] = webidl.recordConverter(
 | 
			
		||||
  webidl.converters.ByteString,
 | 
			
		||||
  webidl.converters.ByteString
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
  webidl
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue