2015-08-17 17:33:13 -04:00
|
|
|
'use strict';
|
|
|
|
|
2019-11-22 18:04:46 +01:00
|
|
|
const {
|
2020-11-07 11:08:09 +01:00
|
|
|
ArrayPrototypeForEach,
|
2019-11-22 18:04:46 +01:00
|
|
|
ObjectDefineProperty,
|
2024-08-29 01:22:57 +02:00
|
|
|
ObjectFreeze,
|
2020-05-07 17:09:51 +02:00
|
|
|
ObjectPrototypeHasOwnProperty,
|
2019-11-22 18:04:46 +01:00
|
|
|
SafeMap,
|
2020-07-17 12:39:02 -05:00
|
|
|
SafeSet,
|
2020-11-07 11:08:09 +01:00
|
|
|
StringPrototypeCharCodeAt,
|
|
|
|
StringPrototypeIncludes,
|
|
|
|
StringPrototypeSlice,
|
|
|
|
StringPrototypeStartsWith,
|
2019-11-22 18:04:46 +01:00
|
|
|
} = primordials;
|
2019-07-18 09:01:59 -05:00
|
|
|
const {
|
2023-05-29 19:45:33 -03:00
|
|
|
ERR_INVALID_ARG_TYPE,
|
2024-08-22 10:48:33 +02:00
|
|
|
ERR_INVALID_RETURN_PROPERTY_VALUE,
|
2019-07-18 09:01:59 -05:00
|
|
|
} = require('internal/errors').codes;
|
2023-04-04 09:13:37 +08:00
|
|
|
const { BuiltinModule } = require('internal/bootstrap/realm');
|
2019-04-09 09:55:53 +02:00
|
|
|
|
2018-12-06 13:50:41 +08:00
|
|
|
const { validateString } = require('internal/validators');
|
2023-09-29 19:24:14 -07:00
|
|
|
const fs = require('fs'); // Import all of `fs` so that it can be monkey-patched.
|
|
|
|
const internalFS = require('internal/fs/utils');
|
2018-11-07 22:17:09 +05:30
|
|
|
const path = require('path');
|
2024-02-01 12:45:42 +01:00
|
|
|
const { pathToFileURL, fileURLToPath } = require('internal/url');
|
|
|
|
const assert = require('internal/assert');
|
2018-01-25 04:55:52 +08:00
|
|
|
|
2024-08-12 15:07:49 +02:00
|
|
|
const { Buffer } = require('buffer');
|
2020-07-17 12:39:02 -05:00
|
|
|
const { getOptionValue } = require('internal/options');
|
2024-08-29 01:22:57 +02:00
|
|
|
const { setOwnProperty, getLazy } = require('internal/util');
|
2024-02-01 12:45:42 +01:00
|
|
|
const { inspect } = require('internal/util/inspect');
|
2020-07-17 12:39:02 -05:00
|
|
|
|
2024-08-29 01:22:57 +02:00
|
|
|
const lazyTmpdir = getLazy(() => require('os').tmpdir());
|
|
|
|
const { join } = path;
|
|
|
|
|
2024-02-01 12:45:42 +01:00
|
|
|
const { canParse: URLCanParse } = internalBinding('url');
|
2024-08-29 01:22:57 +02:00
|
|
|
const {
|
|
|
|
enableCompileCache: _enableCompileCache,
|
|
|
|
getCompileCacheDir: _getCompileCacheDir,
|
|
|
|
compileCacheStatus: _compileCacheStatus,
|
2024-09-04 20:18:12 +02:00
|
|
|
flushCompileCache,
|
2024-08-29 01:22:57 +02:00
|
|
|
} = internalBinding('modules');
|
2022-10-25 00:23:27 -03:00
|
|
|
|
2020-03-14 07:55:44 -04:00
|
|
|
let debug = require('internal/util/debuglog').debuglog('module', (fn) => {
|
|
|
|
debug = fn;
|
|
|
|
});
|
2019-07-18 09:01:59 -05:00
|
|
|
|
2023-09-18 19:48:24 -07:00
|
|
|
/** @typedef {import('internal/modules/cjs/loader.js').Module} Module */
|
|
|
|
|
2023-09-29 19:24:14 -07:00
|
|
|
/**
|
|
|
|
* Cache for storing resolved real paths of modules.
|
|
|
|
* In order to minimize unnecessary lstat() calls, this cache is a list of known-real paths.
|
|
|
|
* Set to an empty Map to reset.
|
|
|
|
* @type {Map<string, string>}
|
|
|
|
*/
|
|
|
|
const realpathCache = new SafeMap();
|
|
|
|
/**
|
|
|
|
* Resolves the path of a given `require` specifier, following symlinks.
|
|
|
|
* @param {string} requestPath The `require` specifier
|
|
|
|
*/
|
|
|
|
function toRealPath(requestPath) {
|
|
|
|
return fs.realpathSync(requestPath, {
|
|
|
|
[internalFS.realpathCacheKey]: realpathCache,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2023-09-18 19:48:24 -07:00
|
|
|
/** @type {Set<string>} */
|
2022-12-13 23:51:05 +01:00
|
|
|
let cjsConditions;
|
2023-09-18 19:48:24 -07:00
|
|
|
/**
|
|
|
|
* Define the conditions that apply to the CommonJS loader.
|
|
|
|
*/
|
2022-12-13 23:51:05 +01:00
|
|
|
function initializeCjsConditions() {
|
|
|
|
const userConditions = getOptionValue('--conditions');
|
|
|
|
const noAddons = getOptionValue('--no-addons');
|
|
|
|
const addonConditions = noAddons ? [] : ['node-addons'];
|
|
|
|
// TODO: Use this set when resolving pkg#exports conditions in loader.js.
|
|
|
|
cjsConditions = new SafeSet([
|
|
|
|
'require',
|
|
|
|
'node',
|
|
|
|
...addonConditions,
|
|
|
|
...userConditions,
|
|
|
|
]);
|
module: implement the "module-sync" exports condition
This patch implements a "module-sync" exports condition
for packages to supply a sycnrhonous ES module to the
Node.js module loader, no matter it's being required
or imported. This is similar to the "module" condition
that bundlers have been using to support `require(esm)`
in Node.js, and allows dual-package authors to opt into
ESM-first only newer versions of Node.js that supports
require(esm) while avoiding the dual-package hazard.
```json
{
"type": "module",
"exports": {
"node": {
// On new version of Node.js, both require() and import get
// the ESM version
"module-sync": "./index.js",
// On older version of Node.js, where "module" and
// require(esm) are not supported, use the transpiled CJS version
// to avoid dual-package hazard. Library authors can decide
// to drop support for older versions of Node.js when they think
// it's time.
"default": "./dist/index.cjs"
},
// On any other environment, use the ESM version.
"default": "./index.js"
}
}
```
We end up implementing a condition with a different name
instead of reusing "module", because existing code in the
ecosystem using the "module" condition sometimes also expect
the module resolution for these ESM files to work in CJS
style, which is supported by bundlers, but the native
Node.js loader has intentionally made ESM resolution
different from CJS resolution (e.g. forbidding `import
'./noext'` or `import './directory'`), so it would be
semver-major to implement a `"module"` condition
without implementing the forbidden ESM resolution rules.
For now, this just implments a new condition as semver-minor
so it can be backported to older LTS.
Refs: https://webpack.js.org/guides/package-exports/#target-environment-independent-packages
PR-URL: https://github.com/nodejs/node/pull/54648
Fixes: https://github.com/nodejs/node/issues/52173
Refs: https://github.com/joyeecheung/test-module-condition
Refs: https://github.com/nodejs/node/issues/52697
Reviewed-By: Jacob Smith <jacob@frende.me>
Reviewed-By: Jan Krems <jan.krems@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
2024-09-25 08:35:26 +02:00
|
|
|
if (getOptionValue('--experimental-require-module')) {
|
|
|
|
cjsConditions.add('module-sync');
|
|
|
|
}
|
2022-12-13 23:51:05 +01:00
|
|
|
}
|
2021-09-02 15:17:42 +02:00
|
|
|
|
2023-09-18 19:48:24 -07:00
|
|
|
/**
|
|
|
|
* Get the conditions that apply to the CommonJS loader.
|
|
|
|
*/
|
2022-12-13 23:51:05 +01:00
|
|
|
function getCjsConditions() {
|
|
|
|
if (cjsConditions === undefined) {
|
|
|
|
initializeCjsConditions();
|
|
|
|
}
|
|
|
|
return cjsConditions;
|
|
|
|
}
|
2020-07-17 12:39:02 -05:00
|
|
|
|
2023-09-18 19:48:24 -07:00
|
|
|
/**
|
|
|
|
* Provide one of Node.js' public modules to user code.
|
|
|
|
* @param {string} id - The identifier/specifier of the builtin module to load
|
|
|
|
* @param {string} request - The module requiring or importing the builtin module
|
|
|
|
*/
|
|
|
|
function loadBuiltinModule(id, request) {
|
|
|
|
if (!BuiltinModule.canBeRequiredByUsers(id)) {
|
2023-04-05 13:13:23 +02:00
|
|
|
return;
|
2019-07-18 09:01:59 -05:00
|
|
|
}
|
2023-09-18 19:48:24 -07:00
|
|
|
/** @type {import('internal/bootstrap/realm.js').BuiltinModule} */
|
|
|
|
const mod = BuiltinModule.map.get(id);
|
2023-04-05 13:13:23 +02:00
|
|
|
debug('load built-in module %s', request);
|
|
|
|
// compileForPublicLoader() throws if canBeRequiredByUsers is false:
|
|
|
|
mod.compileForPublicLoader();
|
|
|
|
return mod;
|
2019-07-18 09:01:59 -05:00
|
|
|
}
|
|
|
|
|
2023-09-18 19:48:24 -07:00
|
|
|
/** @type {Module} */
|
2023-05-29 19:45:33 -03:00
|
|
|
let $Module = null;
|
2023-09-18 19:48:24 -07:00
|
|
|
/**
|
|
|
|
* Import the Module class on first use.
|
|
|
|
*/
|
2023-05-29 19:45:33 -03:00
|
|
|
function lazyModule() {
|
|
|
|
$Module = $Module || require('internal/modules/cjs/loader').Module;
|
|
|
|
return $Module;
|
|
|
|
}
|
|
|
|
|
2023-09-18 19:48:24 -07:00
|
|
|
/**
|
|
|
|
* Create the module-scoped `require` function to pass into CommonJS modules.
|
|
|
|
* @param {Module} mod - The module to create the `require` function for.
|
|
|
|
* @typedef {(specifier: string) => unknown} RequireFunction
|
|
|
|
*/
|
2024-05-07 13:25:45 -03:00
|
|
|
function makeRequireFunction(mod) {
|
2023-05-29 19:45:33 -03:00
|
|
|
// lazy due to cycle
|
|
|
|
const Module = lazyModule();
|
|
|
|
if (mod instanceof Module !== true) {
|
|
|
|
throw new ERR_INVALID_ARG_TYPE('mod', 'Module', mod);
|
|
|
|
}
|
2015-11-25 22:27:29 +01:00
|
|
|
|
2024-05-07 13:25:45 -03:00
|
|
|
function require(path) {
|
|
|
|
return mod.require(path);
|
2015-11-25 22:27:29 +01:00
|
|
|
}
|
|
|
|
|
2023-09-18 19:48:24 -07:00
|
|
|
/**
|
|
|
|
* The `resolve` method that gets attached to module-scope `require`.
|
|
|
|
* @param {string} request
|
|
|
|
* @param {Parameters<Module['_resolveFilename']>[3]} options
|
|
|
|
*/
|
2016-04-25 12:19:28 -04:00
|
|
|
function resolve(request, options) {
|
2018-12-06 13:50:41 +08:00
|
|
|
validateString(request, 'request');
|
2016-04-25 12:19:28 -04:00
|
|
|
return Module._resolveFilename(request, mod, false, options);
|
2016-04-07 10:04:47 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
require.resolve = resolve;
|
2015-11-25 22:27:29 +01:00
|
|
|
|
2023-09-18 19:48:24 -07:00
|
|
|
/**
|
|
|
|
* The `paths` method that gets attached to module-scope `require`.
|
|
|
|
* @param {string} request
|
|
|
|
*/
|
2016-04-25 12:19:28 -04:00
|
|
|
function paths(request) {
|
2018-12-06 13:50:41 +08:00
|
|
|
validateString(request, 'request');
|
2019-03-29 14:46:53 +01:00
|
|
|
return Module._resolveLookupPaths(request, mod);
|
2016-04-25 12:19:28 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
resolve.paths = paths;
|
|
|
|
|
2022-08-05 00:41:48 +02:00
|
|
|
setOwnProperty(require, 'main', process.mainModule);
|
2015-11-25 22:27:29 +01:00
|
|
|
|
|
|
|
// Enable support to add extra extension types.
|
|
|
|
require.extensions = Module._extensions;
|
|
|
|
|
|
|
|
require.cache = Module._cache;
|
|
|
|
|
|
|
|
return require;
|
|
|
|
}
|
2015-08-17 17:33:13 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)
|
|
|
|
* because the buffer-to-string conversion in `fs.readFileSync()`
|
|
|
|
* translates it to FEFF, the UTF-16 BOM.
|
2023-09-18 19:48:24 -07:00
|
|
|
* @param {string} content
|
2015-08-17 17:33:13 -04:00
|
|
|
*/
|
|
|
|
function stripBOM(content) {
|
2020-11-07 11:08:09 +01:00
|
|
|
if (StringPrototypeCharCodeAt(content) === 0xFEFF) {
|
|
|
|
content = StringPrototypeSlice(content, 1);
|
2015-08-17 17:33:13 -04:00
|
|
|
}
|
|
|
|
return content;
|
|
|
|
}
|
2016-04-15 02:03:12 +02:00
|
|
|
|
2023-09-18 19:48:24 -07:00
|
|
|
/**
|
|
|
|
* Add built-in modules to a global or REPL scope object.
|
|
|
|
* @param {Record<string, unknown>} 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.
|
|
|
|
*/
|
2021-08-30 18:09:37 +08:00
|
|
|
function addBuiltinLibsToObject(object, dummyModuleName) {
|
2016-04-15 02:03:12 +02:00
|
|
|
// Make built-in modules available directly (loaded lazily).
|
2021-08-30 18:09:37 +08:00
|
|
|
const Module = require('internal/modules/cjs/loader').Module;
|
|
|
|
const { builtinModules } = Module;
|
|
|
|
|
|
|
|
// To require built-in modules in user-land and ignore modules whose
|
|
|
|
// `canBeRequiredByUsers` is false. So we create a dummy module object and not
|
|
|
|
// use `require()` directly.
|
|
|
|
const dummyModule = new Module(dummyModuleName);
|
|
|
|
|
2020-11-07 11:08:09 +01:00
|
|
|
ArrayPrototypeForEach(builtinModules, (name) => {
|
2020-05-07 17:09:51 +02:00
|
|
|
// Neither add underscored modules, nor ones that contain slashes (e.g.,
|
|
|
|
// 'fs/promises') or ones that are already defined.
|
2020-11-07 11:08:09 +01:00
|
|
|
if (StringPrototypeStartsWith(name, '_') ||
|
|
|
|
StringPrototypeIncludes(name, '/') ||
|
2020-05-07 17:09:51 +02:00
|
|
|
ObjectPrototypeHasOwnProperty(object, name)) {
|
|
|
|
return;
|
|
|
|
}
|
2016-04-18 13:19:12 +02:00
|
|
|
// Goals of this mechanism are:
|
|
|
|
// - Lazy loading of built-in modules
|
|
|
|
// - Having all built-in modules available as non-enumerable properties
|
|
|
|
// - Allowing the user to re-assign these variables as if there were no
|
|
|
|
// pre-existing globals with the same name.
|
|
|
|
|
|
|
|
const setReal = (val) => {
|
|
|
|
// Deleting the property before re-assigning it disables the
|
|
|
|
// getter/setter mechanism.
|
|
|
|
delete object[name];
|
|
|
|
object[name] = val;
|
|
|
|
};
|
|
|
|
|
2019-11-22 18:04:46 +01:00
|
|
|
ObjectDefineProperty(object, name, {
|
2022-06-03 10:23:58 +02:00
|
|
|
__proto__: null,
|
2016-04-15 02:03:12 +02:00
|
|
|
get: () => {
|
2021-08-30 18:09:37 +08:00
|
|
|
const lib = dummyModule.require(name);
|
2016-04-18 13:19:12 +02:00
|
|
|
|
2022-11-17 13:17:48 -05:00
|
|
|
try {
|
|
|
|
// Override the current getter/setter and set up a new
|
|
|
|
// non-enumerable property.
|
|
|
|
ObjectDefineProperty(object, name, {
|
|
|
|
__proto__: null,
|
|
|
|
get: () => lib,
|
|
|
|
set: setReal,
|
|
|
|
configurable: true,
|
|
|
|
enumerable: false,
|
|
|
|
});
|
|
|
|
} catch {
|
|
|
|
// If the property is no longer configurable, ignore the error.
|
|
|
|
}
|
2016-04-18 13:19:12 +02:00
|
|
|
|
|
|
|
return lib;
|
2016-04-15 02:03:12 +02:00
|
|
|
},
|
2016-04-18 13:19:12 +02:00
|
|
|
set: setReal,
|
2016-04-15 02:03:12 +02:00
|
|
|
configurable: true,
|
2023-02-16 18:47:24 +01:00
|
|
|
enumerable: false,
|
2016-04-15 02:03:12 +02:00
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
2017-04-24 15:45:52 -07:00
|
|
|
|
2022-02-25 10:05:55 -06:00
|
|
|
/**
|
2024-02-01 12:45:42 +01:00
|
|
|
* Normalize the referrer name as a URL.
|
|
|
|
* If it's a string containing an absolute path or a URL it's normalized as
|
|
|
|
* a URL string.
|
|
|
|
* Otherwise it's returned as undefined.
|
|
|
|
* @param {string | null | undefined} referrerName
|
|
|
|
* @returns {string | undefined}
|
2022-02-25 10:05:55 -06:00
|
|
|
*/
|
2024-02-01 12:45:42 +01:00
|
|
|
function normalizeReferrerURL(referrerName) {
|
|
|
|
if (referrerName === null || referrerName === undefined) {
|
|
|
|
return undefined;
|
2018-11-07 22:17:09 +05:30
|
|
|
}
|
2024-02-01 12:45:42 +01:00
|
|
|
|
|
|
|
if (typeof referrerName === 'string') {
|
|
|
|
if (path.isAbsolute(referrerName)) {
|
|
|
|
return pathToFileURL(referrerName).href;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (StringPrototypeStartsWith(referrerName, 'file://') ||
|
|
|
|
URLCanParse(referrerName)) {
|
|
|
|
return referrerName;
|
|
|
|
}
|
|
|
|
|
|
|
|
return undefined;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert.fail('Unreachable code reached by ' + inspect(referrerName));
|
2018-11-07 22:17:09 +05:30
|
|
|
}
|
|
|
|
|
2024-02-21 02:59:08 +01:00
|
|
|
|
2024-04-08 16:45:55 +02:00
|
|
|
/**
|
|
|
|
* @param {string|undefined} url URL to convert to filename
|
|
|
|
*/
|
|
|
|
function urlToFilename(url) {
|
|
|
|
if (url && StringPrototypeStartsWith(url, 'file://')) {
|
|
|
|
return fileURLToPath(url);
|
|
|
|
}
|
|
|
|
return url;
|
|
|
|
}
|
2024-03-20 08:48:05 -07:00
|
|
|
|
2024-02-21 02:59:08 +01:00
|
|
|
// Whether we have started executing any user-provided CJS code.
|
|
|
|
// This is set right before we call the wrapped CJS code (not after,
|
|
|
|
// in case we are half-way in the execution when internals check this).
|
|
|
|
// Used for internal assertions.
|
|
|
|
let _hasStartedUserCJSExecution = false;
|
|
|
|
// Similar to _hasStartedUserCJSExecution but for ESM. This is set
|
|
|
|
// right before ESM evaluation in the default ESM loader. We do not
|
|
|
|
// update this during vm SourceTextModule execution because at that point
|
|
|
|
// some user code must already have been run to execute code via vm
|
|
|
|
// there is little value checking whether any user JS code is run anyway.
|
|
|
|
let _hasStartedUserESMExecution = false;
|
|
|
|
|
2024-04-30 18:24:36 +02:00
|
|
|
/**
|
|
|
|
* Load a public built-in module. ID may or may not be prefixed by `node:` and
|
|
|
|
* will be normalized.
|
|
|
|
* @param {string} id ID of the built-in to be loaded.
|
|
|
|
* @returns {object|undefined} exports of the built-in. Undefined if the built-in
|
|
|
|
* does not exist.
|
|
|
|
*/
|
|
|
|
function getBuiltinModule(id) {
|
|
|
|
validateString(id, 'id');
|
|
|
|
const normalizedId = BuiltinModule.normalizeRequirableId(id);
|
|
|
|
return normalizedId ? require(normalizedId) : undefined;
|
|
|
|
}
|
|
|
|
|
2024-08-12 15:07:49 +02:00
|
|
|
/**
|
|
|
|
* TypeScript parsing function, by default Amaro.transformSync.
|
|
|
|
* @type {Function}
|
|
|
|
*/
|
2024-08-09 08:46:58 +02:00
|
|
|
let typeScriptParser;
|
2024-08-12 15:07:49 +02:00
|
|
|
/**
|
|
|
|
* The TypeScript parsing mode, either 'strip-only' or 'transform'.
|
|
|
|
* @type {string}
|
|
|
|
*/
|
|
|
|
let typeScriptParsingMode;
|
|
|
|
/**
|
|
|
|
* Whether source maps are enabled for TypeScript parsing.
|
|
|
|
* @type {boolean}
|
|
|
|
*/
|
|
|
|
let sourceMapEnabled;
|
2024-07-24 18:30:06 +02:00
|
|
|
|
2024-08-09 08:46:58 +02:00
|
|
|
/**
|
|
|
|
* Load the TypeScript parser.
|
|
|
|
* @param {Function} parser - A function that takes a string of TypeScript code
|
|
|
|
* and returns an object with a `code` property.
|
|
|
|
* @returns {Function} The TypeScript parser function.
|
|
|
|
*/
|
|
|
|
function loadTypeScriptParser(parser) {
|
|
|
|
if (typeScriptParser) {
|
|
|
|
return typeScriptParser;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (parser) {
|
|
|
|
typeScriptParser = parser;
|
|
|
|
} else {
|
|
|
|
const amaro = require('internal/deps/amaro/dist/index');
|
|
|
|
// Default option for Amaro is to perform Type Stripping only.
|
2024-08-12 15:07:49 +02:00
|
|
|
typeScriptParsingMode = getOptionValue('--experimental-transform-types') ? 'transform' : 'strip-only';
|
|
|
|
sourceMapEnabled = getOptionValue('--enable-source-maps');
|
2024-08-09 08:46:58 +02:00
|
|
|
// Curry the transformSync function with the default options.
|
2024-08-12 15:07:49 +02:00
|
|
|
typeScriptParser = amaro.transformSync;
|
2024-08-09 08:46:58 +02:00
|
|
|
}
|
|
|
|
return typeScriptParser;
|
2024-07-24 18:30:06 +02:00
|
|
|
}
|
|
|
|
|
2024-08-03 19:15:11 +02:00
|
|
|
/**
|
2024-08-12 15:07:49 +02:00
|
|
|
* @typedef {object} TransformOutput
|
|
|
|
* @property {string} code The compiled code.
|
|
|
|
* @property {string} [map] The source maps (optional).
|
|
|
|
*
|
2024-08-03 19:15:11 +02:00
|
|
|
* Performs type-stripping to TypeScript source code.
|
|
|
|
* @param {string} source TypeScript code to parse.
|
2024-08-12 15:07:49 +02:00
|
|
|
* @param {string} filename The filename of the source code.
|
|
|
|
* @returns {TransformOutput} The stripped TypeScript code.
|
2024-08-03 19:15:11 +02:00
|
|
|
*/
|
2024-08-12 15:07:49 +02:00
|
|
|
function stripTypeScriptTypes(source, filename) {
|
2024-08-12 09:51:40 +02:00
|
|
|
assert(typeof source === 'string');
|
2024-08-09 08:46:58 +02:00
|
|
|
const parse = loadTypeScriptParser();
|
2024-08-12 15:07:49 +02:00
|
|
|
const options = {
|
|
|
|
__proto__: null,
|
|
|
|
mode: typeScriptParsingMode,
|
|
|
|
sourceMap: sourceMapEnabled,
|
|
|
|
filename,
|
|
|
|
};
|
|
|
|
const { code, map } = parse(source, options);
|
|
|
|
if (map) {
|
|
|
|
// TODO(@marco-ippolito) When Buffer.transcode supports utf8 to
|
|
|
|
// base64 transformation, we should change this line.
|
|
|
|
const base64SourceMap = Buffer.from(map).toString('base64');
|
|
|
|
return `${code}\n\n//# sourceMappingURL=data:application/json;base64,${base64SourceMap}`;
|
|
|
|
}
|
2024-08-20 20:45:17 +01:00
|
|
|
// Source map is not necessary in strip-only mode. However, to map the source
|
|
|
|
// file in debuggers to the original TypeScript source, add a sourceURL magic
|
|
|
|
// comment to hint that it is a generated source.
|
|
|
|
return `${code}\n\n//# sourceURL=${filename}`;
|
2024-07-24 18:30:06 +02:00
|
|
|
}
|
|
|
|
|
2024-08-22 10:48:33 +02:00
|
|
|
/** @type {import('internal/util/types')} */
|
|
|
|
let _TYPES = null;
|
|
|
|
/**
|
|
|
|
* Lazily loads and returns the internal/util/types module.
|
|
|
|
*/
|
|
|
|
function lazyTypes() {
|
|
|
|
if (_TYPES !== null) { return _TYPES; }
|
|
|
|
return _TYPES = require('internal/util/types');
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Asserts that the given body is a buffer source (either a string, array buffer, or typed array).
|
|
|
|
* Throws an error if the body is not a buffer source.
|
|
|
|
* @param {string | ArrayBufferView | ArrayBuffer} body - The body to check.
|
|
|
|
* @param {boolean} allowString - Whether or not to allow a string as a valid buffer source.
|
|
|
|
* @param {string} hookName - The name of the hook being called.
|
|
|
|
* @throws {ERR_INVALID_RETURN_PROPERTY_VALUE} If the body is not a buffer source.
|
|
|
|
*/
|
|
|
|
function assertBufferSource(body, allowString, hookName) {
|
|
|
|
if (allowString && typeof body === 'string') {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const { isArrayBufferView, isAnyArrayBuffer } = lazyTypes();
|
|
|
|
if (isArrayBufferView(body) || isAnyArrayBuffer(body)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
throw new ERR_INVALID_RETURN_PROPERTY_VALUE(
|
|
|
|
`${allowString ? 'string, ' : ''}array buffer, or typed array`,
|
|
|
|
hookName,
|
|
|
|
'source',
|
|
|
|
body,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
let DECODER = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Converts a buffer or buffer-like object to a string.
|
|
|
|
* @param {string | ArrayBuffer | ArrayBufferView} body - The buffer or buffer-like object to convert to a string.
|
|
|
|
* @returns {string} The resulting string.
|
|
|
|
*/
|
|
|
|
function stringify(body) {
|
|
|
|
if (typeof body === 'string') { return body; }
|
|
|
|
assertBufferSource(body, false, 'load');
|
|
|
|
const { TextDecoder } = require('internal/encoding');
|
|
|
|
DECODER = DECODER === null ? new TextDecoder() : DECODER;
|
|
|
|
return DECODER.decode(body);
|
|
|
|
}
|
|
|
|
|
2024-08-29 01:22:57 +02:00
|
|
|
/**
|
|
|
|
* Enable on-disk compiled cache for all user modules being complied in the current Node.js instance
|
|
|
|
* after this method is called.
|
|
|
|
* If cacheDir is undefined, defaults to the NODE_MODULE_CACHE environment variable.
|
|
|
|
* If NODE_MODULE_CACHE isn't set, default to path.join(os.tmpdir(), 'node-compile-cache').
|
|
|
|
* @param {string|undefined} cacheDir
|
|
|
|
* @returns {{status: number, message?: string, directory?: string}}
|
|
|
|
*/
|
|
|
|
function enableCompileCache(cacheDir) {
|
|
|
|
if (cacheDir === undefined) {
|
|
|
|
cacheDir = join(lazyTmpdir(), 'node-compile-cache');
|
|
|
|
}
|
|
|
|
const nativeResult = _enableCompileCache(cacheDir);
|
|
|
|
const result = { status: nativeResult[0] };
|
|
|
|
if (nativeResult[1]) {
|
|
|
|
result.message = nativeResult[1];
|
|
|
|
}
|
|
|
|
if (nativeResult[2]) {
|
|
|
|
result.directory = nativeResult[2];
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
const compileCacheStatus = { __proto__: null };
|
|
|
|
for (let i = 0; i < _compileCacheStatus.length; ++i) {
|
|
|
|
compileCacheStatus[_compileCacheStatus[i]] = i;
|
|
|
|
}
|
|
|
|
ObjectFreeze(compileCacheStatus);
|
|
|
|
const constants = { __proto__: null, compileCacheStatus };
|
|
|
|
ObjectFreeze(constants);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the compile cache directory if on-disk compile cache is enabled.
|
|
|
|
* @returns {string|undefined} Path to the module compile cache directory if it is enabled,
|
|
|
|
* or undefined otherwise.
|
|
|
|
*/
|
|
|
|
function getCompileCacheDir() {
|
|
|
|
return _getCompileCacheDir() || undefined;
|
|
|
|
}
|
|
|
|
|
2019-04-04 11:36:41 +08:00
|
|
|
module.exports = {
|
2017-04-24 15:45:52 -07:00
|
|
|
addBuiltinLibsToObject,
|
2024-08-22 10:48:33 +02:00
|
|
|
assertBufferSource,
|
2024-08-29 01:22:57 +02:00
|
|
|
constants,
|
|
|
|
enableCompileCache,
|
2024-09-04 20:18:12 +02:00
|
|
|
flushCompileCache,
|
2024-04-30 18:24:36 +02:00
|
|
|
getBuiltinModule,
|
2022-12-13 23:51:05 +01:00
|
|
|
getCjsConditions,
|
2024-08-29 01:22:57 +02:00
|
|
|
getCompileCacheDir,
|
2022-12-13 23:51:05 +01:00
|
|
|
initializeCjsConditions,
|
2022-08-05 02:32:06 +08:00
|
|
|
loadBuiltinModule,
|
2017-04-24 15:45:52 -07:00
|
|
|
makeRequireFunction,
|
2018-11-07 22:17:09 +05:30
|
|
|
normalizeReferrerURL,
|
2024-08-12 15:07:49 +02:00
|
|
|
stripTypeScriptTypes,
|
2024-08-22 10:48:33 +02:00
|
|
|
stringify,
|
2017-04-24 15:45:52 -07:00
|
|
|
stripBOM,
|
2023-09-29 19:24:14 -07:00
|
|
|
toRealPath,
|
2024-02-21 02:59:08 +01:00
|
|
|
hasStartedUserCJSExecution() {
|
|
|
|
return _hasStartedUserCJSExecution;
|
|
|
|
},
|
|
|
|
setHasStartedUserCJSExecution() {
|
|
|
|
_hasStartedUserCJSExecution = true;
|
|
|
|
},
|
|
|
|
hasStartedUserESMExecution() {
|
|
|
|
return _hasStartedUserESMExecution;
|
|
|
|
},
|
|
|
|
setHasStartedUserESMExecution() {
|
|
|
|
_hasStartedUserESMExecution = true;
|
|
|
|
},
|
2024-04-08 16:45:55 +02:00
|
|
|
urlToFilename,
|
2017-04-24 15:45:52 -07:00
|
|
|
};
|