undici 6.20.0 → 7.0.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -10
- package/docs/docs/api/Agent.md +0 -3
- package/docs/docs/api/Client.md +1 -3
- package/docs/docs/api/Debug.md +1 -1
- package/docs/docs/api/Dispatcher.md +60 -8
- package/docs/docs/api/EnvHttpProxyAgent.md +0 -1
- package/docs/docs/api/Fetch.md +1 -0
- package/docs/docs/api/MockAgent.md +2 -0
- package/docs/docs/api/MockPool.md +2 -1
- package/docs/docs/api/Pool.md +0 -1
- package/docs/docs/api/RetryAgent.md +1 -1
- package/docs/docs/api/RetryHandler.md +1 -1
- package/docs/docs/api/WebSocket.md +45 -3
- package/index.js +6 -6
- package/lib/api/abort-signal.js +2 -0
- package/lib/api/api-connect.js +3 -1
- package/lib/api/api-pipeline.js +7 -6
- package/lib/api/api-request.js +32 -47
- package/lib/api/api-stream.js +39 -50
- package/lib/api/api-upgrade.js +5 -3
- package/lib/api/readable.js +261 -64
- package/lib/api/util.js +2 -0
- package/lib/core/constants.js +11 -9
- package/lib/core/diagnostics.js +122 -128
- package/lib/core/errors.js +4 -4
- package/lib/core/request.js +11 -9
- package/lib/core/symbols.js +2 -1
- package/lib/core/tree.js +9 -1
- package/lib/core/util.js +219 -48
- package/lib/dispatcher/agent.js +3 -17
- package/lib/dispatcher/balanced-pool.js +5 -8
- package/lib/dispatcher/client-h1.js +278 -54
- package/lib/dispatcher/client-h2.js +1 -1
- package/lib/dispatcher/client.js +23 -34
- package/lib/dispatcher/dispatcher-base.js +2 -34
- package/lib/dispatcher/dispatcher.js +3 -24
- package/lib/dispatcher/fixed-queue.js +91 -49
- package/lib/dispatcher/pool-stats.js +2 -0
- package/lib/dispatcher/pool.js +3 -6
- package/lib/dispatcher/proxy-agent.js +6 -7
- package/lib/handler/decorator-handler.js +24 -0
- package/lib/handler/redirect-handler.js +11 -2
- package/lib/handler/retry-handler.js +12 -3
- package/lib/interceptor/dns.js +346 -0
- package/lib/interceptor/dump.js +2 -2
- package/lib/interceptor/redirect.js +11 -14
- package/lib/interceptor/response-error.js +4 -1
- package/lib/llhttp/constants.d.ts +97 -0
- package/lib/llhttp/constants.js +412 -192
- package/lib/llhttp/constants.js.map +1 -0
- package/lib/llhttp/llhttp-wasm.js +11 -1
- package/lib/llhttp/llhttp_simd-wasm.js +11 -1
- package/lib/llhttp/utils.d.ts +2 -0
- package/lib/llhttp/utils.js +9 -9
- package/lib/llhttp/utils.js.map +1 -0
- package/lib/mock/mock-agent.js +5 -8
- package/lib/mock/mock-client.js +9 -4
- package/lib/mock/mock-errors.js +3 -1
- package/lib/mock/mock-interceptor.js +8 -6
- package/lib/mock/mock-pool.js +9 -4
- package/lib/mock/mock-symbols.js +3 -1
- package/lib/mock/mock-utils.js +29 -5
- package/lib/web/cache/cache.js +24 -21
- package/lib/web/cache/cachestorage.js +1 -1
- package/lib/web/cookies/index.js +17 -13
- package/lib/web/cookies/parse.js +2 -2
- package/lib/web/eventsource/eventsource-stream.js +9 -8
- package/lib/web/eventsource/eventsource.js +10 -6
- package/lib/web/fetch/body.js +42 -36
- package/lib/web/fetch/constants.js +35 -26
- package/lib/web/fetch/data-url.js +1 -1
- package/lib/web/fetch/formdata-parser.js +2 -2
- package/lib/web/fetch/formdata.js +65 -54
- package/lib/web/fetch/headers.js +117 -85
- package/lib/web/fetch/index.js +55 -62
- package/lib/web/fetch/request.js +135 -77
- package/lib/web/fetch/response.js +86 -56
- package/lib/web/fetch/util.js +90 -64
- package/lib/web/fetch/webidl.js +99 -64
- package/lib/web/websocket/connection.js +76 -147
- package/lib/web/websocket/constants.js +3 -4
- package/lib/web/websocket/events.js +4 -2
- package/lib/web/websocket/frame.js +45 -3
- package/lib/web/websocket/receiver.js +29 -33
- package/lib/web/websocket/sender.js +18 -13
- package/lib/web/websocket/stream/websocketerror.js +83 -0
- package/lib/web/websocket/stream/websocketstream.js +485 -0
- package/lib/web/websocket/util.js +128 -77
- package/lib/web/websocket/websocket.js +234 -135
- package/package.json +20 -33
- package/scripts/strip-comments.js +3 -1
- package/types/agent.d.ts +7 -7
- package/types/api.d.ts +24 -24
- package/types/balanced-pool.d.ts +11 -11
- package/types/client.d.ts +11 -12
- package/types/diagnostics-channel.d.ts +10 -10
- package/types/dispatcher.d.ts +96 -97
- package/types/env-http-proxy-agent.d.ts +2 -2
- package/types/errors.d.ts +53 -47
- package/types/fetch.d.ts +8 -8
- package/types/formdata.d.ts +7 -7
- package/types/global-dispatcher.d.ts +4 -4
- package/types/global-origin.d.ts +5 -5
- package/types/handlers.d.ts +4 -4
- package/types/header.d.ts +157 -1
- package/types/index.d.ts +42 -46
- package/types/interceptors.d.ts +22 -8
- package/types/mock-agent.d.ts +21 -18
- package/types/mock-client.d.ts +4 -4
- package/types/mock-errors.d.ts +3 -3
- package/types/mock-interceptor.d.ts +19 -19
- package/types/mock-pool.d.ts +4 -4
- package/types/patch.d.ts +0 -4
- package/types/pool-stats.d.ts +8 -8
- package/types/pool.d.ts +12 -12
- package/types/proxy-agent.d.ts +4 -4
- package/types/readable.d.ts +22 -14
- package/types/retry-agent.d.ts +1 -1
- package/types/retry-handler.d.ts +8 -8
- package/types/util.d.ts +3 -3
- package/types/utility.d.ts +7 -0
- package/types/webidl.d.ts +44 -6
- package/types/websocket.d.ts +34 -1
- package/docs/docs/api/DispatchInterceptor.md +0 -60
- package/lib/interceptor/redirect-interceptor.js +0 -21
- package/lib/mock/pluralizer.js +0 -29
- package/lib/web/cache/symbols.js +0 -5
- package/lib/web/fetch/file.js +0 -126
- package/lib/web/fetch/symbols.js +0 -9
- package/lib/web/fileapi/encoding.js +0 -290
- package/lib/web/fileapi/filereader.js +0 -344
- package/lib/web/fileapi/progressevent.js +0 -78
- package/lib/web/fileapi/symbols.js +0 -10
- package/lib/web/fileapi/util.js +0 -391
- package/lib/web/websocket/symbols.js +0 -12
- package/types/file.d.ts +0 -39
- package/types/filereader.d.ts +0 -54
|
@@ -1,27 +1,30 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const corsSafeListedMethods = ['GET', 'HEAD', 'POST']
|
|
3
|
+
const corsSafeListedMethods = /** @type {const} */ (['GET', 'HEAD', 'POST'])
|
|
4
4
|
const corsSafeListedMethodsSet = new Set(corsSafeListedMethods)
|
|
5
5
|
|
|
6
|
-
const nullBodyStatus = [101, 204, 205, 304]
|
|
6
|
+
const nullBodyStatus = /** @type {const} */ ([101, 204, 205, 304])
|
|
7
7
|
|
|
8
|
-
const redirectStatus = [301, 302, 303, 307, 308]
|
|
8
|
+
const redirectStatus = /** @type {const} */ ([301, 302, 303, 307, 308])
|
|
9
9
|
const redirectStatusSet = new Set(redirectStatus)
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
/**
|
|
12
|
+
* @see https://fetch.spec.whatwg.org/#block-bad-port
|
|
13
|
+
*/
|
|
14
|
+
const badPorts = /** @type {const} */ ([
|
|
13
15
|
'1', '7', '9', '11', '13', '15', '17', '19', '20', '21', '22', '23', '25', '37', '42', '43', '53', '69', '77', '79',
|
|
14
16
|
'87', '95', '101', '102', '103', '104', '109', '110', '111', '113', '115', '117', '119', '123', '135', '137',
|
|
15
17
|
'139', '143', '161', '179', '389', '427', '465', '512', '513', '514', '515', '526', '530', '531', '532',
|
|
16
18
|
'540', '548', '554', '556', '563', '587', '601', '636', '989', '990', '993', '995', '1719', '1720', '1723',
|
|
17
19
|
'2049', '3659', '4045', '4190', '5060', '5061', '6000', '6566', '6665', '6666', '6667', '6668', '6669', '6679',
|
|
18
20
|
'6697', '10080'
|
|
19
|
-
]
|
|
20
|
-
|
|
21
|
+
])
|
|
21
22
|
const badPortsSet = new Set(badPorts)
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
/**
|
|
25
|
+
* @see https://w3c.github.io/webappsec-referrer-policy/#referrer-policies
|
|
26
|
+
*/
|
|
27
|
+
const referrerPolicy = /** @type {const} */ ([
|
|
25
28
|
'',
|
|
26
29
|
'no-referrer',
|
|
27
30
|
'no-referrer-when-downgrade',
|
|
@@ -31,29 +34,31 @@ const referrerPolicy = [
|
|
|
31
34
|
'origin-when-cross-origin',
|
|
32
35
|
'strict-origin-when-cross-origin',
|
|
33
36
|
'unsafe-url'
|
|
34
|
-
]
|
|
37
|
+
])
|
|
35
38
|
const referrerPolicySet = new Set(referrerPolicy)
|
|
36
39
|
|
|
37
|
-
const requestRedirect = ['follow', 'manual', 'error']
|
|
40
|
+
const requestRedirect = /** @type {const} */ (['follow', 'manual', 'error'])
|
|
38
41
|
|
|
39
|
-
const safeMethods = ['GET', 'HEAD', 'OPTIONS', 'TRACE']
|
|
42
|
+
const safeMethods = /** @type {const} */ (['GET', 'HEAD', 'OPTIONS', 'TRACE'])
|
|
40
43
|
const safeMethodsSet = new Set(safeMethods)
|
|
41
44
|
|
|
42
|
-
const requestMode = ['navigate', 'same-origin', 'no-cors', 'cors']
|
|
45
|
+
const requestMode = /** @type {const} */ (['navigate', 'same-origin', 'no-cors', 'cors'])
|
|
43
46
|
|
|
44
|
-
const requestCredentials = ['omit', 'same-origin', 'include']
|
|
47
|
+
const requestCredentials = /** @type {const} */ (['omit', 'same-origin', 'include'])
|
|
45
48
|
|
|
46
|
-
const requestCache = [
|
|
49
|
+
const requestCache = /** @type {const} */ ([
|
|
47
50
|
'default',
|
|
48
51
|
'no-store',
|
|
49
52
|
'reload',
|
|
50
53
|
'no-cache',
|
|
51
54
|
'force-cache',
|
|
52
55
|
'only-if-cached'
|
|
53
|
-
]
|
|
56
|
+
])
|
|
54
57
|
|
|
55
|
-
|
|
56
|
-
|
|
58
|
+
/**
|
|
59
|
+
* @see https://fetch.spec.whatwg.org/#request-body-header-name
|
|
60
|
+
*/
|
|
61
|
+
const requestBodyHeader = /** @type {const} */ ([
|
|
57
62
|
'content-encoding',
|
|
58
63
|
'content-language',
|
|
59
64
|
'content-location',
|
|
@@ -63,18 +68,22 @@ const requestBodyHeader = [
|
|
|
63
68
|
// removed in the Headers implementation. However, undici doesn't
|
|
64
69
|
// filter out headers, so we add it here.
|
|
65
70
|
'content-length'
|
|
66
|
-
]
|
|
71
|
+
])
|
|
67
72
|
|
|
68
|
-
|
|
69
|
-
|
|
73
|
+
/**
|
|
74
|
+
* @see https://fetch.spec.whatwg.org/#enumdef-requestduplex
|
|
75
|
+
*/
|
|
76
|
+
const requestDuplex = /** @type {const} */ ([
|
|
70
77
|
'half'
|
|
71
|
-
]
|
|
78
|
+
])
|
|
72
79
|
|
|
73
|
-
|
|
74
|
-
|
|
80
|
+
/**
|
|
81
|
+
* @see http://fetch.spec.whatwg.org/#forbidden-method
|
|
82
|
+
*/
|
|
83
|
+
const forbiddenMethods = /** @type {const} */ (['CONNECT', 'TRACE', 'TRACK'])
|
|
75
84
|
const forbiddenMethodsSet = new Set(forbiddenMethods)
|
|
76
85
|
|
|
77
|
-
const subresource = [
|
|
86
|
+
const subresource = /** @type {const} */ ([
|
|
78
87
|
'audio',
|
|
79
88
|
'audioworklet',
|
|
80
89
|
'font',
|
|
@@ -87,7 +96,7 @@ const subresource = [
|
|
|
87
96
|
'video',
|
|
88
97
|
'xslt',
|
|
89
98
|
''
|
|
90
|
-
]
|
|
99
|
+
])
|
|
91
100
|
const subresourceSet = new Set(subresource)
|
|
92
101
|
|
|
93
102
|
module.exports = {
|
|
@@ -431,7 +431,7 @@ function parseMIMEType (input) {
|
|
|
431
431
|
/** @param {string} data */
|
|
432
432
|
function forgivingBase64 (data) {
|
|
433
433
|
// 1. Remove all ASCII whitespace from data.
|
|
434
|
-
data = data.replace(ASCII_WHITESPACE_REPLACE_REGEX, '')
|
|
434
|
+
data = data.replace(ASCII_WHITESPACE_REPLACE_REGEX, '')
|
|
435
435
|
|
|
436
436
|
let dataLength = data.length
|
|
437
437
|
// 2. If data’s code point length divides by 4 leaving
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
const { isUSVString, bufferToLowerCasedHeaderName } = require('../../core/util')
|
|
4
4
|
const { utf8DecodeBytes } = require('./util')
|
|
5
5
|
const { HTTP_TOKEN_CODEPOINTS, isomorphicDecode } = require('./data-url')
|
|
6
|
-
const { isFileLike } = require('./file')
|
|
7
6
|
const { makeEntry } = require('./formdata')
|
|
7
|
+
const { webidl } = require('./webidl')
|
|
8
8
|
const assert = require('node:assert')
|
|
9
9
|
const { File: NodeFile } = require('node:buffer')
|
|
10
10
|
|
|
@@ -205,7 +205,7 @@ function multipartFormDataParser (input, mimeType) {
|
|
|
205
205
|
|
|
206
206
|
// 5.12. Assert: name is a scalar value string and value is either a scalar value string or a File object.
|
|
207
207
|
assert(isUSVString(name))
|
|
208
|
-
assert((typeof value === 'string' && isUSVString(value)) ||
|
|
208
|
+
assert((typeof value === 'string' && isUSVString(value)) || webidl.is.File(value))
|
|
209
209
|
|
|
210
210
|
// 5.13. Create an entry with name and value, and append it to entry list.
|
|
211
211
|
entryList.push(makeEntry(name, value, filename))
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const {
|
|
4
|
-
const { kState } = require('./symbols')
|
|
3
|
+
const { iteratorMixin } = require('./util')
|
|
5
4
|
const { kEnumerableProperty } = require('../../core/util')
|
|
6
|
-
const { FileLike, isFileLike } = require('./file')
|
|
7
5
|
const { webidl } = require('./webidl')
|
|
8
6
|
const { File: NativeFile } = require('node:buffer')
|
|
9
7
|
const nodeUtil = require('node:util')
|
|
@@ -13,6 +11,8 @@ const File = globalThis.File ?? NativeFile
|
|
|
13
11
|
|
|
14
12
|
// https://xhr.spec.whatwg.org/#formdata
|
|
15
13
|
class FormData {
|
|
14
|
+
#state = []
|
|
15
|
+
|
|
16
16
|
constructor (form) {
|
|
17
17
|
if (form !== undefined) {
|
|
18
18
|
throw webidl.errors.conversionFailed({
|
|
@@ -21,8 +21,6 @@ class FormData {
|
|
|
21
21
|
types: ['undefined']
|
|
22
22
|
})
|
|
23
23
|
}
|
|
24
|
-
|
|
25
|
-
this[kState] = []
|
|
26
24
|
}
|
|
27
25
|
|
|
28
26
|
append (name, value, filename = undefined) {
|
|
@@ -31,28 +29,26 @@ class FormData {
|
|
|
31
29
|
const prefix = 'FormData.append'
|
|
32
30
|
webidl.argumentLengthCheck(arguments, 2, prefix)
|
|
33
31
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
)
|
|
32
|
+
name = webidl.converters.USVString(name)
|
|
33
|
+
|
|
34
|
+
if (arguments.length === 3 || webidl.is.Blob(value)) {
|
|
35
|
+
value = webidl.converters.Blob(value, prefix, 'value')
|
|
36
|
+
|
|
37
|
+
if (filename !== undefined) {
|
|
38
|
+
filename = webidl.converters.USVString(filename)
|
|
39
|
+
}
|
|
40
|
+
} else {
|
|
41
|
+
value = webidl.converters.USVString(value)
|
|
38
42
|
}
|
|
39
43
|
|
|
40
44
|
// 1. Let value be value if given; otherwise blobValue.
|
|
41
45
|
|
|
42
|
-
name = webidl.converters.USVString(name, prefix, 'name')
|
|
43
|
-
value = isBlobLike(value)
|
|
44
|
-
? webidl.converters.Blob(value, prefix, 'value', { strict: false })
|
|
45
|
-
: webidl.converters.USVString(value, prefix, 'value')
|
|
46
|
-
filename = arguments.length === 3
|
|
47
|
-
? webidl.converters.USVString(filename, prefix, 'filename')
|
|
48
|
-
: undefined
|
|
49
|
-
|
|
50
46
|
// 2. Let entry be the result of creating an entry with
|
|
51
47
|
// name, value, and filename if given.
|
|
52
48
|
const entry = makeEntry(name, value, filename)
|
|
53
49
|
|
|
54
50
|
// 3. Append entry to this’s entry list.
|
|
55
|
-
this
|
|
51
|
+
this.#state.push(entry)
|
|
56
52
|
}
|
|
57
53
|
|
|
58
54
|
delete (name) {
|
|
@@ -61,11 +57,11 @@ class FormData {
|
|
|
61
57
|
const prefix = 'FormData.delete'
|
|
62
58
|
webidl.argumentLengthCheck(arguments, 1, prefix)
|
|
63
59
|
|
|
64
|
-
name = webidl.converters.USVString(name
|
|
60
|
+
name = webidl.converters.USVString(name)
|
|
65
61
|
|
|
66
62
|
// The delete(name) method steps are to remove all entries whose name
|
|
67
63
|
// is name from this’s entry list.
|
|
68
|
-
this
|
|
64
|
+
this.#state = this.#state.filter(entry => entry.name !== name)
|
|
69
65
|
}
|
|
70
66
|
|
|
71
67
|
get (name) {
|
|
@@ -74,18 +70,18 @@ class FormData {
|
|
|
74
70
|
const prefix = 'FormData.get'
|
|
75
71
|
webidl.argumentLengthCheck(arguments, 1, prefix)
|
|
76
72
|
|
|
77
|
-
name = webidl.converters.USVString(name
|
|
73
|
+
name = webidl.converters.USVString(name)
|
|
78
74
|
|
|
79
75
|
// 1. If there is no entry whose name is name in this’s entry list,
|
|
80
76
|
// then return null.
|
|
81
|
-
const idx = this
|
|
77
|
+
const idx = this.#state.findIndex((entry) => entry.name === name)
|
|
82
78
|
if (idx === -1) {
|
|
83
79
|
return null
|
|
84
80
|
}
|
|
85
81
|
|
|
86
82
|
// 2. Return the value of the first entry whose name is name from
|
|
87
83
|
// this’s entry list.
|
|
88
|
-
return this[
|
|
84
|
+
return this.#state[idx].value
|
|
89
85
|
}
|
|
90
86
|
|
|
91
87
|
getAll (name) {
|
|
@@ -94,13 +90,13 @@ class FormData {
|
|
|
94
90
|
const prefix = 'FormData.getAll'
|
|
95
91
|
webidl.argumentLengthCheck(arguments, 1, prefix)
|
|
96
92
|
|
|
97
|
-
name = webidl.converters.USVString(name
|
|
93
|
+
name = webidl.converters.USVString(name)
|
|
98
94
|
|
|
99
95
|
// 1. If there is no entry whose name is name in this’s entry list,
|
|
100
96
|
// then return the empty list.
|
|
101
97
|
// 2. Return the values of all entries whose name is name, in order,
|
|
102
98
|
// from this’s entry list.
|
|
103
|
-
return this
|
|
99
|
+
return this.#state
|
|
104
100
|
.filter((entry) => entry.name === name)
|
|
105
101
|
.map((entry) => entry.value)
|
|
106
102
|
}
|
|
@@ -111,11 +107,11 @@ class FormData {
|
|
|
111
107
|
const prefix = 'FormData.has'
|
|
112
108
|
webidl.argumentLengthCheck(arguments, 1, prefix)
|
|
113
109
|
|
|
114
|
-
name = webidl.converters.USVString(name
|
|
110
|
+
name = webidl.converters.USVString(name)
|
|
115
111
|
|
|
116
112
|
// The has(name) method steps are to return true if there is an entry
|
|
117
113
|
// whose name is name in this’s entry list; otherwise false.
|
|
118
|
-
return this
|
|
114
|
+
return this.#state.findIndex((entry) => entry.name === name) !== -1
|
|
119
115
|
}
|
|
120
116
|
|
|
121
117
|
set (name, value, filename = undefined) {
|
|
@@ -124,10 +120,16 @@ class FormData {
|
|
|
124
120
|
const prefix = 'FormData.set'
|
|
125
121
|
webidl.argumentLengthCheck(arguments, 2, prefix)
|
|
126
122
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
)
|
|
123
|
+
name = webidl.converters.USVString(name)
|
|
124
|
+
|
|
125
|
+
if (arguments.length === 3 || webidl.is.Blob(value)) {
|
|
126
|
+
value = webidl.converters.Blob(value, prefix, 'value')
|
|
127
|
+
|
|
128
|
+
if (filename !== undefined) {
|
|
129
|
+
filename = webidl.converters.USVString(filename)
|
|
130
|
+
}
|
|
131
|
+
} else {
|
|
132
|
+
value = webidl.converters.USVString(value)
|
|
131
133
|
}
|
|
132
134
|
|
|
133
135
|
// The set(name, value) and set(name, blobValue, filename) method steps
|
|
@@ -135,35 +137,27 @@ class FormData {
|
|
|
135
137
|
|
|
136
138
|
// 1. Let value be value if given; otherwise blobValue.
|
|
137
139
|
|
|
138
|
-
name = webidl.converters.USVString(name, prefix, 'name')
|
|
139
|
-
value = isBlobLike(value)
|
|
140
|
-
? webidl.converters.Blob(value, prefix, 'name', { strict: false })
|
|
141
|
-
: webidl.converters.USVString(value, prefix, 'name')
|
|
142
|
-
filename = arguments.length === 3
|
|
143
|
-
? webidl.converters.USVString(filename, prefix, 'name')
|
|
144
|
-
: undefined
|
|
145
|
-
|
|
146
140
|
// 2. Let entry be the result of creating an entry with name, value, and
|
|
147
141
|
// filename if given.
|
|
148
142
|
const entry = makeEntry(name, value, filename)
|
|
149
143
|
|
|
150
144
|
// 3. If there are entries in this’s entry list whose name is name, then
|
|
151
145
|
// replace the first such entry with entry and remove the others.
|
|
152
|
-
const idx = this
|
|
146
|
+
const idx = this.#state.findIndex((entry) => entry.name === name)
|
|
153
147
|
if (idx !== -1) {
|
|
154
|
-
this
|
|
155
|
-
...this
|
|
148
|
+
this.#state = [
|
|
149
|
+
...this.#state.slice(0, idx),
|
|
156
150
|
entry,
|
|
157
|
-
...this
|
|
151
|
+
...this.#state.slice(idx + 1).filter((entry) => entry.name !== name)
|
|
158
152
|
]
|
|
159
153
|
} else {
|
|
160
154
|
// 4. Otherwise, append entry to this’s entry list.
|
|
161
|
-
this
|
|
155
|
+
this.#state.push(entry)
|
|
162
156
|
}
|
|
163
157
|
}
|
|
164
158
|
|
|
165
159
|
[nodeUtil.inspect.custom] (depth, options) {
|
|
166
|
-
const state = this
|
|
160
|
+
const state = this.#state.reduce((a, b) => {
|
|
167
161
|
if (a[b.name]) {
|
|
168
162
|
if (Array.isArray(a[b.name])) {
|
|
169
163
|
a[b.name].push(b.value)
|
|
@@ -185,9 +179,28 @@ class FormData {
|
|
|
185
179
|
// remove [Object null prototype]
|
|
186
180
|
return `FormData ${output.slice(output.indexOf(']') + 2)}`
|
|
187
181
|
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* @param {FormData} formData
|
|
185
|
+
*/
|
|
186
|
+
static getFormDataState (formData) {
|
|
187
|
+
return formData.#state
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* @param {FormData} formData
|
|
192
|
+
* @param {any[]} newState
|
|
193
|
+
*/
|
|
194
|
+
static setFormDataState (formData, newState) {
|
|
195
|
+
formData.#state = newState
|
|
196
|
+
}
|
|
188
197
|
}
|
|
189
198
|
|
|
190
|
-
|
|
199
|
+
const { getFormDataState, setFormDataState } = FormData
|
|
200
|
+
Reflect.deleteProperty(FormData, 'getFormDataState')
|
|
201
|
+
Reflect.deleteProperty(FormData, 'setFormDataState')
|
|
202
|
+
|
|
203
|
+
iteratorMixin('FormData', FormData, getFormDataState, 'name', 'value')
|
|
191
204
|
|
|
192
205
|
Object.defineProperties(FormData.prototype, {
|
|
193
206
|
append: kEnumerableProperty,
|
|
@@ -222,10 +235,8 @@ function makeEntry (name, value, filename) {
|
|
|
222
235
|
|
|
223
236
|
// 1. If value is not a File object, then set value to a new File object,
|
|
224
237
|
// representing the same bytes, whose name attribute value is "blob"
|
|
225
|
-
if (!
|
|
226
|
-
value = value
|
|
227
|
-
? new File([value], 'blob', { type: value.type })
|
|
228
|
-
: new FileLike(value, 'blob', { type: value.type })
|
|
238
|
+
if (!webidl.is.File(value)) {
|
|
239
|
+
value = new File([value], 'blob', { type: value.type })
|
|
229
240
|
}
|
|
230
241
|
|
|
231
242
|
// 2. If filename is given, then set value to a new File object,
|
|
@@ -237,9 +248,7 @@ function makeEntry (name, value, filename) {
|
|
|
237
248
|
lastModified: value.lastModified
|
|
238
249
|
}
|
|
239
250
|
|
|
240
|
-
value = value
|
|
241
|
-
? new File([value], filename, options)
|
|
242
|
-
: new FileLike(value, filename, options)
|
|
251
|
+
value = new File([value], filename, options)
|
|
243
252
|
}
|
|
244
253
|
}
|
|
245
254
|
|
|
@@ -247,4 +256,6 @@ function makeEntry (name, value, filename) {
|
|
|
247
256
|
return { name, value }
|
|
248
257
|
}
|
|
249
258
|
|
|
250
|
-
|
|
259
|
+
webidl.is.FormData = webidl.util.MakeTypeAssertion(FormData.prototype)
|
|
260
|
+
|
|
261
|
+
module.exports = { FormData, makeEntry, setFormDataState }
|