* Add built-in modules to a global or REPL scope object. * @param {Record } object - The object such as `globalThis` to add the built-in modules to. * @param {string} dummyModuleName - The label representing the set of built-in modules to add.
(object, dummyModuleName)
| 262 | * @param {string} dummyModuleName - The label representing the set of built-in modules to add. |
| 263 | */ |
| 264 | function addBuiltinLibsToObject(object, dummyModuleName) { |
| 265 | // Make built-in modules available directly (loaded lazily). |
| 266 | const Module = require('internal/modules/cjs/loader').Module; |
| 267 | const { builtinModules } = Module; |
| 268 | |
| 269 | // To require built-in modules in user-land and ignore modules whose |
| 270 | // `canBeRequiredByUsers` is false. So we create a dummy module object and not |
| 271 | // use `require()` directly. |
| 272 | const dummyModule = new Module(dummyModuleName); |
| 273 | |
| 274 | ArrayPrototypeForEach(builtinModules, (name) => { |
| 275 | // Neither add underscored modules, nor ones that contain slashes (e.g., |
| 276 | // 'fs/promises') or ones that are already defined. |
| 277 | if (name[0] === '_' || |
| 278 | StringPrototypeIncludes(name, '/') || |
| 279 | ObjectPrototypeHasOwnProperty(object, name)) { |
| 280 | return; |
| 281 | } |
| 282 | // Goals of this mechanism are: |
| 283 | // - Lazy loading of built-in modules |
| 284 | // - Having all built-in modules available as non-enumerable properties |
| 285 | // - Allowing the user to re-assign these variables as if there were no |
| 286 | // pre-existing globals with the same name. |
| 287 | |
| 288 | const setReal = (val) => { |
| 289 | // Deleting the property before re-assigning it disables the |
| 290 | // getter/setter mechanism. |
| 291 | delete object[name]; |
| 292 | object[name] = val; |
| 293 | }; |
| 294 | |
| 295 | ObjectDefineProperty(object, name, { |
| 296 | __proto__: null, |
| 297 | get: () => { |
| 298 | const lib = dummyModule.require(name); |
| 299 | |
| 300 | try { |
| 301 | // Override the current getter/setter and set up a new |
| 302 | // non-enumerable property. |
| 303 | ObjectDefineProperty(object, name, { |
| 304 | __proto__: null, |
| 305 | get: () => lib, |
| 306 | set: setReal, |
| 307 | configurable: true, |
| 308 | enumerable: false, |
| 309 | }); |
| 310 | } catch { |
| 311 | // If the property is no longer configurable, ignore the error. |
| 312 | } |
| 313 | |
| 314 | return lib; |
| 315 | }, |
| 316 | set: setReal, |
| 317 | configurable: true, |
| 318 | enumerable: false, |
| 319 | }); |
| 320 | }); |
| 321 | } |
no test coverage detected
searching dependent graphs…