Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 31 additions & 6 deletions lib/internal/bootstrap/realm.js
Original file line number Diff line number Diff line change
Expand Up @@ -310,21 +310,46 @@ class BuiltinModule {
}

static isBuiltin(id) {
return BuiltinModule.canBeRequiredWithoutScheme(id) || (
typeof id === 'string' &&
StringPrototypeStartsWith(id, 'node:') &&
if (typeof id !== 'string') {
return false;
}

// Modules starting with underscore (e.g. `_http_agent`) can be required
// by users but those are discouraged and should not be exposed as proper
// public ones, so if `id` starts with `_` (or `node:_`) return `false` right away
if (StringPrototypeStartsWith(id, '_') || StringPrototypeStartsWith(id, 'node:_')) {
return false;
}

// Check if `id` matches a builtin module without the `node:` prefix
if (BuiltinModule.canBeRequiredWithoutScheme(id)) {
return true;
}

// Check if `id` matches a builtin module with the `node:` prefix
if (
StringPrototypeStartsWith(id, 'node:') &&
BuiltinModule.canBeRequiredByUsers(StringPrototypeSlice(id, 5))
);
) {
return true;
}

return false;
}

static getSchemeOnlyModuleNames() {
return ArrayFrom(schemelessBlockList);
}

static getAllBuiltinModuleIds() {
static getAllPublicBuiltinModuleIds() {
const allBuiltins = ArrayFrom(canBeRequiredByUsersWithoutSchemeList);
ArrayPrototypePushApply(allBuiltins, ArrayFrom(schemelessBlockList, (x) => `node:${x}`));
return allBuiltins;
return ArrayPrototypeFilter(allBuiltins, (id) => {
// Modules starting with an underscore (e.g. `_http_agent`) can be
// required by users because of historical reasons, but they are not
// proper documented public modules, so they need to be filtered out
return id[0] !== '_';
});
}

// Used by user-land module loaders to compile and load builtins.
Expand Down
2 changes: 1 addition & 1 deletion lib/internal/modules/cjs/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ Module.isBuiltin = BuiltinModule.isBuiltin;
function initializeCJS() {
// This need to be done at runtime in case --expose-internals is set.

let modules = Module.builtinModules = BuiltinModule.getAllBuiltinModuleIds();
let modules = Module.builtinModules = BuiltinModule.getAllPublicBuiltinModuleIds();
if (!getOptionValue('--experimental-quic')) {
modules = modules.filter((i) => i !== 'node:quic');
}
Expand Down
7 changes: 7 additions & 0 deletions test/parallel/test-module-builtin.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,10 @@ assert.deepStrictEqual(
builtinModules.filter((mod) => mod.startsWith('internal/')),
[]
);

// Does not include modules starting with an underscore
// (these are exposed to users but not proper public documented modules)
assert.deepStrictEqual(
builtinModules.filter((mod) => mod.startsWith('_')),
[]
);
25 changes: 25 additions & 0 deletions test/parallel/test-module-isBuiltin.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,28 @@ assert(!isBuiltin('internal/errors'));
assert(!isBuiltin('test'));
assert(!isBuiltin(''));
assert(!isBuiltin(undefined));

const underscoreModules = [
'_http_agent',
'_http_client',
'_http_common',
'_http_incoming',
'_http_outgoing',
'_http_server',
'_stream_duplex',
'_stream_passthrough',
'_stream_readable',
'_stream_transform',
'_stream_wrap',
'_stream_writable',
'_tls_common',
'_tls_wrap',
];

// Does not include modules starting with underscore
// (these can be required for historical reasons but
// are not proper documented public modules)
for (const module of underscoreModules) {
assert(!isBuiltin(module));
assert(!isBuiltin(`node:${module}`));
}
Loading