Added new "Bugs" group to release notes system for documenting
bug fixes and troubleshooting guides.
Changes:
- Added "Bugs & Fixes" group to _index.json (order: 4)
- Added "webpack-module-resolution" category under bugs group
- Created comprehensive MDX documentation for webpack fix
- Updated TypeScript types to include 'bugs' as valid group
- Updated sort order in getAllReleases() function
- Updated getReleasesGrouped() to include bugs filter
- Updated sidebar to expand bugs group by default
Content:
- Detailed webpack module resolution bug documentation
- Root cause analysis with technical explanation
- Solution implementation with code examples
- Prevention best practices
- Quick reference troubleshooting table
- Related issues and future improvements
Structure:
Group: Bugs & Fixes (order: 4)
└── Webpack Module Resolution (order: 10)
- Error: Cannot read properties of undefined (reading 'call')
- Fix: Wrapper component pattern
- Status: Completed
- Version: 0.2.1
This creates a dedicated space for documenting production issues,
their solutions, and lessons learned for future reference.
123 lines
3.0 KiB
TypeScript
123 lines
3.0 KiB
TypeScript
/**
|
|
* Release Notes MDX Utilities
|
|
*
|
|
* Functions for loading and parsing release note MDX files
|
|
*/
|
|
|
|
import fs from 'fs'
|
|
import path from 'path'
|
|
import matter from 'gray-matter'
|
|
|
|
const RELEASES_DIR = path.join(process.cwd(), 'content/nl/releases')
|
|
|
|
export interface ReleaseFrontmatter {
|
|
title: string
|
|
category: string
|
|
group: 'foundation' | 'features' | 'infrastructure' | 'bugs'
|
|
version: string
|
|
releaseDate: string
|
|
status: 'completed' | 'in_progress' | 'planned'
|
|
description: string
|
|
}
|
|
|
|
export interface ReleaseNote {
|
|
slug: string
|
|
frontmatter: ReleaseFrontmatter
|
|
content: string
|
|
}
|
|
|
|
/**
|
|
* Get all release note files
|
|
*/
|
|
export async function getAllReleases(): Promise<ReleaseNote[]> {
|
|
const files = fs.readdirSync(RELEASES_DIR)
|
|
|
|
const releases = files
|
|
.filter(file => file.endsWith('.mdx') && !file.startsWith('_'))
|
|
.map(file => {
|
|
const slug = file.replace('.mdx', '')
|
|
const filePath = path.join(RELEASES_DIR, file)
|
|
const fileContent = fs.readFileSync(filePath, 'utf-8')
|
|
const { data, content } = matter(fileContent)
|
|
|
|
return {
|
|
slug,
|
|
frontmatter: data as ReleaseFrontmatter,
|
|
content,
|
|
}
|
|
})
|
|
|
|
// Sort by group order and then by category
|
|
return releases.sort((a, b) => {
|
|
const groupOrder = { foundation: 1, features: 2, infrastructure: 3, bugs: 4 }
|
|
const aOrder = groupOrder[a.frontmatter.group]
|
|
const bOrder = groupOrder[b.frontmatter.group]
|
|
|
|
if (aOrder !== bOrder) return aOrder - bOrder
|
|
return a.frontmatter.category.localeCompare(b.frontmatter.category)
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Get a single release by slug
|
|
*/
|
|
export async function getRelease(slug: string): Promise<ReleaseNote | null> {
|
|
const filePath = path.join(RELEASES_DIR, `${slug}.mdx`)
|
|
|
|
if (!fs.existsSync(filePath)) {
|
|
return null
|
|
}
|
|
|
|
const fileContent = fs.readFileSync(filePath, 'utf-8')
|
|
const { data, content } = matter(fileContent)
|
|
|
|
return {
|
|
slug,
|
|
frontmatter: data as ReleaseFrontmatter,
|
|
content,
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get releases grouped by their group (foundation, features, infrastructure, bugs)
|
|
*/
|
|
export async function getReleasesGrouped() {
|
|
const releases = await getAllReleases()
|
|
|
|
return {
|
|
foundation: releases.filter(r => r.frontmatter.group === 'foundation'),
|
|
features: releases.filter(r => r.frontmatter.group === 'features'),
|
|
infrastructure: releases.filter(r => r.frontmatter.group === 'infrastructure'),
|
|
bugs: releases.filter(r => r.frontmatter.group === 'bugs'),
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get category metadata from index file
|
|
*/
|
|
export interface CategoryMetadata {
|
|
slug: string
|
|
title: string
|
|
group: string
|
|
description: string
|
|
order: number
|
|
}
|
|
|
|
export interface GroupMetadata {
|
|
id: string
|
|
title: string
|
|
description: string
|
|
order: number
|
|
}
|
|
|
|
interface IndexData {
|
|
groups: GroupMetadata[]
|
|
categories: CategoryMetadata[]
|
|
}
|
|
|
|
export async function getCategoryMetadata(): Promise<IndexData> {
|
|
const indexPath = path.join(RELEASES_DIR, '_index.json')
|
|
const indexContent = fs.readFileSync(indexPath, 'utf-8')
|
|
return JSON.parse(indexContent)
|
|
}
|