1'use strict'; 2 3const { 4 RegExpPrototypeExec, 5 Uint8Array, 6} = primordials; 7const { getOptionValue } = require('internal/options'); 8 9const { closeSync, openSync, readSync } = require('fs'); 10 11const experimentalWasmModules = getOptionValue('--experimental-wasm-modules'); 12 13const extensionFormatMap = { 14 '__proto__': null, 15 '.cjs': 'commonjs', 16 '.js': 'module', 17 '.json': 'json', 18 '.mjs': 'module', 19}; 20 21const legacyExtensionFormatMap = { 22 '__proto__': null, 23 '.cjs': 'commonjs', 24 '.js': 'commonjs', 25 '.json': 'commonjs', 26 '.mjs': 'module', 27 '.node': 'commonjs', 28}; 29 30if (experimentalWasmModules) { 31 extensionFormatMap['.wasm'] = legacyExtensionFormatMap['.wasm'] = 'wasm'; 32} 33 34/** 35 * @param {string} mime 36 * @returns {string | null} 37 */ 38function mimeToFormat(mime) { 39 if ( 40 RegExpPrototypeExec( 41 /^\s*(text|application)\/javascript\s*(;\s*charset=utf-?8\s*)?$/i, 42 mime, 43 ) !== null 44 ) { return 'module'; } 45 if (mime === 'application/json') { return 'json'; } 46 if (experimentalWasmModules && mime === 'application/wasm') { return 'wasm'; } 47 return null; 48} 49 50function getLegacyExtensionFormat(ext) { 51 return legacyExtensionFormatMap[ext]; 52} 53 54/** 55 * For extensionless files in a `module` package scope, or a default `module` scope enabled by the 56 * `--experimental-default-type` flag, we check the file contents to disambiguate between ES module JavaScript and Wasm. 57 * We do this by taking advantage of the fact that all Wasm files start with the header `0x00 0x61 0x73 0x6d` (`_asm`). 58 * @param {URL} url 59 */ 60function getFormatOfExtensionlessFile(url) { 61 if (!experimentalWasmModules) { return 'module'; } 62 63 const magic = new Uint8Array(4); 64 let fd; 65 try { 66 // TODO(@anonrig): Optimize the following by having a single C++ call 67 fd = openSync(url); 68 readSync(fd, magic, 0, 4); // Only read the first four bytes 69 if (magic[0] === 0x00 && magic[1] === 0x61 && magic[2] === 0x73 && magic[3] === 0x6d) { 70 return 'wasm'; 71 } 72 } finally { 73 if (fd !== undefined) { closeSync(fd); } 74 } 75 76 return 'module'; 77} 78 79module.exports = { 80 extensionFormatMap, 81 getFormatOfExtensionlessFile, 82 getLegacyExtensionFormat, 83 legacyExtensionFormatMap, 84 mimeToFormat, 85}; 86