forked from nodejs/node
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathutils.js
178 lines (154 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 customLoaderPaths = 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;
for (let i = 0; i < customLoaderPaths.length; i++) {
const customLoaderPath = customLoaderPaths[i];
// Importation must be handled by internal loader to avoid polluting user-land
const keyedExportsSublist = await privateModuleLoader.import(
[customLoaderPath], // Import can handle multiple paths, but custom loaders must be sequential
parentURL,
kEmptyObject,
);
hooks.addCustomLoaders(keyedExportsSublist);
}
const preloadScripts = hooks.initializeGlobalPreload();
return { __proto__: null, hooks, preloadScripts };
}
module.exports = {
setCallbackForWrap,
initializeESM,
initializeHooks,
getDefaultConditions,
getConditionsSet,
loaderWorkerId: 'internal/modules/esm/worker',
isLoaderWorker,
};