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.
Files changed (137) hide show
  1. package/README.md +6 -10
  2. package/docs/docs/api/Agent.md +0 -3
  3. package/docs/docs/api/Client.md +1 -3
  4. package/docs/docs/api/Debug.md +1 -1
  5. package/docs/docs/api/Dispatcher.md +60 -8
  6. package/docs/docs/api/EnvHttpProxyAgent.md +0 -1
  7. package/docs/docs/api/Fetch.md +1 -0
  8. package/docs/docs/api/MockAgent.md +2 -0
  9. package/docs/docs/api/MockPool.md +2 -1
  10. package/docs/docs/api/Pool.md +0 -1
  11. package/docs/docs/api/RetryAgent.md +1 -1
  12. package/docs/docs/api/RetryHandler.md +1 -1
  13. package/docs/docs/api/WebSocket.md +45 -3
  14. package/index.js +6 -6
  15. package/lib/api/abort-signal.js +2 -0
  16. package/lib/api/api-connect.js +3 -1
  17. package/lib/api/api-pipeline.js +7 -6
  18. package/lib/api/api-request.js +32 -47
  19. package/lib/api/api-stream.js +39 -50
  20. package/lib/api/api-upgrade.js +5 -3
  21. package/lib/api/readable.js +261 -64
  22. package/lib/api/util.js +2 -0
  23. package/lib/core/constants.js +11 -9
  24. package/lib/core/diagnostics.js +122 -128
  25. package/lib/core/errors.js +4 -4
  26. package/lib/core/request.js +11 -9
  27. package/lib/core/symbols.js +2 -1
  28. package/lib/core/tree.js +9 -1
  29. package/lib/core/util.js +219 -48
  30. package/lib/dispatcher/agent.js +3 -17
  31. package/lib/dispatcher/balanced-pool.js +5 -8
  32. package/lib/dispatcher/client-h1.js +278 -54
  33. package/lib/dispatcher/client-h2.js +1 -1
  34. package/lib/dispatcher/client.js +23 -34
  35. package/lib/dispatcher/dispatcher-base.js +2 -34
  36. package/lib/dispatcher/dispatcher.js +3 -24
  37. package/lib/dispatcher/fixed-queue.js +91 -49
  38. package/lib/dispatcher/pool-stats.js +2 -0
  39. package/lib/dispatcher/pool.js +3 -6
  40. package/lib/dispatcher/proxy-agent.js +6 -7
  41. package/lib/handler/decorator-handler.js +24 -0
  42. package/lib/handler/redirect-handler.js +11 -2
  43. package/lib/handler/retry-handler.js +12 -3
  44. package/lib/interceptor/dns.js +346 -0
  45. package/lib/interceptor/dump.js +2 -2
  46. package/lib/interceptor/redirect.js +11 -14
  47. package/lib/interceptor/response-error.js +4 -1
  48. package/lib/llhttp/constants.d.ts +97 -0
  49. package/lib/llhttp/constants.js +412 -192
  50. package/lib/llhttp/constants.js.map +1 -0
  51. package/lib/llhttp/llhttp-wasm.js +11 -1
  52. package/lib/llhttp/llhttp_simd-wasm.js +11 -1
  53. package/lib/llhttp/utils.d.ts +2 -0
  54. package/lib/llhttp/utils.js +9 -9
  55. package/lib/llhttp/utils.js.map +1 -0
  56. package/lib/mock/mock-agent.js +5 -8
  57. package/lib/mock/mock-client.js +9 -4
  58. package/lib/mock/mock-errors.js +3 -1
  59. package/lib/mock/mock-interceptor.js +8 -6
  60. package/lib/mock/mock-pool.js +9 -4
  61. package/lib/mock/mock-symbols.js +3 -1
  62. package/lib/mock/mock-utils.js +29 -5
  63. package/lib/web/cache/cache.js +24 -21
  64. package/lib/web/cache/cachestorage.js +1 -1
  65. package/lib/web/cookies/index.js +17 -13
  66. package/lib/web/cookies/parse.js +2 -2
  67. package/lib/web/eventsource/eventsource-stream.js +9 -8
  68. package/lib/web/eventsource/eventsource.js +10 -6
  69. package/lib/web/fetch/body.js +42 -36
  70. package/lib/web/fetch/constants.js +35 -26
  71. package/lib/web/fetch/data-url.js +1 -1
  72. package/lib/web/fetch/formdata-parser.js +2 -2
  73. package/lib/web/fetch/formdata.js +65 -54
  74. package/lib/web/fetch/headers.js +117 -85
  75. package/lib/web/fetch/index.js +55 -62
  76. package/lib/web/fetch/request.js +135 -77
  77. package/lib/web/fetch/response.js +86 -56
  78. package/lib/web/fetch/util.js +90 -64
  79. package/lib/web/fetch/webidl.js +99 -64
  80. package/lib/web/websocket/connection.js +76 -147
  81. package/lib/web/websocket/constants.js +3 -4
  82. package/lib/web/websocket/events.js +4 -2
  83. package/lib/web/websocket/frame.js +45 -3
  84. package/lib/web/websocket/receiver.js +29 -33
  85. package/lib/web/websocket/sender.js +18 -13
  86. package/lib/web/websocket/stream/websocketerror.js +83 -0
  87. package/lib/web/websocket/stream/websocketstream.js +485 -0
  88. package/lib/web/websocket/util.js +128 -77
  89. package/lib/web/websocket/websocket.js +234 -135
  90. package/package.json +20 -33
  91. package/scripts/strip-comments.js +3 -1
  92. package/types/agent.d.ts +7 -7
  93. package/types/api.d.ts +24 -24
  94. package/types/balanced-pool.d.ts +11 -11
  95. package/types/client.d.ts +11 -12
  96. package/types/diagnostics-channel.d.ts +10 -10
  97. package/types/dispatcher.d.ts +96 -97
  98. package/types/env-http-proxy-agent.d.ts +2 -2
  99. package/types/errors.d.ts +53 -47
  100. package/types/fetch.d.ts +8 -8
  101. package/types/formdata.d.ts +7 -7
  102. package/types/global-dispatcher.d.ts +4 -4
  103. package/types/global-origin.d.ts +5 -5
  104. package/types/handlers.d.ts +4 -4
  105. package/types/header.d.ts +157 -1
  106. package/types/index.d.ts +42 -46
  107. package/types/interceptors.d.ts +22 -8
  108. package/types/mock-agent.d.ts +21 -18
  109. package/types/mock-client.d.ts +4 -4
  110. package/types/mock-errors.d.ts +3 -3
  111. package/types/mock-interceptor.d.ts +19 -19
  112. package/types/mock-pool.d.ts +4 -4
  113. package/types/patch.d.ts +0 -4
  114. package/types/pool-stats.d.ts +8 -8
  115. package/types/pool.d.ts +12 -12
  116. package/types/proxy-agent.d.ts +4 -4
  117. package/types/readable.d.ts +22 -14
  118. package/types/retry-agent.d.ts +1 -1
  119. package/types/retry-handler.d.ts +8 -8
  120. package/types/util.d.ts +3 -3
  121. package/types/utility.d.ts +7 -0
  122. package/types/webidl.d.ts +44 -6
  123. package/types/websocket.d.ts +34 -1
  124. package/docs/docs/api/DispatchInterceptor.md +0 -60
  125. package/lib/interceptor/redirect-interceptor.js +0 -21
  126. package/lib/mock/pluralizer.js +0 -29
  127. package/lib/web/cache/symbols.js +0 -5
  128. package/lib/web/fetch/file.js +0 -126
  129. package/lib/web/fetch/symbols.js +0 -9
  130. package/lib/web/fileapi/encoding.js +0 -290
  131. package/lib/web/fileapi/filereader.js +0 -344
  132. package/lib/web/fileapi/progressevent.js +0 -78
  133. package/lib/web/fileapi/symbols.js +0 -10
  134. package/lib/web/fileapi/util.js +0 -391
  135. package/lib/web/websocket/symbols.js +0 -12
  136. package/types/file.d.ts +0 -39
  137. 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
- // https://fetch.spec.whatwg.org/#block-bad-port
12
- const badPorts = [
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
- // https://w3c.github.io/webappsec-referrer-policy/#referrer-policies
24
- const referrerPolicy = [
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
- // https://fetch.spec.whatwg.org/#request-body-header-name
56
- const requestBodyHeader = [
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
- // https://fetch.spec.whatwg.org/#enumdef-requestduplex
69
- const requestDuplex = [
73
+ /**
74
+ * @see https://fetch.spec.whatwg.org/#enumdef-requestduplex
75
+ */
76
+ const requestDuplex = /** @type {const} */ ([
70
77
  'half'
71
- ]
78
+ ])
72
79
 
73
- // http://fetch.spec.whatwg.org/#forbidden-method
74
- const forbiddenMethods = ['CONNECT', 'TRACE', 'TRACK']
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, '') // eslint-disable-line
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)) || isFileLike(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 { isBlobLike, iteratorMixin } = require('./util')
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
- if (arguments.length === 3 && !isBlobLike(value)) {
35
- throw new TypeError(
36
- "Failed to execute 'append' on 'FormData': parameter 2 is not of type 'Blob'"
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[kState].push(entry)
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, prefix, '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[kState] = this[kState].filter(entry => entry.name !== name)
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, prefix, '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[kState].findIndex((entry) => entry.name === name)
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[kState][idx].value
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, prefix, '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[kState]
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, prefix, '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[kState].findIndex((entry) => entry.name === name) !== -1
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
- if (arguments.length === 3 && !isBlobLike(value)) {
128
- throw new TypeError(
129
- "Failed to execute 'set' on 'FormData': parameter 2 is not of type 'Blob'"
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[kState].findIndex((entry) => entry.name === name)
146
+ const idx = this.#state.findIndex((entry) => entry.name === name)
153
147
  if (idx !== -1) {
154
- this[kState] = [
155
- ...this[kState].slice(0, idx),
148
+ this.#state = [
149
+ ...this.#state.slice(0, idx),
156
150
  entry,
157
- ...this[kState].slice(idx + 1).filter((entry) => entry.name !== name)
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[kState].push(entry)
155
+ this.#state.push(entry)
162
156
  }
163
157
  }
164
158
 
165
159
  [nodeUtil.inspect.custom] (depth, options) {
166
- const state = this[kState].reduce((a, b) => {
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
- iteratorMixin('FormData', FormData, kState, 'name', 'value')
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 (!isFileLike(value)) {
226
- value = value instanceof Blob
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 instanceof NativeFile
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
- module.exports = { FormData, makeEntry }
259
+ webidl.is.FormData = webidl.util.MakeTypeAssertion(FormData.prototype)
260
+
261
+ module.exports = { FormData, makeEntry, setFormDataState }