diff options
Diffstat (limited to 'lib/internal/modules/cjs/helpers.js')
-rw-r--r-- | lib/internal/modules/cjs/helpers.js | 62 |
1 files changed, 58 insertions, 4 deletions
diff --git a/lib/internal/modules/cjs/helpers.js b/lib/internal/modules/cjs/helpers.js index 71abcbf880..5e0e1b06ae 100644 --- a/lib/internal/modules/cjs/helpers.js +++ b/lib/internal/modules/cjs/helpers.js @@ -1,19 +1,72 @@ 'use strict'; const { Object } = primordials; +const { + ERR_MANIFEST_DEPENDENCY_MISSING, + ERR_UNKNOWN_BUILTIN_MODULE +} = require('internal/errors').codes; +const { NativeModule } = require('internal/bootstrap/loaders'); +const { getOptionValue } = require('internal/options'); +const experimentalModules = getOptionValue('--experimental-modules'); const { validateString } = require('internal/validators'); const path = require('path'); -const { pathToFileURL } = require('internal/url'); +const { pathToFileURL, fileURLToPath } = require('internal/url'); const { URL } = require('url'); +const debug = require('internal/util/debuglog').debuglog('module'); + +function loadNativeModule(filename, request, experimentalModules) { + const mod = NativeModule.map.get(filename); + if (mod) { + debug('load native module %s', request); + mod.compileForPublicLoader(experimentalModules); + return mod; + } +} + // Invoke with makeRequireFunction(module) where |module| is the Module object // to use as the context for the require() function. -function makeRequireFunction(mod) { +// Use redirects to set up a mapping from a policy and restrict dependencies +function makeRequireFunction(mod, redirects) { const Module = mod.constructor; - function require(path) { - return mod.require(path); + let require; + if (redirects) { + const { map, reaction } = redirects; + const id = mod.filename || mod.id; + require = function require(path) { + let missing = true; + if (map === true) { + missing = false; + } else if (map.has(path)) { + const redirect = map.get(path); + if (redirect === true) { + missing = false; + } else if (typeof redirect === 'string') { + const parsed = new URL(redirect); + if (parsed.protocol === 'node:') { + const specifier = parsed.pathname; + const mod = loadNativeModule( + specifier, + redirect, + experimentalModules); + if (mod && mod.canBeRequiredByUsers) return mod.exports; + throw new ERR_UNKNOWN_BUILTIN_MODULE(specifier); + } else if (parsed.protocol === 'file:') { + return mod.require(fileURLToPath(parsed)); + } + } + } + if (missing) { + reaction(new ERR_MANIFEST_DEPENDENCY_MISSING(id, path)); + } + return mod.require(path); + }; + } else { + require = function require(path) { + return mod.require(path); + }; } function resolve(request, options) { @@ -114,6 +167,7 @@ function normalizeReferrerURL(referrer) { module.exports = { addBuiltinLibsToObject, builtinLibs, + loadNativeModule, makeRequireFunction, normalizeReferrerURL, stripBOM, |