• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2const {
3  RegExpPrototypeExec,
4  StringPrototypeStartsWith,
5} = primordials;
6const { extname } = require('path');
7const { getOptionValue } = require('internal/options');
8
9const experimentalJsonModules = getOptionValue('--experimental-json-modules');
10const experimentalSpecifierResolution =
11  getOptionValue('--experimental-specifier-resolution');
12const experimentalWasmModules = getOptionValue('--experimental-wasm-modules');
13const { getPackageType } = require('internal/modules/esm/resolve');
14const { URL, fileURLToPath } = require('internal/url');
15const { ERR_UNKNOWN_FILE_EXTENSION } = require('internal/errors').codes;
16
17const extensionFormatMap = {
18  '__proto__': null,
19  '.cjs': 'commonjs',
20  '.js': 'module',
21  '.mjs': 'module'
22};
23
24const legacyExtensionFormatMap = {
25  '__proto__': null,
26  '.cjs': 'commonjs',
27  '.js': 'commonjs',
28  '.json': 'commonjs',
29  '.mjs': 'module',
30  '.node': 'commonjs'
31};
32
33if (experimentalWasmModules)
34  extensionFormatMap['.wasm'] = legacyExtensionFormatMap['.wasm'] = 'wasm';
35
36if (experimentalJsonModules)
37  extensionFormatMap['.json'] = legacyExtensionFormatMap['.json'] = 'json';
38
39function defaultGetFormat(url, context, defaultGetFormatUnused) {
40  if (StringPrototypeStartsWith(url, 'node:')) {
41    return { format: 'builtin' };
42  }
43  const parsed = new URL(url);
44  if (parsed.protocol === 'data:') {
45    const [ , mime ] = RegExpPrototypeExec(
46      /^([^/]+\/[^;,]+)(?:[^,]*?)(;base64)?,/,
47      parsed.pathname,
48    ) || [ null, null, null ];
49    const format = ({
50      '__proto__': null,
51      'text/javascript': 'module',
52      'application/json': experimentalJsonModules ? 'json' : null,
53      'application/wasm': experimentalWasmModules ? 'wasm' : null
54    })[mime] || null;
55    return { format };
56  } else if (parsed.protocol === 'file:') {
57    const ext = extname(parsed.pathname);
58    let format;
59    if (ext === '.js') {
60      format = getPackageType(parsed.href) === 'module' ? 'module' : 'commonjs';
61    } else {
62      format = extensionFormatMap[ext];
63    }
64    if (!format) {
65      if (experimentalSpecifierResolution === 'node') {
66        process.emitWarning(
67          'The Node.js specifier resolution in ESM is experimental.',
68          'ExperimentalWarning');
69        format = legacyExtensionFormatMap[ext];
70      } else {
71        throw new ERR_UNKNOWN_FILE_EXTENSION(ext, fileURLToPath(url));
72      }
73    }
74    return { format: format || null };
75  }
76  return { format: null };
77}
78
79module.exports = {
80  defaultGetFormat,
81  extensionFormatMap,
82  legacyExtensionFormatMap,
83};
84