Update dependencies (#20)
All checks were successful
Lint / pre-commit Linting (push) Successful in 29s
All checks were successful
Lint / pre-commit Linting (push) Successful in 29s
- @actions/core - glob - screeps-api Reviewed-on: #20 Co-authored-by: Philipp Horstenkamp <philipp@horstenkamp.de> Co-committed-by: Philipp Horstenkamp <philipp@horstenkamp.de>
This commit is contained in:
10
node_modules/undici/lib/fetch/body.js
generated
vendored
10
node_modules/undici/lib/fetch/body.js
generated
vendored
@ -22,6 +22,14 @@ const { isUint8Array, isArrayBuffer } = require('util/types')
|
||||
const { File: UndiciFile } = require('./file')
|
||||
const { parseMIMEType, serializeAMimeType } = require('./dataURL')
|
||||
|
||||
let random
|
||||
try {
|
||||
const crypto = require('node:crypto')
|
||||
random = (max) => crypto.randomInt(0, max)
|
||||
} catch {
|
||||
random = (max) => Math.floor(Math.random(max))
|
||||
}
|
||||
|
||||
let ReadableStream = globalThis.ReadableStream
|
||||
|
||||
/** @type {globalThis['File']} */
|
||||
@ -107,7 +115,7 @@ function extractBody (object, keepalive = false) {
|
||||
// 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 boundary = `----formdata-undici-0${`${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> */
|
||||
|
13
node_modules/undici/lib/fetch/dataURL.js
generated
vendored
13
node_modules/undici/lib/fetch/dataURL.js
generated
vendored
@ -119,17 +119,14 @@ function dataURLProcessor (dataURL) {
|
||||
* @param {boolean} excludeFragment
|
||||
*/
|
||||
function URLSerializer (url, excludeFragment = false) {
|
||||
const href = url.href
|
||||
|
||||
if (!excludeFragment) {
|
||||
return href
|
||||
return url.href
|
||||
}
|
||||
|
||||
const hash = href.lastIndexOf('#')
|
||||
if (hash === -1) {
|
||||
return href
|
||||
}
|
||||
return href.slice(0, hash)
|
||||
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
|
||||
|
9
node_modules/undici/lib/fetch/headers.js
generated
vendored
9
node_modules/undici/lib/fetch/headers.js
generated
vendored
@ -2,7 +2,7 @@
|
||||
|
||||
'use strict'
|
||||
|
||||
const { kHeadersList } = require('../core/symbols')
|
||||
const { kHeadersList, kConstruct } = require('../core/symbols')
|
||||
const { kGuard } = require('./symbols')
|
||||
const { kEnumerableProperty } = require('../core/util')
|
||||
const {
|
||||
@ -10,6 +10,7 @@ const {
|
||||
isValidHeaderName,
|
||||
isValidHeaderValue
|
||||
} = require('./util')
|
||||
const util = require('util')
|
||||
const { webidl } = require('./webidl')
|
||||
const assert = require('assert')
|
||||
|
||||
@ -240,6 +241,9 @@ class HeadersList {
|
||||
// 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:
|
||||
@ -560,6 +564,9 @@ Object.defineProperties(Headers.prototype, {
|
||||
[Symbol.toStringTag]: {
|
||||
value: 'Headers',
|
||||
configurable: true
|
||||
},
|
||||
[util.inspect.custom]: {
|
||||
enumerable: false
|
||||
}
|
||||
})
|
||||
|
||||
|
5
node_modules/undici/lib/fetch/index.js
generated
vendored
5
node_modules/undici/lib/fetch/index.js
generated
vendored
@ -286,7 +286,7 @@ function finalizeAndReportTiming (response, initiatorType = 'other') {
|
||||
}
|
||||
|
||||
// 8. If response’s timing allow passed flag is not set, then:
|
||||
if (!timingInfo.timingAllowPassed) {
|
||||
if (!response.timingAllowPassed) {
|
||||
// 1. Set timingInfo to a the result of creating an opaque timing info for timingInfo.
|
||||
timingInfo = createOpaqueTimingInfo({
|
||||
startTime: timingInfo.startTime
|
||||
@ -1203,6 +1203,9 @@ function httpRedirectFetch (fetchParams, response) {
|
||||
// https://fetch.spec.whatwg.org/#cors-non-wildcard-request-header-name
|
||||
request.headersList.delete('authorization')
|
||||
|
||||
// https://fetch.spec.whatwg.org/#authentication-entries
|
||||
request.headersList.delete('proxy-authorization', true)
|
||||
|
||||
// "Cookie" and "Host" are forbidden request-headers, which undici doesn't implement.
|
||||
request.headersList.delete('cookie')
|
||||
request.headersList.delete('host')
|
||||
|
46
node_modules/undici/lib/fetch/request.js
generated
vendored
46
node_modules/undici/lib/fetch/request.js
generated
vendored
@ -10,7 +10,8 @@ const {
|
||||
isValidHTTPToken,
|
||||
sameOrigin,
|
||||
normalizeMethod,
|
||||
makePolicyContainer
|
||||
makePolicyContainer,
|
||||
normalizeMethodRecord
|
||||
} = require('./util')
|
||||
const {
|
||||
forbiddenMethodsSet,
|
||||
@ -27,13 +28,12 @@ const { kHeaders, kSignal, kState, kGuard, kRealm } = require('./symbols')
|
||||
const { webidl } = require('./webidl')
|
||||
const { getGlobalOrigin } = require('./global')
|
||||
const { URLSerializer } = require('./dataURL')
|
||||
const { kHeadersList } = require('../core/symbols')
|
||||
const { kHeadersList, kConstruct } = require('../core/symbols')
|
||||
const assert = require('assert')
|
||||
const { getMaxListeners, setMaxListeners, getEventListeners, defaultMaxListeners } = require('events')
|
||||
|
||||
let TransformStream = globalThis.TransformStream
|
||||
|
||||
const kInit = Symbol('init')
|
||||
const kAbortController = Symbol('abortController')
|
||||
|
||||
const requestFinalizer = new FinalizationRegistry(({ signal, abort }) => {
|
||||
@ -44,7 +44,7 @@ const requestFinalizer = new FinalizationRegistry(({ signal, abort }) => {
|
||||
class Request {
|
||||
// https://fetch.spec.whatwg.org/#dom-request
|
||||
constructor (input, init = {}) {
|
||||
if (input === kInit) {
|
||||
if (input === kConstruct) {
|
||||
return
|
||||
}
|
||||
|
||||
@ -183,8 +183,10 @@ class Request {
|
||||
urlList: [...request.urlList]
|
||||
})
|
||||
|
||||
const initHasKey = Object.keys(init).length !== 0
|
||||
|
||||
// 13. If init is not empty, then:
|
||||
if (Object.keys(init).length > 0) {
|
||||
if (initHasKey) {
|
||||
// 1. If request’s mode is "navigate", then set it to "same-origin".
|
||||
if (request.mode === 'navigate') {
|
||||
request.mode = 'same-origin'
|
||||
@ -299,7 +301,7 @@ class Request {
|
||||
}
|
||||
|
||||
// 23. If init["integrity"] exists, then set request’s integrity metadata to it.
|
||||
if (init.integrity !== undefined && init.integrity != null) {
|
||||
if (init.integrity != null) {
|
||||
request.integrity = String(init.integrity)
|
||||
}
|
||||
|
||||
@ -315,16 +317,16 @@ class Request {
|
||||
|
||||
// 2. If method is not a method or method is a forbidden method, then
|
||||
// throw a TypeError.
|
||||
if (!isValidHTTPToken(init.method)) {
|
||||
throw new TypeError(`'${init.method}' is not a valid HTTP method.`)
|
||||
if (!isValidHTTPToken(method)) {
|
||||
throw new TypeError(`'${method}' is not a valid HTTP method.`)
|
||||
}
|
||||
|
||||
if (forbiddenMethodsSet.has(method.toUpperCase())) {
|
||||
throw new TypeError(`'${init.method}' HTTP method is unsupported.`)
|
||||
throw new TypeError(`'${method}' HTTP method is unsupported.`)
|
||||
}
|
||||
|
||||
// 3. Normalize method.
|
||||
method = normalizeMethod(init.method)
|
||||
method = normalizeMethodRecord[method] ?? normalizeMethod(method)
|
||||
|
||||
// 4. Set request’s method to method.
|
||||
request.method = method
|
||||
@ -395,7 +397,7 @@ class Request {
|
||||
// 30. Set this’s headers to a new Headers object with this’s relevant
|
||||
// Realm, whose header list is request’s header list and guard is
|
||||
// "request".
|
||||
this[kHeaders] = new Headers()
|
||||
this[kHeaders] = new Headers(kConstruct)
|
||||
this[kHeaders][kHeadersList] = request.headersList
|
||||
this[kHeaders][kGuard] = 'request'
|
||||
this[kHeaders][kRealm] = this[kRealm]
|
||||
@ -415,25 +417,25 @@ class Request {
|
||||
}
|
||||
|
||||
// 32. If init is not empty, then:
|
||||
if (Object.keys(init).length !== 0) {
|
||||
if (initHasKey) {
|
||||
/** @type {HeadersList} */
|
||||
const headersList = this[kHeaders][kHeadersList]
|
||||
// 1. Let headers be a copy of this’s headers and its associated header
|
||||
// list.
|
||||
let headers = new Headers(this[kHeaders])
|
||||
|
||||
// 2. If init["headers"] exists, then set headers to init["headers"].
|
||||
if (init.headers !== undefined) {
|
||||
headers = init.headers
|
||||
}
|
||||
const headers = init.headers !== undefined ? init.headers : new HeadersList(headersList)
|
||||
|
||||
// 3. Empty this’s headers’s header list.
|
||||
this[kHeaders][kHeadersList].clear()
|
||||
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.constructor.name === 'Headers') {
|
||||
if (headers instanceof HeadersList) {
|
||||
for (const [key, val] of headers) {
|
||||
this[kHeaders].append(key, val)
|
||||
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)
|
||||
@ -722,10 +724,10 @@ class Request {
|
||||
|
||||
// 3. Let clonedRequestObject be the result of creating a Request object,
|
||||
// given clonedRequest, this’s headers’s guard, and this’s relevant Realm.
|
||||
const clonedRequestObject = new Request(kInit)
|
||||
const clonedRequestObject = new Request(kConstruct)
|
||||
clonedRequestObject[kState] = clonedRequest
|
||||
clonedRequestObject[kRealm] = this[kRealm]
|
||||
clonedRequestObject[kHeaders] = new Headers()
|
||||
clonedRequestObject[kHeaders] = new Headers(kConstruct)
|
||||
clonedRequestObject[kHeaders][kHeadersList] = clonedRequest.headersList
|
||||
clonedRequestObject[kHeaders][kGuard] = this[kHeaders][kGuard]
|
||||
clonedRequestObject[kHeaders][kRealm] = this[kHeaders][kRealm]
|
||||
|
10
node_modules/undici/lib/fetch/response.js
generated
vendored
10
node_modules/undici/lib/fetch/response.js
generated
vendored
@ -23,7 +23,7 @@ const { webidl } = require('./webidl')
|
||||
const { FormData } = require('./formdata')
|
||||
const { getGlobalOrigin } = require('./global')
|
||||
const { URLSerializer } = require('./dataURL')
|
||||
const { kHeadersList } = require('../core/symbols')
|
||||
const { kHeadersList, kConstruct } = require('../core/symbols')
|
||||
const assert = require('assert')
|
||||
const { types } = require('util')
|
||||
|
||||
@ -144,7 +144,7 @@ class Response {
|
||||
// 2. Set this’s headers to a new Headers object with this’s relevant
|
||||
// Realm, whose header list is this’s response’s header list and guard
|
||||
// is "response".
|
||||
this[kHeaders] = new Headers()
|
||||
this[kHeaders] = new Headers(kConstruct)
|
||||
this[kHeaders][kGuard] = 'response'
|
||||
this[kHeaders][kHeadersList] = this[kState].headersList
|
||||
this[kHeaders][kRealm] = this[kRealm]
|
||||
@ -514,11 +514,7 @@ webidl.converters.XMLHttpRequestBodyInit = function (V) {
|
||||
return webidl.converters.Blob(V, { strict: false })
|
||||
}
|
||||
|
||||
if (
|
||||
types.isAnyArrayBuffer(V) ||
|
||||
types.isTypedArray(V) ||
|
||||
types.isDataView(V)
|
||||
) {
|
||||
if (types.isArrayBuffer(V) || types.isTypedArray(V) || types.isDataView(V)) {
|
||||
return webidl.converters.BufferSource(V)
|
||||
}
|
||||
|
||||
|
171
node_modules/undici/lib/fetch/util.js
generated
vendored
171
node_modules/undici/lib/fetch/util.js
generated
vendored
@ -7,14 +7,18 @@ const { isBlobLike, toUSVString, ReadableStreamFrom } = require('../core/util')
|
||||
const assert = require('assert')
|
||||
const { isUint8Array } = require('util/types')
|
||||
|
||||
let supportedHashes = []
|
||||
|
||||
// https://nodejs.org/api/crypto.html#determining-if-crypto-support-is-unavailable
|
||||
/** @type {import('crypto')|undefined} */
|
||||
let crypto
|
||||
|
||||
try {
|
||||
crypto = require('crypto')
|
||||
const possibleRelevantHashes = ['sha256', 'sha384', 'sha512']
|
||||
supportedHashes = crypto.getHashes().filter((hash) => possibleRelevantHashes.includes(hash))
|
||||
/* c8 ignore next 3 */
|
||||
} catch {
|
||||
|
||||
}
|
||||
|
||||
function responseURL (response) {
|
||||
@ -542,66 +546,56 @@ function bytesMatch (bytes, metadataList) {
|
||||
return true
|
||||
}
|
||||
|
||||
// 3. If parsedMetadata is the empty set, return true.
|
||||
// 3. If response is not eligible for integrity validation, return false.
|
||||
// TODO
|
||||
|
||||
// 4. If parsedMetadata is the empty set, return true.
|
||||
if (parsedMetadata.length === 0) {
|
||||
return true
|
||||
}
|
||||
|
||||
// 4. Let metadata be the result of getting the strongest
|
||||
// 5. Let metadata be the result of getting the strongest
|
||||
// metadata from parsedMetadata.
|
||||
const list = parsedMetadata.sort((c, d) => d.algo.localeCompare(c.algo))
|
||||
// get the strongest algorithm
|
||||
const strongest = list[0].algo
|
||||
// get all entries that use the strongest algorithm; ignore weaker
|
||||
const metadata = list.filter((item) => item.algo === strongest)
|
||||
const strongest = getStrongestMetadata(parsedMetadata)
|
||||
const metadata = filterMetadataListByAlgorithm(parsedMetadata, strongest)
|
||||
|
||||
// 5. For each item in metadata:
|
||||
// 6. For each item in metadata:
|
||||
for (const item of metadata) {
|
||||
// 1. Let algorithm be the alg component of item.
|
||||
const algorithm = item.algo
|
||||
|
||||
// 2. Let expectedValue be the val component of item.
|
||||
let expectedValue = item.hash
|
||||
const expectedValue = item.hash
|
||||
|
||||
// See https://github.com/web-platform-tests/wpt/commit/e4c5cc7a5e48093220528dfdd1c4012dc3837a0e
|
||||
// "be liberal with padding". This is annoying, and it's not even in the spec.
|
||||
|
||||
if (expectedValue.endsWith('==')) {
|
||||
expectedValue = expectedValue.slice(0, -2)
|
||||
}
|
||||
|
||||
// 3. Let actualValue be the result of applying algorithm to bytes.
|
||||
let actualValue = crypto.createHash(algorithm).update(bytes).digest('base64')
|
||||
|
||||
if (actualValue.endsWith('==')) {
|
||||
actualValue = actualValue.slice(0, -2)
|
||||
if (actualValue[actualValue.length - 1] === '=') {
|
||||
if (actualValue[actualValue.length - 2] === '=') {
|
||||
actualValue = actualValue.slice(0, -2)
|
||||
} else {
|
||||
actualValue = actualValue.slice(0, -1)
|
||||
}
|
||||
}
|
||||
|
||||
// 4. If actualValue is a case-sensitive match for expectedValue,
|
||||
// return true.
|
||||
if (actualValue === expectedValue) {
|
||||
return true
|
||||
}
|
||||
|
||||
let actualBase64URL = crypto.createHash(algorithm).update(bytes).digest('base64url')
|
||||
|
||||
if (actualBase64URL.endsWith('==')) {
|
||||
actualBase64URL = actualBase64URL.slice(0, -2)
|
||||
}
|
||||
|
||||
if (actualBase64URL === expectedValue) {
|
||||
if (compareBase64Mixed(actualValue, expectedValue)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// 6. Return false.
|
||||
// 7. Return false.
|
||||
return false
|
||||
}
|
||||
|
||||
// https://w3c.github.io/webappsec-subresource-integrity/#grammardef-hash-with-options
|
||||
// https://www.w3.org/TR/CSP2/#source-list-syntax
|
||||
// https://www.rfc-editor.org/rfc/rfc5234#appendix-B.1
|
||||
const parseHashWithOptions = /((?<algo>sha256|sha384|sha512)-(?<hash>[A-z0-9+/]{1}.*={0,2}))( +[\x21-\x7e]?)?/i
|
||||
const parseHashWithOptions = /(?<algo>sha256|sha384|sha512)-((?<hash>[A-Za-z0-9+/]+|[A-Za-z0-9_-]+)={0,2}(?:\s|$)( +[!-~]*)?)?/i
|
||||
|
||||
/**
|
||||
* @see https://w3c.github.io/webappsec-subresource-integrity/#parse-metadata
|
||||
@ -615,8 +609,6 @@ function parseMetadata (metadata) {
|
||||
// 2. Let empty be equal to true.
|
||||
let empty = true
|
||||
|
||||
const supportedHashes = crypto.getHashes()
|
||||
|
||||
// 3. For each token returned by splitting metadata on spaces:
|
||||
for (const token of metadata.split(' ')) {
|
||||
// 1. Set empty to false.
|
||||
@ -626,7 +618,11 @@ function parseMetadata (metadata) {
|
||||
const parsedToken = parseHashWithOptions.exec(token)
|
||||
|
||||
// 3. If token does not parse, continue to the next token.
|
||||
if (parsedToken === null || parsedToken.groups === undefined) {
|
||||
if (
|
||||
parsedToken === null ||
|
||||
parsedToken.groups === undefined ||
|
||||
parsedToken.groups.algo === undefined
|
||||
) {
|
||||
// Note: Chromium blocks the request at this point, but Firefox
|
||||
// gives a warning that an invalid integrity was given. The
|
||||
// correct behavior is to ignore these, and subsequently not
|
||||
@ -635,11 +631,11 @@ function parseMetadata (metadata) {
|
||||
}
|
||||
|
||||
// 4. Let algorithm be the hash-algo component of token.
|
||||
const algorithm = parsedToken.groups.algo
|
||||
const algorithm = parsedToken.groups.algo.toLowerCase()
|
||||
|
||||
// 5. If algorithm is a hash function recognized by the user
|
||||
// agent, add the parsed token to result.
|
||||
if (supportedHashes.includes(algorithm.toLowerCase())) {
|
||||
if (supportedHashes.includes(algorithm)) {
|
||||
result.push(parsedToken.groups)
|
||||
}
|
||||
}
|
||||
@ -652,6 +648,82 @@ function parseMetadata (metadata) {
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {{ algo: 'sha256' | 'sha384' | 'sha512' }[]} metadataList
|
||||
*/
|
||||
function getStrongestMetadata (metadataList) {
|
||||
// Let algorithm be the algo component of the first item in metadataList.
|
||||
// Can be sha256
|
||||
let algorithm = metadataList[0].algo
|
||||
// If the algorithm is sha512, then it is the strongest
|
||||
// and we can return immediately
|
||||
if (algorithm[3] === '5') {
|
||||
return algorithm
|
||||
}
|
||||
|
||||
for (let i = 1; i < metadataList.length; ++i) {
|
||||
const metadata = metadataList[i]
|
||||
// If the algorithm is sha512, then it is the strongest
|
||||
// and we can break the loop immediately
|
||||
if (metadata.algo[3] === '5') {
|
||||
algorithm = 'sha512'
|
||||
break
|
||||
// If the algorithm is sha384, then a potential sha256 or sha384 is ignored
|
||||
} else if (algorithm[3] === '3') {
|
||||
continue
|
||||
// algorithm is sha256, check if algorithm is sha384 and if so, set it as
|
||||
// the strongest
|
||||
} else if (metadata.algo[3] === '3') {
|
||||
algorithm = 'sha384'
|
||||
}
|
||||
}
|
||||
return algorithm
|
||||
}
|
||||
|
||||
function filterMetadataListByAlgorithm (metadataList, algorithm) {
|
||||
if (metadataList.length === 1) {
|
||||
return metadataList
|
||||
}
|
||||
|
||||
let pos = 0
|
||||
for (let i = 0; i < metadataList.length; ++i) {
|
||||
if (metadataList[i].algo === algorithm) {
|
||||
metadataList[pos++] = metadataList[i]
|
||||
}
|
||||
}
|
||||
|
||||
metadataList.length = pos
|
||||
|
||||
return metadataList
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two base64 strings, allowing for base64url
|
||||
* in the second string.
|
||||
*
|
||||
* @param {string} actualValue always base64
|
||||
* @param {string} expectedValue base64 or base64url
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function compareBase64Mixed (actualValue, expectedValue) {
|
||||
if (actualValue.length !== expectedValue.length) {
|
||||
return false
|
||||
}
|
||||
for (let i = 0; i < actualValue.length; ++i) {
|
||||
if (actualValue[i] !== expectedValue[i]) {
|
||||
if (
|
||||
(actualValue[i] === '+' && expectedValue[i] === '-') ||
|
||||
(actualValue[i] === '/' && expectedValue[i] === '_')
|
||||
) {
|
||||
continue
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// https://w3c.github.io/webappsec-upgrade-insecure-requests/#upgrade-request
|
||||
function tryUpgradeRequestToAPotentiallyTrustworthyURL (request) {
|
||||
// TODO
|
||||
@ -698,11 +770,30 @@ function isCancelled (fetchParams) {
|
||||
fetchParams.controller.state === 'terminated'
|
||||
}
|
||||
|
||||
// https://fetch.spec.whatwg.org/#concept-method-normalize
|
||||
const normalizeMethodRecord = {
|
||||
delete: 'DELETE',
|
||||
DELETE: 'DELETE',
|
||||
get: 'GET',
|
||||
GET: 'GET',
|
||||
head: 'HEAD',
|
||||
HEAD: 'HEAD',
|
||||
options: 'OPTIONS',
|
||||
OPTIONS: 'OPTIONS',
|
||||
post: 'POST',
|
||||
POST: 'POST',
|
||||
put: 'PUT',
|
||||
PUT: 'PUT'
|
||||
}
|
||||
|
||||
// Note: object prototypes should not be able to be referenced. e.g. `Object#hasOwnProperty`.
|
||||
Object.setPrototypeOf(normalizeMethodRecord, null)
|
||||
|
||||
/**
|
||||
* @see https://fetch.spec.whatwg.org/#concept-method-normalize
|
||||
* @param {string} method
|
||||
*/
|
||||
function normalizeMethod (method) {
|
||||
return /^(DELETE|GET|HEAD|OPTIONS|POST|PUT)$/i.test(method)
|
||||
? method.toUpperCase()
|
||||
: method
|
||||
return normalizeMethodRecord[method.toLowerCase()] ?? method
|
||||
}
|
||||
|
||||
// https://infra.spec.whatwg.org/#serialize-a-javascript-value-to-a-json-string
|
||||
@ -1047,5 +1138,7 @@ module.exports = {
|
||||
urlIsLocal,
|
||||
urlHasHttpsScheme,
|
||||
urlIsHttpHttpsScheme,
|
||||
readAllBytes
|
||||
readAllBytes,
|
||||
normalizeMethodRecord,
|
||||
parseMetadata
|
||||
}
|
||||
|
Reference in New Issue
Block a user