• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2const {
3  ArrayIsArray,
4  SafeSet,
5  SafeWeakMap,
6  ObjectFreeze,
7} = primordials;
8
9const {
10  ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING,
11  ERR_INVALID_ARG_VALUE,
12} = require('internal/errors').codes;
13
14const { getOptionValue } = require('internal/options');
15
16const {
17  setImportModuleDynamicallyCallback,
18  setInitializeImportMetaObjectCallback,
19} = internalBinding('module_wrap');
20const {
21  getModuleFromWrap,
22} = require('internal/vm/module');
23const assert = require('internal/assert');
24
25const callbackMap = new SafeWeakMap();
26function setCallbackForWrap(wrap, data) {
27  callbackMap.set(wrap, data);
28}
29
30let defaultConditions;
31function getDefaultConditions() {
32  assert(defaultConditions !== undefined);
33  return defaultConditions;
34}
35
36let defaultConditionsSet;
37function getDefaultConditionsSet() {
38  assert(defaultConditionsSet !== undefined);
39  return defaultConditionsSet;
40}
41
42// This function is called during pre-execution, before any user code is run.
43function initializeDefaultConditions() {
44  const userConditions = getOptionValue('--conditions');
45  const noAddons = getOptionValue('--no-addons');
46  const addonConditions = noAddons ? [] : ['node-addons'];
47
48  defaultConditions = ObjectFreeze([
49    'node',
50    'import',
51    ...addonConditions,
52    ...userConditions,
53  ]);
54  defaultConditionsSet = new SafeSet(defaultConditions);
55}
56
57/**
58 * @param {string[]} [conditions]
59 * @returns {Set<string>}
60 */
61function getConditionsSet(conditions) {
62  if (conditions !== undefined && conditions !== getDefaultConditions()) {
63    if (!ArrayIsArray(conditions)) {
64      throw new ERR_INVALID_ARG_VALUE('conditions', conditions,
65                                      'expected an array');
66    }
67    return new SafeSet(conditions);
68  }
69  return getDefaultConditionsSet();
70}
71
72function initializeImportMetaObject(wrap, meta) {
73  if (callbackMap.has(wrap)) {
74    const { initializeImportMeta } = callbackMap.get(wrap);
75    if (initializeImportMeta !== undefined) {
76      initializeImportMeta(meta, getModuleFromWrap(wrap) || wrap);
77    }
78  }
79}
80
81async function importModuleDynamicallyCallback(wrap, specifier, assertions) {
82  if (callbackMap.has(wrap)) {
83    const { importModuleDynamically } = callbackMap.get(wrap);
84    if (importModuleDynamically !== undefined) {
85      return importModuleDynamically(
86        specifier, getModuleFromWrap(wrap) || wrap, assertions);
87    }
88  }
89  throw new ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING();
90}
91
92function initializeESM() {
93  initializeDefaultConditions();
94  // Setup per-isolate callbacks that locate data or callbacks that we keep
95  // track of for different ESM modules.
96  setInitializeImportMetaObjectCallback(initializeImportMetaObject);
97  setImportModuleDynamicallyCallback(importModuleDynamicallyCallback);
98}
99
100module.exports = {
101  setCallbackForWrap,
102  initializeESM,
103  getDefaultConditions,
104  getConditionsSet,
105};
106