From 7ae14bde37c5ef08dfdde2cff09bdc1f81d098b1 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Tue, 22 Oct 2024 19:29:26 +0530 Subject: [PATCH 01/48] fefewg --- scripts/build-post-list.js | 62 +++++------ scripts/index.js | 14 ++- tests/build-post-list.test.js | 192 ++++++++++++++++++++++++++++++++++ tests/index.test.js | 2 +- 4 files changed, 237 insertions(+), 33 deletions(-) create mode 100644 tests/build-post-list.test.js diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index 288d7dc0c54e..72e857f43b1f 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -1,5 +1,5 @@ const { readdirSync, statSync, existsSync, readFileSync, writeFileSync } = require('fs') -const { resolve, basename } = require('path') +const { basename } = require('path') const frontMatter = require('gray-matter') const toc = require('markdown-toc') const { slugify } = require('markdown-toc/lib/utils') @@ -15,36 +15,36 @@ const result = { docsTree: {} } const releaseNotes = [] -const basePath = 'pages' -const postDirectories = [ - // order of these directories is important, as the blog should come before docs, to create a list of available release notes, which will later be used to release-note-link for spec docs - [`${basePath}/blog`, '/blog'], - [`${basePath}/docs`, '/docs'], - [`${basePath}/about`, '/about'] -]; const addItem = (details) => { - if(details.slug.startsWith('/docs')) + if (details.slug.startsWith('/docs')) result["docs"].push(details) - else if(details.slug.startsWith('/blog')) + else if (details.slug.startsWith('/blog')) result["blog"].push(details) - else if(details.slug.startsWith('/about')) + else if (details.slug.startsWith('/about')) result["about"].push(details) - else {} + else { } } -module.exports = async function buildPostList() { - walkDirectories(postDirectories, result) - const treePosts = buildNavTree(result["docs"].filter((p) => p.slug.startsWith('/docs/'))) - result["docsTree"] = treePosts - result["docs"] = addDocButtons(result["docs"], treePosts) - if (process.env.NODE_ENV === 'production') { - // console.log(inspect(result, { depth: null, colors: true })) +async function buildPostList(postDirectories, basePath, writeFilePath) { + try { + if (postDirectories.length === 0) { + throw new Error('Error while building post list: No post directories provided'); + } + walkDirectories(postDirectories, result, basePath) + const treePosts = buildNavTree(result["docs"].filter((p) => p.slug.startsWith('/docs/'))) + result["docsTree"] = treePosts + result["docs"] = addDocButtons(result["docs"], treePosts) + if (process.env.NODE_ENV === 'production') { + // console.log(inspect(result, { depth: null, colors: true })) + } + writeFileSync(writeFilePath, JSON.stringify(result, null, ' ')) + } catch (error) { + throw new Error(`Error while building post list: ${error.message}`); } - writeFileSync(resolve(__dirname, '..', 'config', 'posts.json'), JSON.stringify(result, null, ' ')) } -function walkDirectories(directories, result, sectionWeight = 0, sectionTitle, sectionId, rootSectionId) { +function walkDirectories(directories, result, basePath, sectionWeight = 0, sectionTitle, sectionId, rootSectionId) { for (let dir of directories) { let directory = dir[0] let sectionSlug = dir[1] || '' @@ -68,8 +68,8 @@ function walkDirectories(directories, result, sectionWeight = 0, sectionTitle, s } details.isSection = true if (slugElements.length > 3) { - details.parent = slugElements[slugElements.length - 2] - details.sectionId = slugElements[slugElements.length - 1] + details.parent = slugElements[slugElements.length - 2] + details.sectionId = slugElements[slugElements.length - 1] } if (!details.parent) { details.isRootSection = true @@ -79,7 +79,7 @@ function walkDirectories(directories, result, sectionWeight = 0, sectionTitle, s details.slug = slug addItem(details) const rootId = details.parent || details.rootSectionId - walkDirectories([[fileName, slug]], result, details.weight, details.title, details.sectionId, rootId) + walkDirectories([[fileName, slug]], result, basePath, details.weight, details.title, details.sectionId, rootId) } else if (file.endsWith('.mdx') && !fileName.endsWith('/_section.mdx')) { const fileContent = readFileSync(fileName, 'utf-8') // Passing a second argument to frontMatter disables cache. See https://github.com/asyncapi/website/issues/1057 @@ -96,18 +96,18 @@ function walkDirectories(directories, result, sectionWeight = 0, sectionTitle, s details.id = fileName details.isIndex = fileName.endsWith('/index.mdx') details.slug = details.isIndex ? sectionSlug : slug.replace(/\.mdx$/, '') - if(details.slug.includes('/reference/specification/') && !details.title) { + if (details.slug.includes('/reference/specification/') && !details.title) { const fileBaseName = basename(data.slug) // ex. v2.0.0 | v2.1.0-next-spec.1 const fileName = fileBaseName.split('-')[0] // v2.0.0 | v2.1.0 details.weight = specWeight-- if (fileName.startsWith('v')) { - details.title = capitalize(fileName.slice(1)) + details.title = capitalize(fileName.slice(1)) } else { details.title = capitalize(fileName) } - if(releaseNotes.includes(details.title)){ + if (releaseNotes.includes(details.title)) { details.releaseNoteLink = `/blog/release-notes-${details.title}` } @@ -122,10 +122,10 @@ function walkDirectories(directories, result, sectionWeight = 0, sectionTitle, s } // To create a list of available ReleaseNotes list, which will be used to add details.releaseNoteLink attribute. - if(file.startsWith("release-notes") && dir[1] === "/blog"){ - const fileName_without_extension = file.slice(0,-4) + if (file.startsWith("release-notes") && dir[1] === "/blog") { + const fileName_without_extension = file.slice(0, -4) // removes the file extension. For example, release-notes-2.1.0.md -> release-notes-2.1.0 - const version = fileName_without_extension.slice(fileName_without_extension.lastIndexOf("-")+1) + const version = fileName_without_extension.slice(fileName_without_extension.lastIndexOf("-") + 1) // gets the version from the name of the releaseNote .md file (from /blog). For example, version = 2.1.0 if fileName_without_extension = release-notes-2.1.0 releaseNotes.push(version) @@ -159,3 +159,5 @@ function isDirectory(dir) { function capitalize(text) { return text.split(/[\s\-]/g).map(word => `${word[0].toUpperCase()}${word.substr(1)}`).join(' ') } + +module.exports = {slugifyToC, buildPostList} diff --git a/scripts/index.js b/scripts/index.js index 33125fe7533b..b063b49bcde6 100644 --- a/scripts/index.js +++ b/scripts/index.js @@ -1,13 +1,23 @@ const { resolve } = require('path'); const fs = require('fs'); const rssFeed = require('./build-rss'); -const buildPostList = require('./build-post-list'); +const {buildPostList} = require('./build-post-list'); const buildCaseStudiesList = require('./casestudies'); const buildAdoptersList = require('./adopters'); const buildFinanceInfoList = require('./finance'); async function start() { - await buildPostList(); + + const postDirectories = [ + ['pages/blog', '/blog'], + ['pages/docs', '/docs'], + ['pages/about', '/about'] + ]; + const basePath = 'pages'; + const writeFilePath = resolve(__dirname, '../config', 'posts.json'); + + await buildPostList(postDirectories, basePath, writeFilePath); + rssFeed( 'blog', 'AsyncAPI Initiative Blog RSS Feed', diff --git a/tests/build-post-list.test.js b/tests/build-post-list.test.js new file mode 100644 index 000000000000..010df5bc5798 --- /dev/null +++ b/tests/build-post-list.test.js @@ -0,0 +1,192 @@ +const { existsSync, readFileSync, writeFileSync, mkdirSync, rmSync } = require('fs'); +const { resolve, join } = require('path'); +const { buildPostList, slugifyToC } = require('../scripts/build-post-list'); + +describe('buildPostList', () => { + let tempDir; + let writeFilePath; + let postDirectories; + + beforeEach(() => { + tempDir = resolve(__dirname, `test-config`); + writeFilePath = resolve(tempDir, 'posts.json'); + postDirectories = [ + [join(tempDir, 'blog'), '/blog'], + [join(tempDir, 'docs'), '/docs'], + [join(tempDir, 'about'), '/about'], + ]; + + mkdirSync(tempDir, { recursive: true }); + + mkdirSync(join(tempDir, 'blog'), { recursive: true }); + writeFileSync(join(tempDir, 'blog', 'release-notes-2.1.0.mdx'), '---\ntitle: Release Notes 2.1.0\n---\nThis is a release note.'); + + mkdirSync(join(tempDir, 'docs'), { recursive: true }); + writeFileSync(join(tempDir, 'docs', 'index.mdx'), '---\ntitle: Docs Home\n---\nThis is the documentation homepage.'); + + mkdirSync(join(tempDir, 'about'), { recursive: true }); + writeFileSync(join(tempDir, 'about', 'index.mdx'), '---\ntitle: About Us\n---\nThis is the about page.'); + + mkdirSync(join(tempDir, 'docs', 'reference', 'specification'), { recursive: true }); + }); + + afterEach(() => { + rmSync(tempDir, { recursive: true, force: true }); + }); + + it('builds a post list and writes the result to a file', async () => { + + await buildPostList(postDirectories, tempDir, writeFilePath); + + const outputExists = existsSync(writeFilePath); + expect(outputExists).toBe(true); + + const output = JSON.parse(readFileSync(writeFilePath, 'utf-8')); + + expect(output).toHaveProperty('docs'); + expect(output).toHaveProperty('blog'); + expect(output).toHaveProperty('about'); + expect(output).toHaveProperty('docsTree'); + + const blogEntry = output.blog.find(item => item.slug === '/blog/release-notes-2.1.0'); + expect(blogEntry).toBeDefined(); + expect(blogEntry.title).toBe('Release Notes 2.1.0'); + }); + + it('handles a directory with only section files', async () => { + mkdirSync(join(tempDir, 'docs', 'section1'), { recursive: true }); + writeFileSync(join(tempDir, 'docs', 'section1', '_section.mdx'), '---\ntitle: Section 1\n---\nThis is section 1.'); + + await buildPostList(postDirectories, tempDir, writeFilePath); + + const output = JSON.parse(readFileSync(writeFilePath, 'utf-8')); + + expect(output.docs.length).toBeGreaterThan(0); + expect(output.docs.find(item => item.title === 'Section 1')).toBeDefined(); + }); + + it('handles multiple release notes correctly', async () => { + writeFileSync(join(tempDir, 'blog', 'release-notes-2.1.1.mdx'), '---\ntitle: Release Notes 2.1.1\n---\nThis is a release note.'); + + await buildPostList(postDirectories, tempDir, writeFilePath); + + const output = JSON.parse(readFileSync(writeFilePath, 'utf-8')); + + const firstReleaseNote = output.blog.find(item => item.slug === '/blog/release-notes-2.1.0'); + const secondReleaseNote = output.blog.find(item => item.slug === '/blog/release-notes-2.1.1'); + + expect(firstReleaseNote).toBeDefined(); + expect(firstReleaseNote.title).toBe('Release Notes 2.1.0'); + + expect(secondReleaseNote).toBeDefined(); + expect(secondReleaseNote.title).toBe('Release Notes 2.1.1'); + }); + + it('handles errors gracefully', async () => { + const invalidDir = [join(tempDir, 'non-existent-dir'), '/invalid']; + await expect(buildPostList([invalidDir], tempDir, writeFilePath)).rejects.toThrow(); + }); + + it('handles heading ids like {# myHeadingId}', () => { + const input = '## My Heading {#custom-id}'; + expect(slugifyToC(input)).toBe('custom-id'); + }); + + it('handles heading ids like {}', () => { + const input = '## My Heading {}'; + expect(slugifyToC(input)).toBe('custom-anchor-id'); + }); + + it('handles empty strings', () => { + expect(slugifyToC('')).toBe(''); + }); + + it('does not process specification files without a title', async () => { + const specDir = join(tempDir, 'docs', 'reference', 'specification'); + writeFileSync( + join(specDir, 'v2.1.0-no-title.mdx'), + '---\n---\nContent of specification without a title.' + ); + + await buildPostList(postDirectories, tempDir, writeFilePath); + + const output = JSON.parse(readFileSync(writeFilePath, 'utf-8')); + const noTitleEntry = output.docs.find(item => item.slug.includes('/reference/specification/v2.1.0-no-title')); + + expect(noTitleEntry).toBeUndefined(); + }); + + it('does not process specification files with "next-spec" in the filename', async () => { + const specDir = join(tempDir, 'docs', 'reference', 'specification'); + writeFileSync( + join(specDir, 'v2.1.0-next-spec.1.mdx'), + '---\n---\nContent of pre-release specification v2.1.0-next-spec.1.' + ); + + await buildPostList(postDirectories, tempDir, writeFilePath); + + const output = JSON.parse(readFileSync(writeFilePath, 'utf-8')); + const nextSpecEntry = output.docs.find(item => item.slug.includes('/reference/specification/v2.1.0-next-spec.1')); + + expect(nextSpecEntry).toBeUndefined(); + }); + + it('does not process specification files with "explorer" in the filename', async () => { + const specDir = join(tempDir, 'docs', 'reference', 'specification'); + writeFileSync( + join(specDir, 'explorer.mdx'), + '---\n---\nContent of explorer specification.' + ); + + await buildPostList(postDirectories, tempDir, writeFilePath); + + const output = JSON.parse(readFileSync(writeFilePath, 'utf-8')); + const explorerEntry = output.docs.find(item => item.slug.includes('/reference/specification/explorer')); + + expect(explorerEntry).toBeUndefined(); + }); + + it('throws an error if the directory cannot be read', async () => { + const invalidDir = [join(tempDir, 'non-existent-dir'), '/invalid']; + + let error; + try { + await buildPostList([invalidDir], tempDir, writeFilePath); + } catch (err) { + error = err; + } + + expect(error).toBeDefined(); + expect(error.message).toMatch(/Error while building post list/); + }); + + + it('throws an error if the front matter cannot be parsed', async () => { + writeFileSync(join(tempDir, 'docs', 'invalid.mdx'), '---\ninvalid front matter\n---\nContent'); + + let error; + try { + await buildPostList(postDirectories, tempDir, writeFilePath); + } catch (err) { + error = err; + } + + expect(error).toBeDefined(); + expect(error.message).toMatch(/Error while building post list/); + }); + + it('throws an error if no post directories are provided', async () => { + + let error; + + try { + await buildPostList([], tempDir, writeFilePath); + } catch (err) { + error = err; + } + + expect(error).toBeDefined(); + expect(error.message).toMatch(/Error while building post list/); + }); + +}); diff --git a/tests/index.test.js b/tests/index.test.js index 78e2c216958f..8231526875cf 100644 --- a/tests/index.test.js +++ b/tests/index.test.js @@ -1,5 +1,5 @@ const rssFeed = require('../scripts/build-rss'); -const buildPostList = require('../scripts/build-post-list'); +const {buildPostList} = require('../scripts/build-post-list'); const buildCaseStudiesList = require('../scripts/casestudies'); const buildAdoptersList = require('../scripts/adopters'); const buildFinanceInfoList = require('../scripts/finance'); From d1cb17932b77afd9d271db0ff2ce50ac2404002e Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Tue, 22 Oct 2024 19:52:55 +0530 Subject: [PATCH 02/48] added logs for debugging --- tests/build-post-list.test.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/build-post-list.test.js b/tests/build-post-list.test.js index 010df5bc5798..fe2856ac6b19 100644 --- a/tests/build-post-list.test.js +++ b/tests/build-post-list.test.js @@ -42,6 +42,7 @@ describe('buildPostList', () => { expect(outputExists).toBe(true); const output = JSON.parse(readFileSync(writeFilePath, 'utf-8')); + console.log(output) expect(output).toHaveProperty('docs'); expect(output).toHaveProperty('blog'); @@ -60,6 +61,7 @@ describe('buildPostList', () => { await buildPostList(postDirectories, tempDir, writeFilePath); const output = JSON.parse(readFileSync(writeFilePath, 'utf-8')); + console.log(output) expect(output.docs.length).toBeGreaterThan(0); expect(output.docs.find(item => item.title === 'Section 1')).toBeDefined(); @@ -71,6 +73,7 @@ describe('buildPostList', () => { await buildPostList(postDirectories, tempDir, writeFilePath); const output = JSON.parse(readFileSync(writeFilePath, 'utf-8')); + console.log(output) const firstReleaseNote = output.blog.find(item => item.slug === '/blog/release-notes-2.1.0'); const secondReleaseNote = output.blog.find(item => item.slug === '/blog/release-notes-2.1.1'); From fbcd76b174feede08fa6f117e6ba51cf9db204b8 Mon Sep 17 00:00:00 2001 From: Ansh Goyal Date: Thu, 31 Oct 2024 09:40:56 +0530 Subject: [PATCH 03/48] lint fix --- scripts/build-post-list.js | 2 +- scripts/index.js | 4 ++-- tests/build-post-list.test.js | 5 +---- tests/index.test.js | 2 +- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index 72e857f43b1f..d6254e96f73c 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -160,4 +160,4 @@ function capitalize(text) { return text.split(/[\s\-]/g).map(word => `${word[0].toUpperCase()}${word.substr(1)}`).join(' ') } -module.exports = {slugifyToC, buildPostList} +module.exports = { slugifyToC, buildPostList } diff --git a/scripts/index.js b/scripts/index.js index b063b49bcde6..0fbbe3940851 100644 --- a/scripts/index.js +++ b/scripts/index.js @@ -1,7 +1,7 @@ const { resolve } = require('path'); const fs = require('fs'); const rssFeed = require('./build-rss'); -const {buildPostList} = require('./build-post-list'); +const { buildPostList } = require('./build-post-list'); const buildCaseStudiesList = require('./casestudies'); const buildAdoptersList = require('./adopters'); const buildFinanceInfoList = require('./finance'); @@ -15,7 +15,7 @@ async function start() { ]; const basePath = 'pages'; const writeFilePath = resolve(__dirname, '../config', 'posts.json'); - + await buildPostList(postDirectories, basePath, writeFilePath); rssFeed( diff --git a/tests/build-post-list.test.js b/tests/build-post-list.test.js index fe2856ac6b19..75a25597df65 100644 --- a/tests/build-post-list.test.js +++ b/tests/build-post-list.test.js @@ -42,7 +42,6 @@ describe('buildPostList', () => { expect(outputExists).toBe(true); const output = JSON.parse(readFileSync(writeFilePath, 'utf-8')); - console.log(output) expect(output).toHaveProperty('docs'); expect(output).toHaveProperty('blog'); @@ -61,7 +60,6 @@ describe('buildPostList', () => { await buildPostList(postDirectories, tempDir, writeFilePath); const output = JSON.parse(readFileSync(writeFilePath, 'utf-8')); - console.log(output) expect(output.docs.length).toBeGreaterThan(0); expect(output.docs.find(item => item.title === 'Section 1')).toBeDefined(); @@ -73,7 +71,6 @@ describe('buildPostList', () => { await buildPostList(postDirectories, tempDir, writeFilePath); const output = JSON.parse(readFileSync(writeFilePath, 'utf-8')); - console.log(output) const firstReleaseNote = output.blog.find(item => item.slug === '/blog/release-notes-2.1.0'); const secondReleaseNote = output.blog.find(item => item.slug === '/blog/release-notes-2.1.1'); @@ -191,5 +188,5 @@ describe('buildPostList', () => { expect(error).toBeDefined(); expect(error.message).toMatch(/Error while building post list/); }); - + }); diff --git a/tests/index.test.js b/tests/index.test.js index 8231526875cf..37b124547efd 100644 --- a/tests/index.test.js +++ b/tests/index.test.js @@ -1,5 +1,5 @@ const rssFeed = require('../scripts/build-rss'); -const {buildPostList} = require('../scripts/build-post-list'); +const { buildPostList } = require('../scripts/build-post-list'); const buildCaseStudiesList = require('../scripts/casestudies'); const buildAdoptersList = require('../scripts/adopters'); const buildFinanceInfoList = require('../scripts/finance'); From 23a5c98bc5e50d09b8d163255af8b50e8808b575 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Mon, 4 Nov 2024 20:28:17 +0530 Subject: [PATCH 04/48] feqf --- tests/build-post-list.test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/build-post-list.test.js b/tests/build-post-list.test.js index 75a25597df65..c26e6ed83636 100644 --- a/tests/build-post-list.test.js +++ b/tests/build-post-list.test.js @@ -188,5 +188,4 @@ describe('buildPostList', () => { expect(error).toBeDefined(); expect(error.message).toMatch(/Error while building post list/); }); - }); From ec110dcb5ebafdef952d01af23c1a4c611e26b9a Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Mon, 4 Nov 2024 20:36:34 +0530 Subject: [PATCH 05/48] feqfeq --- scripts/build-post-list.js | 172 +++++++++++++++++-------------------- 1 file changed, 79 insertions(+), 93 deletions(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index d6254e96f73c..d7488fcbf237 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -1,44 +1,40 @@ -const { readdirSync, statSync, existsSync, readFileSync, writeFileSync } = require('fs') -const { basename } = require('path') -const frontMatter = require('gray-matter') -const toc = require('markdown-toc') -const { slugify } = require('markdown-toc/lib/utils') -const readingTime = require('reading-time') -const { markdownToTxt } = require('markdown-to-txt') -const { buildNavTree, addDocButtons } = require('./build-docs') - -let specWeight = 100 +const { readdirSync, statSync, existsSync, readFileSync, writeFileSync } = require('fs'); +const path = require('path'); +const frontMatter = require('gray-matter'); +const toc = require('markdown-toc'); +const { slugify } = require('markdown-toc/lib/utils'); +const readingTime = require('reading-time'); +const { markdownToTxt } = require('markdown-to-txt'); +const { buildNavTree, addDocButtons } = require('./build-docs'); + +let specWeight = 100; const result = { docs: [], blog: [], about: [], docsTree: {} -} -const releaseNotes = [] +}; +const releaseNotes = []; const addItem = (details) => { - if (details.slug.startsWith('/docs')) - result["docs"].push(details) - else if (details.slug.startsWith('/blog')) - result["blog"].push(details) - else if (details.slug.startsWith('/about')) - result["about"].push(details) - else { } -} + if (details.slug.startsWith('/docs')) result["docs"].push(details); + else if (details.slug.startsWith('/blog')) result["blog"].push(details); + else if (details.slug.startsWith('/about')) result["about"].push(details); +}; async function buildPostList(postDirectories, basePath, writeFilePath) { try { if (postDirectories.length === 0) { throw new Error('Error while building post list: No post directories provided'); } - walkDirectories(postDirectories, result, basePath) - const treePosts = buildNavTree(result["docs"].filter((p) => p.slug.startsWith('/docs/'))) - result["docsTree"] = treePosts - result["docs"] = addDocButtons(result["docs"], treePosts) + walkDirectories(postDirectories, result, basePath); + const treePosts = buildNavTree(result["docs"].filter((p) => p.slug.startsWith('/docs/'))); + result["docsTree"] = treePosts; + result["docs"] = addDocButtons(result["docs"], treePosts); if (process.env.NODE_ENV === 'production') { // console.log(inspect(result, { depth: null, colors: true })) } - writeFileSync(writeFilePath, JSON.stringify(result, null, ' ')) + writeFileSync(writeFilePath, JSON.stringify(result, null, ' ')); } catch (error) { throw new Error(`Error while building post list: ${error.message}`); } @@ -46,118 +42,108 @@ async function buildPostList(postDirectories, basePath, writeFilePath) { function walkDirectories(directories, result, basePath, sectionWeight = 0, sectionTitle, sectionId, rootSectionId) { for (let dir of directories) { - let directory = dir[0] - let sectionSlug = dir[1] || '' - let files = readdirSync(directory); + const directory = path.normalize(dir[0]); + const sectionSlug = dir[1] || ''; + const files = readdirSync(directory); for (let file of files) { - let details - const fileName = [directory, file].join('/') - const fileNameWithSection = [fileName, '_section.mdx'].join('/') - const slug = fileName.replace(new RegExp(`^${basePath}`), '') + let details; + const fileName = path.join(directory, file); + const fileNameWithSection = path.join(fileName, '_section.mdx'); + const slug = fileName.replace(new RegExp(`^${basePath.replace(/\\/g, '\\\\')}`), '').replace(/\\/g, '/'); // Ensure forward slashes for slugs const slugElements = slug.split('/'); + if (isDirectory(fileName)) { if (existsSync(fileNameWithSection)) { - // Passing a second argument to frontMatter disables cache. See https://github.com/asyncapi/website/issues/1057 - details = frontMatter(readFileSync(fileNameWithSection, 'utf-8'), {}).data - details.title = details.title || capitalize(basename(fileName)) + details = frontMatter(readFileSync(fileNameWithSection, 'utf-8'), {}).data; + details.title = details.title || capitalize(path.basename(fileName)); } else { - details = { - title: capitalize(basename(fileName)), - } + details = { title: capitalize(path.basename(fileName)) }; } - details.isSection = true + details.isSection = true; if (slugElements.length > 3) { - details.parent = slugElements[slugElements.length - 2] - details.sectionId = slugElements[slugElements.length - 1] + details.parent = slugElements[slugElements.length - 2]; + details.sectionId = slugElements[slugElements.length - 1]; } if (!details.parent) { - details.isRootSection = true - details.rootSectionId = slugElements[slugElements.length - 1] + details.isRootSection = true; + details.rootSectionId = slugElements[slugElements.length - 1]; } - details.sectionWeight = sectionWeight - details.slug = slug - addItem(details) - const rootId = details.parent || details.rootSectionId - walkDirectories([[fileName, slug]], result, basePath, details.weight, details.title, details.sectionId, rootId) + details.sectionWeight = sectionWeight; + details.slug = slug; + addItem(details); + const rootId = details.parent || details.rootSectionId; + walkDirectories([[fileName, slug]], result, basePath, details.weight, details.title, details.sectionId, rootId); } else if (file.endsWith('.mdx') && !fileName.endsWith('/_section.mdx')) { - const fileContent = readFileSync(fileName, 'utf-8') - // Passing a second argument to frontMatter disables cache. See https://github.com/asyncapi/website/issues/1057 - const { data, content } = frontMatter(fileContent, {}) - details = data - details.toc = toc(content, { slugify: slugifyToC }).json - details.readingTime = Math.ceil(readingTime(content).minutes) - details.excerpt = details.excerpt || markdownToTxt(content).substr(0, 200) - details.sectionSlug = sectionSlug || slug.replace(/\.mdx$/, '') - details.sectionWeight = sectionWeight - details.sectionTitle = sectionTitle - details.sectionId = sectionId - details.rootSectionId = rootSectionId - details.id = fileName - details.isIndex = fileName.endsWith('/index.mdx') - details.slug = details.isIndex ? sectionSlug : slug.replace(/\.mdx$/, '') + const fileContent = readFileSync(fileName, 'utf-8'); + const { data, content } = frontMatter(fileContent, {}); + details = data; + details.toc = toc(content, { slugify: slugifyToC }).json; + details.readingTime = Math.ceil(readingTime(content).minutes); + details.excerpt = details.excerpt || markdownToTxt(content).substr(0, 200); + details.sectionSlug = sectionSlug || slug.replace(/\.mdx$/, ''); + details.sectionWeight = sectionWeight; + details.sectionTitle = sectionTitle; + details.sectionId = sectionId; + details.rootSectionId = rootSectionId; + details.id = fileName; + details.isIndex = fileName.endsWith('/index.mdx'); + details.slug = details.isIndex ? sectionSlug : slug.replace(/\.mdx$/, ''); + if (details.slug.includes('/reference/specification/') && !details.title) { - const fileBaseName = basename(data.slug) // ex. v2.0.0 | v2.1.0-next-spec.1 - const fileName = fileBaseName.split('-')[0] // v2.0.0 | v2.1.0 - details.weight = specWeight-- + const fileBaseName = path.basename(data.slug); + const fileName = fileBaseName.split('-')[0]; + details.weight = specWeight--; if (fileName.startsWith('v')) { - details.title = capitalize(fileName.slice(1)) + details.title = capitalize(fileName.slice(1)); } else { - details.title = capitalize(fileName) + details.title = capitalize(fileName); } if (releaseNotes.includes(details.title)) { - details.releaseNoteLink = `/blog/release-notes-${details.title}` + details.releaseNoteLink = `/blog/release-notes-${details.title}`; } if (fileBaseName.includes('next-spec') || fileBaseName.includes('next-major-spec')) { - details.isPrerelease = true - // this need to be separate because the `-` in "Pre-release" will get removed by `capitalize()` function - details.title += " (Pre-release)" + details.isPrerelease = true; + details.title += " (Pre-release)"; } if (fileBaseName.includes('explorer')) { - details.title += " - Explorer" + details.title += " - Explorer"; } } - // To create a list of available ReleaseNotes list, which will be used to add details.releaseNoteLink attribute. if (file.startsWith("release-notes") && dir[1] === "/blog") { - const fileName_without_extension = file.slice(0, -4) - // removes the file extension. For example, release-notes-2.1.0.md -> release-notes-2.1.0 - const version = fileName_without_extension.slice(fileName_without_extension.lastIndexOf("-") + 1) - - // gets the version from the name of the releaseNote .md file (from /blog). For example, version = 2.1.0 if fileName_without_extension = release-notes-2.1.0 - releaseNotes.push(version) - // releaseNotes is the list of all available releaseNotes + const fileNameWithoutExtension = path.basename(file, path.extname(file)); + const version = fileNameWithoutExtension.slice(fileNameWithoutExtension.lastIndexOf("-") + 1); + releaseNotes.push(version); } - addItem(details) + addItem(details); } } } } function slugifyToC(str) { - let slug - // Try to match heading ids like {# myHeadingId} - const headingIdMatch = str.match(/[\s]?\{\#([\w\d\-_]+)\}/) + let slug; + const headingIdMatch = str.match(/[\s]?\{\#([\w\d\-_]+)\}/); if (headingIdMatch && headingIdMatch.length >= 2) { - slug = headingIdMatch[1] + slug = headingIdMatch[1]; } else { - // Try to match heading ids like {} - const anchorTagMatch = str.match(/[\s]*= 2) slug = anchorTagMatch[1] + const anchorTagMatch = str.match(/[\s]*= 2) slug = anchorTagMatch[1]; } - return slug || slugify(str, { firsth1: true, maxdepth: 6 }) + return slug || slugify(str, { firsth1: true, maxdepth: 6 }); } function isDirectory(dir) { - return statSync(dir).isDirectory() + return statSync(dir).isDirectory(); } function capitalize(text) { - return text.split(/[\s\-]/g).map(word => `${word[0].toUpperCase()}${word.substr(1)}`).join(' ') + return text.split(/[\s\-]/g).map(word => `${word[0].toUpperCase()}${word.substr(1)}`).join(' '); } -module.exports = { slugifyToC, buildPostList } +module.exports = { slugifyToC, buildPostList }; From b653ecfb6f0a39a47d19595610e455ff49640606 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Mon, 4 Nov 2024 20:40:18 +0530 Subject: [PATCH 06/48] ffqef --- scripts/build-post-list.js | 172 ++++++++++++++++++++----------------- 1 file changed, 93 insertions(+), 79 deletions(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index d7488fcbf237..d6254e96f73c 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -1,40 +1,44 @@ -const { readdirSync, statSync, existsSync, readFileSync, writeFileSync } = require('fs'); -const path = require('path'); -const frontMatter = require('gray-matter'); -const toc = require('markdown-toc'); -const { slugify } = require('markdown-toc/lib/utils'); -const readingTime = require('reading-time'); -const { markdownToTxt } = require('markdown-to-txt'); -const { buildNavTree, addDocButtons } = require('./build-docs'); - -let specWeight = 100; +const { readdirSync, statSync, existsSync, readFileSync, writeFileSync } = require('fs') +const { basename } = require('path') +const frontMatter = require('gray-matter') +const toc = require('markdown-toc') +const { slugify } = require('markdown-toc/lib/utils') +const readingTime = require('reading-time') +const { markdownToTxt } = require('markdown-to-txt') +const { buildNavTree, addDocButtons } = require('./build-docs') + +let specWeight = 100 const result = { docs: [], blog: [], about: [], docsTree: {} -}; -const releaseNotes = []; +} +const releaseNotes = [] const addItem = (details) => { - if (details.slug.startsWith('/docs')) result["docs"].push(details); - else if (details.slug.startsWith('/blog')) result["blog"].push(details); - else if (details.slug.startsWith('/about')) result["about"].push(details); -}; + if (details.slug.startsWith('/docs')) + result["docs"].push(details) + else if (details.slug.startsWith('/blog')) + result["blog"].push(details) + else if (details.slug.startsWith('/about')) + result["about"].push(details) + else { } +} async function buildPostList(postDirectories, basePath, writeFilePath) { try { if (postDirectories.length === 0) { throw new Error('Error while building post list: No post directories provided'); } - walkDirectories(postDirectories, result, basePath); - const treePosts = buildNavTree(result["docs"].filter((p) => p.slug.startsWith('/docs/'))); - result["docsTree"] = treePosts; - result["docs"] = addDocButtons(result["docs"], treePosts); + walkDirectories(postDirectories, result, basePath) + const treePosts = buildNavTree(result["docs"].filter((p) => p.slug.startsWith('/docs/'))) + result["docsTree"] = treePosts + result["docs"] = addDocButtons(result["docs"], treePosts) if (process.env.NODE_ENV === 'production') { // console.log(inspect(result, { depth: null, colors: true })) } - writeFileSync(writeFilePath, JSON.stringify(result, null, ' ')); + writeFileSync(writeFilePath, JSON.stringify(result, null, ' ')) } catch (error) { throw new Error(`Error while building post list: ${error.message}`); } @@ -42,108 +46,118 @@ async function buildPostList(postDirectories, basePath, writeFilePath) { function walkDirectories(directories, result, basePath, sectionWeight = 0, sectionTitle, sectionId, rootSectionId) { for (let dir of directories) { - const directory = path.normalize(dir[0]); - const sectionSlug = dir[1] || ''; - const files = readdirSync(directory); + let directory = dir[0] + let sectionSlug = dir[1] || '' + let files = readdirSync(directory); for (let file of files) { - let details; - const fileName = path.join(directory, file); - const fileNameWithSection = path.join(fileName, '_section.mdx'); - const slug = fileName.replace(new RegExp(`^${basePath.replace(/\\/g, '\\\\')}`), '').replace(/\\/g, '/'); // Ensure forward slashes for slugs + let details + const fileName = [directory, file].join('/') + const fileNameWithSection = [fileName, '_section.mdx'].join('/') + const slug = fileName.replace(new RegExp(`^${basePath}`), '') const slugElements = slug.split('/'); - if (isDirectory(fileName)) { if (existsSync(fileNameWithSection)) { - details = frontMatter(readFileSync(fileNameWithSection, 'utf-8'), {}).data; - details.title = details.title || capitalize(path.basename(fileName)); + // Passing a second argument to frontMatter disables cache. See https://github.com/asyncapi/website/issues/1057 + details = frontMatter(readFileSync(fileNameWithSection, 'utf-8'), {}).data + details.title = details.title || capitalize(basename(fileName)) } else { - details = { title: capitalize(path.basename(fileName)) }; + details = { + title: capitalize(basename(fileName)), + } } - details.isSection = true; + details.isSection = true if (slugElements.length > 3) { - details.parent = slugElements[slugElements.length - 2]; - details.sectionId = slugElements[slugElements.length - 1]; + details.parent = slugElements[slugElements.length - 2] + details.sectionId = slugElements[slugElements.length - 1] } if (!details.parent) { - details.isRootSection = true; - details.rootSectionId = slugElements[slugElements.length - 1]; + details.isRootSection = true + details.rootSectionId = slugElements[slugElements.length - 1] } - details.sectionWeight = sectionWeight; - details.slug = slug; - addItem(details); - const rootId = details.parent || details.rootSectionId; - walkDirectories([[fileName, slug]], result, basePath, details.weight, details.title, details.sectionId, rootId); + details.sectionWeight = sectionWeight + details.slug = slug + addItem(details) + const rootId = details.parent || details.rootSectionId + walkDirectories([[fileName, slug]], result, basePath, details.weight, details.title, details.sectionId, rootId) } else if (file.endsWith('.mdx') && !fileName.endsWith('/_section.mdx')) { - const fileContent = readFileSync(fileName, 'utf-8'); - const { data, content } = frontMatter(fileContent, {}); - details = data; - details.toc = toc(content, { slugify: slugifyToC }).json; - details.readingTime = Math.ceil(readingTime(content).minutes); - details.excerpt = details.excerpt || markdownToTxt(content).substr(0, 200); - details.sectionSlug = sectionSlug || slug.replace(/\.mdx$/, ''); - details.sectionWeight = sectionWeight; - details.sectionTitle = sectionTitle; - details.sectionId = sectionId; - details.rootSectionId = rootSectionId; - details.id = fileName; - details.isIndex = fileName.endsWith('/index.mdx'); - details.slug = details.isIndex ? sectionSlug : slug.replace(/\.mdx$/, ''); - + const fileContent = readFileSync(fileName, 'utf-8') + // Passing a second argument to frontMatter disables cache. See https://github.com/asyncapi/website/issues/1057 + const { data, content } = frontMatter(fileContent, {}) + details = data + details.toc = toc(content, { slugify: slugifyToC }).json + details.readingTime = Math.ceil(readingTime(content).minutes) + details.excerpt = details.excerpt || markdownToTxt(content).substr(0, 200) + details.sectionSlug = sectionSlug || slug.replace(/\.mdx$/, '') + details.sectionWeight = sectionWeight + details.sectionTitle = sectionTitle + details.sectionId = sectionId + details.rootSectionId = rootSectionId + details.id = fileName + details.isIndex = fileName.endsWith('/index.mdx') + details.slug = details.isIndex ? sectionSlug : slug.replace(/\.mdx$/, '') if (details.slug.includes('/reference/specification/') && !details.title) { - const fileBaseName = path.basename(data.slug); - const fileName = fileBaseName.split('-')[0]; - details.weight = specWeight--; + const fileBaseName = basename(data.slug) // ex. v2.0.0 | v2.1.0-next-spec.1 + const fileName = fileBaseName.split('-')[0] // v2.0.0 | v2.1.0 + details.weight = specWeight-- if (fileName.startsWith('v')) { - details.title = capitalize(fileName.slice(1)); + details.title = capitalize(fileName.slice(1)) } else { - details.title = capitalize(fileName); + details.title = capitalize(fileName) } if (releaseNotes.includes(details.title)) { - details.releaseNoteLink = `/blog/release-notes-${details.title}`; + details.releaseNoteLink = `/blog/release-notes-${details.title}` } if (fileBaseName.includes('next-spec') || fileBaseName.includes('next-major-spec')) { - details.isPrerelease = true; - details.title += " (Pre-release)"; + details.isPrerelease = true + // this need to be separate because the `-` in "Pre-release" will get removed by `capitalize()` function + details.title += " (Pre-release)" } if (fileBaseName.includes('explorer')) { - details.title += " - Explorer"; + details.title += " - Explorer" } } + // To create a list of available ReleaseNotes list, which will be used to add details.releaseNoteLink attribute. if (file.startsWith("release-notes") && dir[1] === "/blog") { - const fileNameWithoutExtension = path.basename(file, path.extname(file)); - const version = fileNameWithoutExtension.slice(fileNameWithoutExtension.lastIndexOf("-") + 1); - releaseNotes.push(version); + const fileName_without_extension = file.slice(0, -4) + // removes the file extension. For example, release-notes-2.1.0.md -> release-notes-2.1.0 + const version = fileName_without_extension.slice(fileName_without_extension.lastIndexOf("-") + 1) + + // gets the version from the name of the releaseNote .md file (from /blog). For example, version = 2.1.0 if fileName_without_extension = release-notes-2.1.0 + releaseNotes.push(version) + // releaseNotes is the list of all available releaseNotes } - addItem(details); + addItem(details) } } } } function slugifyToC(str) { - let slug; - const headingIdMatch = str.match(/[\s]?\{\#([\w\d\-_]+)\}/); + let slug + // Try to match heading ids like {# myHeadingId} + const headingIdMatch = str.match(/[\s]?\{\#([\w\d\-_]+)\}/) if (headingIdMatch && headingIdMatch.length >= 2) { - slug = headingIdMatch[1]; + slug = headingIdMatch[1] } else { - const anchorTagMatch = str.match(/[\s]*= 2) slug = anchorTagMatch[1]; + // Try to match heading ids like {} + const anchorTagMatch = str.match(/[\s]*= 2) slug = anchorTagMatch[1] } - return slug || slugify(str, { firsth1: true, maxdepth: 6 }); + return slug || slugify(str, { firsth1: true, maxdepth: 6 }) } function isDirectory(dir) { - return statSync(dir).isDirectory(); + return statSync(dir).isDirectory() } function capitalize(text) { - return text.split(/[\s\-]/g).map(word => `${word[0].toUpperCase()}${word.substr(1)}`).join(' '); + return text.split(/[\s\-]/g).map(word => `${word[0].toUpperCase()}${word.substr(1)}`).join(' ') } -module.exports = { slugifyToC, buildPostList }; +module.exports = { slugifyToC, buildPostList } From accec3e16c34f7af1b558429a8de6aac877a399c Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Mon, 4 Nov 2024 22:36:51 +0530 Subject: [PATCH 07/48] path update --- scripts/build-post-list.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index d6254e96f73c..caf2e26e9980 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -1,5 +1,5 @@ const { readdirSync, statSync, existsSync, readFileSync, writeFileSync } = require('fs') -const { basename } = require('path') +const { basename, join, normalize } = require('path') const frontMatter = require('gray-matter') const toc = require('markdown-toc') const { slugify } = require('markdown-toc/lib/utils') @@ -23,7 +23,6 @@ const addItem = (details) => { result["blog"].push(details) else if (details.slug.startsWith('/about')) result["about"].push(details) - else { } } async function buildPostList(postDirectories, basePath, writeFilePath) { @@ -31,7 +30,8 @@ async function buildPostList(postDirectories, basePath, writeFilePath) { if (postDirectories.length === 0) { throw new Error('Error while building post list: No post directories provided'); } - walkDirectories(postDirectories, result, basePath) + const normalizedBasePath = normalize(basePath) + walkDirectories(postDirectories, result, normalizedBasePath) const treePosts = buildNavTree(result["docs"].filter((p) => p.slug.startsWith('/docs/'))) result["docsTree"] = treePosts result["docs"] = addDocButtons(result["docs"], treePosts) @@ -48,14 +48,14 @@ function walkDirectories(directories, result, basePath, sectionWeight = 0, secti for (let dir of directories) { let directory = dir[0] let sectionSlug = dir[1] || '' - let files = readdirSync(directory); + let files = readdirSync(directory) for (let file of files) { let details - const fileName = [directory, file].join('/') - const fileNameWithSection = [fileName, '_section.mdx'].join('/') + const fileName = join(directory, file) + const fileNameWithSection = join(fileName, '_section.mdx') const slug = fileName.replace(new RegExp(`^${basePath}`), '') - const slugElements = slug.split('/'); + const slugElements = slug.split('/') if (isDirectory(fileName)) { if (existsSync(fileNameWithSection)) { // Passing a second argument to frontMatter disables cache. See https://github.com/asyncapi/website/issues/1057 @@ -94,7 +94,7 @@ function walkDirectories(directories, result, basePath, sectionWeight = 0, secti details.sectionId = sectionId details.rootSectionId = rootSectionId details.id = fileName - details.isIndex = fileName.endsWith('/index.mdx') + details.isIndex = fileName.endsWith(join('index.mdx')) details.slug = details.isIndex ? sectionSlug : slug.replace(/\.mdx$/, '') if (details.slug.includes('/reference/specification/') && !details.title) { const fileBaseName = basename(data.slug) // ex. v2.0.0 | v2.1.0-next-spec.1 From bb4ffe03c54fae74406362c281139a241ddc3fff Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Mon, 4 Nov 2024 22:41:52 +0530 Subject: [PATCH 08/48] path update --- tests/build-post-list.test.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/build-post-list.test.js b/tests/build-post-list.test.js index c26e6ed83636..c8064837ded7 100644 --- a/tests/build-post-list.test.js +++ b/tests/build-post-list.test.js @@ -1,5 +1,5 @@ const { existsSync, readFileSync, writeFileSync, mkdirSync, rmSync } = require('fs'); -const { resolve, join } = require('path'); +const { resolve, join, normalize } = require('path'); const { buildPostList, slugifyToC } = require('../scripts/build-post-list'); describe('buildPostList', () => { @@ -16,7 +16,8 @@ describe('buildPostList', () => { [join(tempDir, 'about'), '/about'], ]; - mkdirSync(tempDir, { recursive: true }); + const normalizedDir = normalize(join(tempDir, 'blog')); + mkdirSync(normalizedDir, { recursive: true }); mkdirSync(join(tempDir, 'blog'), { recursive: true }); writeFileSync(join(tempDir, 'blog', 'release-notes-2.1.0.mdx'), '---\ntitle: Release Notes 2.1.0\n---\nThis is a release note.'); From c24eb8eb909a1629a8043ef2e01db705e082936c Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Mon, 4 Nov 2024 22:48:35 +0530 Subject: [PATCH 09/48] logs added --- tests/build-post-list.test.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/build-post-list.test.js b/tests/build-post-list.test.js index c8064837ded7..4ad1995148db 100644 --- a/tests/build-post-list.test.js +++ b/tests/build-post-list.test.js @@ -43,6 +43,7 @@ describe('buildPostList', () => { expect(outputExists).toBe(true); const output = JSON.parse(readFileSync(writeFilePath, 'utf-8')); + console.log(output) expect(output).toHaveProperty('docs'); expect(output).toHaveProperty('blog'); @@ -61,6 +62,7 @@ describe('buildPostList', () => { await buildPostList(postDirectories, tempDir, writeFilePath); const output = JSON.parse(readFileSync(writeFilePath, 'utf-8')); + console.log(output) expect(output.docs.length).toBeGreaterThan(0); expect(output.docs.find(item => item.title === 'Section 1')).toBeDefined(); @@ -72,6 +74,7 @@ describe('buildPostList', () => { await buildPostList(postDirectories, tempDir, writeFilePath); const output = JSON.parse(readFileSync(writeFilePath, 'utf-8')); + console.log(output) const firstReleaseNote = output.blog.find(item => item.slug === '/blog/release-notes-2.1.0'); const secondReleaseNote = output.blog.find(item => item.slug === '/blog/release-notes-2.1.1'); From 63edd8d55d92f42f8f6c7949842c4ce3373fdc39 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Mon, 4 Nov 2024 23:13:39 +0530 Subject: [PATCH 10/48] fwf --- scripts/build-post-list.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index caf2e26e9980..80f82f08a9a8 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -1,5 +1,5 @@ const { readdirSync, statSync, existsSync, readFileSync, writeFileSync } = require('fs') -const { basename, join, normalize } = require('path') +const { basename, join, normalize, sep } = require('path') const frontMatter = require('gray-matter') const toc = require('markdown-toc') const { slugify } = require('markdown-toc/lib/utils') @@ -23,7 +23,7 @@ const addItem = (details) => { result["blog"].push(details) else if (details.slug.startsWith('/about')) result["about"].push(details) -} +}; async function buildPostList(postDirectories, basePath, writeFilePath) { try { @@ -54,7 +54,7 @@ function walkDirectories(directories, result, basePath, sectionWeight = 0, secti let details const fileName = join(directory, file) const fileNameWithSection = join(fileName, '_section.mdx') - const slug = fileName.replace(new RegExp(`^${basePath}`), '') + const slug = normalize(fileName.replace(new RegExp(`^${basePath}`), '')).replace(/\\/g, '/') const slugElements = slug.split('/') if (isDirectory(fileName)) { if (existsSync(fileNameWithSection)) { @@ -80,7 +80,7 @@ function walkDirectories(directories, result, basePath, sectionWeight = 0, secti addItem(details) const rootId = details.parent || details.rootSectionId walkDirectories([[fileName, slug]], result, basePath, details.weight, details.title, details.sectionId, rootId) - } else if (file.endsWith('.mdx') && !fileName.endsWith('/_section.mdx')) { + } else if (file.endsWith('.mdx') && !fileName.endsWith(sep + '_section.mdx')) { const fileContent = readFileSync(fileName, 'utf-8') // Passing a second argument to frontMatter disables cache. See https://github.com/asyncapi/website/issues/1057 const { data, content } = frontMatter(fileContent, {}) From b87b00da9de8f7705a8bbf46f9087513e3e2299c Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Mon, 4 Nov 2024 23:22:05 +0530 Subject: [PATCH 11/48] logs added --- scripts/build-post-list.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index 80f82f08a9a8..48a66c37fb18 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -56,6 +56,10 @@ function walkDirectories(directories, result, basePath, sectionWeight = 0, secti const fileNameWithSection = join(fileName, '_section.mdx') const slug = normalize(fileName.replace(new RegExp(`^${basePath}`), '')).replace(/\\/g, '/') const slugElements = slug.split('/') + + console.log(`Processing file: ${fileName}`); + console.log(`Generated slug: ${slug}`); + if (isDirectory(fileName)) { if (existsSync(fileNameWithSection)) { // Passing a second argument to frontMatter disables cache. See https://github.com/asyncapi/website/issues/1057 @@ -131,7 +135,7 @@ function walkDirectories(directories, result, basePath, sectionWeight = 0, secti releaseNotes.push(version) // releaseNotes is the list of all available releaseNotes } - + console.log(`Details for MDX file: ${JSON.stringify(details, null, 2)}`); addItem(details) } } From 0f1578474939b207fb5fa9bfbda755530e84aa87 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Mon, 4 Nov 2024 23:29:26 +0530 Subject: [PATCH 12/48] posix --- scripts/build-post-list.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index 48a66c37fb18..3807ad684ff2 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -1,5 +1,5 @@ const { readdirSync, statSync, existsSync, readFileSync, writeFileSync } = require('fs') -const { basename, join, normalize, sep } = require('path') +const { basename, join, normalize, sep, posix } = require('path') const frontMatter = require('gray-matter') const toc = require('markdown-toc') const { slugify } = require('markdown-toc/lib/utils') @@ -54,7 +54,7 @@ function walkDirectories(directories, result, basePath, sectionWeight = 0, secti let details const fileName = join(directory, file) const fileNameWithSection = join(fileName, '_section.mdx') - const slug = normalize(fileName.replace(new RegExp(`^${basePath}`), '')).replace(/\\/g, '/') + const slug = posix.normalize(fileName.replace(new RegExp(`^${basePath}`), '')); const slugElements = slug.split('/') console.log(`Processing file: ${fileName}`); From 8f26f50845323651035b5a7eb8dd4eb7306bd93c Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Mon, 4 Nov 2024 23:31:12 +0530 Subject: [PATCH 13/48] fwqfqw --- scripts/build-post-list.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index 3807ad684ff2..f171648776ae 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -97,7 +97,7 @@ function walkDirectories(directories, result, basePath, sectionWeight = 0, secti details.sectionTitle = sectionTitle details.sectionId = sectionId details.rootSectionId = rootSectionId - details.id = fileName + details.id = slug details.isIndex = fileName.endsWith(join('index.mdx')) details.slug = details.isIndex ? sectionSlug : slug.replace(/\.mdx$/, '') if (details.slug.includes('/reference/specification/') && !details.title) { From 10453f4a2d1704633581cb2339249148f670fb4f Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Mon, 4 Nov 2024 23:34:10 +0530 Subject: [PATCH 14/48] path chanegs --- scripts/build-post-list.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index f171648776ae..f445a70b6ae9 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -97,7 +97,7 @@ function walkDirectories(directories, result, basePath, sectionWeight = 0, secti details.sectionTitle = sectionTitle details.sectionId = sectionId details.rootSectionId = rootSectionId - details.id = slug + details.id = fileName.replace(/\\/g, '/'); details.isIndex = fileName.endsWith(join('index.mdx')) details.slug = details.isIndex ? sectionSlug : slug.replace(/\.mdx$/, '') if (details.slug.includes('/reference/specification/') && !details.title) { From 323cdc582434bb2c13d93466646e85de12ac2bf4 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Tue, 5 Nov 2024 10:55:29 +0530 Subject: [PATCH 15/48] fqwefe --- scripts/build-post-list.js | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index f445a70b6ae9..f953df5ce515 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -46,20 +46,17 @@ async function buildPostList(postDirectories, basePath, writeFilePath) { function walkDirectories(directories, result, basePath, sectionWeight = 0, sectionTitle, sectionId, rootSectionId) { for (let dir of directories) { - let directory = dir[0] - let sectionSlug = dir[1] || '' - let files = readdirSync(directory) + let directory = posix.normalize(dir[0]); + let sectionSlug = dir[1] || ''; + let files = readdirSync(directory); for (let file of files) { - let details - const fileName = join(directory, file) - const fileNameWithSection = join(fileName, '_section.mdx') - const slug = posix.normalize(fileName.replace(new RegExp(`^${basePath}`), '')); + let details; + const fileName = posix.join(directory, file); + const fileNameWithSection = posix.join(fileName, '_section.mdx'); + const slug = posix.normalize(fileName.replace(new RegExp(`^${basePath}`), '')).replace(/\\/g, '/'); const slugElements = slug.split('/') - console.log(`Processing file: ${fileName}`); - console.log(`Generated slug: ${slug}`); - if (isDirectory(fileName)) { if (existsSync(fileNameWithSection)) { // Passing a second argument to frontMatter disables cache. See https://github.com/asyncapi/website/issues/1057 @@ -135,7 +132,7 @@ function walkDirectories(directories, result, basePath, sectionWeight = 0, secti releaseNotes.push(version) // releaseNotes is the list of all available releaseNotes } - console.log(`Details for MDX file: ${JSON.stringify(details, null, 2)}`); + addItem(details) } } From bb2d6b6749d6b11d2ba2d1b543984ab315076726 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Tue, 5 Nov 2024 11:05:56 +0530 Subject: [PATCH 16/48] used fs extra --- scripts/build-post-list.js | 26 ++++++------- tests/build-post-list.test.js | 70 +++++++++++++++-------------------- 2 files changed, 42 insertions(+), 54 deletions(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index f953df5ce515..711cda6dc1cb 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -1,4 +1,4 @@ -const { readdirSync, statSync, existsSync, readFileSync, writeFileSync } = require('fs') +const { readdir, stat, pathExists, readFile, writeFile } = require('fs-extra') const { basename, join, normalize, sep, posix } = require('path') const frontMatter = require('gray-matter') const toc = require('markdown-toc') @@ -31,24 +31,24 @@ async function buildPostList(postDirectories, basePath, writeFilePath) { throw new Error('Error while building post list: No post directories provided'); } const normalizedBasePath = normalize(basePath) - walkDirectories(postDirectories, result, normalizedBasePath) + await walkDirectories(postDirectories, result, normalizedBasePath) const treePosts = buildNavTree(result["docs"].filter((p) => p.slug.startsWith('/docs/'))) result["docsTree"] = treePosts result["docs"] = addDocButtons(result["docs"], treePosts) if (process.env.NODE_ENV === 'production') { // console.log(inspect(result, { depth: null, colors: true })) } - writeFileSync(writeFilePath, JSON.stringify(result, null, ' ')) + await writeFile(writeFilePath, JSON.stringify(result, null, ' ')) } catch (error) { throw new Error(`Error while building post list: ${error.message}`); } } -function walkDirectories(directories, result, basePath, sectionWeight = 0, sectionTitle, sectionId, rootSectionId) { +async function walkDirectories(directories, result, basePath, sectionWeight = 0, sectionTitle, sectionId, rootSectionId) { for (let dir of directories) { let directory = posix.normalize(dir[0]); let sectionSlug = dir[1] || ''; - let files = readdirSync(directory); + let files = await readdir(directory) for (let file of files) { let details; @@ -57,10 +57,10 @@ function walkDirectories(directories, result, basePath, sectionWeight = 0, secti const slug = posix.normalize(fileName.replace(new RegExp(`^${basePath}`), '')).replace(/\\/g, '/'); const slugElements = slug.split('/') - if (isDirectory(fileName)) { - if (existsSync(fileNameWithSection)) { + if (await isDirectory(fileName)) { + if (await pathExists(fileNameWithSection)) { // Passing a second argument to frontMatter disables cache. See https://github.com/asyncapi/website/issues/1057 - details = frontMatter(readFileSync(fileNameWithSection, 'utf-8'), {}).data + details = frontMatter(await readFile(fileNameWithSection, 'utf-8'), {}).data details.title = details.title || capitalize(basename(fileName)) } else { details = { @@ -80,9 +80,9 @@ function walkDirectories(directories, result, basePath, sectionWeight = 0, secti details.slug = slug addItem(details) const rootId = details.parent || details.rootSectionId - walkDirectories([[fileName, slug]], result, basePath, details.weight, details.title, details.sectionId, rootId) + await walkDirectories([[fileName, slug]], result, basePath, details.weight, details.title, details.sectionId, rootId) } else if (file.endsWith('.mdx') && !fileName.endsWith(sep + '_section.mdx')) { - const fileContent = readFileSync(fileName, 'utf-8') + const fileContent = await readFile(fileName, 'utf-8') // Passing a second argument to frontMatter disables cache. See https://github.com/asyncapi/website/issues/1057 const { data, content } = frontMatter(fileContent, {}) details = data @@ -94,7 +94,7 @@ function walkDirectories(directories, result, basePath, sectionWeight = 0, secti details.sectionTitle = sectionTitle details.sectionId = sectionId details.rootSectionId = rootSectionId - details.id = fileName.replace(/\\/g, '/'); + details.id = fileName.replace(/\\/g, '/') details.isIndex = fileName.endsWith(join('index.mdx')) details.slug = details.isIndex ? sectionSlug : slug.replace(/\.mdx$/, '') if (details.slug.includes('/reference/specification/') && !details.title) { @@ -153,8 +153,8 @@ function slugifyToC(str) { return slug || slugify(str, { firsth1: true, maxdepth: 6 }) } -function isDirectory(dir) { - return statSync(dir).isDirectory() +async function isDirectory(dir) { + return (await stat(dir)).isDirectory() } function capitalize(text) { diff --git a/tests/build-post-list.test.js b/tests/build-post-list.test.js index 4ad1995148db..76c3da3af5f5 100644 --- a/tests/build-post-list.test.js +++ b/tests/build-post-list.test.js @@ -1,4 +1,4 @@ -const { existsSync, readFileSync, writeFileSync, mkdirSync, rmSync } = require('fs'); +const fs = require('fs-extra'); const { resolve, join, normalize } = require('path'); const { buildPostList, slugifyToC } = require('../scripts/build-post-list'); @@ -7,7 +7,7 @@ describe('buildPostList', () => { let writeFilePath; let postDirectories; - beforeEach(() => { + beforeEach(async () => { tempDir = resolve(__dirname, `test-config`); writeFilePath = resolve(tempDir, 'posts.json'); postDirectories = [ @@ -17,33 +17,32 @@ describe('buildPostList', () => { ]; const normalizedDir = normalize(join(tempDir, 'blog')); - mkdirSync(normalizedDir, { recursive: true }); + await fs.ensureDir(normalizedDir); - mkdirSync(join(tempDir, 'blog'), { recursive: true }); - writeFileSync(join(tempDir, 'blog', 'release-notes-2.1.0.mdx'), '---\ntitle: Release Notes 2.1.0\n---\nThis is a release note.'); + await fs.ensureDir(join(tempDir, 'blog')); + await fs.writeFile(join(tempDir, 'blog', 'release-notes-2.1.0.mdx'), '---\ntitle: Release Notes 2.1.0\n---\nThis is a release note.'); - mkdirSync(join(tempDir, 'docs'), { recursive: true }); - writeFileSync(join(tempDir, 'docs', 'index.mdx'), '---\ntitle: Docs Home\n---\nThis is the documentation homepage.'); + await fs.ensureDir(join(tempDir, 'docs')); + await fs.writeFile(join(tempDir, 'docs', 'index.mdx'), '---\ntitle: Docs Home\n---\nThis is the documentation homepage.'); - mkdirSync(join(tempDir, 'about'), { recursive: true }); - writeFileSync(join(tempDir, 'about', 'index.mdx'), '---\ntitle: About Us\n---\nThis is the about page.'); + await fs.ensureDir(join(tempDir, 'about')); + await fs.writeFile(join(tempDir, 'about', 'index.mdx'), '---\ntitle: About Us\n---\nThis is the about page.'); - mkdirSync(join(tempDir, 'docs', 'reference', 'specification'), { recursive: true }); + await fs.ensureDir(join(tempDir, 'docs', 'reference', 'specification')); }); - afterEach(() => { - rmSync(tempDir, { recursive: true, force: true }); + afterEach(async () => { + await fs.remove(tempDir); }); it('builds a post list and writes the result to a file', async () => { - await buildPostList(postDirectories, tempDir, writeFilePath); - const outputExists = existsSync(writeFilePath); + const outputExists = await fs.pathExists(writeFilePath); expect(outputExists).toBe(true); - const output = JSON.parse(readFileSync(writeFilePath, 'utf-8')); - console.log(output) + const output = JSON.parse(await fs.readFile(writeFilePath, 'utf-8')); + console.log(output); expect(output).toHaveProperty('docs'); expect(output).toHaveProperty('blog'); @@ -56,25 +55,25 @@ describe('buildPostList', () => { }); it('handles a directory with only section files', async () => { - mkdirSync(join(tempDir, 'docs', 'section1'), { recursive: true }); - writeFileSync(join(tempDir, 'docs', 'section1', '_section.mdx'), '---\ntitle: Section 1\n---\nThis is section 1.'); + await fs.ensureDir(join(tempDir, 'docs', 'section1')); + await fs.writeFile(join(tempDir, 'docs', 'section1', '_section.mdx'), '---\ntitle: Section 1\n---\nThis is section 1.'); await buildPostList(postDirectories, tempDir, writeFilePath); - const output = JSON.parse(readFileSync(writeFilePath, 'utf-8')); - console.log(output) + const output = JSON.parse(await fs.readFile(writeFilePath, 'utf-8')); + console.log(output); expect(output.docs.length).toBeGreaterThan(0); expect(output.docs.find(item => item.title === 'Section 1')).toBeDefined(); }); it('handles multiple release notes correctly', async () => { - writeFileSync(join(tempDir, 'blog', 'release-notes-2.1.1.mdx'), '---\ntitle: Release Notes 2.1.1\n---\nThis is a release note.'); + await fs.writeFile(join(tempDir, 'blog', 'release-notes-2.1.1.mdx'), '---\ntitle: Release Notes 2.1.1\n---\nThis is a release note.'); await buildPostList(postDirectories, tempDir, writeFilePath); - const output = JSON.parse(readFileSync(writeFilePath, 'utf-8')); - console.log(output) + const output = JSON.parse(await fs.readFile(writeFilePath, 'utf-8')); + console.log(output); const firstReleaseNote = output.blog.find(item => item.slug === '/blog/release-notes-2.1.0'); const secondReleaseNote = output.blog.find(item => item.slug === '/blog/release-notes-2.1.1'); @@ -107,14 +106,11 @@ describe('buildPostList', () => { it('does not process specification files without a title', async () => { const specDir = join(tempDir, 'docs', 'reference', 'specification'); - writeFileSync( - join(specDir, 'v2.1.0-no-title.mdx'), - '---\n---\nContent of specification without a title.' - ); + await fs.writeFile(join(specDir, 'v2.1.0-no-title.mdx'), '---\n---\nContent of specification without a title.'); await buildPostList(postDirectories, tempDir, writeFilePath); - const output = JSON.parse(readFileSync(writeFilePath, 'utf-8')); + const output = JSON.parse(await fs.readFile(writeFilePath, 'utf-8')); const noTitleEntry = output.docs.find(item => item.slug.includes('/reference/specification/v2.1.0-no-title')); expect(noTitleEntry).toBeUndefined(); @@ -122,14 +118,11 @@ describe('buildPostList', () => { it('does not process specification files with "next-spec" in the filename', async () => { const specDir = join(tempDir, 'docs', 'reference', 'specification'); - writeFileSync( - join(specDir, 'v2.1.0-next-spec.1.mdx'), - '---\n---\nContent of pre-release specification v2.1.0-next-spec.1.' - ); + await fs.writeFile(join(specDir, 'v2.1.0-next-spec.1.mdx'), '---\n---\nContent of pre-release specification v2.1.0-next-spec.1.'); await buildPostList(postDirectories, tempDir, writeFilePath); - const output = JSON.parse(readFileSync(writeFilePath, 'utf-8')); + const output = JSON.parse(await fs.readFile(writeFilePath, 'utf-8')); const nextSpecEntry = output.docs.find(item => item.slug.includes('/reference/specification/v2.1.0-next-spec.1')); expect(nextSpecEntry).toBeUndefined(); @@ -137,14 +130,11 @@ describe('buildPostList', () => { it('does not process specification files with "explorer" in the filename', async () => { const specDir = join(tempDir, 'docs', 'reference', 'specification'); - writeFileSync( - join(specDir, 'explorer.mdx'), - '---\n---\nContent of explorer specification.' - ); + await fs.writeFile(join(specDir, 'explorer.mdx'), '---\n---\nContent of explorer specification.'); await buildPostList(postDirectories, tempDir, writeFilePath); - const output = JSON.parse(readFileSync(writeFilePath, 'utf-8')); + const output = JSON.parse(await fs.readFile(writeFilePath, 'utf-8')); const explorerEntry = output.docs.find(item => item.slug.includes('/reference/specification/explorer')); expect(explorerEntry).toBeUndefined(); @@ -164,9 +154,8 @@ describe('buildPostList', () => { expect(error.message).toMatch(/Error while building post list/); }); - it('throws an error if the front matter cannot be parsed', async () => { - writeFileSync(join(tempDir, 'docs', 'invalid.mdx'), '---\ninvalid front matter\n---\nContent'); + await fs.writeFile(join(tempDir, 'docs', 'invalid.mdx'), '---\ninvalid front matter\n---\nContent'); let error; try { @@ -180,7 +169,6 @@ describe('buildPostList', () => { }); it('throws an error if no post directories are provided', async () => { - let error; try { From a9c95d97b1fe0e9ce16cde00edd8a62e7a4bef89 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sat, 9 Nov 2024 13:09:19 +0530 Subject: [PATCH 17/48] path fix --- scripts/build-post-list.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index 711cda6dc1cb..bd7cd50e962b 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -1,5 +1,5 @@ const { readdir, stat, pathExists, readFile, writeFile } = require('fs-extra') -const { basename, join, normalize, sep, posix } = require('path') +const { basename, join, normalize, sep, posix, relative } = require('path') const frontMatter = require('gray-matter') const toc = require('markdown-toc') const { slugify } = require('markdown-toc/lib/utils') @@ -53,8 +53,9 @@ async function walkDirectories(directories, result, basePath, sectionWeight = 0, for (let file of files) { let details; const fileName = posix.join(directory, file); - const fileNameWithSection = posix.join(fileName, '_section.mdx'); - const slug = posix.normalize(fileName.replace(new RegExp(`^${basePath}`), '')).replace(/\\/g, '/'); + const fileNameWithSection = posix.join(fileName, '_section.mdx') + const normalizedSlug = posix.join('/', relative(basePath, fileName)) + const slug = normalizedSlug.replace(/\\/g,'/') const slugElements = slug.split('/') if (await isDirectory(fileName)) { From a3a8dca144724bff54257bd0c0c4fbb6ccd50da9 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sat, 9 Nov 2024 13:14:26 +0530 Subject: [PATCH 18/48] qwfeg --- scripts/build-post-list.js | 3 --- tests/build-post-list.test.js | 43 ++++++++++++----------------------- 2 files changed, 15 insertions(+), 31 deletions(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index bd7cd50e962b..aaa490575676 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -35,9 +35,6 @@ async function buildPostList(postDirectories, basePath, writeFilePath) { const treePosts = buildNavTree(result["docs"].filter((p) => p.slug.startsWith('/docs/'))) result["docsTree"] = treePosts result["docs"] = addDocButtons(result["docs"], treePosts) - if (process.env.NODE_ENV === 'production') { - // console.log(inspect(result, { depth: null, colors: true })) - } await writeFile(writeFilePath, JSON.stringify(result, null, ' ')) } catch (error) { throw new Error(`Error while building post list: ${error.message}`); diff --git a/tests/build-post-list.test.js b/tests/build-post-list.test.js index 76c3da3af5f5..b98695a1dbf3 100644 --- a/tests/build-post-list.test.js +++ b/tests/build-post-list.test.js @@ -90,20 +90,6 @@ describe('buildPostList', () => { await expect(buildPostList([invalidDir], tempDir, writeFilePath)).rejects.toThrow(); }); - it('handles heading ids like {# myHeadingId}', () => { - const input = '## My Heading {#custom-id}'; - expect(slugifyToC(input)).toBe('custom-id'); - }); - - it('handles heading ids like {}', () => { - const input = '## My Heading {}'; - expect(slugifyToC(input)).toBe('custom-anchor-id'); - }); - - it('handles empty strings', () => { - expect(slugifyToC('')).toBe(''); - }); - it('does not process specification files without a title', async () => { const specDir = join(tempDir, 'docs', 'reference', 'specification'); await fs.writeFile(join(specDir, 'v2.1.0-no-title.mdx'), '---\n---\nContent of specification without a title.'); @@ -140,20 +126,6 @@ describe('buildPostList', () => { expect(explorerEntry).toBeUndefined(); }); - it('throws an error if the directory cannot be read', async () => { - const invalidDir = [join(tempDir, 'non-existent-dir'), '/invalid']; - - let error; - try { - await buildPostList([invalidDir], tempDir, writeFilePath); - } catch (err) { - error = err; - } - - expect(error).toBeDefined(); - expect(error.message).toMatch(/Error while building post list/); - }); - it('throws an error if the front matter cannot be parsed', async () => { await fs.writeFile(join(tempDir, 'docs', 'invalid.mdx'), '---\ninvalid front matter\n---\nContent'); @@ -180,4 +152,19 @@ describe('buildPostList', () => { expect(error).toBeDefined(); expect(error.message).toMatch(/Error while building post list/); }); + + it('handles heading ids like {# myHeadingId}', () => { + const input = '## My Heading {#custom-id}'; + expect(slugifyToC(input)).toBe('custom-id'); + }); + + it('handles heading ids like {}', () => { + const input = '## My Heading {}'; + expect(slugifyToC(input)).toBe('custom-anchor-id'); + }); + + it('handles empty strings', () => { + expect(slugifyToC('')).toBe(''); + }); + }); From 70a0cd14a1bdf69f9378af311a18cc6a6ab40c72 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sat, 9 Nov 2024 13:17:26 +0530 Subject: [PATCH 19/48] remove logs --- tests/build-post-list.test.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/build-post-list.test.js b/tests/build-post-list.test.js index b98695a1dbf3..109b465cfee8 100644 --- a/tests/build-post-list.test.js +++ b/tests/build-post-list.test.js @@ -42,7 +42,6 @@ describe('buildPostList', () => { expect(outputExists).toBe(true); const output = JSON.parse(await fs.readFile(writeFilePath, 'utf-8')); - console.log(output); expect(output).toHaveProperty('docs'); expect(output).toHaveProperty('blog'); @@ -61,7 +60,6 @@ describe('buildPostList', () => { await buildPostList(postDirectories, tempDir, writeFilePath); const output = JSON.parse(await fs.readFile(writeFilePath, 'utf-8')); - console.log(output); expect(output.docs.length).toBeGreaterThan(0); expect(output.docs.find(item => item.title === 'Section 1')).toBeDefined(); @@ -73,7 +71,6 @@ describe('buildPostList', () => { await buildPostList(postDirectories, tempDir, writeFilePath); const output = JSON.parse(await fs.readFile(writeFilePath, 'utf-8')); - console.log(output); const firstReleaseNote = output.blog.find(item => item.slug === '/blog/release-notes-2.1.0'); const secondReleaseNote = output.blog.find(item => item.slug === '/blog/release-notes-2.1.1'); @@ -166,5 +163,5 @@ describe('buildPostList', () => { it('handles empty strings', () => { expect(slugifyToC('')).toBe(''); }); - + }); From 1383ea65f3082d47de986ce2b24ce7a70a992a02 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sat, 9 Nov 2024 14:24:33 +0530 Subject: [PATCH 20/48] apply coderabbit suggetions --- scripts/build-post-list.js | 10 +++++----- tests/build-post-list.test.js | 26 +++++++++++++++----------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index aaa490575676..4f05f1c254f8 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -1,5 +1,5 @@ const { readdir, stat, pathExists, readFile, writeFile } = require('fs-extra') -const { basename, join, normalize, sep, posix, relative } = require('path') +const { basename, join, normalize, sep, posix, relative, extname } = require('path') const frontMatter = require('gray-matter') const toc = require('markdown-toc') const { slugify } = require('markdown-toc/lib/utils') @@ -37,7 +37,7 @@ async function buildPostList(postDirectories, basePath, writeFilePath) { result["docs"] = addDocButtons(result["docs"], treePosts) await writeFile(writeFilePath, JSON.stringify(result, null, ' ')) } catch (error) { - throw new Error(`Error while building post list: ${error.message}`); + throw new Error('Error while building post list', { cause: error }); } } @@ -122,11 +122,11 @@ async function walkDirectories(directories, result, basePath, sectionWeight = 0, // To create a list of available ReleaseNotes list, which will be used to add details.releaseNoteLink attribute. if (file.startsWith("release-notes") && dir[1] === "/blog") { - const fileName_without_extension = file.slice(0, -4) + const fileNameWithoutExtension = basename(file, extname(file)) // removes the file extension. For example, release-notes-2.1.0.md -> release-notes-2.1.0 - const version = fileName_without_extension.slice(fileName_without_extension.lastIndexOf("-") + 1) + const version = fileNameWithoutExtension.slice(fileNameWithoutExtension.lastIndexOf("-") + 1) - // gets the version from the name of the releaseNote .md file (from /blog). For example, version = 2.1.0 if fileName_without_extension = release-notes-2.1.0 + // gets the version from the name of the releaseNote .md file (from /blog). For example, version = 2.1.0 if fileNameWithoutExtension = release-notes-2.1.0 releaseNotes.push(version) // releaseNotes is the list of all available releaseNotes } diff --git a/tests/build-post-list.test.js b/tests/build-post-list.test.js index 109b465cfee8..052bc4485b6b 100644 --- a/tests/build-post-list.test.js +++ b/tests/build-post-list.test.js @@ -150,18 +150,22 @@ describe('buildPostList', () => { expect(error.message).toMatch(/Error while building post list/); }); - it('handles heading ids like {# myHeadingId}', () => { - const input = '## My Heading {#custom-id}'; - expect(slugifyToC(input)).toBe('custom-id'); - }); + describe('slugifyToC', () => { - it('handles heading ids like {}', () => { - const input = '## My Heading {}'; - expect(slugifyToC(input)).toBe('custom-anchor-id'); - }); + it('handles heading ids like {# myHeadingId}', () => { + const input = '## My Heading {#custom-id}'; + expect(slugifyToC(input)).toBe('custom-id'); + }); - it('handles empty strings', () => { - expect(slugifyToC('')).toBe(''); - }); + it('handles heading ids like {}', () => { + const input = '## My Heading {}'; + expect(slugifyToC(input)).toBe('custom-anchor-id'); + }); + it('handles empty strings', () => { + expect(slugifyToC('')).toBe(''); + }); + + }); + }); From fd129fe4d3d3f6868465d8ce3cc470b0aa448961 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sat, 9 Nov 2024 14:26:12 +0530 Subject: [PATCH 21/48] fge --- tests/build-post-list.test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/build-post-list.test.js b/tests/build-post-list.test.js index 052bc4485b6b..f953a8a16304 100644 --- a/tests/build-post-list.test.js +++ b/tests/build-post-list.test.js @@ -167,5 +167,4 @@ describe('buildPostList', () => { }); }); - }); From e63203f1745b3470a5c81c5c1bd55ab0253585b5 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sat, 9 Nov 2024 15:42:37 +0530 Subject: [PATCH 22/48] update tests --- scripts/build-post-list.js | 7 ++++++- tests/build-post-list.test.js | 22 ++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index 4f05f1c254f8..bfacaae90935 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -27,6 +27,11 @@ const addItem = (details) => { async function buildPostList(postDirectories, basePath, writeFilePath) { try { + + if (!basePath || !writeFilePath) { + throw new Error('Error while building post list: basePath and writeFilePath are required'); + } + if (postDirectories.length === 0) { throw new Error('Error while building post list: No post directories provided'); } @@ -37,7 +42,7 @@ async function buildPostList(postDirectories, basePath, writeFilePath) { result["docs"] = addDocButtons(result["docs"], treePosts) await writeFile(writeFilePath, JSON.stringify(result, null, ' ')) } catch (error) { - throw new Error('Error while building post list', { cause: error }); + throw new Error(`Error while building post list: ${error.message}`, { cause: error }); } } diff --git a/tests/build-post-list.test.js b/tests/build-post-list.test.js index f953a8a16304..e85ae52d9077 100644 --- a/tests/build-post-list.test.js +++ b/tests/build-post-list.test.js @@ -150,6 +150,28 @@ describe('buildPostList', () => { expect(error.message).toMatch(/Error while building post list/); }); + it('throws an error if basePath is missing', async () => { + let error; + try { + await buildPostList(postDirectories, undefined, writeFilePath); + } catch (err) { + error = err; + } + expect(error).toBeDefined(); + expect(error.message).toMatch(/Error while building post list: basePath and writeFilePath are required/); + }); + + it('throws an error if writeFilePath is missing', async () => { + let error; + try { + await buildPostList(postDirectories, tempDir, undefined); + } catch (err) { + error = err; + } + expect(error).toBeDefined(); + expect(error.message).toMatch(/Error while building post list: basePath and writeFilePath are required/); + }); + describe('slugifyToC', () => { it('handles heading ids like {# myHeadingId}', () => { From b7e8c77d05c5c5bbc3c8d1d7c3159f8b3fa23c54 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sat, 9 Nov 2024 15:47:47 +0530 Subject: [PATCH 23/48] tests updated --- tests/build-post-list.test.js | 47 ++++++----------------------------- 1 file changed, 8 insertions(+), 39 deletions(-) diff --git a/tests/build-post-list.test.js b/tests/build-post-list.test.js index e85ae52d9077..fb6fe61f40be 100644 --- a/tests/build-post-list.test.js +++ b/tests/build-post-list.test.js @@ -125,52 +125,21 @@ describe('buildPostList', () => { it('throws an error if the front matter cannot be parsed', async () => { await fs.writeFile(join(tempDir, 'docs', 'invalid.mdx'), '---\ninvalid front matter\n---\nContent'); - - let error; - try { - await buildPostList(postDirectories, tempDir, writeFilePath); - } catch (err) { - error = err; - } - - expect(error).toBeDefined(); - expect(error.message).toMatch(/Error while building post list/); + + await expect(buildPostList(postDirectories, tempDir, writeFilePath)).rejects.toThrow(/Error while building post list/); }); - + it('throws an error if no post directories are provided', async () => { - let error; - - try { - await buildPostList([], tempDir, writeFilePath); - } catch (err) { - error = err; - } - - expect(error).toBeDefined(); - expect(error.message).toMatch(/Error while building post list/); + await expect(buildPostList([], tempDir, writeFilePath)).rejects.toThrow(/Error while building post list/); }); - + it('throws an error if basePath is missing', async () => { - let error; - try { - await buildPostList(postDirectories, undefined, writeFilePath); - } catch (err) { - error = err; - } - expect(error).toBeDefined(); - expect(error.message).toMatch(/Error while building post list: basePath and writeFilePath are required/); + await expect(buildPostList(postDirectories, undefined, writeFilePath)).rejects.toThrow(/Error while building post list: basePath and writeFilePath are required/); }); it('throws an error if writeFilePath is missing', async () => { - let error; - try { - await buildPostList(postDirectories, tempDir, undefined); - } catch (err) { - error = err; - } - expect(error).toBeDefined(); - expect(error.message).toMatch(/Error while building post list: basePath and writeFilePath are required/); - }); + await expect(buildPostList(postDirectories, tempDir, undefined)).rejects.toThrow(/Error while building post list: basePath and writeFilePath are required/); + }); describe('slugifyToC', () => { From 4d7b5a04a93167d848e8d3968bf5a7f01347edb6 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sat, 9 Nov 2024 16:22:48 +0530 Subject: [PATCH 24/48] fef --- scripts/build-post-list.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index bfacaae90935..ac62f8eef0db 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -46,7 +46,7 @@ async function buildPostList(postDirectories, basePath, writeFilePath) { } } -async function walkDirectories(directories, result, basePath, sectionWeight = 0, sectionTitle, sectionId, rootSectionId) { +async function walkDirectories(directories, resultObj, basePath, sectionTitle, sectionId, rootSectionId, sectionWeight = 0) { for (let dir of directories) { let directory = posix.normalize(dir[0]); let sectionSlug = dir[1] || ''; @@ -83,7 +83,7 @@ async function walkDirectories(directories, result, basePath, sectionWeight = 0, details.slug = slug addItem(details) const rootId = details.parent || details.rootSectionId - await walkDirectories([[fileName, slug]], result, basePath, details.weight, details.title, details.sectionId, rootId) + await walkDirectories([[fileName, slug]], resultObj, basePath, details.title, details.sectionId, rootId, details.sectionWeight) } else if (file.endsWith('.mdx') && !fileName.endsWith(sep + '_section.mdx')) { const fileContent = await readFile(fileName, 'utf-8') // Passing a second argument to frontMatter disables cache. See https://github.com/asyncapi/website/issues/1057 @@ -102,13 +102,13 @@ async function walkDirectories(directories, result, basePath, sectionWeight = 0, details.slug = details.isIndex ? sectionSlug : slug.replace(/\.mdx$/, '') if (details.slug.includes('/reference/specification/') && !details.title) { const fileBaseName = basename(data.slug) // ex. v2.0.0 | v2.1.0-next-spec.1 - const fileName = fileBaseName.split('-')[0] // v2.0.0 | v2.1.0 + const versionName = fileBaseName.split('-')[0] // v2.0.0 | v2.1.0 details.weight = specWeight-- - if (fileName.startsWith('v')) { - details.title = capitalize(fileName.slice(1)) + if (versionName.startsWith('v')) { + details.title = capitalize(versionName.slice(1)) } else { - details.title = capitalize(fileName) + details.title = capitalize(versionName) } if (releaseNotes.includes(details.title)) { From 09b530d69042f9b7ab889aef0286c34940e43a77 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sun, 10 Nov 2024 22:59:25 +0530 Subject: [PATCH 25/48] updated details.slug --- scripts/build-post-list.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index ac62f8eef0db..c48d7271d0ce 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -29,7 +29,7 @@ async function buildPostList(postDirectories, basePath, writeFilePath) { try { if (!basePath || !writeFilePath) { - throw new Error('Error while building post list: basePath and writeFilePath are required'); + throw new Error('Error while building post list: basePath and writeFilePath are required'); } if (postDirectories.length === 0) { @@ -101,7 +101,7 @@ async function walkDirectories(directories, resultObj, basePath, sectionTitle, s details.isIndex = fileName.endsWith(join('index.mdx')) details.slug = details.isIndex ? sectionSlug : slug.replace(/\.mdx$/, '') if (details.slug.includes('/reference/specification/') && !details.title) { - const fileBaseName = basename(data.slug) // ex. v2.0.0 | v2.1.0-next-spec.1 + const fileBaseName = basename(data.slug || details.slug) // ex. v2.0.0 | v2.1.0-next-spec.1 const versionName = fileBaseName.split('-')[0] // v2.0.0 | v2.1.0 details.weight = specWeight-- From 69ca91a3589bdc7b50324771f5e8a8a7666bb95a Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sun, 10 Nov 2024 23:19:04 +0530 Subject: [PATCH 26/48] quick fix --- scripts/build-post-list.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index c48d7271d0ce..9092bc20c960 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -101,7 +101,7 @@ async function walkDirectories(directories, resultObj, basePath, sectionTitle, s details.isIndex = fileName.endsWith(join('index.mdx')) details.slug = details.isIndex ? sectionSlug : slug.replace(/\.mdx$/, '') if (details.slug.includes('/reference/specification/') && !details.title) { - const fileBaseName = basename(data.slug || details.slug) // ex. v2.0.0 | v2.1.0-next-spec.1 + const fileBaseName = basename(details.slug) // ex. v2.0.0 | v2.1.0-next-spec.1 const versionName = fileBaseName.split('-')[0] // v2.0.0 | v2.1.0 details.weight = specWeight-- From 46159381c26f098c645c65ece8ab71c04002f698 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Wed, 13 Nov 2024 17:31:58 +0530 Subject: [PATCH 27/48] nkn --- tests/build-post-list.test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/build-post-list.test.js b/tests/build-post-list.test.js index fb6fe61f40be..6d38dfe06e99 100644 --- a/tests/build-post-list.test.js +++ b/tests/build-post-list.test.js @@ -156,6 +156,5 @@ describe('buildPostList', () => { it('handles empty strings', () => { expect(slugifyToC('')).toBe(''); }); - }); }); From f7cf1b684fb0fdd7aed7226ed36e86a6925b3fcc Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sat, 23 Nov 2024 10:16:15 +0530 Subject: [PATCH 28/48] applied suggested changes --- tests/build-post-list.test.js | 53 +++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/tests/build-post-list.test.js b/tests/build-post-list.test.js index 6d38dfe06e99..181b37f19958 100644 --- a/tests/build-post-list.test.js +++ b/tests/build-post-list.test.js @@ -16,9 +16,6 @@ describe('buildPostList', () => { [join(tempDir, 'about'), '/about'], ]; - const normalizedDir = normalize(join(tempDir, 'blog')); - await fs.ensureDir(normalizedDir); - await fs.ensureDir(join(tempDir, 'blog')); await fs.writeFile(join(tempDir, 'blog', 'release-notes-2.1.0.mdx'), '---\ntitle: Release Notes 2.1.0\n---\nThis is a release note.'); @@ -43,10 +40,44 @@ describe('buildPostList', () => { const output = JSON.parse(await fs.readFile(writeFilePath, 'utf-8')); - expect(output).toHaveProperty('docs'); - expect(output).toHaveProperty('blog'); - expect(output).toHaveProperty('about'); - expect(output).toHaveProperty('docsTree'); + expect(output.docs).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + title: 'Docs Home', + slug: '/docs', + }), + expect.objectContaining({ + title: 'Reference', + slug: '/docs/reference', + isRootSection: true, + }), + expect.objectContaining({ + title: 'Specification', + slug: '/docs/reference/specification', + isSection: true, + }), + ]) + ); + + expect(output.blog).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + title: 'Release Notes 2.1.0', + slug: '/blog/release-notes-2.1.0', + }), + ]) + ); + + expect(output.about).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + title: 'About Us', + slug: '/about', + }), + ]) + ); + + expect(output.docsTree).toBeDefined(); const blogEntry = output.blog.find(item => item.slug === '/blog/release-notes-2.1.0'); expect(blogEntry).toBeDefined(); @@ -61,8 +92,12 @@ describe('buildPostList', () => { const output = JSON.parse(await fs.readFile(writeFilePath, 'utf-8')); - expect(output.docs.length).toBeGreaterThan(0); - expect(output.docs.find(item => item.title === 'Section 1')).toBeDefined(); + const sectionEntry = output.docs.find(item => item.title === 'Section 1'); + expect(sectionEntry).toMatchObject({ + title: 'Section 1', + slug: expect.stringContaining('/docs/section1'), + isSection: true + }); }); it('handles multiple release notes correctly', async () => { From 49722d06971e57c2b6f51f82900330b64fc3dcc4 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Wed, 4 Dec 2024 12:24:16 +0530 Subject: [PATCH 29/48] apply nitpick --- tests/build-post-list.test.js | 52 +++++++++++++++++------------ tests/fixtures/buildPostListData.js | 29 ++++++++++++++++ 2 files changed, 60 insertions(+), 21 deletions(-) create mode 100644 tests/fixtures/buildPostListData.js diff --git a/tests/build-post-list.test.js b/tests/build-post-list.test.js index 181b37f19958..be04db6ad643 100644 --- a/tests/build-post-list.test.js +++ b/tests/build-post-list.test.js @@ -1,5 +1,6 @@ const fs = require('fs-extra'); -const { resolve, join, normalize } = require('path'); +const { resolve, join } = require('path'); +const { TEST_CONTENT } = require("../tests/fixtures/buildPostListData"); const { buildPostList, slugifyToC } = require('../scripts/build-post-list'); describe('buildPostList', () => { @@ -8,7 +9,7 @@ describe('buildPostList', () => { let postDirectories; beforeEach(async () => { - tempDir = resolve(__dirname, `test-config`); + tempDir = resolve(__dirname, `test-config-${Date.now()}-${Math.random().toString(36).slice(2)}`); writeFilePath = resolve(tempDir, 'posts.json'); postDirectories = [ [join(tempDir, 'blog'), '/blog'], @@ -16,16 +17,25 @@ describe('buildPostList', () => { [join(tempDir, 'about'), '/about'], ]; - await fs.ensureDir(join(tempDir, 'blog')); - await fs.writeFile(join(tempDir, 'blog', 'release-notes-2.1.0.mdx'), '---\ntitle: Release Notes 2.1.0\n---\nThis is a release note.'); + await fs.ensureDir(join(tempDir, TEST_CONTENT.blog.dir)); + await fs.writeFile( + join(tempDir, TEST_CONTENT.blog.dir, TEST_CONTENT.blog.file), + TEST_CONTENT.blog.content + ); - await fs.ensureDir(join(tempDir, 'docs')); - await fs.writeFile(join(tempDir, 'docs', 'index.mdx'), '---\ntitle: Docs Home\n---\nThis is the documentation homepage.'); + await fs.ensureDir(join(tempDir, TEST_CONTENT.docs.dir)); + await fs.writeFile( + join(tempDir, TEST_CONTENT.docs.dir, TEST_CONTENT.docs.file), + TEST_CONTENT.docs.content + ); - await fs.ensureDir(join(tempDir, 'about')); - await fs.writeFile(join(tempDir, 'about', 'index.mdx'), '---\ntitle: About Us\n---\nThis is the about page.'); + await fs.ensureDir(join(tempDir, TEST_CONTENT.docs.dir, TEST_CONTENT.docs.subDir)); - await fs.ensureDir(join(tempDir, 'docs', 'reference', 'specification')); + await fs.ensureDir(join(tempDir, TEST_CONTENT.about.dir)); + await fs.writeFile( + join(tempDir, TEST_CONTENT.about.dir, TEST_CONTENT.about.file), + TEST_CONTENT.about.content + ); }); afterEach(async () => { @@ -67,7 +77,7 @@ describe('buildPostList', () => { }), ]) ); - + expect(output.about).toEqual( expect.arrayContaining([ expect.objectContaining({ @@ -76,8 +86,8 @@ describe('buildPostList', () => { }), ]) ); - - expect(output.docsTree).toBeDefined(); + + expect(output.docsTree).toBeDefined(); const blogEntry = output.blog.find(item => item.slug === '/blog/release-notes-2.1.0'); expect(blogEntry).toBeDefined(); @@ -117,7 +127,7 @@ describe('buildPostList', () => { expect(secondReleaseNote.title).toBe('Release Notes 2.1.1'); }); - it('handles errors gracefully', async () => { + it('throws an error when accessing non-existent directory', async () => { const invalidDir = [join(tempDir, 'non-existent-dir'), '/invalid']; await expect(buildPostList([invalidDir], tempDir, writeFilePath)).rejects.toThrow(); }); @@ -158,23 +168,23 @@ describe('buildPostList', () => { expect(explorerEntry).toBeUndefined(); }); - it('throws an error if the front matter cannot be parsed', async () => { + it('throws "Error while building post list" when front matter is invalid', async () => { await fs.writeFile(join(tempDir, 'docs', 'invalid.mdx'), '---\ninvalid front matter\n---\nContent'); - + await expect(buildPostList(postDirectories, tempDir, writeFilePath)).rejects.toThrow(/Error while building post list/); }); - + it('throws an error if no post directories are provided', async () => { await expect(buildPostList([], tempDir, writeFilePath)).rejects.toThrow(/Error while building post list/); }); - - it('throws an error if basePath is missing', async () => { + + it('throws specific error message when basePath parameter is undefined', async () => { await expect(buildPostList(postDirectories, undefined, writeFilePath)).rejects.toThrow(/Error while building post list: basePath and writeFilePath are required/); }); - - it('throws an error if writeFilePath is missing', async () => { + + it('throws specific error message when writeFilePath parameter is undefined', async () => { await expect(buildPostList(postDirectories, tempDir, undefined)).rejects.toThrow(/Error while building post list: basePath and writeFilePath are required/); - }); + }); describe('slugifyToC', () => { diff --git a/tests/fixtures/buildPostListData.js b/tests/fixtures/buildPostListData.js new file mode 100644 index 000000000000..71416b2b6816 --- /dev/null +++ b/tests/fixtures/buildPostListData.js @@ -0,0 +1,29 @@ +const TEST_CONTENT = { + blog: { + dir: 'blog', + file: 'release-notes-2.1.0.mdx', + content: `--- +title: Release Notes 2.1.0 +--- +This is a release note.`, + }, + docs: { + dir: 'docs', + file: 'index.mdx', + content: `--- +title: Docs Home +--- +This is the documentation homepage.`, + subDir: 'reference/specification', + }, + about: { + dir: 'about', + file: 'index.mdx', + content: `--- +title: About Us +--- +This is the about page.`, + }, +}; + +module.exports = { TEST_CONTENT }; \ No newline at end of file From f8e7dfd4e515df55a02845e84dfda0b80c9be9d2 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sun, 8 Dec 2024 22:25:06 +0530 Subject: [PATCH 30/48] format code --- tests/build-post-list.test.js | 106 ++++++++++++++++++++++++---------- 1 file changed, 77 insertions(+), 29 deletions(-) diff --git a/tests/build-post-list.test.js b/tests/build-post-list.test.js index be04db6ad643..0bfd6ab3aa5f 100644 --- a/tests/build-post-list.test.js +++ b/tests/build-post-list.test.js @@ -1,6 +1,6 @@ const fs = require('fs-extra'); const { resolve, join } = require('path'); -const { TEST_CONTENT } = require("../tests/fixtures/buildPostListData"); +const { TEST_CONTENT } = require('../tests/fixtures/buildPostListData'); const { buildPostList, slugifyToC } = require('../scripts/build-post-list'); describe('buildPostList', () => { @@ -9,7 +9,10 @@ describe('buildPostList', () => { let postDirectories; beforeEach(async () => { - tempDir = resolve(__dirname, `test-config-${Date.now()}-${Math.random().toString(36).slice(2)}`); + tempDir = resolve( + __dirname, + `test-config-${Date.now()}-${Math.random().toString(36).slice(2)}`, + ); writeFilePath = resolve(tempDir, 'posts.json'); postDirectories = [ [join(tempDir, 'blog'), '/blog'], @@ -20,21 +23,23 @@ describe('buildPostList', () => { await fs.ensureDir(join(tempDir, TEST_CONTENT.blog.dir)); await fs.writeFile( join(tempDir, TEST_CONTENT.blog.dir, TEST_CONTENT.blog.file), - TEST_CONTENT.blog.content + TEST_CONTENT.blog.content, ); await fs.ensureDir(join(tempDir, TEST_CONTENT.docs.dir)); await fs.writeFile( join(tempDir, TEST_CONTENT.docs.dir, TEST_CONTENT.docs.file), - TEST_CONTENT.docs.content + TEST_CONTENT.docs.content, ); - await fs.ensureDir(join(tempDir, TEST_CONTENT.docs.dir, TEST_CONTENT.docs.subDir)); + await fs.ensureDir( + join(tempDir, TEST_CONTENT.docs.dir, TEST_CONTENT.docs.subDir), + ); await fs.ensureDir(join(tempDir, TEST_CONTENT.about.dir)); await fs.writeFile( join(tempDir, TEST_CONTENT.about.dir, TEST_CONTENT.about.file), - TEST_CONTENT.about.content + TEST_CONTENT.about.content, ); }); @@ -66,7 +71,7 @@ describe('buildPostList', () => { slug: '/docs/reference/specification', isSection: true, }), - ]) + ]), ); expect(output.blog).toEqual( @@ -75,7 +80,7 @@ describe('buildPostList', () => { title: 'Release Notes 2.1.0', slug: '/blog/release-notes-2.1.0', }), - ]) + ]), ); expect(output.about).toEqual( @@ -84,41 +89,53 @@ describe('buildPostList', () => { title: 'About Us', slug: '/about', }), - ]) + ]), ); expect(output.docsTree).toBeDefined(); - const blogEntry = output.blog.find(item => item.slug === '/blog/release-notes-2.1.0'); + const blogEntry = output.blog.find( + (item) => item.slug === '/blog/release-notes-2.1.0', + ); expect(blogEntry).toBeDefined(); expect(blogEntry.title).toBe('Release Notes 2.1.0'); }); it('handles a directory with only section files', async () => { await fs.ensureDir(join(tempDir, 'docs', 'section1')); - await fs.writeFile(join(tempDir, 'docs', 'section1', '_section.mdx'), '---\ntitle: Section 1\n---\nThis is section 1.'); + await fs.writeFile( + join(tempDir, 'docs', 'section1', '_section.mdx'), + '---\ntitle: Section 1\n---\nThis is section 1.', + ); await buildPostList(postDirectories, tempDir, writeFilePath); const output = JSON.parse(await fs.readFile(writeFilePath, 'utf-8')); - const sectionEntry = output.docs.find(item => item.title === 'Section 1'); + const sectionEntry = output.docs.find((item) => item.title === 'Section 1'); expect(sectionEntry).toMatchObject({ title: 'Section 1', slug: expect.stringContaining('/docs/section1'), - isSection: true + isSection: true, }); }); it('handles multiple release notes correctly', async () => { - await fs.writeFile(join(tempDir, 'blog', 'release-notes-2.1.1.mdx'), '---\ntitle: Release Notes 2.1.1\n---\nThis is a release note.'); + await fs.writeFile( + join(tempDir, 'blog', 'release-notes-2.1.1.mdx'), + '---\ntitle: Release Notes 2.1.1\n---\nThis is a release note.', + ); await buildPostList(postDirectories, tempDir, writeFilePath); const output = JSON.parse(await fs.readFile(writeFilePath, 'utf-8')); - const firstReleaseNote = output.blog.find(item => item.slug === '/blog/release-notes-2.1.0'); - const secondReleaseNote = output.blog.find(item => item.slug === '/blog/release-notes-2.1.1'); + const firstReleaseNote = output.blog.find( + (item) => item.slug === '/blog/release-notes-2.1.0', + ); + const secondReleaseNote = output.blog.find( + (item) => item.slug === '/blog/release-notes-2.1.1', + ); expect(firstReleaseNote).toBeDefined(); expect(firstReleaseNote.title).toBe('Release Notes 2.1.0'); @@ -129,65 +146,96 @@ describe('buildPostList', () => { it('throws an error when accessing non-existent directory', async () => { const invalidDir = [join(tempDir, 'non-existent-dir'), '/invalid']; - await expect(buildPostList([invalidDir], tempDir, writeFilePath)).rejects.toThrow(); + await expect( + buildPostList([invalidDir], tempDir, writeFilePath), + ).rejects.toThrow(); }); it('does not process specification files without a title', async () => { const specDir = join(tempDir, 'docs', 'reference', 'specification'); - await fs.writeFile(join(specDir, 'v2.1.0-no-title.mdx'), '---\n---\nContent of specification without a title.'); + await fs.writeFile( + join(specDir, 'v2.1.0-no-title.mdx'), + '---\n---\nContent of specification without a title.', + ); await buildPostList(postDirectories, tempDir, writeFilePath); const output = JSON.parse(await fs.readFile(writeFilePath, 'utf-8')); - const noTitleEntry = output.docs.find(item => item.slug.includes('/reference/specification/v2.1.0-no-title')); + const noTitleEntry = output.docs.find((item) => + item.slug.includes('/reference/specification/v2.1.0-no-title'), + ); expect(noTitleEntry).toBeUndefined(); }); it('does not process specification files with "next-spec" in the filename', async () => { const specDir = join(tempDir, 'docs', 'reference', 'specification'); - await fs.writeFile(join(specDir, 'v2.1.0-next-spec.1.mdx'), '---\n---\nContent of pre-release specification v2.1.0-next-spec.1.'); + await fs.writeFile( + join(specDir, 'v2.1.0-next-spec.1.mdx'), + '---\n---\nContent of pre-release specification v2.1.0-next-spec.1.', + ); await buildPostList(postDirectories, tempDir, writeFilePath); const output = JSON.parse(await fs.readFile(writeFilePath, 'utf-8')); - const nextSpecEntry = output.docs.find(item => item.slug.includes('/reference/specification/v2.1.0-next-spec.1')); + const nextSpecEntry = output.docs.find((item) => + item.slug.includes('/reference/specification/v2.1.0-next-spec.1'), + ); expect(nextSpecEntry).toBeUndefined(); }); it('does not process specification files with "explorer" in the filename', async () => { const specDir = join(tempDir, 'docs', 'reference', 'specification'); - await fs.writeFile(join(specDir, 'explorer.mdx'), '---\n---\nContent of explorer specification.'); + await fs.writeFile( + join(specDir, 'explorer.mdx'), + '---\n---\nContent of explorer specification.', + ); await buildPostList(postDirectories, tempDir, writeFilePath); const output = JSON.parse(await fs.readFile(writeFilePath, 'utf-8')); - const explorerEntry = output.docs.find(item => item.slug.includes('/reference/specification/explorer')); + const explorerEntry = output.docs.find((item) => + item.slug.includes('/reference/specification/explorer'), + ); expect(explorerEntry).toBeUndefined(); }); it('throws "Error while building post list" when front matter is invalid', async () => { - await fs.writeFile(join(tempDir, 'docs', 'invalid.mdx'), '---\ninvalid front matter\n---\nContent'); + await fs.writeFile( + join(tempDir, 'docs', 'invalid.mdx'), + '---\ninvalid front matter\n---\nContent', + ); - await expect(buildPostList(postDirectories, tempDir, writeFilePath)).rejects.toThrow(/Error while building post list/); + await expect( + buildPostList(postDirectories, tempDir, writeFilePath), + ).rejects.toThrow(/Error while building post list/); }); it('throws an error if no post directories are provided', async () => { - await expect(buildPostList([], tempDir, writeFilePath)).rejects.toThrow(/Error while building post list/); + await expect(buildPostList([], tempDir, writeFilePath)).rejects.toThrow( + /Error while building post list/, + ); }); it('throws specific error message when basePath parameter is undefined', async () => { - await expect(buildPostList(postDirectories, undefined, writeFilePath)).rejects.toThrow(/Error while building post list: basePath and writeFilePath are required/); + await expect( + buildPostList(postDirectories, undefined, writeFilePath), + ).rejects.toThrow( + /Error while building post list: basePath and writeFilePath are required/, + ); }); it('throws specific error message when writeFilePath parameter is undefined', async () => { - await expect(buildPostList(postDirectories, tempDir, undefined)).rejects.toThrow(/Error while building post list: basePath and writeFilePath are required/); + await expect( + buildPostList(postDirectories, tempDir, undefined), + ).rejects.toThrow( + /Error while building post list: basePath and writeFilePath are required/, + ); }); describe('slugifyToC', () => { - it('handles heading ids like {# myHeadingId}', () => { const input = '## My Heading {#custom-id}'; expect(slugifyToC(input)).toBe('custom-id'); From 45adee8401c45d82d162809cf58f88c38d1302b6 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Mon, 9 Dec 2024 12:05:34 +0530 Subject: [PATCH 31/48] added helper function for setup --- tests/build-post-list.test.js | 23 ++--------------------- tests/helper/buildPostListSetup.js | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 21 deletions(-) create mode 100644 tests/helper/buildPostListSetup.js diff --git a/tests/build-post-list.test.js b/tests/build-post-list.test.js index 0bfd6ab3aa5f..bc9439a431fa 100644 --- a/tests/build-post-list.test.js +++ b/tests/build-post-list.test.js @@ -1,6 +1,6 @@ const fs = require('fs-extra'); const { resolve, join } = require('path'); -const { TEST_CONTENT } = require('../tests/fixtures/buildPostListData'); +const { setupTestDirectories } = require('./helper/buildPostListSetup') const { buildPostList, slugifyToC } = require('../scripts/build-post-list'); describe('buildPostList', () => { @@ -20,27 +20,8 @@ describe('buildPostList', () => { [join(tempDir, 'about'), '/about'], ]; - await fs.ensureDir(join(tempDir, TEST_CONTENT.blog.dir)); - await fs.writeFile( - join(tempDir, TEST_CONTENT.blog.dir, TEST_CONTENT.blog.file), - TEST_CONTENT.blog.content, - ); - - await fs.ensureDir(join(tempDir, TEST_CONTENT.docs.dir)); - await fs.writeFile( - join(tempDir, TEST_CONTENT.docs.dir, TEST_CONTENT.docs.file), - TEST_CONTENT.docs.content, - ); + await setupTestDirectories(tempDir); - await fs.ensureDir( - join(tempDir, TEST_CONTENT.docs.dir, TEST_CONTENT.docs.subDir), - ); - - await fs.ensureDir(join(tempDir, TEST_CONTENT.about.dir)); - await fs.writeFile( - join(tempDir, TEST_CONTENT.about.dir, TEST_CONTENT.about.file), - TEST_CONTENT.about.content, - ); }); afterEach(async () => { diff --git a/tests/helper/buildPostListSetup.js b/tests/helper/buildPostListSetup.js new file mode 100644 index 000000000000..7e793a2e7b9e --- /dev/null +++ b/tests/helper/buildPostListSetup.js @@ -0,0 +1,17 @@ +const { TEST_CONTENT } = require("../fixtures/buildPostListData"); +const fs = require('fs-extra'); +const { join } = require("path") + +async function setupTestDirectories(tempDir) { + const dirs = ['blog', 'docs', 'about']; + for (const dir of dirs) { + await fs.ensureDir(join(tempDir, TEST_CONTENT[dir].dir)); + await fs.writeFile( + join(tempDir, TEST_CONTENT[dir].dir, TEST_CONTENT[dir].file), + TEST_CONTENT[dir].content + ); + } + await fs.ensureDir(join(tempDir, TEST_CONTENT.docs.dir, TEST_CONTENT.docs.subDir)); +} + +module.exports = { setupTestDirectories }; \ No newline at end of file From 4893712e7d0fa0f8e6582eab619c0e3cf9f121d2 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Tue, 10 Dec 2024 10:07:27 +0530 Subject: [PATCH 32/48] apply coderabbit suggestions --- tests/build-post-list.test.js | 17 +++++++++++------ tests/helper/buildPostListSetup.js | 11 +++++++++-- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/tests/build-post-list.test.js b/tests/build-post-list.test.js index bc9439a431fa..8683af0bdf7c 100644 --- a/tests/build-post-list.test.js +++ b/tests/build-post-list.test.js @@ -1,6 +1,6 @@ const fs = require('fs-extra'); const { resolve, join } = require('path'); -const { setupTestDirectories } = require('./helper/buildPostListSetup') +const { setupTestDirectories, generateTempDirPath } = require('./helper/buildPostListSetup') const { buildPostList, slugifyToC } = require('../scripts/build-post-list'); describe('buildPostList', () => { @@ -9,10 +9,7 @@ describe('buildPostList', () => { let postDirectories; beforeEach(async () => { - tempDir = resolve( - __dirname, - `test-config-${Date.now()}-${Math.random().toString(36).slice(2)}`, - ); + tempDir = generateTempDirPath(__dirname); writeFilePath = resolve(tempDir, 'posts.json'); postDirectories = [ [join(tempDir, 'blog'), '/blog'], @@ -28,12 +25,15 @@ describe('buildPostList', () => { await fs.remove(tempDir); }); - it('builds a post list and writes the result to a file', async () => { + it('writes the result to a file', async () => { await buildPostList(postDirectories, tempDir, writeFilePath); const outputExists = await fs.pathExists(writeFilePath); expect(outputExists).toBe(true); + }); + it('correctly structures docs entries', async () => { + await buildPostList(postDirectories, tempDir, writeFilePath); const output = JSON.parse(await fs.readFile(writeFilePath, 'utf-8')); expect(output.docs).toEqual( @@ -54,6 +54,11 @@ describe('buildPostList', () => { }), ]), ); + }); + + it('correctly structures blog entries', async () => { + await buildPostList(postDirectories, tempDir, writeFilePath); + const output = JSON.parse(await fs.readFile(writeFilePath, 'utf-8')); expect(output.blog).toEqual( expect.arrayContaining([ diff --git a/tests/helper/buildPostListSetup.js b/tests/helper/buildPostListSetup.js index 7e793a2e7b9e..d7ee2908ba5a 100644 --- a/tests/helper/buildPostListSetup.js +++ b/tests/helper/buildPostListSetup.js @@ -1,6 +1,6 @@ const { TEST_CONTENT } = require("../fixtures/buildPostListData"); const fs = require('fs-extra'); -const { join } = require("path") +const { join, resolve } = require("path") async function setupTestDirectories(tempDir) { const dirs = ['blog', 'docs', 'about']; @@ -14,4 +14,11 @@ async function setupTestDirectories(tempDir) { await fs.ensureDir(join(tempDir, TEST_CONTENT.docs.dir, TEST_CONTENT.docs.subDir)); } -module.exports = { setupTestDirectories }; \ No newline at end of file +function generateTempDirPath(baseDir) { + return resolve( + baseDir, + `test-config-${Date.now()}-${Math.random().toString(36).slice(2)}` + ); +} + +module.exports = { setupTestDirectories, generateTempDirPath }; \ No newline at end of file From 10d1b727ec412aa42c7b23b3d439ac0e8a0aa1b8 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Tue, 10 Dec 2024 10:22:52 +0530 Subject: [PATCH 33/48] apply coderabbit suggestion --- scripts/build-post-list.js | 23 ++++++++++++++--------- tests/build-post-list.test.js | 10 ++++++++++ 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index 9092bc20c960..df55aa6f515b 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -143,17 +143,22 @@ async function walkDirectories(directories, resultObj, basePath, sectionTitle, s } function slugifyToC(str) { - let slug - // Try to match heading ids like {# myHeadingId} - const headingIdMatch = str.match(/[\s]?\{\#([\w\d\-_]+)\}/) - if (headingIdMatch && headingIdMatch.length >= 2) { - slug = headingIdMatch[1] + let slug = ''; + + // Match heading IDs like {# myHeadingId} + const headingIdMatch = str.match(/[\s]?\{\#([\w\d\-_]+)\}/); + if (headingIdMatch && headingIdMatch[1].trim()) { + slug = headingIdMatch[1]; } else { - // Try to match heading ids like {} - const anchorTagMatch = str.match(/[\s]*= 2) slug = anchorTagMatch[1] + // Match heading IDs like {} + const anchorTagMatch = str.match(/[\s]* { it('handles empty strings', () => { expect(slugifyToC('')).toBe(''); }); + + it('returns empty string for malformed heading IDs', () => { + expect(slugifyToC('## Heading {#}')).toBe(''); + expect(slugifyToC('## Heading {# }')).toBe(''); + expect(slugifyToC('## Heading {}')).toBe(''); + }); + + it('handles mixed format heading IDs', () => { + expect(slugifyToC('## Heading {#id} {}')).toBe('id'); + }); }); }); From 89f7fbc0505af385044b51585aabe1b63c11f9d6 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sat, 14 Dec 2024 14:33:39 +0530 Subject: [PATCH 34/48] apply nitpicks --- scripts/build-post-list.js | 14 +++++++++----- tests/build-post-list.test.js | 22 ++++++++++++++++++---- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index df55aa6f515b..a2d5477f693a 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -29,7 +29,10 @@ async function buildPostList(postDirectories, basePath, writeFilePath) { try { if (!basePath || !writeFilePath) { - throw new Error('Error while building post list: basePath and writeFilePath are required'); + const missing = []; + if (!basePath) missing.push('basePath'); + if (!writeFilePath) missing.push('writeFilePath'); + throw new Error(`Error while building post list: ${missing.join(' and ')} ${missing.length > 1 ? 'are' : 'is'} required`); } if (postDirectories.length === 0) { @@ -57,7 +60,7 @@ async function walkDirectories(directories, resultObj, basePath, sectionTitle, s const fileName = posix.join(directory, file); const fileNameWithSection = posix.join(fileName, '_section.mdx') const normalizedSlug = posix.join('/', relative(basePath, fileName)) - const slug = normalizedSlug.replace(/\\/g,'/') + const slug = normalizedSlug.replace(/\\/g, '/') const slugElements = slug.split('/') if (await isDirectory(fileName)) { @@ -143,15 +146,16 @@ async function walkDirectories(directories, resultObj, basePath, sectionTitle, s } function slugifyToC(str) { + if (typeof str !== 'string') return ''; let slug = ''; // Match heading IDs like {# myHeadingId} - const headingIdMatch = str.match(/[\s]?\{\#([\w\d\-_]+)\}/); + const headingIdMatch = str.match(/[\s]*\{#([a-zA-Z0-9\-_]+)\}/); if (headingIdMatch && headingIdMatch[1].trim()) { slug = headingIdMatch[1]; } else { // Match heading IDs like {} - const anchorTagMatch = str.match(/[\s]* `${word[0].toUpperCase()}${word.substr(1)}`).join(' ') + return text.replace(/(?:^|\s|-)([a-z])/g, (_, char) => char.toUpperCase()) } module.exports = { slugifyToC, buildPostList } diff --git a/tests/build-post-list.test.js b/tests/build-post-list.test.js index 29817c275e56..e35ea489e153 100644 --- a/tests/build-post-list.test.js +++ b/tests/build-post-list.test.js @@ -25,11 +25,14 @@ describe('buildPostList', () => { await fs.remove(tempDir); }); - it('writes the result to a file', async () => { + it('writes a valid JSON file with the expected structure', async () => { await buildPostList(postDirectories, tempDir, writeFilePath); const outputExists = await fs.pathExists(writeFilePath); expect(outputExists).toBe(true); + + const content = await fs.readFile(writeFilePath, 'utf-8'); + expect(() => JSON.parse(content)).not.toThrow(); }); it('correctly structures docs entries', async () => { @@ -134,7 +137,7 @@ describe('buildPostList', () => { const invalidDir = [join(tempDir, 'non-existent-dir'), '/invalid']; await expect( buildPostList([invalidDir], tempDir, writeFilePath), - ).rejects.toThrow(); + ).rejects.toThrow(/Error while building post list: ENOENT/); }); it('does not process specification files without a title', async () => { @@ -209,7 +212,7 @@ describe('buildPostList', () => { await expect( buildPostList(postDirectories, undefined, writeFilePath), ).rejects.toThrow( - /Error while building post list: basePath and writeFilePath are required/, + "Error while building post list: Error while building post list: basePath is required", ); }); @@ -217,7 +220,7 @@ describe('buildPostList', () => { await expect( buildPostList(postDirectories, tempDir, undefined), ).rejects.toThrow( - /Error while building post list: basePath and writeFilePath are required/, + "Error while building post list: Error while building post list: writeFilePath is required", ); }); @@ -245,5 +248,16 @@ describe('buildPostList', () => { it('handles mixed format heading IDs', () => { expect(slugifyToC('## Heading {#id} {}')).toBe('id'); }); + + it('handles invalid input types gracefully', () => { + expect(slugifyToC(null)).toBe(''); + expect(slugifyToC(undefined)).toBe(''); + expect(slugifyToC(123)).toBe(''); + }); + + it('ignores invalid characters in heading IDs', () => { + expect(slugifyToC('## Heading {#invalid@id}')).toBe(''); + expect(slugifyToC('## Heading {#invalid spaces}')).toBe(''); + }); }); }); From ccc22cb94eeb9b0eb486021ac5215f82825c5223 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sat, 14 Dec 2024 20:56:35 +0530 Subject: [PATCH 35/48] apply nitpicks --- scripts/build-post-list.js | 9 ++++----- tests/build-post-list.test.js | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index a2d5477f693a..70ac6e72bf8a 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -32,7 +32,7 @@ async function buildPostList(postDirectories, basePath, writeFilePath) { const missing = []; if (!basePath) missing.push('basePath'); if (!writeFilePath) missing.push('writeFilePath'); - throw new Error(`Error while building post list: ${missing.join(' and ')} ${missing.length > 1 ? 'are' : 'is'} required`); + throw new Error(`${missing.join(' and ')} ${missing.length > 1 ? 'are' : 'is'} required`); } if (postDirectories.length === 0) { @@ -57,10 +57,9 @@ async function walkDirectories(directories, resultObj, basePath, sectionTitle, s for (let file of files) { let details; - const fileName = posix.join(directory, file); - const fileNameWithSection = posix.join(fileName, '_section.mdx') - const normalizedSlug = posix.join('/', relative(basePath, fileName)) - const slug = normalizedSlug.replace(/\\/g, '/') + const fileName = normalize(join(directory, file)); + const fileNameWithSection = normalize(join(fileName, '_section.mdx')) + const slug = '/' + normalize(relative(basePath, fileName)).replace(/\\/g, '/') const slugElements = slug.split('/') if (await isDirectory(fileName)) { diff --git a/tests/build-post-list.test.js b/tests/build-post-list.test.js index e35ea489e153..702d7b27f554 100644 --- a/tests/build-post-list.test.js +++ b/tests/build-post-list.test.js @@ -212,7 +212,7 @@ describe('buildPostList', () => { await expect( buildPostList(postDirectories, undefined, writeFilePath), ).rejects.toThrow( - "Error while building post list: Error while building post list: basePath is required", + "Error while building post list: basePath is required", ); }); @@ -220,7 +220,7 @@ describe('buildPostList', () => { await expect( buildPostList(postDirectories, tempDir, undefined), ).rejects.toThrow( - "Error while building post list: Error while building post list: writeFilePath is required", + "Error while building post list: writeFilePath is required", ); }); From c951b9157ba54522474891062ccc68a6fb3f6f23 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sat, 14 Dec 2024 20:58:10 +0530 Subject: [PATCH 36/48] apply nitpick 2 --- tests/build-post-list.test.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/build-post-list.test.js b/tests/build-post-list.test.js index 702d7b27f554..fe0c8f8be5de 100644 --- a/tests/build-post-list.test.js +++ b/tests/build-post-list.test.js @@ -25,14 +25,16 @@ describe('buildPostList', () => { await fs.remove(tempDir); }); - it('writes a valid JSON file with the expected structure', async () => { + it('writes the file successfully', async () => { await buildPostList(postDirectories, tempDir, writeFilePath); - const outputExists = await fs.pathExists(writeFilePath); expect(outputExists).toBe(true); - - const content = await fs.readFile(writeFilePath, 'utf-8'); - expect(() => JSON.parse(content)).not.toThrow(); + }); + + it('writes valid JSON content', async () => { + await buildPostList(postDirectories, tempDir, writeFilePath); + const content = await fs.readFile(writeFilePath, 'utf-8'); + expect(() => JSON.parse(content)).not.toThrow(); }); it('correctly structures docs entries', async () => { From 8ffb9b97a67a2f43d0fc478b1369bfc64a37c28b Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sat, 14 Dec 2024 21:10:41 +0530 Subject: [PATCH 37/48] apply nitpicks 3 --- scripts/build-post-list.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index 70ac6e72bf8a..d716a32b4542 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -25,6 +25,14 @@ const addItem = (details) => { result["about"].push(details) }; +/** + * Builds a list of posts from the specified directories and writes it to a file + * @param {Array>} postDirectories - Array of [directory, slug] tuples + * @param {string} basePath - Base path for resolving relative paths + * @param {string} writeFilePath - Path where the output JSON will be written + * @throws {Error} If required parameters are missing or if any operation fails + * @returns {Promise} + */ async function buildPostList(postDirectories, basePath, writeFilePath) { try { @@ -144,6 +152,11 @@ async function walkDirectories(directories, resultObj, basePath, sectionTitle, s } } +/** + * Extracts heading IDs from markdown headings + * @param {string} str - The heading text containing potential ID + * @returns {string} The extracted ID or empty string if no valid ID found + */ function slugifyToC(str) { if (typeof str !== 'string') return ''; let slug = ''; From 893ac66181b6b1c787c1efdb5760af45b5c7a571 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Mon, 16 Dec 2024 19:06:38 +0530 Subject: [PATCH 38/48] apply nitpicks --- scripts/build-post-list.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index d716a32b4542..062d304e63af 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -40,7 +40,7 @@ async function buildPostList(postDirectories, basePath, writeFilePath) { const missing = []; if (!basePath) missing.push('basePath'); if (!writeFilePath) missing.push('writeFilePath'); - throw new Error(`${missing.join(' and ')} ${missing.length > 1 ? 'are' : 'is'} required`); + throw new Error(`Error while building post list: ${missing.join(' and ')} ${missing.length > 1 ? 'are' : 'is'} required`); } if (postDirectories.length === 0) { @@ -57,7 +57,15 @@ async function buildPostList(postDirectories, basePath, writeFilePath) { } } -async function walkDirectories(directories, resultObj, basePath, sectionTitle, sectionId, rootSectionId, sectionWeight = 0) { +async function walkDirectories( + directories, + resultObj, + basePath, + sectionTitle, + sectionId, + rootSectionId, + sectionWeight = 0 +) { for (let dir of directories) { let directory = posix.normalize(dir[0]); let sectionSlug = dir[1] || ''; @@ -163,12 +171,12 @@ function slugifyToC(str) { // Match heading IDs like {# myHeadingId} const headingIdMatch = str.match(/[\s]*\{#([a-zA-Z0-9\-_]+)\}/); - if (headingIdMatch && headingIdMatch[1].trim()) { + if (headingIdMatch?.[1]?.trim()) { slug = headingIdMatch[1]; } else { // Match heading IDs like {} const anchorTagMatch = str.match(/[\s]* Date: Mon, 16 Dec 2024 19:21:25 +0530 Subject: [PATCH 39/48] apply nitpicks 2 --- scripts/build-post-list.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index 062d304e63af..bfe371082782 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -18,11 +18,11 @@ const releaseNotes = [] const addItem = (details) => { if (details.slug.startsWith('/docs')) - result["docs"].push(details) + result.docs.push(details) else if (details.slug.startsWith('/blog')) - result["blog"].push(details) + result.blog.push(details) else if (details.slug.startsWith('/about')) - result["about"].push(details) + result.about.push(details) }; /** From 778b257bafcb04c3c22a081d7f6fdf120619d4dd Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Mon, 16 Dec 2024 19:27:30 +0530 Subject: [PATCH 40/48] apply nitpicks 3 --- scripts/build-post-list.js | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index bfe371082782..d87b7e13d99b 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -48,9 +48,9 @@ async function buildPostList(postDirectories, basePath, writeFilePath) { } const normalizedBasePath = normalize(basePath) await walkDirectories(postDirectories, result, normalizedBasePath) - const treePosts = buildNavTree(result["docs"].filter((p) => p.slug.startsWith('/docs/'))) - result["docsTree"] = treePosts - result["docs"] = addDocButtons(result["docs"], treePosts) + const treePosts = buildNavTree(result.docs.filter((p) => p.slug.startsWith('/docs/'))) + result.docsTree = treePosts + result.docs = addDocButtons(result.docs, treePosts) await writeFile(writeFilePath, JSON.stringify(result, null, ' ')) } catch (error) { throw new Error(`Error while building post list: ${error.message}`, { cause: error }); @@ -67,9 +67,9 @@ async function walkDirectories( sectionWeight = 0 ) { for (let dir of directories) { - let directory = posix.normalize(dir[0]); - let sectionSlug = dir[1] || ''; - let files = await readdir(directory) + const directory = posix.normalize(dir[0]); + const sectionSlug = dir[1] || ''; + const files = await readdir(directory) for (let file of files) { let details; @@ -171,13 +171,15 @@ function slugifyToC(str) { // Match heading IDs like {# myHeadingId} const headingIdMatch = str.match(/[\s]*\{#([a-zA-Z0-9\-_]+)\}/); - if (headingIdMatch?.[1]?.trim()) { - slug = headingIdMatch[1]; + const [, headingId] = headingIdMatch || []; + if (headingId?.trim()) { + slug = headingId; } else { // Match heading IDs like {} const anchorTagMatch = str.match(/[\s]* Date: Tue, 17 Dec 2024 19:04:54 +0530 Subject: [PATCH 41/48] apply nitpicks --- scripts/build-post-list.js | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index d87b7e13d99b..a6cb61781015 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -37,10 +37,11 @@ async function buildPostList(postDirectories, basePath, writeFilePath) { try { if (!basePath || !writeFilePath) { - const missing = []; - if (!basePath) missing.push('basePath'); - if (!writeFilePath) missing.push('writeFilePath'); - throw new Error(`Error while building post list: ${missing.join(' and ')} ${missing.length > 1 ? 'are' : 'is'} required`); + const missing = [ + !basePath && 'basePath', + !writeFilePath && 'writeFilePath' + ].filter(Boolean); + throw new Error(`Error while building post list: ${missing.join(' and ')} ${missing.length > 1 ? 'are' : 'is'} required`); } if (postDirectories.length === 0) { @@ -69,7 +70,10 @@ async function walkDirectories( for (let dir of directories) { const directory = posix.normalize(dir[0]); const sectionSlug = dir[1] || ''; - const files = await readdir(directory) + const files = await Promise.all([ + readdir(directory), + pathExists(directory) + ]).then(([files]) => files) for (let file of files) { let details; @@ -170,18 +174,9 @@ function slugifyToC(str) { let slug = ''; // Match heading IDs like {# myHeadingId} - const headingIdMatch = str.match(/[\s]*\{#([a-zA-Z0-9\-_]+)\}/); - const [, headingId] = headingIdMatch || []; - if (headingId?.trim()) { - slug = headingId; - } else { - // Match heading IDs like {} - const anchorTagMatch = str.match(/[\s]* Date: Tue, 17 Dec 2024 19:19:21 +0530 Subject: [PATCH 42/48] apply nitpicks again --- scripts/build-post-list.js | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index a6cb61781015..10ade062dc40 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -2,7 +2,6 @@ const { readdir, stat, pathExists, readFile, writeFile } = require('fs-extra') const { basename, join, normalize, sep, posix, relative, extname } = require('path') const frontMatter = require('gray-matter') const toc = require('markdown-toc') -const { slugify } = require('markdown-toc/lib/utils') const readingTime = require('reading-time') const { markdownToTxt } = require('markdown-to-txt') const { buildNavTree, addDocButtons } = require('./build-docs') @@ -36,12 +35,11 @@ const addItem = (details) => { async function buildPostList(postDirectories, basePath, writeFilePath) { try { - if (!basePath || !writeFilePath) { - const missing = [ - !basePath && 'basePath', - !writeFilePath && 'writeFilePath' - ].filter(Boolean); - throw new Error(`Error while building post list: ${missing.join(' and ')} ${missing.length > 1 ? 'are' : 'is'} required`); + if (!basePath) { + throw new Error('Error while building post list: basePath is required'); + } + if (!writeFilePath) { + throw new Error('Error while building post list: writeFilePath is required'); } if (postDirectories.length === 0) { @@ -73,7 +71,7 @@ async function walkDirectories( const files = await Promise.all([ readdir(directory), pathExists(directory) - ]).then(([files]) => files) + ]).then(([files]) => files) for (let file of files) { let details; @@ -148,14 +146,9 @@ async function walkDirectories( } // To create a list of available ReleaseNotes list, which will be used to add details.releaseNoteLink attribute. - if (file.startsWith("release-notes") && dir[1] === "/blog") { - const fileNameWithoutExtension = basename(file, extname(file)) - // removes the file extension. For example, release-notes-2.1.0.md -> release-notes-2.1.0 - const version = fileNameWithoutExtension.slice(fileNameWithoutExtension.lastIndexOf("-") + 1) - - // gets the version from the name of the releaseNote .md file (from /blog). For example, version = 2.1.0 if fileNameWithoutExtension = release-notes-2.1.0 - releaseNotes.push(version) - // releaseNotes is the list of all available releaseNotes + if (file.startsWith('release-notes') && dir[1] === '/blog') { + const version = basename(file, extname(file)).split('-').pop(); + releaseNotes.push(version); } addItem(details) @@ -164,6 +157,8 @@ async function walkDirectories( } } +const HEADING_ID_REGEX = /[\s]*(?:\{#([a-zA-Z0-9\-_]+)\}| Date: Tue, 17 Dec 2024 19:38:08 +0530 Subject: [PATCH 43/48] apply nitpicks --- scripts/build-post-list.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index 10ade062dc40..90298401d96f 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -183,7 +183,9 @@ async function isDirectory(dir) { } function capitalize(text) { - return text.replace(/(?:^|\s|-)([a-z])/g, (_, char) => char.toUpperCase()) + return text.split(/[\s-]/) + .map(word => word.charAt(0).toUpperCase() + word.slice(1)) + .join(' '); } module.exports = { slugifyToC, buildPostList } From b47cb4b9849dd9a6a7cfa97f4cce7900ade8b698 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Tue, 17 Dec 2024 19:48:52 +0530 Subject: [PATCH 44/48] apply nitpicks once again --- scripts/build-post-list.js | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index 90298401d96f..ebd0cb572213 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -24,6 +24,17 @@ const addItem = (details) => { result.about.push(details) }; +function getVersionDetails(slug) { + const fileBaseName = basename(slug); + const versionName = fileBaseName.split('-')[0]; + return { + title: versionName.startsWith('v') ? + capitalize(versionName.slice(1)) : + capitalize(versionName), + weight: specWeight-- + }; + } + /** * Builds a list of posts from the specified directories and writes it to a file * @param {Array>} postDirectories - Array of [directory, slug] tuples @@ -36,14 +47,14 @@ async function buildPostList(postDirectories, basePath, writeFilePath) { try { if (!basePath) { - throw new Error('Error while building post list: basePath is required'); + throw new Error('Error while building post list: basePath is required. Please provide a valid base path for resolving relative paths.'); } if (!writeFilePath) { - throw new Error('Error while building post list: writeFilePath is required'); + throw new Error('Error while building post list: writeFilePath is required. Please provide a valid path where the output JSON will be written.'); } if (postDirectories.length === 0) { - throw new Error('Error while building post list: No post directories provided'); + throw new Error('Error while building post list: No post directories provided. Please provide an array of [directory, slug] tuples.'); } const normalizedBasePath = normalize(basePath) await walkDirectories(postDirectories, result, normalizedBasePath) @@ -121,15 +132,10 @@ async function walkDirectories( details.isIndex = fileName.endsWith(join('index.mdx')) details.slug = details.isIndex ? sectionSlug : slug.replace(/\.mdx$/, '') if (details.slug.includes('/reference/specification/') && !details.title) { - const fileBaseName = basename(details.slug) // ex. v2.0.0 | v2.1.0-next-spec.1 - const versionName = fileBaseName.split('-')[0] // v2.0.0 | v2.1.0 - details.weight = specWeight-- - - if (versionName.startsWith('v')) { - details.title = capitalize(versionName.slice(1)) - } else { - details.title = capitalize(versionName) - } + const fileBaseName = basename(details.slug) + const versionDetails = getVersionDetails(details.slug); + details.title = versionDetails.title; + details.weight = versionDetails.weight; if (releaseNotes.includes(details.title)) { details.releaseNoteLink = `/blog/release-notes-${details.title}` @@ -157,6 +163,9 @@ async function walkDirectories( } } +// Matches heading IDs in two formats: +// 1. {#my-heading-id} +// 2. const HEADING_ID_REGEX = /[\s]*(?:\{#([a-zA-Z0-9\-_]+)\}| Date: Wed, 18 Dec 2024 11:32:41 +0530 Subject: [PATCH 45/48] apply nitpicks --- scripts/build-post-list.js | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index ebd0cb572213..a683e1c25cf7 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -1,5 +1,5 @@ const { readdir, stat, pathExists, readFile, writeFile } = require('fs-extra') -const { basename, join, normalize, sep, posix, relative, extname } = require('path') +const { basename, join, normalize, sep, posix, relative, parse } = require('path') const frontMatter = require('gray-matter') const toc = require('markdown-toc') const readingTime = require('reading-time') @@ -25,15 +25,15 @@ const addItem = (details) => { }; function getVersionDetails(slug) { - const fileBaseName = basename(slug); - const versionName = fileBaseName.split('-')[0]; - return { - title: versionName.startsWith('v') ? - capitalize(versionName.slice(1)) : - capitalize(versionName), - weight: specWeight-- - }; - } + const fileBaseName = basename(slug); + const versionName = fileBaseName.split('-')[0]; + return { + title: versionName.startsWith('v') ? + capitalize(versionName.slice(1)) : + capitalize(versionName), + weight: specWeight-- + }; +} /** * Builds a list of posts from the specified directories and writes it to a file @@ -79,10 +79,7 @@ async function walkDirectories( for (let dir of directories) { const directory = posix.normalize(dir[0]); const sectionSlug = dir[1] || ''; - const files = await Promise.all([ - readdir(directory), - pathExists(directory) - ]).then(([files]) => files) + const files = await readdir(directory) for (let file of files) { let details; @@ -153,7 +150,8 @@ async function walkDirectories( // To create a list of available ReleaseNotes list, which will be used to add details.releaseNoteLink attribute. if (file.startsWith('release-notes') && dir[1] === '/blog') { - const version = basename(file, extname(file)).split('-').pop(); + const { name } = parse(file); + const version = name.split('-').pop(); releaseNotes.push(version); } From a795ce0cf7221628d74bc195278f9a4b8109fab7 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Wed, 18 Dec 2024 11:44:56 +0530 Subject: [PATCH 46/48] apply nitpicks --- scripts/build-post-list.js | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index a683e1c25cf7..8cba75c33af9 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -16,12 +16,15 @@ const result = { const releaseNotes = [] const addItem = (details) => { - if (details.slug.startsWith('/docs')) - result.docs.push(details) - else if (details.slug.startsWith('/blog')) - result.blog.push(details) - else if (details.slug.startsWith('/about')) - result.about.push(details) + const sectionMap = { + '/docs': 'docs', + '/blog': 'blog', + '/about': 'about' + }; + const section = Object.keys(sectionMap).find(key => details.slug.startsWith(key)); + if (section) { + result[sectionMap[section]].push(details); + } }; function getVersionDetails(slug) { @@ -47,14 +50,15 @@ async function buildPostList(postDirectories, basePath, writeFilePath) { try { if (!basePath) { - throw new Error('Error while building post list: basePath is required. Please provide a valid base path for resolving relative paths.'); + throw new Error('Error while building post list: basePath is required'); } + if (!writeFilePath) { - throw new Error('Error while building post list: writeFilePath is required. Please provide a valid path where the output JSON will be written.'); + throw new Error('Error while building post list: writeFilePath is required'); } if (postDirectories.length === 0) { - throw new Error('Error while building post list: No post directories provided. Please provide an array of [directory, slug] tuples.'); + throw new Error('Error while building post list: postDirectories array is empty'); } const normalizedBasePath = normalize(basePath) await walkDirectories(postDirectories, result, normalizedBasePath) @@ -85,7 +89,7 @@ async function walkDirectories( let details; const fileName = normalize(join(directory, file)); const fileNameWithSection = normalize(join(fileName, '_section.mdx')) - const slug = '/' + normalize(relative(basePath, fileName)).replace(/\\/g, '/') + const slug = `/${normalize(relative(basePath, fileName)).replace(/\\/g, '/')}` const slugElements = slug.split('/') if (await isDirectory(fileName)) { From 8f00a15fe2630e970179ac8a0dc159eb6a66d10c Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Wed, 18 Dec 2024 11:55:28 +0530 Subject: [PATCH 47/48] apply actionable commet --- scripts/build-post-list.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index 8cba75c33af9..33acdaad9bad 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -27,14 +27,14 @@ const addItem = (details) => { } }; -function getVersionDetails(slug) { +function getVersionDetails(slug, weight) { const fileBaseName = basename(slug); const versionName = fileBaseName.split('-')[0]; return { - title: versionName.startsWith('v') ? - capitalize(versionName.slice(1)) : - capitalize(versionName), - weight: specWeight-- + title: versionName.startsWith('v') + ? capitalize(versionName.slice(1)) + : capitalize(versionName), + weight }; } @@ -134,7 +134,7 @@ async function walkDirectories( details.slug = details.isIndex ? sectionSlug : slug.replace(/\.mdx$/, '') if (details.slug.includes('/reference/specification/') && !details.title) { const fileBaseName = basename(details.slug) - const versionDetails = getVersionDetails(details.slug); + const versionDetails = getVersionDetails(details.slug, specWeight--); details.title = versionDetails.title; details.weight = versionDetails.weight; From f5023ed1bbcdc3a056b2824d35b7a789b28f4c8a Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Wed, 25 Dec 2024 10:36:53 +0530 Subject: [PATCH 48/48] update tests --- scripts/build-post-list.js | 25 ++++++++++++++++--------- tests/build-post-list.test.js | 9 ++++++++- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/scripts/build-post-list.js b/scripts/build-post-list.js index 33acdaad9bad..44b7273c2106 100644 --- a/scripts/build-post-list.js +++ b/scripts/build-post-list.js @@ -16,6 +16,9 @@ const result = { const releaseNotes = [] const addItem = (details) => { + if (!details || typeof details.slug !== 'string') { + throw new Error('Invalid details object provided to addItem'); + } const sectionMap = { '/docs': 'docs', '/blog': 'blog', @@ -71,6 +74,17 @@ async function buildPostList(postDirectories, basePath, writeFilePath) { } } +function handleSpecificationVersion(details, fileBaseName) { + if (fileBaseName.includes('next-spec') || fileBaseName.includes('next-major-spec')) { + details.isPrerelease = true; + details.title += " (Pre-release)"; + } + if (fileBaseName.includes('explorer')) { + details.title += " - Explorer"; + } + return details; +} + async function walkDirectories( directories, resultObj, @@ -142,14 +156,7 @@ async function walkDirectories( details.releaseNoteLink = `/blog/release-notes-${details.title}` } - if (fileBaseName.includes('next-spec') || fileBaseName.includes('next-major-spec')) { - details.isPrerelease = true - // this need to be separate because the `-` in "Pre-release" will get removed by `capitalize()` function - details.title += " (Pre-release)" - } - if (fileBaseName.includes('explorer')) { - details.title += " - Explorer" - } + details = handleSpecificationVersion(details, fileBaseName); } // To create a list of available ReleaseNotes list, which will be used to add details.releaseNoteLink attribute. @@ -199,4 +206,4 @@ function capitalize(text) { .join(' '); } -module.exports = { slugifyToC, buildPostList } +module.exports = { slugifyToC, buildPostList, addItem } diff --git a/tests/build-post-list.test.js b/tests/build-post-list.test.js index fe0c8f8be5de..388364a447ab 100644 --- a/tests/build-post-list.test.js +++ b/tests/build-post-list.test.js @@ -1,7 +1,7 @@ const fs = require('fs-extra'); const { resolve, join } = require('path'); const { setupTestDirectories, generateTempDirPath } = require('./helper/buildPostListSetup') -const { buildPostList, slugifyToC } = require('../scripts/build-post-list'); +const { buildPostList, slugifyToC, addItem } = require('../scripts/build-post-list'); describe('buildPostList', () => { let tempDir; @@ -226,6 +226,13 @@ describe('buildPostList', () => { ); }); + it('throws an error when details object is invalid', () => { + expect(() => addItem(null)).toThrow('Invalid details object provided to addItem'); + expect(() => addItem({})).toThrow('Invalid details object provided to addItem'); + expect(() => addItem({ slug: 123 })).toThrow('Invalid details object provided to addItem'); + expect(() => addItem(undefined)).toThrow('Invalid details object provided to addItem'); + }); + describe('slugifyToC', () => { it('handles heading ids like {# myHeadingId}', () => { const input = '## My Heading {#custom-id}';