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 'AggregateError', 'Array', 'ArrayBuffer', 'DataView', 'Date', 'Error', 17 'EvalError', 'Function', 'Map', 'Object', 'Promise', 'Proxy', '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#class-abortcontroller', 28 'AbortSignal': 'globals.html#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 'AsyncFunction': 'https://tc39.es/ecma262/#sec-async-function-constructor', 38 39 'AsyncGeneratorFunction': 'https://tc39.es/proposal-async-iteration/#sec-asyncgeneratorfunction-constructor', 40 41 'bigint': `${jsDocPrefix}Reference/Global_Objects/BigInt`, 42 'WebAssembly.Instance': 43 `${jsDocPrefix}Reference/Global_Objects/WebAssembly/Instance`, 44 45 'Blob': 'buffer.html#class-blob', 46 'File': 'buffer.html#class-file', 47 48 'BroadcastChannel': 49 'worker_threads.html#class-broadcastchannel-' + 50 'extends-eventtarget', 51 52 'Iterable': 53 `${jsDocPrefix}Reference/Iteration_protocols#The_iterable_protocol`, 54 'Iterator': 55 `${jsDocPrefix}Reference/Iteration_protocols#The_iterator_protocol`, 56 57 'Module Namespace Object': 58 'https://tc39.github.io/ecma262/#sec-module-namespace-exotic-objects', 59 60 'AsyncLocalStorage': 'async_context.html#class-asynclocalstorage', 61 62 'AsyncHook': 'async_hooks.html#async_hookscreatehookcallbacks', 63 'AsyncResource': 'async_hooks.html#class-asyncresource', 64 65 'brotli options': 'zlib.html#class-brotlioptions', 66 67 'Buffer': 'buffer.html#class-buffer', 68 69 'ChildProcess': 'child_process.html#class-childprocess', 70 71 'cluster.Worker': 'cluster.html#class-worker', 72 73 'Cipher': 'crypto.html#class-cipher', 74 'Decipher': 'crypto.html#class-decipher', 75 'DiffieHellman': 'crypto.html#class-diffiehellman', 76 'DiffieHellmanGroup': 'crypto.html#class-diffiehellmangroup', 77 'ECDH': 'crypto.html#class-ecdh', 78 'Hash': 'crypto.html#class-hash', 79 'Hmac': 'crypto.html#class-hmac', 80 'KeyObject': 'crypto.html#class-keyobject', 81 'Sign': 'crypto.html#class-sign', 82 'Verify': 'crypto.html#class-verify', 83 'crypto.constants': 'crypto.html#cryptoconstants', 84 85 'CryptoKey': 'webcrypto.html#class-cryptokey', 86 'CryptoKeyPair': 'webcrypto.html#class-cryptokeypair', 87 'Crypto': 'webcrypto.html#class-crypto', 88 'SubtleCrypto': 'webcrypto.html#class-subtlecrypto', 89 'RsaOaepParams': 'webcrypto.html#class-rsaoaepparams', 90 'AlgorithmIdentifier': 'webcrypto.html#class-algorithmidentifier', 91 'AesCtrParams': 'webcrypto.html#class-aesctrparams', 92 'AesCbcParams': 'webcrypto.html#class-aescbcparams', 93 'AesGcmParams': 'webcrypto.html#class-aesgcmparams', 94 'EcdhKeyDeriveParams': 'webcrypto.html#class-ecdhkeyderiveparams', 95 'HkdfParams': 'webcrypto.html#class-hkdfparams', 96 'Pbkdf2Params': 'webcrypto.html#class-pbkdf2params', 97 'HmacKeyGenParams': 'webcrypto.html#class-hmackeygenparams', 98 'AesKeyGenParams': 'webcrypto.html#class-aeskeygenparams', 99 'RsaHashedKeyGenParams': 100 'webcrypto.html#class-rsahashedkeygenparams', 101 'EcKeyGenParams': 'webcrypto.html#class-eckeygenparams', 102 'RsaHashedImportParams': 103 'webcrypto.html#class-rsahashedimportparams', 104 'EcKeyImportParams': 'webcrypto.html#class-eckeyimportparams', 105 'HmacImportParams': 'webcrypto.html#class-hmacimportparams', 106 'EcdsaParams': 'webcrypto.html#class-ecdsaparams', 107 'RsaPssParams': 'webcrypto.html#class-rsapssparams', 108 'Ed448Params': 'webcrypto.html#class-ed448params', 109 110 'dgram.Socket': 'dgram.html#class-dgramsocket', 111 112 'Channel': 'diagnostics_channel.html#class-channel', 113 'TracingChannel': 'diagnostics_channel.html#class-tracingchannel', 114 115 'Domain': 'domain.html#class-domain', 116 117 'errors.Error': 'errors.html#class-error', 118 119 'import.meta': 'esm.html#importmeta', 120 121 'EventEmitter': 'events.html#class-eventemitter', 122 'EventTarget': 'events.html#class-eventtarget', 123 'Event': 'events.html#class-event', 124 'CustomEvent': 'events.html#class-customevent', 125 'EventListener': 'events.html#event-listener', 126 127 'FileHandle': 'fs.html#class-filehandle', 128 'fs.Dir': 'fs.html#class-fsdir', 129 'fs.Dirent': 'fs.html#class-fsdirent', 130 'fs.FSWatcher': 'fs.html#class-fsfswatcher', 131 'fs.ReadStream': 'fs.html#class-fsreadstream', 132 'fs.Stats': 'fs.html#class-fsstats', 133 'fs.StatFs': 'fs.html#class-fsstatfs', 134 'fs.StatWatcher': 'fs.html#class-fsstatwatcher', 135 'fs.WriteStream': 'fs.html#class-fswritestream', 136 137 'http.Agent': 'http.html#class-httpagent', 138 'http.ClientRequest': 'http.html#class-httpclientrequest', 139 'http.IncomingMessage': 'http.html#class-httpincomingmessage', 140 'http.OutgoingMessage': 'http.html#class-httpoutgoingmessage', 141 'http.Server': 'http.html#class-httpserver', 142 'http.ServerResponse': 'http.html#class-httpserverresponse', 143 144 'ClientHttp2Session': 'http2.html#class-clienthttp2session', 145 'ClientHttp2Stream': 'http2.html#class-clienthttp2stream', 146 'HTTP/2 Headers Object': 'http2.html#headers-object', 147 'HTTP/2 Settings Object': 'http2.html#settings-object', 148 'http2.Http2ServerRequest': 'http2.html#class-http2http2serverrequest', 149 'http2.Http2ServerResponse': 150 'http2.html#class-http2http2serverresponse', 151 'Http2SecureServer': 'http2.html#class-http2secureserver', 152 'Http2Server': 'http2.html#class-http2server', 153 'Http2Session': 'http2.html#class-http2session', 154 'Http2Stream': 'http2.html#class-http2stream', 155 'ServerHttp2Stream': 'http2.html#class-serverhttp2stream', 156 'ServerHttp2Session': 'http2.html#class-serverhttp2session', 157 158 'https.Server': 'https.html#class-httpsserver', 159 160 'module': 'modules.html#the-module-object', 161 162 'module.SourceMap': 163 'module.html#class-modulesourcemap', 164 165 'require': 'modules.html#requireid', 166 167 'Handle': 'net.html#serverlistenhandle-backlog-callback', 168 'net.BlockList': 'net.html#class-netblocklist', 169 'net.Server': 'net.html#class-netserver', 170 'net.Socket': 'net.html#class-netsocket', 171 'net.SocketAddress': 'net.html#class-netsocketaddress', 172 173 'NodeEventTarget': 174 'events.html#class-nodeeventtarget', 175 176 'os.constants.dlopen': 'os.html#dlopen-constants', 177 178 'Histogram': 'perf_hooks.html#class-histogram', 179 'IntervalHistogram': 180 'perf_hooks.html#class-intervalhistogram-extends-histogram', 181 'RecordableHistogram': 182 'perf_hooks.html#class-recordablehistogram-extends-histogram', 183 'PerformanceEntry': 'perf_hooks.html#class-performanceentry', 184 'PerformanceNodeTiming': 185 'perf_hooks.html#class-performancenodetiming', 186 'PerformanceObserver': 187 'perf_hooks.html#class-perf_hooksperformanceobserver', 188 'PerformanceObserverEntryList': 189 'perf_hooks.html#class-performanceobserverentrylist', 190 191 'readline.Interface': 192 'readline.html#class-readlineinterface', 193 'readline.InterfaceConstructor': 194 'readline.html#class-interfaceconstructor', 195 'readlinePromises.Interface': 196 'readline.html#class-readlinepromisesinterface', 197 198 'repl.REPLServer': 'repl.html#class-replserver', 199 200 'Stream': 'stream.html#stream', 201 'stream.Duplex': 'stream.html#class-streamduplex', 202 'Duplex': 'stream.html#class-streamduplex', 203 'stream.Readable': 'stream.html#class-streamreadable', 204 'Readable': 'stream.html#class-streamreadable', 205 'stream.Transform': 'stream.html#class-streamtransform', 206 'Transform': 'stream.html#class-streamtransform', 207 'stream.Writable': 'stream.html#class-streamwritable', 208 'Writable': 'stream.html#class-streamwritable', 209 210 'Immediate': 'timers.html#class-immediate', 211 'Timeout': 'timers.html#class-timeout', 212 'Timer': 'timers.html#timers', 213 214 'TestsStream': 'test.html#class-testsstream', 215 216 'tls.SecureContext': 'tls.html#tlscreatesecurecontextoptions', 217 'tls.Server': 'tls.html#class-tlsserver', 218 'tls.TLSSocket': 'tls.html#class-tlstlssocket', 219 220 'Tracing': 'tracing.html#tracing-object', 221 222 'URL': 'url.html#the-whatwg-url-api', 223 'URLSearchParams': 'url.html#class-urlsearchparams', 224 225 'MIMEParams': 'util.html#class-utilmimeparams', 226 227 'vm.Module': 'vm.html#class-vmmodule', 228 'vm.Script': 'vm.html#class-vmscript', 229 'vm.SourceTextModule': 'vm.html#class-vmsourcetextmodule', 230 231 'MessagePort': 'worker_threads.html#class-messageport', 232 'Worker': 'worker_threads.html#class-worker', 233 234 'X509Certificate': 'crypto.html#class-x509certificate', 235 236 'zlib options': 'zlib.html#class-options', 237 238 'ReadableStream': 239 'webstreams.html#class-readablestream', 240 'ReadableStreamDefaultReader': 241 'webstreams.html#class-readablestreamdefaultreader', 242 'ReadableStreamBYOBReader': 243 'webstreams.html#class-readablestreambyobreader', 244 'ReadableStreamDefaultController': 245 'webstreams.html#class-readablestreamdefaultcontroller', 246 'ReadableByteStreamController': 247 'webstreams.html#class-readablebytestreamcontroller', 248 'ReadableStreamBYOBRequest': 249 'webstreams.html#class-readablestreambyobrequest', 250 'WritableStream': 251 'webstreams.html#class-writablestream', 252 'WritableStreamDefaultWriter': 253 'webstreams.html#class-writablestreamdefaultwriter', 254 'WritableStreamDefaultController': 255 'webstreams.html#class-writablestreamdefaultcontroller', 256 'TransformStream': 257 'webstreams.html#class-transformstream', 258 'TransformStreamDefaultController': 259 'webstreams.html#class-transformstreamdefaultcontroller', 260 'ByteLengthQueuingStrategy': 261 'webstreams.html#class-bytelengthqueuingstrategy', 262 'CountQueuingStrategy': 263 'webstreams.html#class-countqueuingstrategy', 264 'TextEncoderStream': 265 'webstreams.html#class-textencoderstream', 266 'TextDecoderStream': 267 'webstreams.html#class-textdecoderstream', 268 269 'FormData': 'https://developer.mozilla.org/en-US/docs/Web/API/FormData', 270 'Headers': 'https://developer.mozilla.org/en-US/docs/Web/API/Headers', 271 'Response': 'https://developer.mozilla.org/en-US/docs/Web/API/Response', 272 'Request': 'https://developer.mozilla.org/en-US/docs/Web/API/Request', 273 'Disposable': 'https://tc39.es/proposal-explicit-resource-management/#sec-disposable-interface', 274}; 275 276const arrayPart = /(?:\[])+$/; 277 278export function toLink(typeInput) { 279 const typeLinks = []; 280 typeInput = typeInput.replace('{', '').replace('}', ''); 281 const typeTexts = typeInput.split('|'); 282 283 typeTexts.forEach((typeText) => { 284 typeText = typeText.trim(); 285 if (typeText) { 286 let typeUrl; 287 288 // To support type[], type[][] etc., we store the full string 289 // and use the bracket-less version to lookup the type URL. 290 const typeTextFull = typeText; 291 typeText = typeText.replace(arrayPart, ''); 292 293 const primitive = jsPrimitives[typeText]; 294 295 if (primitive !== undefined) { 296 typeUrl = `${jsDataStructuresUrl}#${primitive}_type`; 297 } else if (jsGlobalTypes.includes(typeText)) { 298 typeUrl = `${jsGlobalObjectsUrl}${typeText}`; 299 } else { 300 typeUrl = customTypesMap[typeText]; 301 } 302 303 if (typeUrl) { 304 typeLinks.push( 305 `<a href="${typeUrl}" class="type"><${typeTextFull}></a>`); 306 } else { 307 throw new Error( 308 `Unrecognized type: '${typeTextFull}'.\n` + 309 `Please, edit the type or update '${import.meta.url}'.`, 310 ); 311 } 312 } else { 313 throw new Error(`Empty type slot: ${typeInput}`); 314 } 315 }); 316 317 return typeLinks.length ? typeLinks.join(' | ') : typeInput; 318} 319