From 991e21146fe15e68da87fa83ce39d3d16d115aa4 Mon Sep 17 00:00:00 2001 From: Khafra <42794878+KhafraDev@users.noreply.github.com> Date: Sat, 19 Nov 2022 15:58:25 -0500 Subject: [PATCH 1/2] feat(fetch): add in native File class support --- lib/fetch/body.js | 7 +++++-- lib/fetch/file.js | 13 ++++++++----- lib/fetch/formdata.js | 7 +++++-- test/wpt/status/FileAPI.status.json | 13 ++++++++----- 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/lib/fetch/body.js b/lib/fetch/body.js index cf89c7d59f6..21f1aa30040 100644 --- a/lib/fetch/body.js +++ b/lib/fetch/body.js @@ -7,18 +7,21 @@ const { FormData } = require('./formdata') const { kState } = require('./symbols') const { webidl } = require('./webidl') const { DOMException, structuredClone } = require('./constants') -const { Blob } = require('buffer') +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 } = require('./file') +const { File: UndiciFile } = require('./file') const { StringDecoder } = require('string_decoder') const { parseMIMEType, serializeAMimeType } = require('./dataURL') /** @type {globalThis['ReadableStream']} */ let ReadableStream +/** @type {globalThis['File']} */ +const File = NativeFile ?? UndiciFile + // https://fetch.spec.whatwg.org/#concept-bodyinit-extract function extractBody (object, keepalive = false) { if (!ReadableStream) { diff --git a/lib/fetch/file.js b/lib/fetch/file.js index f27fc7fb7be..e5645ecc938 100644 --- a/lib/fetch/file.js +++ b/lib/fetch/file.js @@ -329,11 +329,14 @@ function convertLineEndingsNative (s) { // rollup) will warn about circular dependencies. See: // https://github.com/nodejs/undici/issues/1629 function isFileLike (object) { - return object instanceof File || ( - object && - (typeof object.stream === 'function' || - typeof object.arrayBuffer === 'function') && - object[Symbol.toStringTag] === 'File' + return ( + (globalThis.File && object instanceof globalThis.File) || + object instanceof File || ( + object && + (typeof object.stream === 'function' || + typeof object.arrayBuffer === 'function') && + object[Symbol.toStringTag] === 'File' + ) ) } diff --git a/lib/fetch/formdata.js b/lib/fetch/formdata.js index 5d0649ba92e..a0c9e2f9373 100644 --- a/lib/fetch/formdata.js +++ b/lib/fetch/formdata.js @@ -2,9 +2,12 @@ const { isBlobLike, toUSVString, makeIterator } = require('./util') const { kState } = require('./symbols') -const { File, FileLike, isFileLike } = require('./file') +const { File: UndiciFile, FileLike, isFileLike } = require('./file') const { webidl } = require('./webidl') -const { Blob } = require('buffer') +const { Blob, File: NativeFile } = require('buffer') + +/** @type {globalThis['File']} */ +const File = NativeFile ?? UndiciFile // https://xhr.spec.whatwg.org/#formdata class FormData { diff --git a/test/wpt/status/FileAPI.status.json b/test/wpt/status/FileAPI.status.json index 420c4f71809..d0d9825c6ef 100644 --- a/test/wpt/status/FileAPI.status.json +++ b/test/wpt/status/FileAPI.status.json @@ -5,13 +5,18 @@ ] }, "idlharness.any.js": { - "fail": [ + "note": "These flaky tests only fail in < node v19; add in a way to mark them as such eventually", + "flaky": [ "Blob interface: attribute size", "Blob interface: attribute type", "Blob interface: operation slice(optional long long, optional long long, optional DOMString)", "Blob interface: operation stream()", "Blob interface: operation text()", "Blob interface: operation arrayBuffer()", + "URL interface: operation createObjectURL((Blob or MediaSource))", + "URL interface: operation revokeObjectURL(DOMString)" + ], + "fail": [ "FileList interface: existence and properties of interface object", "FileList interface object length", "FileList interface object name", @@ -19,9 +24,7 @@ "FileList interface: existence and properties of interface prototype object's \"constructor\" property", "FileList interface: existence and properties of interface prototype object's @@unscopables property", "FileList interface: operation item(unsigned long)", - "FileList interface: attribute length", - "URL interface: operation createObjectURL((Blob or MediaSource))", - "URL interface: operation revokeObjectURL(DOMString)" + "FileList interface: attribute length" ] }, "filereader_events.any.js": { @@ -30,4 +33,4 @@ "events are dispatched in the correct order for a non-empty blob" ] } -} \ No newline at end of file +} From 8320108fab1e2424a71f144f89ee3c766d6973a9 Mon Sep 17 00:00:00 2001 From: Khafra <42794878+KhafraDev@users.noreply.github.com> Date: Sun, 20 Nov 2022 09:50:54 -0500 Subject: [PATCH 2/2] fix: File isn't a global yet --- lib/fetch/file.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/fetch/file.js b/lib/fetch/file.js index e5645ecc938..81bb7b2441a 100644 --- a/lib/fetch/file.js +++ b/lib/fetch/file.js @@ -1,6 +1,6 @@ 'use strict' -const { Blob } = require('buffer') +const { Blob, File: NativeFile } = require('buffer') const { types } = require('util') const { kState } = require('./symbols') const { isBlobLike } = require('./util') @@ -330,7 +330,7 @@ function convertLineEndingsNative (s) { // https://github.com/nodejs/undici/issues/1629 function isFileLike (object) { return ( - (globalThis.File && object instanceof globalThis.File) || + (NativeFile && object instanceof NativeFile) || object instanceof File || ( object && (typeof object.stream === 'function' ||