diff --git a/README.md b/README.md index 6eb0171c..28ee11fe 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,8 @@ The main module's default export is a class which you can construct with a few o - `implSuffix`: a suffix used, if any, to find files within the source directory based on the IDL file name - `suppressErrors`: set to true to suppress errors during generation - `processCEReactions` and `processHTMLConstructor`: see below +- `processReflect`: see below +- `importedTypes`: see below The `addSource()` method can then be called multiple times to add directories containing `.webidl` IDL files and `.js` implementation class files. @@ -240,6 +242,27 @@ function processReflect(idl, implName) { } ``` +### `importedTypes` + +The `importedTypes` option takes a `record` parameter, where keys are the names of Web IDL types, and the values are the path to the wrapper class API. + +In case where a single module exports multiple webidl2js interface wrappers under different namespaces, it's possible to use the `#` symbol to separate the module path from the property name, eg.: + +```js +new WebIDL2JS({ + importedTypes: { + // The `domexception` package exports the wrapper class API + // for `DOMException` at the top level of `domexception/webidl-wrapper`: + DOMException: "domexception/webidl-wrapper", + + // The `whatwg-url` package exports the wrapper class APIs + // for `URL` and `URLSearchParams` as properties of `whatwg-url/webidl-wrapper`: + URL: "whatwg-url/webidl-wrapper#URL", + URLSearchParams: "whatwg-url/webidl-wrapper#URLSearchParams", + } +}); +``` + ## Generated wrapper class file API The example above showed a simplified generated wrapper file with only three exports: `create`, `is`, and `interface`. In reality the generated wrapper file will contain more functionality, documented here. This functionality is different between generated wrapper files for interfaces and for dictionaries. @@ -264,6 +287,10 @@ Performs the Web IDL conversion algorithm for this interface, converting _value_ In practice, this means doing a type-check equivalent to `is(value)`, and if it passes, returns the corresponding impl. If the type-check fails, it throws an informative exception. _context_ can be used to describe the provided value in any resulting error message. +#### `validate(value, { context })` + +Like `convert(value)`, but returns the wrapper class. This exists to support imported types, which can't use `utils.wrapperFromImpl(value)` as the wrapper and impl private symbols aren't shared between packages. + #### `install(globalObject, globalNames)` This method creates a brand new wrapper constructor and prototype and attach it to the passed `globalObject`. It also registers the created constructor with the `globalObject`'s global constructor registry, which makes `create()`, `createImpl()`, and `setup()` work. (Thus, it is important to invoke `install()` before invoking those methods, as otherwise they will throw.) diff --git a/lib/constructs/interface.js b/lib/constructs/interface.js index 4ae4f19c..11d30825 100644 --- a/lib/constructs/interface.js +++ b/lib/constructs/interface.js @@ -605,6 +605,12 @@ class Interface { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; + exports.validate = (value, { context = "The provided value" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type '${this.name}'.\`); + } + return value; + }; exports.convert = (value, { context = "The provided value" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); diff --git a/lib/context.js b/lib/context.js index d2bb1dc6..91205b6c 100644 --- a/lib/context.js +++ b/lib/context.js @@ -24,8 +24,11 @@ class Context { processCEReactions = defaultProcessor, processHTMLConstructor = defaultProcessor, processReflect = null, - options = { suppressErrors: false } - } = {}) { + importedTypes = {}, + options = { + suppressErrors: false + } + }) { this.implSuffix = implSuffix; this.processCEReactions = processCEReactions; this.processHTMLConstructor = processHTMLConstructor; @@ -33,6 +36,12 @@ class Context { this.options = options; this.initialize(); + this.importedTypes = new Map( + Object.entries(importedTypes).map(([name, data]) => { + const [path, property] = data.split("#", 2); + return [name, { path, property }]; + }) + ); } initialize() { @@ -75,6 +84,9 @@ class Context { if (this.enumerations.has(name)) { return "enumeration"; } + if (this.importedTypes.has(name)) { + return "webidl2js:imported"; + } return undefined; } diff --git a/lib/transformer.js b/lib/transformer.js index 969f544f..f188d618 100644 --- a/lib/transformer.js +++ b/lib/transformer.js @@ -22,6 +22,9 @@ class Transformer { processCEReactions: opts.processCEReactions, processHTMLConstructor: opts.processHTMLConstructor, processReflect: opts.processReflect, + importedTypes: { + ...opts.importedTypes + }, options: { suppressErrors: Boolean(opts.suppressErrors) } diff --git a/lib/types.js b/lib/types.js index 3ec2d5f0..8f4d03c7 100644 --- a/lib/types.js +++ b/lib/types.js @@ -26,7 +26,14 @@ function mergeExtAttrs(a = [], b = []) { } // Types of types that generate an output file. -const resolvedTypes = new Set(["callback", "callback interface", "dictionary", "enumeration", "interface"]); +const resolvedTypes = new Set([ + "callback", + "callback interface", + "dictionary", + "enumeration", + "interface", + "webidl2js:imported" +]); function resolveType(ctx, idlType, stack = []) { if (resolvedMap.has(idlType)) { @@ -107,6 +114,7 @@ function generateTypeConversion(ctx, name, idlType, argAttrs = [], parentName, e } } + let typeKind; if (idlType.union) { // union type generateUnion(); @@ -130,13 +138,20 @@ function generateTypeConversion(ctx, name, idlType, argAttrs = [], parentName, e ) { // string or number type compatible with webidl-conversions generateGeneric(`conversions["${idlType.idlType}"]`); - } else if (resolvedTypes.has(ctx.typeOf(idlType.idlType))) { + } else if (resolvedTypes.has(typeKind = ctx.typeOf(idlType.idlType))) { // callback functions, callback interfaces, dictionaries, enumerations, and interfaces let fn; // Avoid requiring the interface itself if (idlType.idlType !== parentName) { - fn = `${idlType.idlType}.convert`; - requires.addRelative(idlType.idlType); + // webidl2js:imported types can't use `convert`, as we'd have no way + // to convert them back to their wrappers. + if (typeKind === "webidl2js:imported") { + const { path, property } = ctx.importedTypes.get(idlType.idlType); + fn = `${requires.add(path, property)}.validate`; + } else { + fn = `${idlType.idlType}.convert`; + requires.addRelative(idlType.idlType); + } } else { fn = `exports.convert`; } diff --git a/lib/utils.js b/lib/utils.js index 004d78bd..54bf5271 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -104,7 +104,7 @@ function formatArgs(args) { } function toKey(type, func = "") { - return String(func + type).replace(/[./-]+/g, " ").trim().replace(/ /g, "_"); + return String(`${func}@${type}`).replace(/[@./-]+/g, " ").trim().replace(/ /g, "_"); } const PACKAGE_NAME_REGEX = /^(?:@([^/]+?)[/])?([^/]+?)$/u; diff --git a/test/__snapshots__/test.js.snap b/test/__snapshots__/test.js.snap index 8023678b..116581d1 100644 --- a/test/__snapshots__/test.js.snap +++ b/test/__snapshots__/test.js.snap @@ -84,6 +84,292 @@ exports.convert = (value, { context = \\"The provided value\\" } = {}) => { " `; +exports[`with external imports UsingExternal.webidl 1`] = ` +"\\"use strict\\"; + +const conversions = require(\\"webidl-conversions\\"); +const utils = require(\\"./utils.js\\"); + +const domexception_webidl2js_wrapper = require(\\"domexception/webidl2js-wrapper.js\\"); +const URL_whatwg_url_webidl2js_wrapper = require(\\"whatwg-url/webidl2js-wrapper.js\\").URL; +const URLSearchParams_whatwg_url_webidl2js_wrapper = require(\\"whatwg-url/webidl2js-wrapper.js\\").URLSearchParams; +const implSymbol = utils.implSymbol; +const ctorRegistrySymbol = utils.ctorRegistrySymbol; + +const interfaceName = \\"UsingExternal\\"; + +exports.is = value => { + return utils.isObject(value) && utils.hasOwn(value, implSymbol) && value[implSymbol] instanceof Impl.implementation; +}; +exports.isImpl = value => { + return utils.isObject(value) && value instanceof Impl.implementation; +}; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'UsingExternal'.\`); + } + return value; +}; +exports.convert = (value, { context = \\"The provided value\\" } = {}) => { + if (exports.is(value)) { + return utils.implForWrapper(value); + } + throw new TypeError(\`\${context} is not of type 'UsingExternal'.\`); +}; + +function makeWrapper(globalObject) { + if (globalObject[ctorRegistrySymbol] === undefined) { + throw new Error(\\"Internal error: invalid global object\\"); + } + + const ctor = globalObject[ctorRegistrySymbol][\\"UsingExternal\\"]; + if (ctor === undefined) { + throw new Error(\\"Internal error: constructor UsingExternal is not installed on the passed global object\\"); + } + + return Object.create(ctor.prototype); +} + +exports.create = (globalObject, constructorArgs, privateData) => { + const wrapper = makeWrapper(globalObject); + return exports.setup(wrapper, globalObject, constructorArgs, privateData); +}; + +exports.createImpl = (globalObject, constructorArgs, privateData) => { + const wrapper = exports.create(globalObject, constructorArgs, privateData); + return utils.implForWrapper(wrapper); +}; + +exports._internalSetup = (wrapper, globalObject) => {}; + +exports.setup = (wrapper, globalObject, constructorArgs = [], privateData = {}) => { + privateData.wrapper = wrapper; + + exports._internalSetup(wrapper, globalObject); + Object.defineProperty(wrapper, implSymbol, { + value: new Impl.implementation(globalObject, constructorArgs, privateData), + configurable: true + }); + + wrapper[implSymbol][utils.wrapperSymbol] = wrapper; + if (Impl.init) { + Impl.init(wrapper[implSymbol]); + } + return wrapper; +}; + +exports.new = globalObject => { + const wrapper = makeWrapper(globalObject); + + exports._internalSetup(wrapper, globalObject); + Object.defineProperty(wrapper, implSymbol, { + value: Object.create(Impl.implementation.prototype), + configurable: true + }); + + wrapper[implSymbol][utils.wrapperSymbol] = wrapper; + if (Impl.init) { + Impl.init(wrapper[implSymbol]); + } + return wrapper[implSymbol]; +}; + +const exposed = new Set([\\"Window\\"]); + +exports.install = (globalObject, globalNames) => { + if (!globalNames.some(globalName => exposed.has(globalName))) { + return; + } + class UsingExternal { + constructor() { + throw new TypeError(\\"Illegal constructor\\"); + } + + methodImportedDOMException(domException) { + const esValue = this !== null && this !== undefined ? this : globalObject; + if (!exports.is(esValue)) { + throw new TypeError( + \\"'methodImportedDOMException' called on an object that is not a valid instance of UsingExternal.\\" + ); + } + + if (arguments.length < 1) { + throw new TypeError( + \\"Failed to execute 'methodImportedDOMException' on 'UsingExternal': 1 argument required, but only \\" + + arguments.length + + \\" present.\\" + ); + } + const args = []; + { + let curArg = arguments[0]; + curArg = domexception_webidl2js_wrapper.validate(curArg, { + context: \\"Failed to execute 'methodImportedDOMException' on 'UsingExternal': parameter 1\\" + }); + args.push(curArg); + } + return esValue[implSymbol].methodImportedDOMException(...args); + } + + methodImportedURL(url) { + const esValue = this !== null && this !== undefined ? this : globalObject; + if (!exports.is(esValue)) { + throw new TypeError(\\"'methodImportedURL' called on an object that is not a valid instance of UsingExternal.\\"); + } + + if (arguments.length < 1) { + throw new TypeError( + \\"Failed to execute 'methodImportedURL' on 'UsingExternal': 1 argument required, but only \\" + + arguments.length + + \\" present.\\" + ); + } + const args = []; + { + let curArg = arguments[0]; + curArg = URL_whatwg_url_webidl2js_wrapper.validate(curArg, { + context: \\"Failed to execute 'methodImportedURL' on 'UsingExternal': parameter 1\\" + }); + args.push(curArg); + } + return esValue[implSymbol].methodImportedURL(...args); + } + + methodImportedURLSearchParams(url) { + const esValue = this !== null && this !== undefined ? this : globalObject; + if (!exports.is(esValue)) { + throw new TypeError( + \\"'methodImportedURLSearchParams' called on an object that is not a valid instance of UsingExternal.\\" + ); + } + + if (arguments.length < 1) { + throw new TypeError( + \\"Failed to execute 'methodImportedURLSearchParams' on 'UsingExternal': 1 argument required, but only \\" + + arguments.length + + \\" present.\\" + ); + } + const args = []; + { + let curArg = arguments[0]; + curArg = URLSearchParams_whatwg_url_webidl2js_wrapper.validate(curArg, { + context: \\"Failed to execute 'methodImportedURLSearchParams' on 'UsingExternal': parameter 1\\" + }); + args.push(curArg); + } + return esValue[implSymbol].methodImportedURLSearchParams(...args); + } + + get propertyImportedDOMException() { + const esValue = this !== null && this !== undefined ? this : globalObject; + + if (!exports.is(esValue)) { + throw new TypeError( + \\"'get propertyImportedDOMException' called on an object that is not a valid instance of UsingExternal.\\" + ); + } + + return utils.tryWrapperForImpl(esValue[implSymbol][\\"propertyImportedDOMException\\"]); + } + + set propertyImportedDOMException(V) { + const esValue = this !== null && this !== undefined ? this : globalObject; + + if (!exports.is(esValue)) { + throw new TypeError( + \\"'set propertyImportedDOMException' called on an object that is not a valid instance of UsingExternal.\\" + ); + } + + V = domexception_webidl2js_wrapper.validate(V, { + context: \\"Failed to set the 'propertyImportedDOMException' property on 'UsingExternal': The provided value\\" + }); + + esValue[implSymbol][\\"propertyImportedDOMException\\"] = V; + } + + get propertyImportedURL() { + const esValue = this !== null && this !== undefined ? this : globalObject; + + if (!exports.is(esValue)) { + throw new TypeError( + \\"'get propertyImportedURL' called on an object that is not a valid instance of UsingExternal.\\" + ); + } + + return utils.tryWrapperForImpl(esValue[implSymbol][\\"propertyImportedURL\\"]); + } + + set propertyImportedURL(V) { + const esValue = this !== null && this !== undefined ? this : globalObject; + + if (!exports.is(esValue)) { + throw new TypeError( + \\"'set propertyImportedURL' called on an object that is not a valid instance of UsingExternal.\\" + ); + } + + V = URL_whatwg_url_webidl2js_wrapper.validate(V, { + context: \\"Failed to set the 'propertyImportedURL' property on 'UsingExternal': The provided value\\" + }); + + esValue[implSymbol][\\"propertyImportedURL\\"] = V; + } + + get propertyImportedURLSearchParams() { + const esValue = this !== null && this !== undefined ? this : globalObject; + + if (!exports.is(esValue)) { + throw new TypeError( + \\"'get propertyImportedURLSearchParams' called on an object that is not a valid instance of UsingExternal.\\" + ); + } + + return utils.tryWrapperForImpl(esValue[implSymbol][\\"propertyImportedURLSearchParams\\"]); + } + + set propertyImportedURLSearchParams(V) { + const esValue = this !== null && this !== undefined ? this : globalObject; + + if (!exports.is(esValue)) { + throw new TypeError( + \\"'set propertyImportedURLSearchParams' called on an object that is not a valid instance of UsingExternal.\\" + ); + } + + V = URLSearchParams_whatwg_url_webidl2js_wrapper.validate(V, { + context: \\"Failed to set the 'propertyImportedURLSearchParams' property on 'UsingExternal': The provided value\\" + }); + + esValue[implSymbol][\\"propertyImportedURLSearchParams\\"] = V; + } + } + Object.defineProperties(UsingExternal.prototype, { + methodImportedDOMException: { enumerable: true }, + methodImportedURL: { enumerable: true }, + methodImportedURLSearchParams: { enumerable: true }, + propertyImportedDOMException: { enumerable: true }, + propertyImportedURL: { enumerable: true }, + propertyImportedURLSearchParams: { enumerable: true }, + [Symbol.toStringTag]: { value: \\"UsingExternal\\", configurable: true } + }); + if (globalObject[ctorRegistrySymbol] === undefined) { + globalObject[ctorRegistrySymbol] = Object.create(null); + } + globalObject[ctorRegistrySymbol][interfaceName] = UsingExternal; + + Object.defineProperty(globalObject, interfaceName, { + configurable: true, + writable: true, + value: UsingExternal + }); +}; + +const Impl = require(\\"../implementations/UsingExternal.js\\"); +" +`; + exports[`with processors AsyncCallbackFunction.webidl 1`] = ` "\\"use strict\\"; @@ -234,6 +520,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'AsyncIterablePairArgs'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -507,6 +799,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'AsyncIterablePairNoArgs'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -718,6 +1016,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'AsyncIterableValueArgs'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -906,6 +1210,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'AsyncIterableValueNoArgs'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -1110,6 +1420,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'AsyncIterableWithReturn'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -1250,6 +1566,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'BufferSourceTypes'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -1525,6 +1847,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'CEReactions'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -2020,6 +2348,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'DOMImplementation'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -2254,6 +2588,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'DOMRect'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -2608,6 +2948,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'DictionaryConvert'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -2744,6 +3090,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'Enum'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -2942,6 +3294,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'EventTarget'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -3089,6 +3447,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'Global'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -3319,6 +3683,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'HTMLConstructor'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -3430,6 +3800,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'LegacyLenientAttributes'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -3635,6 +4011,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'LegacyUnforgeable'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -3844,6 +4226,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'LegacyUnforgeableMap'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -4153,6 +4541,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'MixedIn'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -4419,6 +4813,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'Overloads'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -4840,6 +5240,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'PromiseTypes'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -5091,6 +5497,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'Reflect'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -5391,6 +5803,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'Replaceable'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -5562,6 +5980,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'SeqAndRec'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -5878,6 +6302,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'Static'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -6041,6 +6471,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'Storage'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -6434,6 +6870,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'StringifierAttribute'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -6566,6 +7008,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'StringifierDefaultOperation'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -6691,6 +7139,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'StringifierNamedOperation'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -6828,6 +7282,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'StringifierOperation'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -6951,6 +7411,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'TypedefsAndUnions'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -7509,6 +7975,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'URL'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -8022,6 +8494,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'URLList'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -8367,6 +8845,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'URLSearchParams'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -8798,6 +9282,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'URLSearchParamsCollection'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -9168,6 +9658,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'URLSearchParamsCollection2'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -9509,6 +10005,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'UnderscoredProperties'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -9711,6 +10213,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'Unscopable'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -9859,6 +10367,277 @@ const Impl = require(\\"../implementations/Unscopable.js\\"); " `; +exports[`with processors UsingExternal.webidl 1`] = ` +"\\"use strict\\"; + +const conversions = require(\\"webidl-conversions\\"); +const utils = require(\\"./utils.js\\"); + +const implSymbol = utils.implSymbol; +const ctorRegistrySymbol = utils.ctorRegistrySymbol; + +const interfaceName = \\"UsingExternal\\"; + +exports.is = value => { + return utils.isObject(value) && utils.hasOwn(value, implSymbol) && value[implSymbol] instanceof Impl.implementation; +}; +exports.isImpl = value => { + return utils.isObject(value) && value instanceof Impl.implementation; +}; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'UsingExternal'.\`); + } + return value; +}; +exports.convert = (value, { context = \\"The provided value\\" } = {}) => { + if (exports.is(value)) { + return utils.implForWrapper(value); + } + throw new TypeError(\`\${context} is not of type 'UsingExternal'.\`); +}; + +function makeWrapper(globalObject) { + if (globalObject[ctorRegistrySymbol] === undefined) { + throw new Error(\\"Internal error: invalid global object\\"); + } + + const ctor = globalObject[ctorRegistrySymbol][\\"UsingExternal\\"]; + if (ctor === undefined) { + throw new Error(\\"Internal error: constructor UsingExternal is not installed on the passed global object\\"); + } + + return Object.create(ctor.prototype); +} + +exports.create = (globalObject, constructorArgs, privateData) => { + const wrapper = makeWrapper(globalObject); + return exports.setup(wrapper, globalObject, constructorArgs, privateData); +}; + +exports.createImpl = (globalObject, constructorArgs, privateData) => { + const wrapper = exports.create(globalObject, constructorArgs, privateData); + return utils.implForWrapper(wrapper); +}; + +exports._internalSetup = (wrapper, globalObject) => {}; + +exports.setup = (wrapper, globalObject, constructorArgs = [], privateData = {}) => { + privateData.wrapper = wrapper; + + exports._internalSetup(wrapper, globalObject); + Object.defineProperty(wrapper, implSymbol, { + value: new Impl.implementation(globalObject, constructorArgs, privateData), + configurable: true + }); + + wrapper[implSymbol][utils.wrapperSymbol] = wrapper; + if (Impl.init) { + Impl.init(wrapper[implSymbol]); + } + return wrapper; +}; + +exports.new = globalObject => { + const wrapper = makeWrapper(globalObject); + + exports._internalSetup(wrapper, globalObject); + Object.defineProperty(wrapper, implSymbol, { + value: Object.create(Impl.implementation.prototype), + configurable: true + }); + + wrapper[implSymbol][utils.wrapperSymbol] = wrapper; + if (Impl.init) { + Impl.init(wrapper[implSymbol]); + } + return wrapper[implSymbol]; +}; + +const exposed = new Set([\\"Window\\"]); + +exports.install = (globalObject, globalNames) => { + if (!globalNames.some(globalName => exposed.has(globalName))) { + return; + } + class UsingExternal { + constructor() { + throw new TypeError(\\"Illegal constructor\\"); + } + + methodImportedDOMException(domException) { + const esValue = this !== null && this !== undefined ? this : globalObject; + if (!exports.is(esValue)) { + throw new TypeError( + \\"'methodImportedDOMException' called on an object that is not a valid instance of UsingExternal.\\" + ); + } + + if (arguments.length < 1) { + throw new TypeError( + \\"Failed to execute 'methodImportedDOMException' on 'UsingExternal': 1 argument required, but only \\" + + arguments.length + + \\" present.\\" + ); + } + const args = []; + { + let curArg = arguments[0]; + curArg = utils.tryImplForWrapper(curArg); + args.push(curArg); + } + return esValue[implSymbol].methodImportedDOMException(...args); + } + + methodImportedURL(url) { + const esValue = this !== null && this !== undefined ? this : globalObject; + if (!exports.is(esValue)) { + throw new TypeError(\\"'methodImportedURL' called on an object that is not a valid instance of UsingExternal.\\"); + } + + if (arguments.length < 1) { + throw new TypeError( + \\"Failed to execute 'methodImportedURL' on 'UsingExternal': 1 argument required, but only \\" + + arguments.length + + \\" present.\\" + ); + } + const args = []; + { + let curArg = arguments[0]; + curArg = utils.tryImplForWrapper(curArg); + args.push(curArg); + } + return esValue[implSymbol].methodImportedURL(...args); + } + + methodImportedURLSearchParams(url) { + const esValue = this !== null && this !== undefined ? this : globalObject; + if (!exports.is(esValue)) { + throw new TypeError( + \\"'methodImportedURLSearchParams' called on an object that is not a valid instance of UsingExternal.\\" + ); + } + + if (arguments.length < 1) { + throw new TypeError( + \\"Failed to execute 'methodImportedURLSearchParams' on 'UsingExternal': 1 argument required, but only \\" + + arguments.length + + \\" present.\\" + ); + } + const args = []; + { + let curArg = arguments[0]; + curArg = utils.tryImplForWrapper(curArg); + args.push(curArg); + } + return esValue[implSymbol].methodImportedURLSearchParams(...args); + } + + get propertyImportedDOMException() { + const esValue = this !== null && this !== undefined ? this : globalObject; + + if (!exports.is(esValue)) { + throw new TypeError( + \\"'get propertyImportedDOMException' called on an object that is not a valid instance of UsingExternal.\\" + ); + } + + return utils.tryWrapperForImpl(esValue[implSymbol][\\"propertyImportedDOMException\\"]); + } + + set propertyImportedDOMException(V) { + const esValue = this !== null && this !== undefined ? this : globalObject; + + if (!exports.is(esValue)) { + throw new TypeError( + \\"'set propertyImportedDOMException' called on an object that is not a valid instance of UsingExternal.\\" + ); + } + + V = utils.tryImplForWrapper(V); + + esValue[implSymbol][\\"propertyImportedDOMException\\"] = V; + } + + get propertyImportedURL() { + const esValue = this !== null && this !== undefined ? this : globalObject; + + if (!exports.is(esValue)) { + throw new TypeError( + \\"'get propertyImportedURL' called on an object that is not a valid instance of UsingExternal.\\" + ); + } + + return utils.tryWrapperForImpl(esValue[implSymbol][\\"propertyImportedURL\\"]); + } + + set propertyImportedURL(V) { + const esValue = this !== null && this !== undefined ? this : globalObject; + + if (!exports.is(esValue)) { + throw new TypeError( + \\"'set propertyImportedURL' called on an object that is not a valid instance of UsingExternal.\\" + ); + } + + V = utils.tryImplForWrapper(V); + + esValue[implSymbol][\\"propertyImportedURL\\"] = V; + } + + get propertyImportedURLSearchParams() { + const esValue = this !== null && this !== undefined ? this : globalObject; + + if (!exports.is(esValue)) { + throw new TypeError( + \\"'get propertyImportedURLSearchParams' called on an object that is not a valid instance of UsingExternal.\\" + ); + } + + return utils.tryWrapperForImpl(esValue[implSymbol][\\"propertyImportedURLSearchParams\\"]); + } + + set propertyImportedURLSearchParams(V) { + const esValue = this !== null && this !== undefined ? this : globalObject; + + if (!exports.is(esValue)) { + throw new TypeError( + \\"'set propertyImportedURLSearchParams' called on an object that is not a valid instance of UsingExternal.\\" + ); + } + + V = utils.tryImplForWrapper(V); + + esValue[implSymbol][\\"propertyImportedURLSearchParams\\"] = V; + } + } + Object.defineProperties(UsingExternal.prototype, { + methodImportedDOMException: { enumerable: true }, + methodImportedURL: { enumerable: true }, + methodImportedURLSearchParams: { enumerable: true }, + propertyImportedDOMException: { enumerable: true }, + propertyImportedURL: { enumerable: true }, + propertyImportedURLSearchParams: { enumerable: true }, + [Symbol.toStringTag]: { value: \\"UsingExternal\\", configurable: true } + }); + if (globalObject[ctorRegistrySymbol] === undefined) { + globalObject[ctorRegistrySymbol] = Object.create(null); + } + globalObject[ctorRegistrySymbol][interfaceName] = UsingExternal; + + Object.defineProperty(globalObject, interfaceName, { + configurable: true, + writable: true, + value: UsingExternal + }); +}; + +const Impl = require(\\"../implementations/UsingExternal.js\\"); +" +`; + exports[`with processors Variadic.webidl 1`] = ` "\\"use strict\\"; @@ -9877,6 +10656,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'Variadic'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -10143,6 +10928,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'ZeroArgConstructor'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -10387,6 +11178,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'AsyncIterablePairArgs'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -10660,6 +11457,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'AsyncIterablePairNoArgs'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -10871,6 +11674,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'AsyncIterableValueArgs'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -11059,6 +11868,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'AsyncIterableValueNoArgs'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -11263,6 +12078,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'AsyncIterableWithReturn'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -11403,6 +12224,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'BufferSourceTypes'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -11677,6 +12504,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'CEReactions'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -12132,6 +12965,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'DOMImplementation'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -12366,6 +13205,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'DOMRect'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -12720,6 +13565,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'DictionaryConvert'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -12856,6 +13707,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'Enum'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -13054,6 +13911,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'EventTarget'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -13201,6 +14064,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'Global'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -13430,6 +14299,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'HTMLConstructor'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -13541,6 +14416,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'LegacyLenientAttributes'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -13746,6 +14627,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'LegacyUnforgeable'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -13955,6 +14842,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'LegacyUnforgeableMap'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -14264,6 +15157,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'MixedIn'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -14530,6 +15429,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'Overloads'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -14951,6 +15856,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'PromiseTypes'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -15201,6 +16112,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'Reflect'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -15487,6 +16404,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'Replaceable'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -15658,6 +16581,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'SeqAndRec'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -15974,6 +16903,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'Static'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -16137,6 +17072,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'Storage'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -16530,6 +17471,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'StringifierAttribute'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -16662,6 +17609,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'StringifierDefaultOperation'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -16787,6 +17740,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'StringifierNamedOperation'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -16924,6 +17883,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'StringifierOperation'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -17047,6 +18012,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'TypedefsAndUnions'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -17605,6 +18576,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'URL'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -18118,6 +19095,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'URLList'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -18463,6 +19446,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'URLSearchParams'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -18894,6 +19883,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'URLSearchParamsCollection'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -19264,6 +20259,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'URLSearchParamsCollection2'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -19605,6 +20606,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'UnderscoredProperties'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -19807,6 +20814,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'Unscopable'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -19955,6 +20968,277 @@ const Impl = require(\\"../implementations/Unscopable.js\\"); " `; +exports[`without processors UsingExternal.webidl 1`] = ` +"\\"use strict\\"; + +const conversions = require(\\"webidl-conversions\\"); +const utils = require(\\"./utils.js\\"); + +const implSymbol = utils.implSymbol; +const ctorRegistrySymbol = utils.ctorRegistrySymbol; + +const interfaceName = \\"UsingExternal\\"; + +exports.is = value => { + return utils.isObject(value) && utils.hasOwn(value, implSymbol) && value[implSymbol] instanceof Impl.implementation; +}; +exports.isImpl = value => { + return utils.isObject(value) && value instanceof Impl.implementation; +}; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'UsingExternal'.\`); + } + return value; +}; +exports.convert = (value, { context = \\"The provided value\\" } = {}) => { + if (exports.is(value)) { + return utils.implForWrapper(value); + } + throw new TypeError(\`\${context} is not of type 'UsingExternal'.\`); +}; + +function makeWrapper(globalObject) { + if (globalObject[ctorRegistrySymbol] === undefined) { + throw new Error(\\"Internal error: invalid global object\\"); + } + + const ctor = globalObject[ctorRegistrySymbol][\\"UsingExternal\\"]; + if (ctor === undefined) { + throw new Error(\\"Internal error: constructor UsingExternal is not installed on the passed global object\\"); + } + + return Object.create(ctor.prototype); +} + +exports.create = (globalObject, constructorArgs, privateData) => { + const wrapper = makeWrapper(globalObject); + return exports.setup(wrapper, globalObject, constructorArgs, privateData); +}; + +exports.createImpl = (globalObject, constructorArgs, privateData) => { + const wrapper = exports.create(globalObject, constructorArgs, privateData); + return utils.implForWrapper(wrapper); +}; + +exports._internalSetup = (wrapper, globalObject) => {}; + +exports.setup = (wrapper, globalObject, constructorArgs = [], privateData = {}) => { + privateData.wrapper = wrapper; + + exports._internalSetup(wrapper, globalObject); + Object.defineProperty(wrapper, implSymbol, { + value: new Impl.implementation(globalObject, constructorArgs, privateData), + configurable: true + }); + + wrapper[implSymbol][utils.wrapperSymbol] = wrapper; + if (Impl.init) { + Impl.init(wrapper[implSymbol]); + } + return wrapper; +}; + +exports.new = globalObject => { + const wrapper = makeWrapper(globalObject); + + exports._internalSetup(wrapper, globalObject); + Object.defineProperty(wrapper, implSymbol, { + value: Object.create(Impl.implementation.prototype), + configurable: true + }); + + wrapper[implSymbol][utils.wrapperSymbol] = wrapper; + if (Impl.init) { + Impl.init(wrapper[implSymbol]); + } + return wrapper[implSymbol]; +}; + +const exposed = new Set([\\"Window\\"]); + +exports.install = (globalObject, globalNames) => { + if (!globalNames.some(globalName => exposed.has(globalName))) { + return; + } + class UsingExternal { + constructor() { + throw new TypeError(\\"Illegal constructor\\"); + } + + methodImportedDOMException(domException) { + const esValue = this !== null && this !== undefined ? this : globalObject; + if (!exports.is(esValue)) { + throw new TypeError( + \\"'methodImportedDOMException' called on an object that is not a valid instance of UsingExternal.\\" + ); + } + + if (arguments.length < 1) { + throw new TypeError( + \\"Failed to execute 'methodImportedDOMException' on 'UsingExternal': 1 argument required, but only \\" + + arguments.length + + \\" present.\\" + ); + } + const args = []; + { + let curArg = arguments[0]; + curArg = utils.tryImplForWrapper(curArg); + args.push(curArg); + } + return esValue[implSymbol].methodImportedDOMException(...args); + } + + methodImportedURL(url) { + const esValue = this !== null && this !== undefined ? this : globalObject; + if (!exports.is(esValue)) { + throw new TypeError(\\"'methodImportedURL' called on an object that is not a valid instance of UsingExternal.\\"); + } + + if (arguments.length < 1) { + throw new TypeError( + \\"Failed to execute 'methodImportedURL' on 'UsingExternal': 1 argument required, but only \\" + + arguments.length + + \\" present.\\" + ); + } + const args = []; + { + let curArg = arguments[0]; + curArg = utils.tryImplForWrapper(curArg); + args.push(curArg); + } + return esValue[implSymbol].methodImportedURL(...args); + } + + methodImportedURLSearchParams(url) { + const esValue = this !== null && this !== undefined ? this : globalObject; + if (!exports.is(esValue)) { + throw new TypeError( + \\"'methodImportedURLSearchParams' called on an object that is not a valid instance of UsingExternal.\\" + ); + } + + if (arguments.length < 1) { + throw new TypeError( + \\"Failed to execute 'methodImportedURLSearchParams' on 'UsingExternal': 1 argument required, but only \\" + + arguments.length + + \\" present.\\" + ); + } + const args = []; + { + let curArg = arguments[0]; + curArg = utils.tryImplForWrapper(curArg); + args.push(curArg); + } + return esValue[implSymbol].methodImportedURLSearchParams(...args); + } + + get propertyImportedDOMException() { + const esValue = this !== null && this !== undefined ? this : globalObject; + + if (!exports.is(esValue)) { + throw new TypeError( + \\"'get propertyImportedDOMException' called on an object that is not a valid instance of UsingExternal.\\" + ); + } + + return utils.tryWrapperForImpl(esValue[implSymbol][\\"propertyImportedDOMException\\"]); + } + + set propertyImportedDOMException(V) { + const esValue = this !== null && this !== undefined ? this : globalObject; + + if (!exports.is(esValue)) { + throw new TypeError( + \\"'set propertyImportedDOMException' called on an object that is not a valid instance of UsingExternal.\\" + ); + } + + V = utils.tryImplForWrapper(V); + + esValue[implSymbol][\\"propertyImportedDOMException\\"] = V; + } + + get propertyImportedURL() { + const esValue = this !== null && this !== undefined ? this : globalObject; + + if (!exports.is(esValue)) { + throw new TypeError( + \\"'get propertyImportedURL' called on an object that is not a valid instance of UsingExternal.\\" + ); + } + + return utils.tryWrapperForImpl(esValue[implSymbol][\\"propertyImportedURL\\"]); + } + + set propertyImportedURL(V) { + const esValue = this !== null && this !== undefined ? this : globalObject; + + if (!exports.is(esValue)) { + throw new TypeError( + \\"'set propertyImportedURL' called on an object that is not a valid instance of UsingExternal.\\" + ); + } + + V = utils.tryImplForWrapper(V); + + esValue[implSymbol][\\"propertyImportedURL\\"] = V; + } + + get propertyImportedURLSearchParams() { + const esValue = this !== null && this !== undefined ? this : globalObject; + + if (!exports.is(esValue)) { + throw new TypeError( + \\"'get propertyImportedURLSearchParams' called on an object that is not a valid instance of UsingExternal.\\" + ); + } + + return utils.tryWrapperForImpl(esValue[implSymbol][\\"propertyImportedURLSearchParams\\"]); + } + + set propertyImportedURLSearchParams(V) { + const esValue = this !== null && this !== undefined ? this : globalObject; + + if (!exports.is(esValue)) { + throw new TypeError( + \\"'set propertyImportedURLSearchParams' called on an object that is not a valid instance of UsingExternal.\\" + ); + } + + V = utils.tryImplForWrapper(V); + + esValue[implSymbol][\\"propertyImportedURLSearchParams\\"] = V; + } + } + Object.defineProperties(UsingExternal.prototype, { + methodImportedDOMException: { enumerable: true }, + methodImportedURL: { enumerable: true }, + methodImportedURLSearchParams: { enumerable: true }, + propertyImportedDOMException: { enumerable: true }, + propertyImportedURL: { enumerable: true }, + propertyImportedURLSearchParams: { enumerable: true }, + [Symbol.toStringTag]: { value: \\"UsingExternal\\", configurable: true } + }); + if (globalObject[ctorRegistrySymbol] === undefined) { + globalObject[ctorRegistrySymbol] = Object.create(null); + } + globalObject[ctorRegistrySymbol][interfaceName] = UsingExternal; + + Object.defineProperty(globalObject, interfaceName, { + configurable: true, + writable: true, + value: UsingExternal + }); +}; + +const Impl = require(\\"../implementations/UsingExternal.js\\"); +" +`; + exports[`without processors Variadic.webidl 1`] = ` "\\"use strict\\"; @@ -19973,6 +21257,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'Variadic'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); @@ -20239,6 +21529,12 @@ exports.is = value => { exports.isImpl = value => { return utils.isObject(value) && value instanceof Impl.implementation; }; +exports.validate = (value, { context = \\"The provided value\\" } = {}) => { + if (!exports.is(value)) { + throw new TypeError(\`\${context} is not of type 'ZeroArgConstructor'.\`); + } + return value; +}; exports.convert = (value, { context = \\"The provided value\\" } = {}) => { if (exports.is(value)) { return utils.implForWrapper(value); diff --git a/test/cases/UsingExternal.webidl b/test/cases/UsingExternal.webidl new file mode 100644 index 00000000..075e8c22 --- /dev/null +++ b/test/cases/UsingExternal.webidl @@ -0,0 +1,10 @@ +[Exposed=Window] +interface UsingExternal { + void methodImportedDOMException(Imported-DOMException domException); + void methodImportedURL(Imported-URL url); + void methodImportedURLSearchParams(Imported-URLSearchParams url); + + attribute Imported-DOMException propertyImportedDOMException; + attribute Imported-URL propertyImportedURL; + attribute Imported-URLSearchParams propertyImportedURLSearchParams; +}; diff --git a/test/test.js b/test/test.js index a1e045d7..1e950e7b 100644 --- a/test/test.js +++ b/test/test.js @@ -118,6 +118,28 @@ describe("with processors", () => { } }); +describe("with external imports", () => { + beforeAll(() => { + const transformer = new Transformer({ + importedTypes: { + "Imported-DOMException": "domexception/webidl2js-wrapper", + "Imported-URL": "whatwg-url/webidl2js-wrapper#URL", + "Imported-URLSearchParams": "whatwg-url/webidl2js-wrapper#URLSearchParams" + } + }); + transformer.addSource(casesDir, implsDir); + + return transformer.generate(outputDir); + }); + + test("UsingExternal.webidl", () => { + const outputFile = path.resolve(outputDir, "UsingExternal.js"); + const output = fs.readFileSync(outputFile, { encoding: "utf-8" }); + + expect(output).toMatchSnapshot(); + }); +}); + test("utils.js", () => { const input = fs.readFileSync(path.resolve(rootDir, "lib/output/utils.js"), { encoding: "utf-8" }); const output = fs.readFileSync(path.resolve(outputDir, "utils.js"), { encoding: "utf-8" });