1'use strict'
2
3const semver = require('semver')
4
5const permanentModules = [
6  'assert',
7  'buffer',
8  'child_process',
9  'cluster',
10  'console',
11  'constants',
12  'crypto',
13  'dgram',
14  'dns',
15  'domain',
16  'events',
17  'fs',
18  'http',
19  'https',
20  'module',
21  'net',
22  'os',
23  'path',
24  'punycode',
25  'querystring',
26  'readline',
27  'repl',
28  'stream',
29  'string_decoder',
30  'sys',
31  'timers',
32  'tls',
33  'tty',
34  'url',
35  'util',
36  'vm',
37  'zlib'
38]
39
40const versionLockedModules = {
41  freelist: '<6.0.0',
42  v8: '>=1.0.0',
43  process: '>=1.1.0',
44  inspector: '>=8.0.0',
45  async_hooks: '>=8.1.0',
46  http2: '>=8.4.0',
47  perf_hooks: '>=8.5.0',
48  trace_events: '>=10.0.0',
49  worker_threads: '>=12.0.0',
50  'node:test': '>=18.0.0'
51}
52
53const experimentalModules = {
54  worker_threads: '>=10.5.0',
55  wasi: '>=12.16.0',
56  diagnostics_channel: '^14.17.0 || >=15.1.0'
57}
58
59module.exports = ({ version = process.version, experimental = false } = {}) => {
60  const builtins = [...permanentModules]
61
62  for (const [name, semverRange] of Object.entries(versionLockedModules)) {
63    if (version === '*' || semver.satisfies(version, semverRange)) {
64      builtins.push(name)
65    }
66  }
67
68  if (experimental) {
69    for (const [name, semverRange] of Object.entries(experimentalModules)) {
70      if (
71        !builtins.includes(name) &&
72        (version === '*' || semver.satisfies(version, semverRange))
73      ) {
74        builtins.push(name)
75      }
76    }
77  }
78
79  return builtins
80}
81