From caf9ec3385c7e407748ac442c9972065f63e1985 Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Sat, 27 Nov 2021 18:40:17 +0100 Subject: [PATCH] fix: some cleanup --- lib/fetch/body.js | 2 +- lib/fetch/file.js | 6 +++++- lib/fetch/formdata.js | 35 ++++++++++++++++++++++++++++++++--- test/fetch/file.js | 4 ++-- 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/lib/fetch/body.js b/lib/fetch/body.js index de4089da7b1..871e6292b11 100644 --- a/lib/fetch/body.js +++ b/lib/fetch/body.js @@ -276,7 +276,7 @@ const methods = { throw new TypeError('locked') } - // NOTE: stream.isDisturbed hasn't landed on Node 16.x yet. + // Compat. stream[kBodyUsed] = true for await (const chunk of stream) { diff --git a/lib/fetch/file.js b/lib/fetch/file.js index 4c1065b9818..b1069f21077 100644 --- a/lib/fetch/file.js +++ b/lib/fetch/file.js @@ -67,7 +67,11 @@ class File extends Blob { } get [Symbol.toStringTag] () { - return 'File' + if (!(this instanceof File)) { + throw new TypeError('Illegal invocation') + } + + return this.constructor.name } } diff --git a/lib/fetch/formdata.js b/lib/fetch/formdata.js index 321207cf122..550e1e46947 100644 --- a/lib/fetch/formdata.js +++ b/lib/fetch/formdata.js @@ -20,16 +20,19 @@ class FormData { if (!(this instanceof FormData)) { throw new TypeError('Illegal invocation') } + if (args.length < 2) { throw new TypeError( `Failed to execute 'append' on 'FormData': 2 arguments required, but only ${args.length} present.` ) } + if (args.length === 3 && !isBlobLike(args[1])) { throw new TypeError( "Failed to execute 'append' on 'FormData': parameter 2 is not of type 'Blob'" ) } + const name = toUSVString(args[0]) const filename = args.length === 3 ? toUSVString(args[2]) : undefined @@ -48,11 +51,13 @@ class FormData { if (!(this instanceof FormData)) { throw new TypeError('Illegal invocation') } + if (args.length < 1) { throw new TypeError( `Failed to execute 'delete' on 'FormData': 1 arguments required, but only ${args.length} present.` ) } + const name = toUSVString(args[0]) // The delete(name) method steps are to remove all entries whose name @@ -71,11 +76,13 @@ class FormData { if (!(this instanceof FormData)) { throw new TypeError('Illegal invocation') } + if (args.length < 1) { throw new TypeError( `Failed to execute 'get' on 'FormData': 1 arguments required, but only ${args.length} present.` ) } + const name = toUSVString(args[0]) // 1. If there is no entry whose name is name in this’s entry list, @@ -94,11 +101,13 @@ class FormData { if (!(this instanceof FormData)) { throw new TypeError('Illegal invocation') } + if (args.length < 1) { throw new TypeError( `Failed to execute 'getAll' on 'FormData': 1 arguments required, but only ${args.length} present.` ) } + const name = toUSVString(args[0]) // 1. If there is no entry whose name is name in this’s entry list, @@ -114,11 +123,13 @@ class FormData { if (!(this instanceof FormData)) { throw new TypeError('Illegal invocation') } + if (args.length < 1) { throw new TypeError( `Failed to execute 'has' on 'FormData': 1 arguments required, but only ${args.length} present.` ) } + const name = toUSVString(args[0]) // The has(name) method steps are to return true if there is an entry @@ -130,11 +141,13 @@ class FormData { if (!(this instanceof FormData)) { throw new TypeError('Illegal invocation') } + if (args.length < 2) { throw new TypeError( `Failed to execute 'set' on 'FormData': 2 arguments required, but only ${args.length} present.` ) } + if (args.length === 3 && !isBlobLike(args[1])) { throw new TypeError( "Failed to execute 'set' on 'FormData': parameter 2 is not of type 'Blob'" @@ -169,22 +182,38 @@ class FormData { } get [Symbol.toStringTag] () { - return 'FormData' + if (!(this instanceof FormData)) { + throw new TypeError('Illegal invocation') + } + + return this.constructor.name } * entries () { + if (!(this instanceof FormData)) { + throw new TypeError('Illegal invocation') + } + for (const pair of this) { yield pair } } * keys () { + if (!(this instanceof FormData)) { + throw new TypeError('Illegal invocation') + } + for (const [key] of this) { yield key } } * values () { + if (!(this instanceof FormData)) { + throw new TypeError('Illegal invocation') + } + for (const [, value] of this) { yield value } @@ -214,7 +243,7 @@ function makeEntry (name, value, filename) { // 3. If value is a Blob object and not a File object, then set value to a new File // object, representing the same bytes, whose name attribute value is "blob". - if (isBlobLike(value) && !(isFileLike(value))) { + if (isBlobLike(value) && !isFileLike(value)) { value = value instanceof Blob ? new File([value], 'blob') : new FileLike(value, 'blob') @@ -227,7 +256,7 @@ function makeEntry (name, value, filename) { // Do we just override the name attribute? Since it says "if value is (now)" // does that mean that this lives inside the previous condition? In which case // creating one more File instance doesn't make much sense.... - if (isFileLike(value) && filename) { + if (isFileLike(value) && filename != null) { value = value instanceof File ? new File([value], filename) : new FileLike(value, filename) diff --git a/test/fetch/file.js b/test/fetch/file.js index 45193b00d55..1e65c9325a3 100644 --- a/test/fetch/file.js +++ b/test/fetch/file.js @@ -5,6 +5,6 @@ const { File, FileLike } = require('../../lib/fetch/file') test('Symbol.toStringTag', (t) => { t.plan(2) - t.equal(File.prototype[Symbol.toStringTag], 'File') - t.equal(FileLike.prototype[Symbol.toStringTag], 'File') + t.equal(new File()[Symbol.toStringTag], 'File') + t.equal(new FileLike()[Symbol.toStringTag], 'File') })