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