-
Notifications
You must be signed in to change notification settings - Fork 30.4k
/
Copy pathutils.js
178 lines (155 loc) Β· 5.23 KB
/
utils.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
'use strict';
const {
ArrayIsArray,
PromisePrototypeThen,
SafeSet,
SafeWeakMap,
ObjectFreeze,
} = primordials;
const {
ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING,
ERR_INVALID_ARG_VALUE,
} = require('internal/errors').codes;
const { getOptionValue } = require('internal/options');
const { pathToFileURL } = require('internal/url');
const { kEmptyObject } = require('internal/util');
const {
setImportModuleDynamicallyCallback,
setInitializeImportMetaObjectCallback,
} = internalBinding('module_wrap');
const {
getModuleFromWrap,
} = require('internal/vm/module');
const assert = require('internal/assert');
const callbackMap = new SafeWeakMap();
function setCallbackForWrap(wrap, data) {
callbackMap.set(wrap, data);
}
let defaultConditions;
function getDefaultConditions() {
assert(defaultConditions !== undefined);
return defaultConditions;
}
let defaultConditionsSet;
function getDefaultConditionsSet() {
assert(defaultConditionsSet !== undefined);
return defaultConditionsSet;
}
// This function is called during pre-execution, before any user code is run.
function initializeDefaultConditions() {
const userConditions = getOptionValue('--conditions');
const noAddons = getOptionValue('--no-addons');
const addonConditions = noAddons ? [] : ['node-addons'];
defaultConditions = ObjectFreeze([
'node',
'import',
...addonConditions,
...userConditions,
]);
defaultConditionsSet = new SafeSet(defaultConditions);
}
/**
* @param {string[]} [conditions]
* @returns {Set<string>}
*/
function getConditionsSet(conditions) {
if (conditions !== undefined && conditions !== getDefaultConditions()) {
if (!ArrayIsArray(conditions)) {
throw new ERR_INVALID_ARG_VALUE('conditions', conditions,
'expected an array');
}
return new SafeSet(conditions);
}
return getDefaultConditionsSet();
}
function initializeImportMetaObject(wrap, meta) {
if (callbackMap.has(wrap)) {
const { initializeImportMeta } = callbackMap.get(wrap);
if (initializeImportMeta !== undefined) {
meta = initializeImportMeta(meta, getModuleFromWrap(wrap) || wrap);
}
}
}
async function importModuleDynamicallyCallback(wrap, specifier, assertions) {
if (callbackMap.has(wrap)) {
const { importModuleDynamically } = callbackMap.get(wrap);
if (importModuleDynamically !== undefined) {
return importModuleDynamically(
specifier, getModuleFromWrap(wrap) || wrap, assertions);
}
}
throw new ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING();
}
// This is configured during pre-execution. Specifically it's set to true for
// the loader worker in internal/main/worker_thread.js.
let _isLoaderWorker = false;
function initializeESM(isLoaderWorker = false) {
_isLoaderWorker = isLoaderWorker;
initializeDefaultConditions();
// Setup per-isolate callbacks that locate data or callbacks that we keep
// track of for different ESM modules.
setInitializeImportMetaObjectCallback(initializeImportMetaObject);
setImportModuleDynamicallyCallback(importModuleDynamicallyCallback);
}
function isLoaderWorker() {
return _isLoaderWorker;
}
async function initializeHooks() {
const customLoaderURLs = getOptionValue('--experimental-loader');
let cwd;
try {
// `process.cwd()` can fail if the parent directory is deleted while the process runs.
cwd = process.cwd() + '/';
} catch {
cwd = '/';
}
const { Hooks } = require('internal/modules/esm/hooks');
const hooks = new Hooks();
const { DefaultModuleLoader } = require('internal/modules/esm/loader');
class ModuleLoader extends DefaultModuleLoader {
loaderType = 'internal';
async #getModuleJob(specifier, parentURL, importAssertions) {
const resolveResult = await hooks.resolve(specifier, parentURL, importAssertions);
return this.getJobFromResolveResult(resolveResult, parentURL, importAssertions);
}
getModuleJob(specifier, parentURL, importAssertions) {
const jobPromise = this.#getModuleJob(specifier, parentURL, importAssertions);
return {
run() {
return PromisePrototypeThen(jobPromise, (job) => job.run());
},
get modulePromise() {
return PromisePrototypeThen(jobPromise, (job) => job.modulePromise);
},
get linked() {
return PromisePrototypeThen(jobPromise, (job) => job.linked);
},
};
}
load(url, context) { return hooks.load(url, context); }
}
const privateModuleLoader = new ModuleLoader();
const parentURL = pathToFileURL(cwd).href;
// TODO(jlenon7): reuse the `Hooks.register()` method for registering loaders.
for (let i = 0; i < customLoaderURLs.length; i++) {
const customLoaderURL = customLoaderURLs[i];
// Importation must be handled by internal loader to avoid polluting user-land
const keyedExports = await privateModuleLoader.import(
customLoaderURL,
parentURL,
kEmptyObject,
);
hooks.addCustomLoader(customLoaderURL, keyedExports);
}
const preloadScripts = hooks.initializeGlobalPreload();
return { __proto__: null, hooks, preloadScripts };
}
module.exports = {
setCallbackForWrap,
initializeESM,
initializeHooks,
getDefaultConditions,
getConditionsSet,
loaderWorkerId: 'internal/modules/esm/worker',
isLoaderWorker,
};