1'use strict'; 2 3const { getOptionValue } = require('internal/options'); 4const experimentalImportMetaResolve = getOptionValue('--experimental-import-meta-resolve'); 5 6/** 7 * Generate a function to be used as import.meta.resolve for a particular module. 8 * @param {string} defaultParentURL The default base to use for resolution 9 * @param {typeof import('./loader.js').ModuleLoader} loader Reference to the current module loader 10 * @param {bool} allowParentURL Whether to permit parentURL second argument for contextual resolution 11 * @returns {(specifier: string) => string} Function to assign to import.meta.resolve 12 */ 13function createImportMetaResolve(defaultParentURL, loader, allowParentURL) { 14 /** 15 * @param {string} specifier 16 * @param {URL['href']} [parentURL] When `--experimental-import-meta-resolve` is specified, a 17 * second argument can be provided. 18 */ 19 return function resolve(specifier, parentURL = defaultParentURL) { 20 let url; 21 22 if (!allowParentURL) { 23 parentURL = defaultParentURL; 24 } 25 26 try { 27 ({ url } = loader.resolveSync(specifier, parentURL)); 28 return url; 29 } catch (error) { 30 switch (error?.code) { 31 case 'ERR_UNSUPPORTED_DIR_IMPORT': 32 case 'ERR_MODULE_NOT_FOUND': 33 ({ url } = error); 34 if (url) { 35 return url; 36 } 37 } 38 throw error; 39 } 40 }; 41} 42 43/** 44 * Create the `import.meta` object for a module. 45 * @param {object} meta 46 * @param {{url: string}} context 47 * @param {typeof import('./loader.js').ModuleLoader} loader Reference to the current module loader 48 * @returns {{url: string, resolve?: Function}} 49 */ 50function initializeImportMeta(meta, context, loader) { 51 const { url } = context; 52 53 // Alphabetical 54 if (!loader || loader.allowImportMetaResolve) { 55 meta.resolve = createImportMetaResolve(url, loader, experimentalImportMetaResolve); 56 } 57 58 meta.url = url; 59 60 return meta; 61} 62 63module.exports = { 64 initializeImportMeta, 65}; 66