mirror of
https://github.com/HeyPuter/puter.git
synced 2025-02-02 14:18:43 +08:00
dev: improve module docgen
- fixes some bugs - adds list of relative requires
This commit is contained in:
parent
c0257c482f
commit
9e5429b9ab
1
package-lock.json
generated
1
package-lock.json
generated
@ -17661,6 +17661,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "^7.26.2",
|
"@babel/parser": "^7.26.2",
|
||||||
"@babel/traverse": "^7.25.9",
|
"@babel/traverse": "^7.25.9",
|
||||||
|
"dedent": "^1.5.3",
|
||||||
"doctrine": "^3.0.0"
|
"doctrine": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -20,13 +20,7 @@ Initializes socket.io
|
|||||||
|
|
||||||
###### Parameters
|
###### Parameters
|
||||||
|
|
||||||
- `server`: The server to attach socket.io to.
|
- **server:** The server to attach socket.io to.
|
||||||
|
|
||||||
### WebModule
|
|
||||||
|
|
||||||
undefined
|
|
||||||
|
|
||||||
#### Listeners
|
|
||||||
|
|
||||||
### WebServerService
|
### WebServerService
|
||||||
|
|
||||||
@ -53,7 +47,22 @@ If the `config.http_port` is set to 'auto', it will try to find an available por
|
|||||||
Once the server is up and running, it emits the 'start.webserver' and 'ready.webserver' events.
|
Once the server is up and running, it emits the 'start.webserver' and 'ready.webserver' events.
|
||||||
If the `config.env` is set to 'dev' and `config.no_browser_launch` is false, it will open the Puter URL in the default browser.
|
If the `config.env` is set to 'dev' and `config.no_browser_launch` is false, it will open the Puter URL in the default browser.
|
||||||
|
|
||||||
##### `start.webserver`
|
## Notes
|
||||||
|
|
||||||
|
### Outside Imports
|
||||||
|
|
||||||
|
This module has external relative imports. When these are
|
||||||
|
removed it may become possible to move this module to an
|
||||||
|
extension.
|
||||||
|
|
||||||
|
**Imports:**
|
||||||
|
- `../../services/BaseService` (use.BaseService)
|
||||||
|
- `../../api/eggspress.js`
|
||||||
|
- `../../util/context.js`
|
||||||
|
- `../../services/BaseService.js`
|
||||||
|
- `../../config.js`
|
||||||
|
- `../../middleware/auth.js`
|
||||||
|
- `../../util/strutil.js`
|
||||||
|
- `../../fun/dev-console-ui-utils.js`
|
||||||
|
- `../../helpers.js`
|
||||||
|
- `../../fun/logos.js`
|
||||||
|
@ -94,10 +94,6 @@ class WebServerService extends BaseService {
|
|||||||
*
|
*
|
||||||
* @return {Promise} A promise that resolves when the server is up and running.
|
* @return {Promise} A promise that resolves when the server is up and running.
|
||||||
*/
|
*/
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
async ['__on_start.webserver'] () {
|
|
||||||
// ... rest of the method code
|
|
||||||
}
|
|
||||||
async ['__on_start.webserver'] () {
|
async ['__on_start.webserver'] () {
|
||||||
await es_import_promise;
|
await es_import_promise;
|
||||||
|
|
||||||
|
161
tools/module-docgen/defs.js
Normal file
161
tools/module-docgen/defs.js
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
const dedent = require('dedent');
|
||||||
|
const doctrine = require('doctrine');
|
||||||
|
|
||||||
|
class Out {
|
||||||
|
constructor () {
|
||||||
|
this.str = '';
|
||||||
|
const fn = this.out.bind(this);
|
||||||
|
fn.h = this.h.bind(this);
|
||||||
|
fn.lf = this.lf.bind(this);
|
||||||
|
fn.text = () => this.str;
|
||||||
|
return fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
h (n, text) {
|
||||||
|
this.str += '#'.repeat(n) + ' ' + text + '\n\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
lf () { this.str += '\n'; }
|
||||||
|
|
||||||
|
out (str) {
|
||||||
|
this.str += str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Doc {
|
||||||
|
constructor () {
|
||||||
|
this._construct();
|
||||||
|
}
|
||||||
|
provide_comment (comment) {
|
||||||
|
const parsed_comment = doctrine.parse(comment.value, { unwrap: true });
|
||||||
|
this.comment = parsed_comment.description;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ModuleDoc extends Doc {
|
||||||
|
_construct () {
|
||||||
|
this.services = [];
|
||||||
|
this.requires = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
add_service () {
|
||||||
|
const service = new ServiceDoc();
|
||||||
|
this.services.push(service);
|
||||||
|
return service;
|
||||||
|
}
|
||||||
|
|
||||||
|
ready () {
|
||||||
|
this.notes = [];
|
||||||
|
const rel_requires = this.requires.filter(r => r.startsWith('../'));
|
||||||
|
if ( rel_requires.length > 0 ) {
|
||||||
|
this.notes.push({
|
||||||
|
title: 'Outside Imports',
|
||||||
|
desc: dedent(`
|
||||||
|
This module has external relative imports. When these are
|
||||||
|
removed it may become possible to move this module to an
|
||||||
|
extension.
|
||||||
|
|
||||||
|
**Imports:**
|
||||||
|
${rel_requires.map(r => {
|
||||||
|
let maybe_aside = '';
|
||||||
|
if ( r.endsWith('BaseService') ) {
|
||||||
|
maybe_aside = ' (use.BaseService)';
|
||||||
|
}
|
||||||
|
return `- \`${r}\`` + maybe_aside;
|
||||||
|
}).join('\n')}
|
||||||
|
`)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toMarkdown ({ hl, out } = { hl: 1 }) {
|
||||||
|
this.ready();
|
||||||
|
|
||||||
|
out = out ?? new Out();
|
||||||
|
|
||||||
|
out.h(hl, this.name);
|
||||||
|
|
||||||
|
out(this.comment + '\n\n');
|
||||||
|
|
||||||
|
if ( this.services.length > 0 ) {
|
||||||
|
out.h(hl + 1, 'Services');
|
||||||
|
|
||||||
|
for ( const service of this.services ) {
|
||||||
|
service.toMarkdown({ out, hl: hl + 2 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( this.notes.length > 0 ) {
|
||||||
|
out.h(hl + 1, 'Notes');
|
||||||
|
for ( const note of this.notes ) {
|
||||||
|
out.h(hl + 2, note.title);
|
||||||
|
out(note.desc);
|
||||||
|
out.lf();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return out.text();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ServiceDoc extends Doc {
|
||||||
|
_construct () {
|
||||||
|
this.listeners = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
provide_comment (comment) {
|
||||||
|
const parsed_comment = doctrine.parse(comment.value, { unwrap: true });
|
||||||
|
this.comment = parsed_comment.description;
|
||||||
|
}
|
||||||
|
|
||||||
|
provide_listener (listener) {
|
||||||
|
const parsed_comment = doctrine.parse(listener.comment, { unwrap: true });
|
||||||
|
|
||||||
|
const params = [];
|
||||||
|
for ( const tag of parsed_comment.tags ) {
|
||||||
|
if ( tag.title !== 'evtparam' ) continue;
|
||||||
|
const name = tag.description.slice(0, tag.description.indexOf(' '));
|
||||||
|
const desc = tag.description.slice(tag.description.indexOf(' '));
|
||||||
|
params.push({ name, desc })
|
||||||
|
}
|
||||||
|
|
||||||
|
this.listeners.push({
|
||||||
|
...listener,
|
||||||
|
comment: parsed_comment.description,
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
toMarkdown ({ hl, out } = { hl: 1 }) {
|
||||||
|
out = out ?? new Out();
|
||||||
|
|
||||||
|
out.h(hl, this.name);
|
||||||
|
|
||||||
|
out(this.comment + '\n\n');
|
||||||
|
|
||||||
|
if ( this.listeners.length > 0 ) {
|
||||||
|
out.h(hl + 1, 'Listeners');
|
||||||
|
|
||||||
|
for ( const listener of this.listeners ) {
|
||||||
|
out.h(hl + 2, '`' + listener.key + '`');
|
||||||
|
out (listener.comment + '\n\n');
|
||||||
|
|
||||||
|
if ( listener.params.length > 0 ) {
|
||||||
|
out.h(hl + 3, 'Parameters');
|
||||||
|
for ( const param of listener.params ) {
|
||||||
|
out(`- **${param.name}:** ${param.desc}\n`);
|
||||||
|
}
|
||||||
|
out.lf();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out.text();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
ModuleDoc,
|
||||||
|
ServiceDoc,
|
||||||
|
};
|
@ -5,51 +5,9 @@ const rootdir = path_.resolve(process.argv[2] ?? '.');
|
|||||||
|
|
||||||
const parser = require('@babel/parser');
|
const parser = require('@babel/parser');
|
||||||
const traverse = require('@babel/traverse').default;
|
const traverse = require('@babel/traverse').default;
|
||||||
const doctrine = require('doctrine');
|
const { ModuleDoc } = require("./defs");
|
||||||
|
|
||||||
const def_module = {
|
const doc_module = new ModuleDoc();
|
||||||
services: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
const to_module_add_service = (def_module, values) => {
|
|
||||||
def_module.services.push({
|
|
||||||
...values,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const to_service_add_listener = (def_service, values) => {
|
|
||||||
const parsed_comment = doctrine.parse(values.comment, { unwrap: true });
|
|
||||||
|
|
||||||
const params = [];
|
|
||||||
for ( const tag of parsed_comment.tags ) {
|
|
||||||
if ( tag.title !== 'evtparam' ) continue;
|
|
||||||
const name = tag.description.slice(0, tag.description.indexOf(' '));
|
|
||||||
const desc = tag.description.slice(tag.description.indexOf(' '));
|
|
||||||
params.push({ name, desc })
|
|
||||||
}
|
|
||||||
|
|
||||||
def_service.listeners.push({
|
|
||||||
...values,
|
|
||||||
comment: parsed_comment.description,
|
|
||||||
params,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const to_service_add_comment = (def_service, comment) => {
|
|
||||||
console.log('comment', comment);
|
|
||||||
const parsed_comment = doctrine.parse(comment.value, { unwrap: true });
|
|
||||||
def_service.comment = parsed_comment.description;
|
|
||||||
};
|
|
||||||
|
|
||||||
const to_module_add_comment = (def_module, comment) => {
|
|
||||||
console.log('comment', comment);
|
|
||||||
const parsed_comment = doctrine.parse(comment.value, { unwrap: true });
|
|
||||||
def_module.comment = parsed_comment.description;
|
|
||||||
};
|
|
||||||
|
|
||||||
const create_service = () => ({
|
|
||||||
listeners: []
|
|
||||||
});
|
|
||||||
|
|
||||||
// List files in this directory
|
// List files in this directory
|
||||||
const files = fs.readdirSync(rootdir);
|
const files = fs.readdirSync(rootdir);
|
||||||
@ -67,16 +25,21 @@ for ( const file of files ) {
|
|||||||
|
|
||||||
if ( type === null ) continue;
|
if ( type === null ) continue;
|
||||||
|
|
||||||
const def_service = create_service();
|
|
||||||
|
|
||||||
console.log('file', file);
|
console.log('file', file);
|
||||||
const code = fs.readFileSync(path_.join(rootdir, file), 'utf8');
|
const code = fs.readFileSync(path_.join(rootdir, file), 'utf8');
|
||||||
const ast = parser.parse(code);
|
const ast = parser.parse(code);
|
||||||
traverse(ast, {
|
traverse(ast, {
|
||||||
|
CallExpression (path) {
|
||||||
|
const callee = path.get('callee');
|
||||||
|
if ( ! callee.isIdentifier() ) return;
|
||||||
|
|
||||||
|
if ( callee.node.name === 'require' ) {
|
||||||
|
doc_module.requires.push(path.node.arguments[0].value);
|
||||||
|
}
|
||||||
|
},
|
||||||
ClassDeclaration (path) {
|
ClassDeclaration (path) {
|
||||||
const node = path.node;
|
const node = path.node;
|
||||||
const name = node.id.name;
|
const name = node.id.name;
|
||||||
def_service.name = name;
|
|
||||||
|
|
||||||
// Skip utility classes (for now)
|
// Skip utility classes (for now)
|
||||||
if ( name !== file.slice(0, -3) ) {
|
if ( name !== file.slice(0, -3) ) {
|
||||||
@ -88,16 +51,24 @@ for ( const file of files ) {
|
|||||||
node.leadingComments[node.leadingComments.length - 1]
|
node.leadingComments[node.leadingComments.length - 1]
|
||||||
)) ?? '';
|
)) ?? '';
|
||||||
|
|
||||||
if ( type === 'module' ) {
|
let doc_item = doc_module;
|
||||||
def_module.name = name;
|
if ( type !== 'module' ) {
|
||||||
if ( comment !== '' ) {
|
doc_item = doc_module.add_service();
|
||||||
to_module_add_comment(def_module, comment);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
doc_item.name = name;
|
||||||
if ( comment !== '' ) {
|
if ( comment !== '' ) {
|
||||||
to_service_add_comment(def_service, comment);
|
doc_item.provide_comment(comment);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( type === 'module' ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ( comment !== '' ) {
|
||||||
|
doc_item.provide_comment(comment);
|
||||||
|
// to_service_add_comment(def_service, comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('class', name);
|
console.log('class', name);
|
||||||
@ -111,7 +82,7 @@ for ( const file of files ) {
|
|||||||
// we want the list of keys in the object:
|
// we want the list of keys in the object:
|
||||||
const params = member.params?.[1]?.properties ?? [];
|
const params = member.params?.[1]?.properties ?? [];
|
||||||
|
|
||||||
to_service_add_listener(def_service, {
|
doc_item.provide_listener({
|
||||||
key: key.slice(5),
|
key: key.slice(5),
|
||||||
comment,
|
comment,
|
||||||
params,
|
params,
|
||||||
@ -119,48 +90,12 @@ for ( const file of files ) {
|
|||||||
}
|
}
|
||||||
console.log(member.type, key, member.leadingComments);
|
console.log(member.type, key, member.leadingComments);
|
||||||
});
|
});
|
||||||
// module_info.services.push({
|
|
||||||
// name,
|
|
||||||
// file,
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
to_module_add_service(def_module, def_service);
|
|
||||||
// console.log('parsed?', parsed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('module', JSON.stringify(def_module, undefined, ' '));
|
|
||||||
|
|
||||||
const outfile = path_.join(rootdir, 'README.md');
|
const outfile = path_.join(rootdir, 'README.md');
|
||||||
|
|
||||||
let out = '';
|
const out = doc_module.toMarkdown();
|
||||||
|
|
||||||
out += `# ${def_module.name}\n\n`;
|
|
||||||
|
|
||||||
if ( def_module.comment ) {
|
|
||||||
out += `${def_module.comment}\n\n`;
|
|
||||||
}
|
|
||||||
|
|
||||||
out += '## Services\n\n';
|
|
||||||
|
|
||||||
for ( const service of def_module.services ) {
|
|
||||||
out += `### ${service.name}\n\n`;
|
|
||||||
out += `${service.comment}\n\n`;
|
|
||||||
|
|
||||||
out += '#### Listeners\n\n';
|
|
||||||
for ( const listener of service.listeners ) {
|
|
||||||
out += `##### \`${listener.key}\`\n\n`;
|
|
||||||
out += `${listener.comment}\n\n`;
|
|
||||||
|
|
||||||
if ( listener.params.length > 0 ) {
|
|
||||||
out += '###### Parameters\n\n';
|
|
||||||
for ( const param of listener.params ) {
|
|
||||||
out += `- \`${param.name}\`: ${param.desc}\n`;
|
|
||||||
}
|
|
||||||
out += '\n';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fs.writeFileSync(outfile, out);
|
fs.writeFileSync(outfile, out);
|
@ -12,6 +12,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "^7.26.2",
|
"@babel/parser": "^7.26.2",
|
||||||
"@babel/traverse": "^7.25.9",
|
"@babel/traverse": "^7.25.9",
|
||||||
|
"dedent": "^1.5.3",
|
||||||
"doctrine": "^3.0.0"
|
"doctrine": "^3.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user