index.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788
  1. 'use strict'
  2. const { types, inspect } = require('node:util')
  3. const { markAsUncloneable } = require('node:worker_threads')
  4. const UNDEFINED = 1
  5. const BOOLEAN = 2
  6. const STRING = 3
  7. const SYMBOL = 4
  8. const NUMBER = 5
  9. const BIGINT = 6
  10. const NULL = 7
  11. const OBJECT = 8 // function and object
  12. const FunctionPrototypeSymbolHasInstance = Function.call.bind(Function.prototype[Symbol.hasInstance])
  13. /** @type {import('../../../types/webidl').Webidl} */
  14. const webidl = {
  15. converters: {},
  16. util: {},
  17. errors: {},
  18. is: {}
  19. }
  20. /**
  21. * @description Instantiate an error.
  22. *
  23. * @param {Object} opts
  24. * @param {string} opts.header
  25. * @param {string} opts.message
  26. * @returns {TypeError}
  27. */
  28. webidl.errors.exception = function (message) {
  29. return new TypeError(`${message.header}: ${message.message}`)
  30. }
  31. /**
  32. * @description Instantiate an error when conversion from one type to another has failed.
  33. *
  34. * @param {Object} opts
  35. * @param {string} opts.prefix
  36. * @param {string} opts.argument
  37. * @param {string[]} opts.types
  38. * @returns {TypeError}
  39. */
  40. webidl.errors.conversionFailed = function (opts) {
  41. const plural = opts.types.length === 1 ? '' : ' one of'
  42. const message =
  43. `${opts.argument} could not be converted to` +
  44. `${plural}: ${opts.types.join(', ')}.`
  45. return webidl.errors.exception({
  46. header: opts.prefix,
  47. message
  48. })
  49. }
  50. /**
  51. * @description Instantiate an error when an invalid argument is provided
  52. *
  53. * @param {Object} context
  54. * @param {string} context.prefix
  55. * @param {string} context.value
  56. * @param {string} context.type
  57. * @returns {TypeError}
  58. */
  59. webidl.errors.invalidArgument = function (context) {
  60. return webidl.errors.exception({
  61. header: context.prefix,
  62. message: `"${context.value}" is an invalid ${context.type}.`
  63. })
  64. }
  65. // https://webidl.spec.whatwg.org/#implements
  66. webidl.brandCheck = function (V, I) {
  67. if (!FunctionPrototypeSymbolHasInstance(I, V)) {
  68. const err = new TypeError('Illegal invocation')
  69. err.code = 'ERR_INVALID_THIS' // node compat.
  70. throw err
  71. }
  72. }
  73. webidl.brandCheckMultiple = function (List) {
  74. const prototypes = List.map((c) => webidl.util.MakeTypeAssertion(c))
  75. return (V) => {
  76. if (prototypes.every(typeCheck => !typeCheck(V))) {
  77. const err = new TypeError('Illegal invocation')
  78. err.code = 'ERR_INVALID_THIS' // node compat.
  79. throw err
  80. }
  81. }
  82. }
  83. webidl.argumentLengthCheck = function ({ length }, min, ctx) {
  84. if (length < min) {
  85. throw webidl.errors.exception({
  86. message: `${min} argument${min !== 1 ? 's' : ''} required, ` +
  87. `but${length ? ' only' : ''} ${length} found.`,
  88. header: ctx
  89. })
  90. }
  91. }
  92. webidl.illegalConstructor = function () {
  93. throw webidl.errors.exception({
  94. header: 'TypeError',
  95. message: 'Illegal constructor'
  96. })
  97. }
  98. webidl.util.MakeTypeAssertion = function (I) {
  99. return (O) => FunctionPrototypeSymbolHasInstance(I, O)
  100. }
  101. // https://tc39.es/ecma262/#sec-ecmascript-data-types-and-values
  102. webidl.util.Type = function (V) {
  103. switch (typeof V) {
  104. case 'undefined': return UNDEFINED
  105. case 'boolean': return BOOLEAN
  106. case 'string': return STRING
  107. case 'symbol': return SYMBOL
  108. case 'number': return NUMBER
  109. case 'bigint': return BIGINT
  110. case 'function':
  111. case 'object': {
  112. if (V === null) {
  113. return NULL
  114. }
  115. return OBJECT
  116. }
  117. }
  118. }
  119. webidl.util.Types = {
  120. UNDEFINED,
  121. BOOLEAN,
  122. STRING,
  123. SYMBOL,
  124. NUMBER,
  125. BIGINT,
  126. NULL,
  127. OBJECT
  128. }
  129. webidl.util.TypeValueToString = function (o) {
  130. switch (webidl.util.Type(o)) {
  131. case UNDEFINED: return 'Undefined'
  132. case BOOLEAN: return 'Boolean'
  133. case STRING: return 'String'
  134. case SYMBOL: return 'Symbol'
  135. case NUMBER: return 'Number'
  136. case BIGINT: return 'BigInt'
  137. case NULL: return 'Null'
  138. case OBJECT: return 'Object'
  139. }
  140. }
  141. webidl.util.markAsUncloneable = markAsUncloneable || (() => {})
  142. // https://webidl.spec.whatwg.org/#abstract-opdef-converttoint
  143. webidl.util.ConvertToInt = function (V, bitLength, signedness, opts) {
  144. let upperBound
  145. let lowerBound
  146. // 1. If bitLength is 64, then:
  147. if (bitLength === 64) {
  148. // 1. Let upperBound be 2^53 − 1.
  149. upperBound = Math.pow(2, 53) - 1
  150. // 2. If signedness is "unsigned", then let lowerBound be 0.
  151. if (signedness === 'unsigned') {
  152. lowerBound = 0
  153. } else {
  154. // 3. Otherwise let lowerBound be −2^53 + 1.
  155. lowerBound = Math.pow(-2, 53) + 1
  156. }
  157. } else if (signedness === 'unsigned') {
  158. // 2. Otherwise, if signedness is "unsigned", then:
  159. // 1. Let lowerBound be 0.
  160. lowerBound = 0
  161. // 2. Let upperBound be 2^bitLength − 1.
  162. upperBound = Math.pow(2, bitLength) - 1
  163. } else {
  164. // 3. Otherwise:
  165. // 1. Let lowerBound be -2^bitLength − 1.
  166. lowerBound = Math.pow(-2, bitLength) - 1
  167. // 2. Let upperBound be 2^bitLength − 1 − 1.
  168. upperBound = Math.pow(2, bitLength - 1) - 1
  169. }
  170. // 4. Let x be ? ToNumber(V).
  171. let x = Number(V)
  172. // 5. If x is −0, then set x to +0.
  173. if (x === 0) {
  174. x = 0
  175. }
  176. // 6. If the conversion is to an IDL type associated
  177. // with the [EnforceRange] extended attribute, then:
  178. if (opts?.enforceRange === true) {
  179. // 1. If x is NaN, +∞, or −∞, then throw a TypeError.
  180. if (
  181. Number.isNaN(x) ||
  182. x === Number.POSITIVE_INFINITY ||
  183. x === Number.NEGATIVE_INFINITY
  184. ) {
  185. throw webidl.errors.exception({
  186. header: 'Integer conversion',
  187. message: `Could not convert ${webidl.util.Stringify(V)} to an integer.`
  188. })
  189. }
  190. // 2. Set x to IntegerPart(x).
  191. x = webidl.util.IntegerPart(x)
  192. // 3. If x < lowerBound or x > upperBound, then
  193. // throw a TypeError.
  194. if (x < lowerBound || x > upperBound) {
  195. throw webidl.errors.exception({
  196. header: 'Integer conversion',
  197. message: `Value must be between ${lowerBound}-${upperBound}, got ${x}.`
  198. })
  199. }
  200. // 4. Return x.
  201. return x
  202. }
  203. // 7. If x is not NaN and the conversion is to an IDL
  204. // type associated with the [Clamp] extended
  205. // attribute, then:
  206. if (!Number.isNaN(x) && opts?.clamp === true) {
  207. // 1. Set x to min(max(x, lowerBound), upperBound).
  208. x = Math.min(Math.max(x, lowerBound), upperBound)
  209. // 2. Round x to the nearest integer, choosing the
  210. // even integer if it lies halfway between two,
  211. // and choosing +0 rather than −0.
  212. if (Math.floor(x) % 2 === 0) {
  213. x = Math.floor(x)
  214. } else {
  215. x = Math.ceil(x)
  216. }
  217. // 3. Return x.
  218. return x
  219. }
  220. // 8. If x is NaN, +0, +∞, or −∞, then return +0.
  221. if (
  222. Number.isNaN(x) ||
  223. (x === 0 && Object.is(0, x)) ||
  224. x === Number.POSITIVE_INFINITY ||
  225. x === Number.NEGATIVE_INFINITY
  226. ) {
  227. return 0
  228. }
  229. // 9. Set x to IntegerPart(x).
  230. x = webidl.util.IntegerPart(x)
  231. // 10. Set x to x modulo 2^bitLength.
  232. x = x % Math.pow(2, bitLength)
  233. // 11. If signedness is "signed" and x ≥ 2^bitLength − 1,
  234. // then return x − 2^bitLength.
  235. if (signedness === 'signed' && x >= Math.pow(2, bitLength) - 1) {
  236. return x - Math.pow(2, bitLength)
  237. }
  238. // 12. Otherwise, return x.
  239. return x
  240. }
  241. // https://webidl.spec.whatwg.org/#abstract-opdef-integerpart
  242. webidl.util.IntegerPart = function (n) {
  243. // 1. Let r be floor(abs(n)).
  244. const r = Math.floor(Math.abs(n))
  245. // 2. If n < 0, then return -1 × r.
  246. if (n < 0) {
  247. return -1 * r
  248. }
  249. // 3. Otherwise, return r.
  250. return r
  251. }
  252. webidl.util.Stringify = function (V) {
  253. const type = webidl.util.Type(V)
  254. switch (type) {
  255. case SYMBOL:
  256. return `Symbol(${V.description})`
  257. case OBJECT:
  258. return inspect(V)
  259. case STRING:
  260. return `"${V}"`
  261. case BIGINT:
  262. return `${V}n`
  263. default:
  264. return `${V}`
  265. }
  266. }
  267. // https://webidl.spec.whatwg.org/#es-sequence
  268. webidl.sequenceConverter = function (converter) {
  269. return (V, prefix, argument, Iterable) => {
  270. // 1. If Type(V) is not Object, throw a TypeError.
  271. if (webidl.util.Type(V) !== OBJECT) {
  272. throw webidl.errors.exception({
  273. header: prefix,
  274. message: `${argument} (${webidl.util.Stringify(V)}) is not iterable.`
  275. })
  276. }
  277. // 2. Let method be ? GetMethod(V, @@iterator).
  278. /** @type {Generator} */
  279. const method = typeof Iterable === 'function' ? Iterable() : V?.[Symbol.iterator]?.()
  280. const seq = []
  281. let index = 0
  282. // 3. If method is undefined, throw a TypeError.
  283. if (
  284. method === undefined ||
  285. typeof method.next !== 'function'
  286. ) {
  287. throw webidl.errors.exception({
  288. header: prefix,
  289. message: `${argument} is not iterable.`
  290. })
  291. }
  292. // https://webidl.spec.whatwg.org/#create-sequence-from-iterable
  293. while (true) {
  294. const { done, value } = method.next()
  295. if (done) {
  296. break
  297. }
  298. seq.push(converter(value, prefix, `${argument}[${index++}]`))
  299. }
  300. return seq
  301. }
  302. }
  303. // https://webidl.spec.whatwg.org/#es-to-record
  304. webidl.recordConverter = function (keyConverter, valueConverter) {
  305. return (O, prefix, argument) => {
  306. // 1. If Type(O) is not Object, throw a TypeError.
  307. if (webidl.util.Type(O) !== OBJECT) {
  308. throw webidl.errors.exception({
  309. header: prefix,
  310. message: `${argument} ("${webidl.util.TypeValueToString(O)}") is not an Object.`
  311. })
  312. }
  313. // 2. Let result be a new empty instance of record<K, V>.
  314. const result = {}
  315. if (!types.isProxy(O)) {
  316. // 1. Let desc be ? O.[[GetOwnProperty]](key).
  317. const keys = [...Object.getOwnPropertyNames(O), ...Object.getOwnPropertySymbols(O)]
  318. for (const key of keys) {
  319. const keyName = webidl.util.Stringify(key)
  320. // 1. Let typedKey be key converted to an IDL value of type K.
  321. const typedKey = keyConverter(key, prefix, `Key ${keyName} in ${argument}`)
  322. // 2. Let value be ? Get(O, key).
  323. // 3. Let typedValue be value converted to an IDL value of type V.
  324. const typedValue = valueConverter(O[key], prefix, `${argument}[${keyName}]`)
  325. // 4. Set result[typedKey] to typedValue.
  326. result[typedKey] = typedValue
  327. }
  328. // 5. Return result.
  329. return result
  330. }
  331. // 3. Let keys be ? O.[[OwnPropertyKeys]]().
  332. const keys = Reflect.ownKeys(O)
  333. // 4. For each key of keys.
  334. for (const key of keys) {
  335. // 1. Let desc be ? O.[[GetOwnProperty]](key).
  336. const desc = Reflect.getOwnPropertyDescriptor(O, key)
  337. // 2. If desc is not undefined and desc.[[Enumerable]] is true:
  338. if (desc?.enumerable) {
  339. // 1. Let typedKey be key converted to an IDL value of type K.
  340. const typedKey = keyConverter(key, prefix, argument)
  341. // 2. Let value be ? Get(O, key).
  342. // 3. Let typedValue be value converted to an IDL value of type V.
  343. const typedValue = valueConverter(O[key], prefix, argument)
  344. // 4. Set result[typedKey] to typedValue.
  345. result[typedKey] = typedValue
  346. }
  347. }
  348. // 5. Return result.
  349. return result
  350. }
  351. }
  352. webidl.interfaceConverter = function (TypeCheck, name) {
  353. return (V, prefix, argument) => {
  354. if (!TypeCheck(V)) {
  355. throw webidl.errors.exception({
  356. header: prefix,
  357. message: `Expected ${argument} ("${webidl.util.Stringify(V)}") to be an instance of ${name}.`
  358. })
  359. }
  360. return V
  361. }
  362. }
  363. webidl.dictionaryConverter = function (converters) {
  364. return (dictionary, prefix, argument) => {
  365. const dict = {}
  366. if (dictionary != null && webidl.util.Type(dictionary) !== OBJECT) {
  367. throw webidl.errors.exception({
  368. header: prefix,
  369. message: `Expected ${dictionary} to be one of: Null, Undefined, Object.`
  370. })
  371. }
  372. for (const options of converters) {
  373. const { key, defaultValue, required, converter } = options
  374. if (required === true) {
  375. if (dictionary == null || !Object.hasOwn(dictionary, key)) {
  376. throw webidl.errors.exception({
  377. header: prefix,
  378. message: `Missing required key "${key}".`
  379. })
  380. }
  381. }
  382. let value = dictionary?.[key]
  383. const hasDefault = defaultValue !== undefined
  384. // Only use defaultValue if value is undefined and
  385. // a defaultValue options was provided.
  386. if (hasDefault && value === undefined) {
  387. value = defaultValue()
  388. }
  389. // A key can be optional and have no default value.
  390. // When this happens, do not perform a conversion,
  391. // and do not assign the key a value.
  392. if (required || hasDefault || value !== undefined) {
  393. value = converter(value, prefix, `${argument}.${key}`)
  394. if (
  395. options.allowedValues &&
  396. !options.allowedValues.includes(value)
  397. ) {
  398. throw webidl.errors.exception({
  399. header: prefix,
  400. message: `${value} is not an accepted type. Expected one of ${options.allowedValues.join(', ')}.`
  401. })
  402. }
  403. dict[key] = value
  404. }
  405. }
  406. return dict
  407. }
  408. }
  409. webidl.nullableConverter = function (converter) {
  410. return (V, prefix, argument) => {
  411. if (V === null) {
  412. return V
  413. }
  414. return converter(V, prefix, argument)
  415. }
  416. }
  417. /**
  418. * @param {*} value
  419. * @returns {boolean}
  420. */
  421. webidl.is.USVString = function (value) {
  422. return (
  423. typeof value === 'string' &&
  424. value.isWellFormed()
  425. )
  426. }
  427. webidl.is.ReadableStream = webidl.util.MakeTypeAssertion(ReadableStream)
  428. webidl.is.Blob = webidl.util.MakeTypeAssertion(Blob)
  429. webidl.is.URLSearchParams = webidl.util.MakeTypeAssertion(URLSearchParams)
  430. webidl.is.File = webidl.util.MakeTypeAssertion(globalThis.File ?? require('node:buffer').File)
  431. webidl.is.URL = webidl.util.MakeTypeAssertion(URL)
  432. webidl.is.AbortSignal = webidl.util.MakeTypeAssertion(AbortSignal)
  433. webidl.is.MessagePort = webidl.util.MakeTypeAssertion(MessagePort)
  434. // https://webidl.spec.whatwg.org/#es-DOMString
  435. webidl.converters.DOMString = function (V, prefix, argument, opts) {
  436. // 1. If V is null and the conversion is to an IDL type
  437. // associated with the [LegacyNullToEmptyString]
  438. // extended attribute, then return the DOMString value
  439. // that represents the empty string.
  440. if (V === null && opts?.legacyNullToEmptyString) {
  441. return ''
  442. }
  443. // 2. Let x be ? ToString(V).
  444. if (typeof V === 'symbol') {
  445. throw webidl.errors.exception({
  446. header: prefix,
  447. message: `${argument} is a symbol, which cannot be converted to a DOMString.`
  448. })
  449. }
  450. // 3. Return the IDL DOMString value that represents the
  451. // same sequence of code units as the one the
  452. // ECMAScript String value x represents.
  453. return String(V)
  454. }
  455. // https://webidl.spec.whatwg.org/#es-ByteString
  456. webidl.converters.ByteString = function (V, prefix, argument) {
  457. // 1. Let x be ? ToString(V).
  458. if (typeof V === 'symbol') {
  459. throw webidl.errors.exception({
  460. header: prefix,
  461. message: `${argument} is a symbol, which cannot be converted to a ByteString.`
  462. })
  463. }
  464. const x = String(V)
  465. // 2. If the value of any element of x is greater than
  466. // 255, then throw a TypeError.
  467. for (let index = 0; index < x.length; index++) {
  468. if (x.charCodeAt(index) > 255) {
  469. throw new TypeError(
  470. 'Cannot convert argument to a ByteString because the character at ' +
  471. `index ${index} has a value of ${x.charCodeAt(index)} which is greater than 255.`
  472. )
  473. }
  474. }
  475. // 3. Return an IDL ByteString value whose length is the
  476. // length of x, and where the value of each element is
  477. // the value of the corresponding element of x.
  478. return x
  479. }
  480. /**
  481. * @param {unknown} value
  482. * @returns {string}
  483. * @see https://webidl.spec.whatwg.org/#es-USVString
  484. */
  485. webidl.converters.USVString = function (value) {
  486. // TODO: rewrite this so we can control the errors thrown
  487. if (typeof value === 'string') {
  488. return value.toWellFormed()
  489. }
  490. return `${value}`.toWellFormed()
  491. }
  492. // https://webidl.spec.whatwg.org/#es-boolean
  493. webidl.converters.boolean = function (V) {
  494. // 1. Let x be the result of computing ToBoolean(V).
  495. // https://262.ecma-international.org/10.0/index.html#table-10
  496. const x = Boolean(V)
  497. // 2. Return the IDL boolean value that is the one that represents
  498. // the same truth value as the ECMAScript Boolean value x.
  499. return x
  500. }
  501. // https://webidl.spec.whatwg.org/#es-any
  502. webidl.converters.any = function (V) {
  503. return V
  504. }
  505. // https://webidl.spec.whatwg.org/#es-long-long
  506. webidl.converters['long long'] = function (V, prefix, argument) {
  507. // 1. Let x be ? ConvertToInt(V, 64, "signed").
  508. const x = webidl.util.ConvertToInt(V, 64, 'signed', undefined, prefix, argument)
  509. // 2. Return the IDL long long value that represents
  510. // the same numeric value as x.
  511. return x
  512. }
  513. // https://webidl.spec.whatwg.org/#es-unsigned-long-long
  514. webidl.converters['unsigned long long'] = function (V, prefix, argument) {
  515. // 1. Let x be ? ConvertToInt(V, 64, "unsigned").
  516. const x = webidl.util.ConvertToInt(V, 64, 'unsigned', undefined, prefix, argument)
  517. // 2. Return the IDL unsigned long long value that
  518. // represents the same numeric value as x.
  519. return x
  520. }
  521. // https://webidl.spec.whatwg.org/#es-unsigned-long
  522. webidl.converters['unsigned long'] = function (V, prefix, argument) {
  523. // 1. Let x be ? ConvertToInt(V, 32, "unsigned").
  524. const x = webidl.util.ConvertToInt(V, 32, 'unsigned', undefined, prefix, argument)
  525. // 2. Return the IDL unsigned long value that
  526. // represents the same numeric value as x.
  527. return x
  528. }
  529. // https://webidl.spec.whatwg.org/#es-unsigned-short
  530. webidl.converters['unsigned short'] = function (V, prefix, argument, opts) {
  531. // 1. Let x be ? ConvertToInt(V, 16, "unsigned").
  532. const x = webidl.util.ConvertToInt(V, 16, 'unsigned', opts, prefix, argument)
  533. // 2. Return the IDL unsigned short value that represents
  534. // the same numeric value as x.
  535. return x
  536. }
  537. // https://webidl.spec.whatwg.org/#idl-ArrayBuffer
  538. webidl.converters.ArrayBuffer = function (V, prefix, argument, opts) {
  539. // 1. If Type(V) is not Object, or V does not have an
  540. // [[ArrayBufferData]] internal slot, then throw a
  541. // TypeError.
  542. // see: https://tc39.es/ecma262/#sec-properties-of-the-arraybuffer-instances
  543. // see: https://tc39.es/ecma262/#sec-properties-of-the-sharedarraybuffer-instances
  544. if (
  545. webidl.util.Type(V) !== OBJECT ||
  546. !types.isAnyArrayBuffer(V)
  547. ) {
  548. throw webidl.errors.conversionFailed({
  549. prefix,
  550. argument: `${argument} ("${webidl.util.Stringify(V)}")`,
  551. types: ['ArrayBuffer']
  552. })
  553. }
  554. // 2. If the conversion is not to an IDL type associated
  555. // with the [AllowShared] extended attribute, and
  556. // IsSharedArrayBuffer(V) is true, then throw a
  557. // TypeError.
  558. if (opts?.allowShared === false && types.isSharedArrayBuffer(V)) {
  559. throw webidl.errors.exception({
  560. header: 'ArrayBuffer',
  561. message: 'SharedArrayBuffer is not allowed.'
  562. })
  563. }
  564. // 3. If the conversion is not to an IDL type associated
  565. // with the [AllowResizable] extended attribute, and
  566. // IsResizableArrayBuffer(V) is true, then throw a
  567. // TypeError.
  568. if (V.resizable || V.growable) {
  569. throw webidl.errors.exception({
  570. header: 'ArrayBuffer',
  571. message: 'Received a resizable ArrayBuffer.'
  572. })
  573. }
  574. // 4. Return the IDL ArrayBuffer value that is a
  575. // reference to the same object as V.
  576. return V
  577. }
  578. webidl.converters.TypedArray = function (V, T, prefix, name, opts) {
  579. // 1. Let T be the IDL type V is being converted to.
  580. // 2. If Type(V) is not Object, or V does not have a
  581. // [[TypedArrayName]] internal slot with a value
  582. // equal to T’s name, then throw a TypeError.
  583. if (
  584. webidl.util.Type(V) !== OBJECT ||
  585. !types.isTypedArray(V) ||
  586. V.constructor.name !== T.name
  587. ) {
  588. throw webidl.errors.conversionFailed({
  589. prefix,
  590. argument: `${name} ("${webidl.util.Stringify(V)}")`,
  591. types: [T.name]
  592. })
  593. }
  594. // 3. If the conversion is not to an IDL type associated
  595. // with the [AllowShared] extended attribute, and
  596. // IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is
  597. // true, then throw a TypeError.
  598. if (opts?.allowShared === false && types.isSharedArrayBuffer(V.buffer)) {
  599. throw webidl.errors.exception({
  600. header: 'ArrayBuffer',
  601. message: 'SharedArrayBuffer is not allowed.'
  602. })
  603. }
  604. // 4. If the conversion is not to an IDL type associated
  605. // with the [AllowResizable] extended attribute, and
  606. // IsResizableArrayBuffer(V.[[ViewedArrayBuffer]]) is
  607. // true, then throw a TypeError.
  608. if (V.buffer.resizable || V.buffer.growable) {
  609. throw webidl.errors.exception({
  610. header: 'ArrayBuffer',
  611. message: 'Received a resizable ArrayBuffer.'
  612. })
  613. }
  614. // 5. Return the IDL value of type T that is a reference
  615. // to the same object as V.
  616. return V
  617. }
  618. webidl.converters.DataView = function (V, prefix, name, opts) {
  619. // 1. If Type(V) is not Object, or V does not have a
  620. // [[DataView]] internal slot, then throw a TypeError.
  621. if (webidl.util.Type(V) !== OBJECT || !types.isDataView(V)) {
  622. throw webidl.errors.exception({
  623. header: prefix,
  624. message: `${name} is not a DataView.`
  625. })
  626. }
  627. // 2. If the conversion is not to an IDL type associated
  628. // with the [AllowShared] extended attribute, and
  629. // IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is true,
  630. // then throw a TypeError.
  631. if (opts?.allowShared === false && types.isSharedArrayBuffer(V.buffer)) {
  632. throw webidl.errors.exception({
  633. header: 'ArrayBuffer',
  634. message: 'SharedArrayBuffer is not allowed.'
  635. })
  636. }
  637. // 3. If the conversion is not to an IDL type associated
  638. // with the [AllowResizable] extended attribute, and
  639. // IsResizableArrayBuffer(V.[[ViewedArrayBuffer]]) is
  640. // true, then throw a TypeError.
  641. if (V.buffer.resizable || V.buffer.growable) {
  642. throw webidl.errors.exception({
  643. header: 'ArrayBuffer',
  644. message: 'Received a resizable ArrayBuffer.'
  645. })
  646. }
  647. // 4. Return the IDL DataView value that is a reference
  648. // to the same object as V.
  649. return V
  650. }
  651. webidl.converters['sequence<ByteString>'] = webidl.sequenceConverter(
  652. webidl.converters.ByteString
  653. )
  654. webidl.converters['sequence<sequence<ByteString>>'] = webidl.sequenceConverter(
  655. webidl.converters['sequence<ByteString>']
  656. )
  657. webidl.converters['record<ByteString, ByteString>'] = webidl.recordConverter(
  658. webidl.converters.ByteString,
  659. webidl.converters.ByteString
  660. )
  661. webidl.converters.Blob = webidl.interfaceConverter(webidl.is.Blob, 'Blob')
  662. webidl.converters.AbortSignal = webidl.interfaceConverter(
  663. webidl.is.AbortSignal,
  664. 'AbortSignal'
  665. )
  666. module.exports = {
  667. webidl
  668. }