Rewrite store JSDoc, split quote/order into modules, and generate typed API docs
- Rewrite JSDoc across all store methods to document the actual async methods (real params, returns, throws) instead of the internal wrappers - Split quote/order into individual module files backed by shared manifestDoc helpers; remove the createStore factory and thin wrappers - Deduplicate manifest line helpers into src/store/manifestLines.js - Extend generate-api-doc.js to render parameter/return/throws types and emit per-namespace API.<module>.md files with an API.md index - Regenerate all API docs
This commit is contained in:
@@ -58,13 +58,27 @@ const INTERNAL_FILES = new Set([
|
||||
'peekNumber.js',
|
||||
'shape.js',
|
||||
'createStore.js',
|
||||
'manifestLines.js',
|
||||
'index.js',
|
||||
]);
|
||||
|
||||
/**
|
||||
* Strip the outer braces from a JSDoc type (e.g. `{number}` -> `number`),
|
||||
* preserving nested braces inside generics.
|
||||
* @param {string} type
|
||||
* @returns {string}
|
||||
*/
|
||||
function stripBraces(type) {
|
||||
if (type.startsWith('{') && type.endsWith('}')) {
|
||||
return type.slice(1, -1);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the leading JSDoc block from a source string.
|
||||
* @param {string} source
|
||||
* @returns {{ description: string, example: string } | null}
|
||||
* @returns {{ description: string, example: string, params: Array<object>, returns: string|null, throws: string|null } | null}
|
||||
*/
|
||||
function extractJsDoc(source) {
|
||||
const match = source.match(/\/\*\*([\s\S]*?)\*\//);
|
||||
@@ -77,27 +91,53 @@ function extractJsDoc(source) {
|
||||
|
||||
const description = [];
|
||||
const example = [];
|
||||
const params = [];
|
||||
let returns = null;
|
||||
let throws = null;
|
||||
let inExample = false;
|
||||
|
||||
for (const line of lines) {
|
||||
if (line.trim() === '@example') {
|
||||
const trimmed = line.trim();
|
||||
if (trimmed === '@example') {
|
||||
inExample = true;
|
||||
continue;
|
||||
}
|
||||
if (line.trim().startsWith('@')) {
|
||||
if (trimmed.startsWith('@')) {
|
||||
inExample = false;
|
||||
const paramMatch = trimmed.match(/^@param\s+(\{.*\})\s+(\S+)\s*[-–]?\s*(.*)$/);
|
||||
if (paramMatch) {
|
||||
params.push({
|
||||
type: stripBraces(paramMatch[1]),
|
||||
name: paramMatch[2],
|
||||
description: paramMatch[3].trim(),
|
||||
});
|
||||
continue;
|
||||
}
|
||||
const returnsMatch = trimmed.match(/^@returns\s+(\{.*\})\s*[-–]?\s*(.*)$/);
|
||||
if (returnsMatch) {
|
||||
returns = { type: stripBraces(returnsMatch[1]), description: returnsMatch[2].trim() };
|
||||
continue;
|
||||
}
|
||||
const throwsMatch = trimmed.match(/^@throws\s+(\{.*\})\s*[-–]?\s*(.*)$/);
|
||||
if (throwsMatch) {
|
||||
throws = { type: stripBraces(throwsMatch[1]), description: throwsMatch[2].trim() };
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (inExample) {
|
||||
example.push(line);
|
||||
} else if (line.trim()) {
|
||||
description.push(line.trim());
|
||||
} else if (trimmed) {
|
||||
description.push(trimmed);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
description: description.join(' ').trim(),
|
||||
example: example.join('\n').trim(),
|
||||
params,
|
||||
returns,
|
||||
throws,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -146,6 +186,9 @@ function buildModules() {
|
||||
file: rel.join('/'),
|
||||
description: doc.description,
|
||||
example: doc.example,
|
||||
params: doc.params,
|
||||
returns: doc.returns,
|
||||
throws: doc.throws,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -170,7 +213,31 @@ function renderSection(moduleName, entries) {
|
||||
lines.push(entry.description);
|
||||
lines.push('');
|
||||
}
|
||||
if (entry.params && entry.params.length) {
|
||||
lines.push('**Parameters**');
|
||||
lines.push('');
|
||||
lines.push('| Name | Type | Description |');
|
||||
lines.push('| --- | --- | --- |');
|
||||
for (const p of entry.params) {
|
||||
lines.push(`| \`${p.name}\` | \`${p.type}\` | ${p.description} |`);
|
||||
}
|
||||
lines.push('');
|
||||
}
|
||||
if (entry.returns) {
|
||||
lines.push('**Returns**');
|
||||
lines.push('');
|
||||
lines.push(`\`${entry.returns.type}\`${entry.returns.description ? ` — ${entry.returns.description}` : ''}`);
|
||||
lines.push('');
|
||||
}
|
||||
if (entry.throws) {
|
||||
lines.push('**Throws**');
|
||||
lines.push('');
|
||||
lines.push(`\`${entry.throws.type}\`${entry.throws.description ? ` — ${entry.throws.description}` : ''}`);
|
||||
lines.push('');
|
||||
}
|
||||
if (entry.example) {
|
||||
lines.push('**Example**');
|
||||
lines.push('');
|
||||
lines.push('```js');
|
||||
lines.push(entry.example);
|
||||
lines.push('```');
|
||||
|
||||
Reference in New Issue
Block a user