Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

change webidl.util.Type return to an enum value #3520

Merged
merged 1 commit into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/web/fetch/headers.js
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,7 @@ Object.defineProperties(Headers.prototype, {
})

webidl.converters.HeadersInit = function (V, prefix, argument) {
if (webidl.util.Type(V) === 'Object') {
if (webidl.util.Type(V) === webidl.util.Types.OBJECT) {
const iterator = Reflect.get(V, Symbol.iterator)

// A work-around to ensure we send the properly-cased Headers when V is a Headers object.
Expand Down
69 changes: 51 additions & 18 deletions lib/web/fetch/webidl.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@
const { types, inspect } = require('node:util')
const { toUSVString } = require('../../core/util')

const UNDEFINED = 1
const BOOLEAN = 2
const STRING = 3
const SYMBOL = 4
const NUMBER = 5
const BIGINT = 6
const NULL = 7
const OBJECT = 8 // function and object

/** @type {import('../../../types/webidl').Webidl} */
const webidl = {}
webidl.converters = {}
Expand Down Expand Up @@ -69,23 +78,47 @@ webidl.illegalConstructor = function () {
// https://tc39.es/ecma262/#sec-ecmascript-data-types-and-values
webidl.util.Type = function (V) {
switch (typeof V) {
case 'undefined': return 'Undefined'
case 'boolean': return 'Boolean'
case 'string': return 'String'
case 'symbol': return 'Symbol'
case 'number': return 'Number'
case 'bigint': return 'BigInt'
case 'undefined': return UNDEFINED
case 'boolean': return BOOLEAN
case 'string': return STRING
case 'symbol': return SYMBOL
case 'number': return NUMBER
case 'bigint': return BIGINT
case 'function':
case 'object': {
if (V === null) {
return 'Null'
return NULL
}

return 'Object'
return OBJECT
}
}
}

webidl.util.Types = {
UNDEFINED,
BOOLEAN,
STRING,
SYMBOL,
NUMBER,
BIGINT,
NULL,
OBJECT
}

webidl.util.TypeValueToString = function (o) {
switch (webidl.util.Type(o)) {
case UNDEFINED: return 'Undefined'
case BOOLEAN: return 'Boolean'
case STRING: return 'String'
case SYMBOL: return 'Symbol'
case NUMBER: return 'Number'
case BIGINT: return 'BigInt'
case NULL: return 'Null'
case OBJECT: return 'Object'
}
}

// https://webidl.spec.whatwg.org/#abstract-opdef-converttoint
webidl.util.ConvertToInt = function (V, bitLength, signedness, opts) {
let upperBound
Expand Down Expand Up @@ -224,11 +257,11 @@ webidl.util.Stringify = function (V) {
const type = webidl.util.Type(V)

switch (type) {
case 'Symbol':
case SYMBOL:
return `Symbol(${V.description})`
case 'Object':
case OBJECT:
return inspect(V)
case 'String':
case STRING:
return `"${V}"`
default:
return `${V}`
Expand All @@ -239,7 +272,7 @@ webidl.util.Stringify = function (V) {
webidl.sequenceConverter = function (converter) {
return (V, prefix, argument, Iterable) => {
// 1. If Type(V) is not Object, throw a TypeError.
if (webidl.util.Type(V) !== 'Object') {
if (webidl.util.Type(V) !== OBJECT) {
throw webidl.errors.exception({
header: prefix,
message: `${argument} (${webidl.util.Stringify(V)}) is not iterable.`
Expand Down Expand Up @@ -282,10 +315,10 @@ webidl.sequenceConverter = function (converter) {
webidl.recordConverter = function (keyConverter, valueConverter) {
return (O, prefix, argument) => {
// 1. If Type(O) is not Object, throw a TypeError.
if (webidl.util.Type(O) !== 'Object') {
if (webidl.util.Type(O) !== OBJECT) {
throw webidl.errors.exception({
header: prefix,
message: `${argument} ("${webidl.util.Type(O)}") is not an Object.`
message: `${argument} ("${webidl.util.TypeValueToString(O)}") is not an Object.`
})
}

Expand Down Expand Up @@ -356,7 +389,7 @@ webidl.dictionaryConverter = function (converters) {
return (dictionary, prefix, argument) => {
const dict = {}

if (dictionary != null && webidl.util.Type(dictionary) !== 'Object') {
if (dictionary != null && webidl.util.Type(dictionary) !== OBJECT) {
throw webidl.errors.exception({
header: prefix,
message: `Expected ${dictionary} to be one of: Null, Undefined, Object.`
Expand Down Expand Up @@ -532,7 +565,7 @@ webidl.converters.ArrayBuffer = function (V, prefix, argument, opts) {
// see: https://tc39.es/ecma262/#sec-properties-of-the-arraybuffer-instances
// see: https://tc39.es/ecma262/#sec-properties-of-the-sharedarraybuffer-instances
if (
webidl.util.Type(V) !== 'Object' ||
webidl.util.Type(V) !== OBJECT ||
!types.isAnyArrayBuffer(V)
) {
throw webidl.errors.conversionFailed({
Expand Down Expand Up @@ -576,7 +609,7 @@ webidl.converters.TypedArray = function (V, T, prefix, name, opts) {
// [[TypedArrayName]] internal slot with a value
// equal to T’s name, then throw a TypeError.
if (
webidl.util.Type(V) !== 'Object' ||
webidl.util.Type(V) !== OBJECT ||
!types.isTypedArray(V) ||
V.constructor.name !== T.name
) {
Expand Down Expand Up @@ -617,7 +650,7 @@ webidl.converters.TypedArray = function (V, T, prefix, name, opts) {
webidl.converters.DataView = function (V, prefix, name, opts) {
// 1. If Type(V) is not Object, or V does not have a
// [[DataView]] internal slot, then throw a TypeError.
if (webidl.util.Type(V) !== 'Object' || !types.isDataView(V)) {
if (webidl.util.Type(V) !== OBJECT || !types.isDataView(V)) {
throw webidl.errors.exception({
header: prefix,
message: `${name} is not a DataView.`
Expand Down
6 changes: 3 additions & 3 deletions lib/web/websocket/websocket.js
Original file line number Diff line number Diff line change
Expand Up @@ -758,7 +758,7 @@ webidl.converters['sequence<DOMString>'] = webidl.sequenceConverter(
)

webidl.converters['DOMString or sequence<DOMString>'] = function (V, prefix, argument) {
if (webidl.util.Type(V) === 'Object' && Symbol.iterator in V) {
if (webidl.util.Type(V) === webidl.util.Types.OBJECT && Symbol.iterator in V) {
return webidl.converters['sequence<DOMString>'](V)
}

Expand All @@ -784,15 +784,15 @@ webidl.converters.WebSocketInit = webidl.dictionaryConverter([
])

webidl.converters['DOMString or sequence<DOMString> or WebSocketInit'] = function (V) {
if (webidl.util.Type(V) === 'Object' && !(Symbol.iterator in V)) {
if (webidl.util.Type(V) === webidl.util.Types.OBJECT && !(Symbol.iterator in V)) {
return webidl.converters.WebSocketInit(V)
}

return { protocols: webidl.converters['DOMString or sequence<DOMString>'](V) }
}

webidl.converters.WebSocketSendData = function (V) {
if (webidl.util.Type(V) === 'Object') {
if (webidl.util.Type(V) === webidl.util.Types.OBJECT) {
if (V instanceof Blob) {
return V
}
Expand Down
9 changes: 9 additions & 0 deletions test/webidl/converters.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,3 +238,12 @@ test('webidl.util.Stringify', (t) => {
assert.deepStrictEqual(webidl.util.Stringify(value), expected)
}
})

test('recordConverter', () => {
const anyConverter = webidl.recordConverter(webidl.converters.any, webidl.converters.any)

assert.throws(
() => anyConverter(null, 'prefix', 'argument'),
new TypeError('prefix: argument ("Null") is not an Object.')
)
})
20 changes: 11 additions & 9 deletions test/webidl/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@ const { webidl } = require('../../lib/web/fetch/webidl')

test('Type(V)', () => {
const Type = webidl.util.Type

assert.equal(Type(undefined), 'Undefined')
assert.equal(Type(null), 'Null')
assert.equal(Type(true), 'Boolean')
assert.equal(Type('string'), 'String')
assert.equal(Type(Symbol('symbol')), 'Symbol')
assert.equal(Type(1.23), 'Number')
assert.equal(Type(1n), 'BigInt')
assert.equal(Type({ a: 'b' }), 'Object')
const Types = webidl.util.Types

assert.equal(Type(undefined), Types.UNDEFINED)
assert.equal(Type(null), Types.NULL)
assert.equal(Type(true), Types.BOOLEAN)
assert.equal(Type('string'), Types.STRING)
assert.equal(Type(Symbol('symbol')), Types.SYMBOL)
assert.equal(Type(1.23), Types.NUMBER)
assert.equal(Type(1n), Types.BIGINT)
assert.equal(Type({ a: 'b' }), Types.OBJECT)
assert.equal(Type(function () {}), Types.OBJECT)
})

test('ConvertToInt(V)', () => {
Expand Down
17 changes: 16 additions & 1 deletion types/webidl.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,24 @@ interface WebidlErrors {
}): TypeError
}

interface WebIDLTypes {
UNDEFINED: 1,
BOOLEAN: 2,
STRING: 3,
SYMBOL: 4,
NUMBER: 5,
BIGINT: 6,
NULL: 7
OBJECT: 8
}

interface WebidlUtil {
/**
* @see https://tc39.es/ecma262/#sec-ecmascript-data-types-and-values
*/
Type (object: unknown):
Type (object: unknown): WebIDLTypes

TypeValueToString (o: unknown):
| 'Undefined'
| 'Boolean'
| 'String'
Expand All @@ -48,6 +61,8 @@ interface WebidlUtil {
| 'Null'
| 'Object'

Types: WebIDLTypes

/**
* @see https://webidl.spec.whatwg.org/#abstract-opdef-converttoint
*/
Expand Down
Loading