From 2382133aaf890b4fb19ec02383c298622417197f Mon Sep 17 00:00:00 2001 From: avivkeller Date: Sat, 26 Jul 2025 17:25:21 -0400 Subject: [PATCH 1/2] fix(types,css): fix type parsing, and css headers --- .../metadata/__tests__/slugger.test.mjs | 22 ----- src/generators/metadata/constants.mjs | 11 --- src/generators/metadata/utils/parse.mjs | 2 +- src/generators/metadata/utils/slugger.mjs | 39 --------- src/generators/web/ui/index.css | 2 +- src/utils/parser/__tests__/index.test.mjs | 7 ++ src/utils/parser/constants.mjs | 85 +++++++------------ src/utils/parser/index.mjs | 9 ++ src/utils/parser/slugger.mjs | 39 +++++++++ src/utils/queries/index.mjs | 6 +- 10 files changed, 89 insertions(+), 133 deletions(-) delete mode 100644 src/generators/metadata/__tests__/slugger.test.mjs delete mode 100644 src/generators/metadata/constants.mjs delete mode 100644 src/generators/metadata/utils/slugger.mjs create mode 100644 src/utils/parser/slugger.mjs diff --git a/src/generators/metadata/__tests__/slugger.test.mjs b/src/generators/metadata/__tests__/slugger.test.mjs deleted file mode 100644 index 223dd519..00000000 --- a/src/generators/metadata/__tests__/slugger.test.mjs +++ /dev/null @@ -1,22 +0,0 @@ -import { strictEqual } from 'node:assert'; -import { describe, it } from 'node:test'; - -import { createNodeSlugger } from '../utils/slugger.mjs'; - -describe('createNodeSlugger', () => { - it('should create a new instance of the GitHub Slugger', () => { - const slugger = createNodeSlugger(); - strictEqual(typeof slugger.slug, 'function'); - strictEqual(typeof slugger.reset, 'function'); - }); - - it('should create a new slug based on the provided string', () => { - const slugger = createNodeSlugger(); - strictEqual(slugger.slug('Test'), 'test'); - }); - - it('should reset the cache of the Slugger', () => { - const slugger = createNodeSlugger(); - slugger.reset(); - }); -}); diff --git a/src/generators/metadata/constants.mjs b/src/generators/metadata/constants.mjs deleted file mode 100644 index 99b84e91..00000000 --- a/src/generators/metadata/constants.mjs +++ /dev/null @@ -1,11 +0,0 @@ -'use strict'; - -// These are string replacements specific to Node.js API docs for anchor IDs -export const DOC_API_SLUGS_REPLACEMENTS = [ - { from: /node.js/i, to: 'nodejs' }, // Replace Node.js - { from: /&/, to: '-and-' }, // Replace & - { from: /[/_,:;\\ ]/g, to: '-' }, // Replace /_,:;\. and whitespace - { from: /--+/g, to: '-' }, // Replace multiple hyphens with single - { from: /^-/, to: '' }, // Remove any leading hyphen - { from: /-$/, to: '' }, // Remove any trailing hyphen -]; diff --git a/src/generators/metadata/utils/parse.mjs b/src/generators/metadata/utils/parse.mjs index eb8e6a62..031e00fb 100644 --- a/src/generators/metadata/utils/parse.mjs +++ b/src/generators/metadata/utils/parse.mjs @@ -6,8 +6,8 @@ import { remove } from 'unist-util-remove'; import { selectAll } from 'unist-util-select'; import { SKIP, visit } from 'unist-util-visit'; -import { createNodeSlugger } from './slugger.mjs'; import createMetadata from '../../../metadata.mjs'; +import createNodeSlugger from '../../../utils/parser/slugger.mjs'; import createQueries from '../../../utils/queries/index.mjs'; import { getRemark } from '../../../utils/remark.mjs'; diff --git a/src/generators/metadata/utils/slugger.mjs b/src/generators/metadata/utils/slugger.mjs deleted file mode 100644 index fc0eb933..00000000 --- a/src/generators/metadata/utils/slugger.mjs +++ /dev/null @@ -1,39 +0,0 @@ -'use strict'; - -import GitHubSlugger from 'github-slugger'; - -import { DOC_API_SLUGS_REPLACEMENTS } from '../constants.mjs'; - -/** - * Creates a modified version of the GitHub Slugger - * - * @returns {InstanceType} The modified GitHub Slugger - */ -export const createNodeSlugger = () => { - const slugger = new GitHubSlugger(); - - return { - /** - * Creates a new slug based on the provided string - * - * @param {string} title The title to be parsed into a slug - */ - slug: title => { - // Applies certain string replacements that are specific - // to the way how Node.js generates slugs/anchor IDs - return DOC_API_SLUGS_REPLACEMENTS.reduce( - (piece, { from, to }) => piece.replace(from, to), - // Slugify the title using GitHub Slugger - slugger.slug(title) - ); - }, - - /** - * Resets the cache of the Slugger, preventing repeated slugs - * to be marked as repeated. - * - * @returns {void} - */ - reset: () => slugger.reset(), - }; -}; diff --git a/src/generators/web/ui/index.css b/src/generators/web/ui/index.css index f2950c97..745c9c49 100644 --- a/src/generators/web/ui/index.css +++ b/src/generators/web/ui/index.css @@ -29,7 +29,7 @@ main { } /* Change history positioning */ - div:has(> h1, > h2, > h3, > h4) { + div:has(> h1, > h2, > h3, > h4, > h5, > h6) { display: flex; align-items: center; gap: 8px; diff --git a/src/utils/parser/__tests__/index.test.mjs b/src/utils/parser/__tests__/index.test.mjs index 53b97a0c..944d3de6 100644 --- a/src/utils/parser/__tests__/index.test.mjs +++ b/src/utils/parser/__tests__/index.test.mjs @@ -22,6 +22,13 @@ describe('transformTypeToReferenceLink', () => { '[``](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)' ); }); + + it('should transform a prefixed type into a Markdown link', () => { + strictEqual( + transformTypeToReferenceLink('prefix.Type'), + '[``](prefix.html#class-prefixtype)' + ); + }); }); describe('normalizeYamlSyntax', () => { diff --git a/src/utils/parser/constants.mjs b/src/utils/parser/constants.mjs index fb6f221c..47808590 100644 --- a/src/utils/parser/constants.mjs +++ b/src/utils/parser/constants.mjs @@ -1,5 +1,15 @@ 'use strict'; +// These are string replacements specific to Node.js API docs for anchor IDs +export const DOC_API_SLUGS_REPLACEMENTS = [ + { from: /node.js/i, to: 'nodejs' }, // Replace Node.js + { from: /&/, to: '-and-' }, // Replace & + { from: /[/_,:;\\ ]/g, to: '-' }, // Replace /_,:;\. and whitespace + { from: /--+/g, to: '-' }, // Replace multiple hyphens with single + { from: /^-/, to: '' }, // Remove any leading hyphen + { from: /-$/, to: '' }, // Remove any trailing hyphen +]; + // This is the base URL of the MDN Web documentation export const DOC_MDN_BASE_URL = 'https://developer.mozilla.org/en-US/docs/Web/'; @@ -94,6 +104,7 @@ export const DOC_TYPES_MAPPING_GLOBALS = { 'WeakSet', 'TypedArray', + 'Float16Array', 'Float32Array', 'Float64Array', 'Int8Array', @@ -127,6 +138,7 @@ export const DOC_TYPES_MAPPING_NODE_MODULES = { AesGcmParams: 'webcrypto.html#class-aesgcmparams', AesKeyAlgorithm: 'webcrypto.html#class-aeskeyalgorithm', AesKeyGenParams: 'webcrypto.html#class-aeskeygenparams', + AesDerivedKeyParams: 'webcrypto.html#class-aesderivedkeyparams', Blob: 'buffer.html#class-blob', BroadcastChannel: @@ -138,6 +150,8 @@ export const DOC_TYPES_MAPPING_NODE_MODULES = { Channel: 'diagnostics_channel.html#class-channel', ChildProcess: 'child_process.html#class-childprocess', Cipher: 'crypto.html#class-cipher', + Cipheriv: 'crypto.html#class-cipheriv', + Decipheriv: 'crypto.html#class-decipheriv', ClientHttp2Session: 'http2.html#class-clienthttp2session', ClientHttp2Stream: 'http2.html#class-clienthttp2stream', @@ -191,6 +205,8 @@ export const DOC_TYPES_MAPPING_NODE_MODULES = { IntervalHistogram: 'perf_hooks.html#class-intervalhistogram-extends-histogram', + LockManager: 'worker_threads.html#class-lockmanager', + KeyAlgorithm: 'webcrypto.html#class-keyalgorithm', KeyObject: 'crypto.html#class-keyobject', @@ -219,6 +235,10 @@ export const DOC_TYPES_MAPPING_NODE_MODULES = { ReadableStreamDefaultReader: 'webstreams.html#class-readablestreamdefaultreader', + ModuleRequest: 'vm.html#type-modulerequest', + + DatabaseSync: 'sqlite.html#class-databasesync', + RecordableHistogram: 'perf_hooks.html#class-recordablehistogram-extends-histogram', @@ -233,6 +253,10 @@ export const DOC_TYPES_MAPPING_NODE_MODULES = { Sign: 'crypto.html#class-sign', + Disposable: + 'https://tc39.es/proposal-explicit-resource-management/#sec-disposable-interface', + + Session: 'sqlite.html#class-session', StatementSync: 'sqlite.html#class-statementsync', Stream: 'stream.html#stream', @@ -273,71 +297,20 @@ export const DOC_TYPES_MAPPING_NODE_MODULES = { 'brotli options': 'zlib.html#class-brotlioptions', - 'cluster.Worker': 'cluster.html#class-worker', - - 'crypto.constants': 'crypto.html#cryptoconstants', - - 'dgram.Socket': 'dgram.html#class-dgramsocket', - - 'errors.Error': 'errors.html#class-error', - - 'fs.Dir': 'fs.html#class-fsdir', - 'fs.Dirent': 'fs.html#class-fsdirent', - 'fs.FSWatcher': 'fs.html#class-fsfswatcher', - 'fs.ReadStream': 'fs.html#class-fsreadstream', - 'fs.StatFs': 'fs.html#class-fsstatfs', - 'fs.Stats': 'fs.html#class-fsstats', - 'fs.StatWatcher': 'fs.html#class-fsstatwatcher', - 'fs.WriteStream': 'fs.html#class-fswritestream', - - 'http.Agent': 'http.html#class-httpagent', - 'http.ClientRequest': 'http.html#class-httpclientrequest', - 'http.IncomingMessage': 'http.html#class-httpincomingmessage', - 'http.OutgoingMessage': 'http.html#class-httpoutgoingmessage', - 'http.Server': 'http.html#class-httpserver', - 'http.ServerResponse': 'http.html#class-httpserverresponse', - - 'http2.Http2ServerRequest': 'http2.html#class-http2http2serverrequest', - 'http2.Http2ServerResponse': 'http2.html#class-http2http2serverresponse', - 'import.meta': 'esm.html#importmeta', - 'module.SourceMap': 'module.html#class-modulesourcemap', - - 'net.BlockList': 'net.html#class-netblocklist', - 'net.Server': 'net.html#class-netserver', - 'net.Socket': 'net.html#class-netsocket', - 'net.SocketAddress': 'net.html#class-netsocketaddress', - 'os.constants.dlopen': 'os.html#dlopen-constants', - 'readline.Interface': 'readline.html#class-readlineinterface', - 'readline.InterfaceConstructor': 'readline.html#class-interfaceconstructor', 'readlinePromises.Interface': 'readline.html#class-readlinepromisesinterface', - 'repl.REPLServer': 'repl.html#class-replserver', - require: 'modules.html#requireid', - - 'stream.Duplex': 'stream.html#class-streamduplex', - 'stream.Readable': 'stream.html#class-streamreadable', - 'stream.Transform': 'stream.html#class-streamtransform', - 'stream.Writable': 'stream.html#class-streamwritable', - - 'tls.SecureContext': 'tls.html#tlscreatesecurecontextoptions', - 'tls.Server': 'tls.html#class-tlsserver', - 'tls.TLSSocket': 'tls.html#class-tlstlssocket', - - 'tty.ReadStream': 'tty.html#class-ttyreadstream', - 'tty.WriteStream': 'tty.html#class-ttywritestream', - - 'vm.Module': 'vm.html#class-vmmodule', - 'vm.Script': 'vm.html#class-vmscript', - 'vm.SourceTextModule': 'vm.html#class-vmsourcetextmodule', - 'vm.constants.USE_MAIN_CONTEXT_DEFAULT_LOADER': - 'vm.html#vmconstantsuse_main_context_default_loader', + module: 'modules.html#the-module-object', 'zlib options': 'zlib.html#class-options', + 'zstd options': 'zlib.html#class-zstdoptions', + + 'HTTP/2 Headers Object': 'http2.html#headers-object', + 'HTTP/2 Settings Object': 'http2.html#settings-object', }; // This is a mapping for miscellaneous types within the Markdown content and their respective diff --git a/src/utils/parser/index.mjs b/src/utils/parser/index.mjs index f964ba1f..8a91a071 100644 --- a/src/utils/parser/index.mjs +++ b/src/utils/parser/index.mjs @@ -12,6 +12,7 @@ import { DOC_TYPES_MAPPING_PRIMITIVES, DOC_MAN_BASE_URL, } from './constants.mjs'; +import { slug } from './slugger.mjs'; import createQueries from '../queries/index.mjs'; /** @@ -103,6 +104,14 @@ export const transformTypeToReferenceLink = type => { return DOC_TYPES_MAPPING_NODE_MODULES[lookupPiece]; } + // Transform Node.js types like 'vm.Something'. + if (lookupPiece.indexOf('.') >= 0) { + const [mod, ...pieces] = lookupPiece.split('.'); + const isClass = pieces.at(-1).match(/^[A-Z][a-z]/); + + return `${mod}.html#${isClass ? 'class-' : ''}${slug(lookupPiece)}`; + } + return ''; }; diff --git a/src/utils/parser/slugger.mjs b/src/utils/parser/slugger.mjs new file mode 100644 index 00000000..d194cb62 --- /dev/null +++ b/src/utils/parser/slugger.mjs @@ -0,0 +1,39 @@ +'use strict'; + +import GitHubSlugger, { slug as defaultSlugFn } from 'github-slugger'; + +import { DOC_API_SLUGS_REPLACEMENTS } from './constants.mjs'; + +/** + * Creates a modified version of the GitHub Slugger + * + * @returns {InstanceType} The modified GitHub Slugger + */ +const createNodeSlugger = () => { + const slugger = new GitHubSlugger(); + const slugFn = slugger.slug.bind(slugger); + + return { + ...slugger, + /** + * Creates a new slug based on the provided string + * + * @param {string} title The title to be parsed into a slug + */ + // Applies certain string replacements that are specific + // to the way how Node.js generates slugs/anchor IDs + slug: title => slug(title, slugFn), + }; +}; + +/** + * @param {string} title + * @param {typeof defaultSlugFn} slugFn + */ +export const slug = (title, slugFn = defaultSlugFn) => + DOC_API_SLUGS_REPLACEMENTS.reduce( + (piece, { from, to }) => piece.replace(from, to), + slugFn(title) + ); + +export default createNodeSlugger; diff --git a/src/utils/queries/index.mjs b/src/utils/queries/index.mjs index 341addbf..71824b44 100644 --- a/src/utils/queries/index.mjs +++ b/src/utils/queries/index.mjs @@ -197,11 +197,11 @@ createQueries.QUERIES = { // Fixes the references to Markdown pages into the API documentation markdownUrl: /^(?![+a-zA-Z]+:)([^#?]+)\.md(#.+)?$/, // ReGeX to match the {Type} (API type references) - // eslint-disable-next-line no-useless-escape - normalizeTypes: /(\{|<)(?! )[a-zA-Z0-9.| \[\]\\]+(?! )(\}|>)/g, + + normalizeTypes: /(\{|<)(?! )[^<({})>]+(?! )(\}|>)/g, // ReGex to match the type API type references that got already parsed // so that they can be transformed into HTML links - linksWithTypes: /\[`<([a-zA-Z0-9.| \\[\]]+)>`\]\((\S+)\)/g, + linksWithTypes: /\[`<[^<({})>]+>`\]\((\S+)\)/g, // ReGeX for handling Stability Indexes Metadata stabilityIndex: /^Stability: ([0-5](?:\.[0-3])?)(?:\s*-\s*)?(.*)$/s, // ReGeX for handling the Stability Index Prefix From 5a04985b4277396518be878bde15465ced159230 Mon Sep 17 00:00:00 2001 From: Aviv Keller Date: Sun, 27 Jul 2025 10:51:14 -0400 Subject: [PATCH 2/2] fixup! --- src/utils/queries/index.mjs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/utils/queries/index.mjs b/src/utils/queries/index.mjs index 71824b44..76810097 100644 --- a/src/utils/queries/index.mjs +++ b/src/utils/queries/index.mjs @@ -197,7 +197,6 @@ createQueries.QUERIES = { // Fixes the references to Markdown pages into the API documentation markdownUrl: /^(?![+a-zA-Z]+:)([^#?]+)\.md(#.+)?$/, // ReGeX to match the {Type} (API type references) - normalizeTypes: /(\{|<)(?! )[^<({})>]+(?! )(\}|>)/g, // ReGex to match the type API type references that got already parsed // so that they can be transformed into HTML links