UNPKG

node-osc

Version:

pyOSC inspired library for sending and receiving OSC messages

230 lines (191 loc) 6.66 kB
#!/usr/bin/env node /** * Converts JSDoc JSON output to Markdown documentation. * This script reads JSDoc JSON data and generates a formatted Markdown file. */ import { writeFileSync } from 'node:fs'; import { execSync } from 'node:child_process'; // Generate JSDoc JSON let jsdocJson; try { jsdocJson = execSync('npx jsdoc -X -c jsdoc.json', { encoding: 'utf8', maxBuffer: 10 * 1024 * 1024 }); } catch (error) { console.error('❌ Failed to run JSDoc:'); console.error(error.message); process.exit(1); } let docs; try { docs = JSON.parse(jsdocJson); } catch (error) { console.error('❌ Failed to parse JSDoc JSON output:'); console.error(error.message); process.exit(1); } // Filter and organize documentation const classes = {}; const functions = {}; docs.forEach(item => { if (item.undocumented || item.ignore) return; if (item.kind === 'class' && item.classdesc) { if (!classes[item.name]) { classes[item.name] = { desc: item.classdesc, constructor: null, methods: [], examples: item.examples || [], augments: item.augments || [] }; } // Look for constructor params if (item.params) { classes[item.name].constructor = { params: item.params, examples: item.examples || [] }; } } else if (item.kind === 'function' && item.memberof) { // Method of a class const className = item.memberof; if (!classes[className]) { classes[className] = { desc: '', constructor: null, methods: [], examples: [] }; } classes[className].methods.push(item); } else if (item.kind === 'function' && !item.memberof && item.scope === 'global') { // Top-level function functions[item.name] = item; } }); // Generate Markdown let markdown = `<!-- Generated by JSDoc. Update this documentation by updating the source code. --> # API Reference > **⚠️ This file is auto-generated from JSDoc comments in the source code.** > To update this documentation, edit the JSDoc comments in the source files and run \`npm run docs\`. This document provides detailed API reference for all classes, methods, and functions in node-osc. For usage guides, best practices, and troubleshooting, see the **[Guide](./GUIDE.md)**. ## Table of Contents `; // Define order: Server → Client → Message → Bundle → Low Level const classOrder = ['Server', 'Client', 'Message', 'Bundle']; const functionOrder = ['encode', 'decode']; // Add classes to TOC classOrder.forEach(name => { if (classes[name]) { markdown += `- [${name}](#${name.toLowerCase()})\n`; if (classes[name].constructor) { markdown += ` - [Constructor](#${name.toLowerCase()}-constructor)\n`; } classes[name].methods.forEach(method => { markdown += ` - [${method.name}()](#${name.toLowerCase()}-${method.name.toLowerCase()})\n`; }); } }); // Add functions to TOC markdown += `- [Low Level Functions](#low-level-functions)\n`; functionOrder.forEach(name => { if (functions[name]) { markdown += ` - [${name}()](#${name.toLowerCase()})\n`; } }); markdown += `\n---\n\n`; // Helper function to format parameters function formatParams(params) { if (!params || params.length === 0) return ''; let result = '\n**Parameters:**\n\n'; params.forEach(param => { const optional = param.optional ? ' (optional)' : ''; const defaultVal = param.defaultvalue ? ` - Default: \`${param.defaultvalue}\`` : ''; const types = param.type ? param.type.names.join(' | ') : 'any'; result += `- \`${param.name}\` *{${types}}*${optional}${defaultVal} - ${param.description || ''}\n`; }); return result; } // Helper function to format examples function formatExamples(examples) { if (!examples || examples.length === 0) return ''; let result = '\n**Examples:**\n\n'; examples.forEach(example => { result += '```javascript\n' + example + '\n```\n\n'; }); return result; } // Helper function to format returns function formatReturns(returns) { if (!returns || returns.length === 0) return ''; const ret = returns[0]; const types = ret.type ? ret.type.names.join(' | ') : 'any'; return `\n**Returns:** *{${types}}* - ${ret.description || ''}\n`; } // Helper function to format throws function formatThrows(exceptions) { if (!exceptions || exceptions.length === 0) return ''; let result = '\n**Throws:**\n\n'; exceptions.forEach(ex => { const types = ex.type ? ex.type.names.join(' | ') : 'Error'; result += `- *{${types}}* - ${ex.description || ''}\n`; }); return result; } // Generate class documentation classOrder.forEach(className => { const classInfo = classes[className]; if (!classInfo) return; markdown += `## ${className}\n\n`; // Add extends info if (classInfo.augments && classInfo.augments.length > 0) { markdown += `**Extends:** ${classInfo.augments.join(', ')}\n\n`; } markdown += `${classInfo.desc}\n`; // Class-level examples if (classInfo.examples.length > 0 && !classInfo.constructor) { markdown += formatExamples(classInfo.examples); } // Constructor if (classInfo.constructor) { markdown += `\n### ${className} Constructor\n\n`; markdown += `Creates a new ${className} instance.\n`; markdown += formatParams(classInfo.constructor.params); markdown += formatExamples(classInfo.constructor.examples); } // Methods classInfo.methods.forEach(method => { markdown += `\n### ${className}.${method.name}()\n\n`; markdown += `${method.description || ''}\n`; markdown += formatParams(method.params); markdown += formatReturns(method.returns); markdown += formatThrows(method.exceptions); markdown += formatExamples(method.examples); }); markdown += `\n---\n\n`; }); // Generate function documentation markdown += `## Low Level Functions\n\n`; markdown += `These functions provide low-level access to OSC encoding and decoding for advanced use cases.\n\n`; functionOrder.forEach(funcName => { const func = functions[funcName]; if (!func) return; markdown += `### ${funcName}()\n\n`; markdown += `${func.description || ''}\n`; markdown += formatParams(func.params); markdown += formatReturns(func.returns); markdown += formatThrows(func.exceptions); markdown += formatExamples(func.examples); markdown += `\n`; }); // Write output try { writeFileSync('docs/API.md', markdown, 'utf8'); console.log('✅ API documentation generated: docs/API.md'); } catch (error) { console.error('❌ Failed to write API.md:'); console.error(error.message); process.exit(1); }