• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1const jsDocPrefix = 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/';
2
3const jsDataStructuresUrl = `${jsDocPrefix}Data_structures`;
4const jsPrimitives = {
5  boolean: 'Boolean',
6  integer: 'Number', // Not a primitive, used for clarification.
7  null: 'Null',
8  number: 'Number',
9  string: 'String',
10  symbol: 'Symbol',
11  undefined: 'Undefined'
12};
13
14const jsGlobalObjectsUrl = `${jsDocPrefix}Reference/Global_Objects/`;
15const jsGlobalTypes = [
16  'Array', 'ArrayBuffer', 'DataView', 'Date', 'Error',
17  'EvalError', 'Function', 'Map', 'Object', 'Promise', 'RangeError',
18  'ReferenceError', 'RegExp', 'Set', 'SharedArrayBuffer', 'SyntaxError',
19  'TypeError', 'TypedArray', 'URIError', 'Uint8Array',
20];
21
22const customTypesMap = {
23  'any': `${jsDataStructuresUrl}#Data_types`,
24
25  'this': `${jsDocPrefix}Reference/Operators/this`,
26
27  'AbortController': 'globals.html#globals_class_abortcontroller',
28  'AbortSignal': 'globals.html#globals_class_abortsignal',
29
30  'ArrayBufferView':
31    'https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView',
32
33  'AsyncIterator': 'https://tc39.github.io/ecma262/#sec-asynciterator-interface',
34
35  'AsyncIterable': 'https://tc39.github.io/ecma262/#sec-asynciterable-interface',
36
37  'bigint': `${jsDocPrefix}Reference/Global_Objects/BigInt`,
38  'WebAssembly.Instance':
39    `${jsDocPrefix}Reference/Global_Objects/WebAssembly/Instance`,
40
41  'Blob': 'buffer.html#buffer_class_blob',
42
43  'Iterable':
44    `${jsDocPrefix}Reference/Iteration_protocols#The_iterable_protocol`,
45  'Iterator':
46    `${jsDocPrefix}Reference/Iteration_protocols#The_iterator_protocol`,
47
48  'Module Namespace Object':
49    'https://tc39.github.io/ecma262/#sec-module-namespace-exotic-objects',
50
51  'AsyncHook': 'async_hooks.html#async_hooks_async_hooks_createhook_callbacks',
52  'AsyncResource': 'async_hooks.html#async_hooks_class_asyncresource',
53
54  'brotli options': 'zlib.html#zlib_class_brotlioptions',
55
56  'Buffer': 'buffer.html#buffer_class_buffer',
57
58  'ChildProcess': 'child_process.html#child_process_class_childprocess',
59
60  'cluster.Worker': 'cluster.html#cluster_class_worker',
61
62  'Cipher': 'crypto.html#crypto_class_cipher',
63  'Decipher': 'crypto.html#crypto_class_decipher',
64  'DiffieHellman': 'crypto.html#crypto_class_diffiehellman',
65  'DiffieHellmanGroup': 'crypto.html#crypto_class_diffiehellmangroup',
66  'ECDH': 'crypto.html#crypto_class_ecdh',
67  'Hash': 'crypto.html#crypto_class_hash',
68  'Hmac': 'crypto.html#crypto_class_hmac',
69  'KeyObject': 'crypto.html#crypto_class_keyobject',
70  'Sign': 'crypto.html#crypto_class_sign',
71  'Verify': 'crypto.html#crypto_class_verify',
72  'crypto.constants': 'crypto.html#crypto_crypto_constants_1',
73
74  'dgram.Socket': 'dgram.html#dgram_class_dgram_socket',
75
76  'Channel': 'diagnostics_channel.html#diagnostics_channel_class_channel',
77
78  'Domain': 'domain.html#domain_class_domain',
79
80  'errors.Error': 'errors.html#errors_class_error',
81
82  'import.meta': 'esm.html#esm_import_meta',
83
84  'EventEmitter': 'events.html#events_class_eventemitter',
85  'EventTarget': 'events.html#events_class_eventtarget',
86  'Event': 'events.html#events_class_event',
87  'EventListener': 'events.html#events_event_listener',
88
89  'FileHandle': 'fs.html#fs_class_filehandle',
90  'fs.Dir': 'fs.html#fs_class_fs_dir',
91  'fs.Dirent': 'fs.html#fs_class_fs_dirent',
92  'fs.FSWatcher': 'fs.html#fs_class_fs_fswatcher',
93  'fs.ReadStream': 'fs.html#fs_class_fs_readstream',
94  'fs.Stats': 'fs.html#fs_class_fs_stats',
95  'fs.StatWatcher': 'fs.html#fs_class_fs_statwatcher',
96  'fs.WriteStream': 'fs.html#fs_class_fs_writestream',
97
98  'http.Agent': 'http.html#http_class_http_agent',
99  'http.ClientRequest': 'http.html#http_class_http_clientrequest',
100  'http.IncomingMessage': 'http.html#http_class_http_incomingmessage',
101  'http.Server': 'http.html#http_class_http_server',
102  'http.ServerResponse': 'http.html#http_class_http_serverresponse',
103
104  'ClientHttp2Session': 'http2.html#http2_class_clienthttp2session',
105  'ClientHttp2Stream': 'http2.html#http2_class_clienthttp2stream',
106  'HTTP/2 Headers Object': 'http2.html#http2_headers_object',
107  'HTTP/2 Settings Object': 'http2.html#http2_settings_object',
108  'http2.Http2ServerRequest': 'http2.html#http2_class_http2_http2serverrequest',
109  'http2.Http2ServerResponse':
110    'http2.html#http2_class_http2_http2serverresponse',
111  'Http2SecureServer': 'http2.html#http2_class_http2secureserver',
112  'Http2Server': 'http2.html#http2_class_http2server',
113  'Http2Session': 'http2.html#http2_class_http2session',
114  'Http2Stream': 'http2.html#http2_class_http2stream',
115  'ServerHttp2Stream': 'http2.html#http2_class_serverhttp2stream',
116
117  'https.Server': 'https.html#https_class_https_server',
118
119  'module': 'modules.html#modules_the_module_object',
120
121  'module.SourceMap':
122    'module.html#module_class_module_sourcemap',
123
124  'require': 'modules.html#modules_require_id',
125
126  'Handle': 'net.html#net_server_listen_handle_backlog_callback',
127  'net.BlockList': 'net.html#net_class_net_blocklist',
128  'net.Server': 'net.html#net_class_net_server',
129  'net.Socket': 'net.html#net_class_net_socket',
130  'net.SocketAddress': 'net.html#net_class_net_socketaddress',
131
132  'NodeEventTarget':
133    'events.html#events_class_nodeeventtarget',
134
135  'os.constants.dlopen': 'os.html#os_dlopen_constants',
136
137  'Histogram': 'perf_hooks.html#perf_hooks_class_histogram',
138  'IntervalHistogram':
139     'perf_hooks.html#perf_hooks_class_intervalhistogram_extends_histogram',
140  'RecordableHistogram':
141     'perf_hooks.html#perf_hooks_class_recordablehistogram_extends_histogram',
142  'PerformanceEntry': 'perf_hooks.html#perf_hooks_class_performanceentry',
143  'PerformanceNodeTiming':
144    'perf_hooks.html#perf_hooks_class_performancenodetiming',
145  'PerformanceObserver':
146    'perf_hooks.html#perf_hooks_class_perf_hooks_performanceobserver',
147  'PerformanceObserverEntryList':
148    'perf_hooks.html#perf_hooks_class_performanceobserverentrylist',
149
150  'readline.Interface': 'readline.html#readline_class_interface',
151
152  'repl.REPLServer': 'repl.html#repl_class_replserver',
153
154  'Stream': 'stream.html#stream_stream',
155  'stream.Duplex': 'stream.html#stream_class_stream_duplex',
156  'stream.Readable': 'stream.html#stream_class_stream_readable',
157  'stream.Transform': 'stream.html#stream_class_stream_transform',
158  'stream.Writable': 'stream.html#stream_class_stream_writable',
159
160  'Immediate': 'timers.html#timers_class_immediate',
161  'Timeout': 'timers.html#timers_class_timeout',
162  'Timer': 'timers.html#timers_timers',
163
164  'tls.SecureContext': 'tls.html#tls_tls_createsecurecontext_options',
165  'tls.Server': 'tls.html#tls_class_tls_server',
166  'tls.TLSSocket': 'tls.html#tls_class_tls_tlssocket',
167
168  'Tracing': 'tracing.html#tracing_tracing_object',
169
170  'URL': 'url.html#url_the_whatwg_url_api',
171  'URLSearchParams': 'url.html#url_class_urlsearchparams',
172
173  'vm.Module': 'vm.html#vm_class_vm_module',
174  'vm.Script': 'vm.html#vm_class_vm_script',
175  'vm.SourceTextModule': 'vm.html#vm_class_vm_sourcetextmodule',
176
177  'MessagePort': 'worker_threads.html#worker_threads_class_messageport',
178  'Worker': 'worker_threads.html#worker_threads_class_worker',
179
180  'zlib options': 'zlib.html#zlib_class_options',
181};
182
183const arrayPart = /(?:\[])+$/;
184
185export function toLink(typeInput) {
186  const typeLinks = [];
187  typeInput = typeInput.replace('{', '').replace('}', '');
188  const typeTexts = typeInput.split('|');
189
190  typeTexts.forEach((typeText) => {
191    typeText = typeText.trim();
192    if (typeText) {
193      let typeUrl;
194
195      // To support type[], type[][] etc., we store the full string
196      // and use the bracket-less version to lookup the type URL.
197      const typeTextFull = typeText;
198      typeText = typeText.replace(arrayPart, '');
199
200      const primitive = jsPrimitives[typeText];
201
202      if (primitive !== undefined) {
203        typeUrl = `${jsDataStructuresUrl}#${primitive}_type`;
204      } else if (jsGlobalTypes.includes(typeText)) {
205        typeUrl = `${jsGlobalObjectsUrl}${typeText}`;
206      } else {
207        typeUrl = customTypesMap[typeText];
208      }
209
210      if (typeUrl) {
211        typeLinks.push(
212          `<a href="${typeUrl}" class="type">&lt;${typeTextFull}&gt;</a>`);
213      } else {
214        throw new Error(
215          `Unrecognized type: '${typeTextFull}'.\n` +
216          `Please, edit the type or update '${import.meta.url}'.`
217        );
218      }
219    } else {
220      throw new Error(`Empty type slot: ${typeInput}`);
221    }
222  });
223
224  return typeLinks.length ? typeLinks.join(' | ') : typeInput;
225}
226