11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst { 41cb0ef41Sopenharmony_ci ArrayPrototypeFilter, 51cb0ef41Sopenharmony_ci ArrayPrototypeIncludes, 61cb0ef41Sopenharmony_ci ObjectKeys, 71cb0ef41Sopenharmony_ci ObjectValues, 81cb0ef41Sopenharmony_ci ObjectPrototypeHasOwnProperty, 91cb0ef41Sopenharmony_ci} = primordials; 101cb0ef41Sopenharmony_ciconst { validateString } = require('internal/validators'); 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_ciconst { 131cb0ef41Sopenharmony_ci ERR_IMPORT_ASSERTION_TYPE_FAILED, 141cb0ef41Sopenharmony_ci ERR_IMPORT_ASSERTION_TYPE_MISSING, 151cb0ef41Sopenharmony_ci ERR_IMPORT_ASSERTION_TYPE_UNSUPPORTED, 161cb0ef41Sopenharmony_ci ERR_IMPORT_ATTRIBUTE_UNSUPPORTED, 171cb0ef41Sopenharmony_ci} = require('internal/errors').codes; 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_ci// The HTML spec has an implied default type of `'javascript'`. 201cb0ef41Sopenharmony_ciconst kImplicitAssertType = 'javascript'; 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_ci/** 231cb0ef41Sopenharmony_ci * Define a map of module formats to import attributes types (the value of 241cb0ef41Sopenharmony_ci * `type` in `with { type: 'json' }`). 251cb0ef41Sopenharmony_ci * @type {Map<string, string>} 261cb0ef41Sopenharmony_ci */ 271cb0ef41Sopenharmony_ciconst formatTypeMap = { 281cb0ef41Sopenharmony_ci '__proto__': null, 291cb0ef41Sopenharmony_ci 'builtin': kImplicitAssertType, 301cb0ef41Sopenharmony_ci 'commonjs': kImplicitAssertType, 311cb0ef41Sopenharmony_ci 'json': 'json', 321cb0ef41Sopenharmony_ci 'module': kImplicitAssertType, 331cb0ef41Sopenharmony_ci 'wasm': kImplicitAssertType, // It's unclear whether the HTML spec will require an attribute type or not for Wasm; see https://github.com/WebAssembly/esm-integration/issues/42 341cb0ef41Sopenharmony_ci}; 351cb0ef41Sopenharmony_ci 361cb0ef41Sopenharmony_ci/** 371cb0ef41Sopenharmony_ci * The HTML spec disallows the default type to be explicitly specified 381cb0ef41Sopenharmony_ci * (for now); so `import './file.js'` is okay but 391cb0ef41Sopenharmony_ci * `import './file.js' with { type: 'javascript' }` throws. 401cb0ef41Sopenharmony_ci * @type {Array<string, string>} 411cb0ef41Sopenharmony_ci */ 421cb0ef41Sopenharmony_ciconst supportedAssertionTypes = ArrayPrototypeFilter( 431cb0ef41Sopenharmony_ci ObjectValues(formatTypeMap), 441cb0ef41Sopenharmony_ci (type) => type !== kImplicitAssertType); 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ci/** 481cb0ef41Sopenharmony_ci * Test a module's import attributes. 491cb0ef41Sopenharmony_ci * @param {string} url The URL of the imported module, for error reporting. 501cb0ef41Sopenharmony_ci * @param {string} format One of Node's supported translators 511cb0ef41Sopenharmony_ci * @param {Record<string, string>} importAttributes Validations for the 521cb0ef41Sopenharmony_ci * module import. 531cb0ef41Sopenharmony_ci * @returns {true} 541cb0ef41Sopenharmony_ci * @throws {TypeError} If the format and assertion type are incompatible. 551cb0ef41Sopenharmony_ci */ 561cb0ef41Sopenharmony_cifunction validateAttributes(url, format, 571cb0ef41Sopenharmony_ci importAttributes = { __proto__: null }) { 581cb0ef41Sopenharmony_ci const keys = ObjectKeys(importAttributes); 591cb0ef41Sopenharmony_ci for (let i = 0; i < keys.length; i++) { 601cb0ef41Sopenharmony_ci if (keys[i] !== 'type') { 611cb0ef41Sopenharmony_ci throw new ERR_IMPORT_ATTRIBUTE_UNSUPPORTED(keys[i], importAttributes[keys[i]]); 621cb0ef41Sopenharmony_ci } 631cb0ef41Sopenharmony_ci } 641cb0ef41Sopenharmony_ci const validType = formatTypeMap[format]; 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ci switch (validType) { 671cb0ef41Sopenharmony_ci case undefined: 681cb0ef41Sopenharmony_ci // Ignore attributes for module formats we don't recognize, to allow new 691cb0ef41Sopenharmony_ci // formats in the future. 701cb0ef41Sopenharmony_ci return true; 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_ci case kImplicitAssertType: 731cb0ef41Sopenharmony_ci // This format doesn't allow an import assertion type, so the property 741cb0ef41Sopenharmony_ci // must not be set on the import attributes object. 751cb0ef41Sopenharmony_ci if (!ObjectPrototypeHasOwnProperty(importAttributes, 'type')) { 761cb0ef41Sopenharmony_ci return true; 771cb0ef41Sopenharmony_ci } 781cb0ef41Sopenharmony_ci return handleInvalidType(url, importAttributes.type); 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_ci case importAttributes.type: 811cb0ef41Sopenharmony_ci // The asserted type is the valid type for this format. 821cb0ef41Sopenharmony_ci return true; 831cb0ef41Sopenharmony_ci 841cb0ef41Sopenharmony_ci default: 851cb0ef41Sopenharmony_ci // There is an expected type for this format, but the value of 861cb0ef41Sopenharmony_ci // `importAttributes.type` might not have been it. 871cb0ef41Sopenharmony_ci if (!ObjectPrototypeHasOwnProperty(importAttributes, 'type')) { 881cb0ef41Sopenharmony_ci // `type` wasn't specified at all. 891cb0ef41Sopenharmony_ci throw new ERR_IMPORT_ASSERTION_TYPE_MISSING(url, validType); 901cb0ef41Sopenharmony_ci } 911cb0ef41Sopenharmony_ci return handleInvalidType(url, importAttributes.type); 921cb0ef41Sopenharmony_ci } 931cb0ef41Sopenharmony_ci} 941cb0ef41Sopenharmony_ci 951cb0ef41Sopenharmony_ci/** 961cb0ef41Sopenharmony_ci * Throw the correct error depending on what's wrong with the type assertion. 971cb0ef41Sopenharmony_ci * @param {string} url The resolved URL for the module to be imported 981cb0ef41Sopenharmony_ci * @param {string} type The value of the import assertion `type` property 991cb0ef41Sopenharmony_ci */ 1001cb0ef41Sopenharmony_cifunction handleInvalidType(url, type) { 1011cb0ef41Sopenharmony_ci // `type` might have not been a string. 1021cb0ef41Sopenharmony_ci validateString(type, 'type'); 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ci // `type` might not have been one of the types we understand. 1051cb0ef41Sopenharmony_ci if (!ArrayPrototypeIncludes(supportedAssertionTypes, type)) { 1061cb0ef41Sopenharmony_ci throw new ERR_IMPORT_ASSERTION_TYPE_UNSUPPORTED(type); 1071cb0ef41Sopenharmony_ci } 1081cb0ef41Sopenharmony_ci 1091cb0ef41Sopenharmony_ci // `type` was the wrong value for this format. 1101cb0ef41Sopenharmony_ci throw new ERR_IMPORT_ASSERTION_TYPE_FAILED(url, type); 1111cb0ef41Sopenharmony_ci} 1121cb0ef41Sopenharmony_ci 1131cb0ef41Sopenharmony_ci 1141cb0ef41Sopenharmony_cimodule.exports = { 1151cb0ef41Sopenharmony_ci kImplicitAssertType, 1161cb0ef41Sopenharmony_ci validateAttributes, 1171cb0ef41Sopenharmony_ci}; 118