diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 74f34364dfc..921972f4711 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -17,6 +17,9 @@ jobs: post-test-steps: | - name: Coverage Report uses: codecov/codecov-action@v2 + include: | + - runs-on: ubuntu-latest + node-version: 16.8 automerge: if: > github.event_name == 'pull_request' && diff --git a/README.md b/README.md index 432eb265932..323b2ca38bb 100644 --- a/README.md +++ b/README.md @@ -176,7 +176,7 @@ Implements [fetch](https://fetch.spec.whatwg.org/#fetch-method). * https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch * https://fetch.spec.whatwg.org/#fetch-method -Only supported on Node 16.5+. +Only supported on Node 16.8+. This is [experimental](https://nodejs.org/api/documentation.html#documentation_stability_index) and is not yet fully compliant with the Fetch Standard. We plan to ship breaking changes to this feature until it is out of experimental. diff --git a/index.js b/index.js index 2248619749c..b2144c844ba 100644 --- a/index.js +++ b/index.js @@ -80,7 +80,7 @@ function makeDispatcher (fn) { module.exports.setGlobalDispatcher = setGlobalDispatcher module.exports.getGlobalDispatcher = getGlobalDispatcher -if (nodeMajor > 16 || (nodeMajor === 16 && nodeMinor >= 5)) { +if (nodeMajor > 16 || (nodeMajor === 16 && nodeMinor >= 8)) { let fetchImpl = null module.exports.fetch = async function fetch (resource) { if (!fetchImpl) { diff --git a/lib/core/request.js b/lib/core/request.js index 1969f84deb1..0a3d8558958 100644 --- a/lib/core/request.js +++ b/lib/core/request.js @@ -140,8 +140,8 @@ class Request { } if (util.isFormDataLike(this.body)) { - if (nodeMajor < 16 || (nodeMajor === 16 && nodeMinor < 5)) { - throw new InvalidArgumentError('Form-Data bodies are only supported in node v16.5 and newer.') + if (nodeMajor < 16 || (nodeMajor === 16 && nodeMinor < 8)) { + throw new InvalidArgumentError('Form-Data bodies are only supported in node v16.8 and newer.') } if (!extractBody) { diff --git a/lib/fetch/body.js b/lib/fetch/body.js index 2228376d889..14af1251785 100644 --- a/lib/fetch/body.js +++ b/lib/fetch/body.js @@ -15,12 +15,7 @@ const { isUint8Array, isArrayBuffer } = require('util/types') let ReadableStream async function * blobGen (blob) { - if (blob.stream) { - yield * blob.stream() - } else { - // istanbul ignore next: node < 16.7 - yield await blob.arrayBuffer() - } + yield * blob.stream() } // https://fetch.spec.whatwg.org/#concept-bodyinit-extract diff --git a/lib/fetch/constants.js b/lib/fetch/constants.js index 6d201e01cff..44a86702d62 100644 --- a/lib/fetch/constants.js +++ b/lib/fetch/constants.js @@ -63,7 +63,7 @@ const subresource = [ /** @type {globalThis['DOMException']} */ const DOMException = globalThis.DOMException ?? (() => { // DOMException was only made a global in Node v17.0.0, - // but fetch supports >= v16.5. + // but fetch supports >= v16.8. try { atob('~') } catch (err) { diff --git a/lib/fetch/util.js b/lib/fetch/util.js index e309e3263f4..17c68162980 100644 --- a/lib/fetch/util.js +++ b/lib/fetch/util.js @@ -431,6 +431,11 @@ function makeIterator (iterator, name) { return Object.setPrototypeOf({}, i) } +/** + * Fetch supports node >= 16.8.0, but Object.hasOwn was added in v16.9.0. + */ +const hasOwn = Object.hasOwn || ((dict, key) => Object.prototype.hasOwnProperty.call(dict, key)) + module.exports = { isAborted, isCancelled, @@ -463,5 +468,6 @@ module.exports = { serializeJavascriptValueToJSONString, makeIterator, isValidHeaderName, - isValidHeaderValue + isValidHeaderValue, + hasOwn } diff --git a/lib/fetch/webidl.js b/lib/fetch/webidl.js index 252dab29b83..f9a780ccaa7 100644 --- a/lib/fetch/webidl.js +++ b/lib/fetch/webidl.js @@ -1,6 +1,7 @@ 'use strict' -const { toUSVString, types } = require('util') +const { types } = require('util') +const { hasOwn, toUSVString } = require('./util') const webidl = {} webidl.converters = {} @@ -315,7 +316,7 @@ webidl.dictionaryConverter = function (converters) { const { key, defaultValue, required, converter } = options if (required === true) { - if (!Object.hasOwn(dictionary, key)) { + if (!hasOwn(dictionary, key)) { webidl.errors.exception({ header: 'Dictionary', message: `Missing required key "${key}".` @@ -324,7 +325,7 @@ webidl.dictionaryConverter = function (converters) { } let value = dictionary[key] - const hasDefault = Object.hasOwn(options, 'defaultValue') + const hasDefault = hasOwn(options, 'defaultValue') // Only use defaultValue if value is undefined and // a defaultValue options was provided.