-
Notifications
You must be signed in to change notification settings - Fork 0
feat: modules page #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,151 @@ | ||
| #!/usr/bin/env node | ||
|
|
||
| // Purpose: Enhances the modules.json with filesystem content structure | ||
| // for both auto-generated and human-written documentation | ||
|
|
||
| const fs = require('fs'); | ||
| const path = require('path'); | ||
|
|
||
| // Get paths from environment or use defaults | ||
| const DOCS_VERSION_DIR = process.env.DOCS_VERSION_DIR || path.join(__dirname, '../../../website/src/content/docs/main'); | ||
| const OUTPUT_DIR = path.join(DOCS_VERSION_DIR, 'modules'); | ||
| const MODULES_JSON_PATH = path.join(DOCS_VERSION_DIR, 'modules.json'); | ||
|
|
||
| // Read the existing modules.json generated by the bash script | ||
| function readExistingModulesJson() { | ||
| try { | ||
| const content = fs.readFileSync(MODULES_JSON_PATH, 'utf8'); | ||
| return JSON.parse(content); | ||
| } catch (error) { | ||
| console.error('Error reading modules.json:', error); | ||
| return { modules: [] }; | ||
| } | ||
| } | ||
|
|
||
| // Scan a module directory for manual documentation files | ||
| function scanModuleDirectory(moduleDir, moduleName) { | ||
| const content = { reference: null, guides: [], examples: [] }; | ||
|
|
||
| if (!fs.existsSync(moduleDir)) { | ||
| return content; | ||
| } | ||
|
|
||
| const items = fs.readdirSync(moduleDir, { withFileTypes: true }); | ||
|
|
||
| for (const item of items) { | ||
| if (item.name === 'reference' && item.isDirectory()) { | ||
| // Reference docs are auto-generated, just mark as present | ||
| content.reference = { path: '/reference', text: 'Reference' }; | ||
| } else if (item.isFile() && item.name.endsWith('.mdx') && item.name !== 'index.mdx') { | ||
| // Human-written guides at the module root level | ||
| const baseName = path.basename(item.name, '.mdx'); | ||
| const title = formatTitle(baseName); | ||
| content.guides.push({ | ||
| path: `/${baseName}`, | ||
| text: title, | ||
| file: item.name | ||
| }); | ||
| } else if (item.isDirectory() && item.name === 'examples') { | ||
| // Examples subdirectory | ||
| const examplesDir = path.join(moduleDir, 'examples'); | ||
| const exampleFiles = fs.readdirSync(examplesDir, { withFileTypes: true }) | ||
| .filter(file => file.isFile() && file.name.endsWith('.mdx')) | ||
| .map(file => { | ||
| const baseName = path.basename(file.name, '.mdx'); | ||
| const title = formatTitle(baseName); | ||
| return { | ||
| path: `/examples/${baseName}`, | ||
| text: title, | ||
| file: file.name | ||
| }; | ||
| }); | ||
|
|
||
| if (exampleFiles.length > 0) { | ||
| content.examples = exampleFiles; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return content; | ||
| } | ||
|
|
||
| // Convert kebab-case to Title Case | ||
| function formatTitle(str) { | ||
| return str | ||
| .split('-') | ||
| .map(word => word.charAt(0).toUpperCase() + word.slice(1)) | ||
| .join(' '); | ||
| } | ||
|
|
||
| // Build the enhanced module structure | ||
| function buildEnhancedModuleStructure(module) { | ||
| const moduleDir = path.join(OUTPUT_DIR, module.module); | ||
| const content = scanModuleDirectory(moduleDir, module.module); | ||
|
|
||
| // Build the sub-navigation structure | ||
| const sub = []; | ||
|
|
||
| // Always add reference first if it exists | ||
| if (content.reference) { | ||
| sub.push(content.reference); | ||
| } | ||
|
|
||
| // Add guides | ||
| if (content.guides.length > 0) { | ||
| sub.push(...content.guides); | ||
| } | ||
|
|
||
| // Add examples as a submenu if they exist | ||
| if (content.examples.length > 0) { | ||
| sub.push({ | ||
| path: '/examples', | ||
| text: 'Examples', | ||
| sub: content.examples | ||
| }); | ||
| } | ||
|
|
||
| return { | ||
| ...module, | ||
| sub: sub.length > 0 ? sub : undefined, | ||
| hasContent: sub.length > 0 | ||
| }; | ||
| } | ||
|
|
||
| // Main function | ||
| function enhanceModulesJson() { | ||
| console.log('Enhancing modules.json with filesystem content...'); | ||
|
|
||
| const existingData = readExistingModulesJson(); | ||
|
|
||
| // Enhance each module with content structure | ||
| const enhancedModules = existingData.modules.map(buildEnhancedModuleStructure); | ||
|
|
||
| // Update the JSON structure | ||
| const enhancedData = { | ||
| ...existingData, | ||
| modules: enhancedModules, | ||
| generatedAt: new Date().toISOString(), | ||
| version: '2.0' | ||
| }; | ||
|
|
||
| // Write the enhanced JSON back | ||
| fs.writeFileSync(MODULES_JSON_PATH, JSON.stringify(enhancedData, null, 2)); | ||
|
|
||
| console.log(`Enhanced modules.json with ${enhancedModules.length} modules`); | ||
|
|
||
| // Log summary of content found | ||
| const modulesWithContent = enhancedModules.filter(m => m.hasContent); | ||
| const modulesWithGuides = enhancedModules.filter(m => m.sub?.some(s => s.file)); | ||
| const modulesWithExamples = enhancedModules.filter(m => m.sub?.some(s => s.sub)); | ||
|
|
||
| console.log(`- ${modulesWithContent.length} modules have additional content`); | ||
| console.log(`- ${modulesWithGuides.length} modules have human-written guides`); | ||
| console.log(`- ${modulesWithExamples.length} modules have examples`); | ||
| } | ||
|
|
||
| // Run if called directly | ||
| if (require.main === module) { | ||
| enhanceModulesJson(); | ||
| } | ||
|
|
||
| module.exports = { enhanceModulesJson, scanModuleDirectory, formatTitle }; |
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| // Enhanced module type with optional sub-navigation | ||
| interface EnhancedModule { | ||
| type: string; | ||
| group: string; | ||
| module: string; | ||
| sub?: Array<{ | ||
| path: string; | ||
| text: string; | ||
| sub?: Array<{ path: string; text: string }>; | ||
| }>; | ||
| hasContent?: boolean; | ||
| } | ||
|
|
||
| export function makeModuleDir( | ||
| modules: Array<{ type: string; group: string; module: string }>, | ||
| group: string, | ||
| type: string, | ||
| ) { | ||
| return modules | ||
| .filter((module) => module.group === group && module.type === type) | ||
| .map(({ module }) => ({ | ||
| text: module, | ||
| path: `/${module}`, | ||
| })); | ||
| } | ||
|
|
||
| export function makeFlatModuleList( | ||
| modules: Array<EnhancedModule>, | ||
| ) { | ||
| return modules | ||
| .map((module) => ({ | ||
| text: module.module, | ||
| path: `/${module.module}`, | ||
| sub: module.sub, // Include sub-navigation if present | ||
| })) | ||
| .sort((a, b) => a.text.localeCompare(b.text)); | ||
| } | ||
|
|
||
| // Create hierarchical module list grouped by type and group | ||
| export function makeHierarchicalModuleList( | ||
| modules: Array<EnhancedModule>, | ||
| ) { | ||
| const grouped: Record<string, Record<string, EnhancedModule[]>> = {}; | ||
|
|
||
| modules.forEach((module) => { | ||
| grouped[module.type][module.group].push(module); | ||
| }); | ||
|
|
||
| return Object.entries(grouped).map(([type, groups]) => ({ | ||
| text: formatTypeTitle(type), | ||
| path: `/${type}`, | ||
| sub: Object.entries(groups).map(([group, moduleList]) => ({ | ||
| text: formatGroupTitle(group), | ||
| path: `/${type}/${group}`, | ||
| sub: moduleList | ||
| .sort((a, b) => a.module.localeCompare(b.module)) | ||
| .map((module) => ({ | ||
| text: module.module, | ||
| path: `/${module.module}`, | ||
| sub: module.sub, | ||
| })), | ||
| })), | ||
| })); | ||
| } | ||
|
|
||
| function formatTypeTitle(type: string): string { | ||
| return type.charAt(0).toUpperCase() + type.slice(1); | ||
| } | ||
|
|
||
| function formatGroupTitle(group: string): string { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this isnt correct logic There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above. would rather have a static mapping with a fallback. this fails for aws |
||
| return group | ||
| .split('_') | ||
| .map(word => word.charAt(0).toUpperCase() + word.slice(1)) | ||
| .join(' '); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
id rather just have a static mapping with this as a fallback