doxdox-parser-jsdoc
Version:
JSDoc parser for doxdox
81 lines (80 loc) • 3.02 kB
JavaScript
import fs from 'node:fs/promises';
import { fileURLToPath } from 'node:url';
import { platform } from 'node:os';
import { dirname, join } from 'node:path';
import spawn from 'spawn-please';
import temp from 'temp';
import { findParentNodeModules, slugify } from 'doxdox-core';
const parser = async (cwd, path) => {
try {
const parserDir = dirname(fileURLToPath(import.meta.url));
const nodeModulesDir = await findParentNodeModules(parserDir);
if (!nodeModulesDir) {
throw new Error('node_modules directory was not found');
}
const { stdout: output } = await spawn(join(nodeModulesDir, `.bin/${platform() === 'win32' ? 'jsdoc.cmd' : 'jsdoc'}`), [
'--explain',
join(cwd, path),
'--configure',
join(parserDir, 'config.json')
]);
const docs = JSON.parse(output);
const methods = docs
.filter((jsdoc) => jsdoc.kind === 'function' && !jsdoc.undocumented)
.map((jsdoc) => {
const params = (jsdoc.params || []).map(({ name = null, description = null, type = {} }) => ({
name,
description,
types: type.names || []
}));
const returns = (jsdoc.returns || []).map(({ name = null, description = null, type = {} }) => ({
name,
description,
types: type.names || []
}));
const isPrivate = jsdoc.access === 'private' ||
(jsdoc.tags &&
jsdoc.tags.findIndex(tag => tag.title === 'api' && tag.value === 'private') !== -1) ||
false;
return {
slug: `${slugify(path)}-${slugify(jsdoc.name)}`,
name: jsdoc.name,
fullName: `${jsdoc.name}(${params
.map(param => param.name)
.filter(name => name && !name.match(/\./))
.join(', ')})`,
description: jsdoc.description || null,
params,
returns,
private: isPrivate
};
})
.sort((a, b) => {
if (a.name.toLocaleLowerCase() < b.name.toLocaleLowerCase()) {
return -1;
}
if (a.name.toLocaleLowerCase() > b.name.toLocaleLowerCase()) {
return 1;
}
return 0;
});
return { path, methods };
}
catch (err) {
if (process.env.DEBUG) {
console.error(err);
}
}
return { path, methods: [] };
};
export const parseString = async (path, content) => {
temp.track();
const tempDir = await temp.mkdir({ prefix: 'doxdox-' });
const tempPath = join(tempDir, path);
await fs.mkdir(dirname(tempPath), { recursive: true });
await fs.writeFile(tempPath, content);
const file = await parser(tempDir, path);
await temp.cleanup();
return file;
};
export default parser;