Move to new docgen

This commit is contained in:
Schuyler Cebulskie
2016-11-22 18:24:29 -05:00
parent c8858de71e
commit 7c97244854
33 changed files with 200 additions and 953 deletions

View File

@@ -7,7 +7,7 @@ cache:
install: npm install
script:
- npm run test
- bash ./docs/deploy/deploy.sh
- bash ./deploy/deploy.sh
env:
global:
- ENCRYPTION_LABEL: "af862fa96d3e"

View File

@@ -59,10 +59,10 @@ the entire `Discord` object is available as a global (on the `window` object).
The ShardingManager and any voice-related functionality is unavailable in these builds.
## Links
* [Website](http://discord.js.org/)
* [Website](https://discord.js.org/)
* [Discord.js server](https://discord.gg/bRCvFy9)
* [Discord API server](https://discord.gg/rV4BwdK)
* [Documentation](http://discord.js.org/#/docs)
* [Documentation](https://discord.js.org/#/docs)
* [Legacy (v8) documentation](http://discordjs.readthedocs.io/en/8.2.0/docs_client.html)
* [Examples](https://github.com/hydrabolt/discord.js/tree/master/docs/custom/examples)
* [GitHub](https://github.com/hydrabolt/discord.js)
@@ -71,7 +71,7 @@ The ShardingManager and any voice-related functionality is unavailable in these
## Contributing
Before creating an issue, please ensure that it hasn't already been reported/suggested, and double-check the
[documentation](http://discord.js.org/#/docs).
[documentation](https://discord.js.org/#/docs).
See [the contributing guide](CONTRIBUTING.md) if you'd like to submit a PR.
## Help

View File

@@ -5,7 +5,7 @@ set -e
function build {
# Build docs
node docs/generator
npm run docs
# Build the webpack
VERSIONED=false npm run web-dist

View File

@@ -1,2 +1 @@
# discord.js docs
[View documentation here](http://discord.js.org/#/docs)
## [View the documentation here.](https://discord.js.org/#/docs)

View File

@@ -1,10 +0,0 @@
const fs = require('fs');
module.exports = {
category: 'Examples',
name: 'Avatars',
data:
`\`\`\`js
${fs.readFileSync('./docs/custom/examples/avatar.js').toString('utf-8')}
\`\`\``,
};

View File

@@ -1,7 +0,0 @@
const fs = require('fs');
module.exports = {
category: 'General',
name: 'FAQ',
data: fs.readFileSync('./docs/custom/documents/faq.md').toString('utf-8'),
};

View File

@@ -1,17 +0,0 @@
const files = [
require('./welcome'),
require('./updating'),
require('./faq'),
require('./ping_pong'),
require('./avatar'),
require('./webhook'),
];
const categories = {};
for (const file of files) {
file.category = file.category.toLowerCase();
if (!categories[file.category]) categories[file.category] = [];
categories[file.category].push(file);
}
module.exports = categories;

View File

@@ -1,10 +0,0 @@
const fs = require('fs');
module.exports = {
category: 'Examples',
name: 'Ping Pong',
data:
`\`\`\`js
${fs.readFileSync('./docs/custom/examples/ping_pong.js').toString('utf-8')}
\`\`\``,
};

View File

@@ -1,7 +0,0 @@
const fs = require('fs');
module.exports = {
category: 'General',
name: 'Updating your code',
data: fs.readFileSync('./docs/custom/documents/updating.md').toString('utf-8'),
};

View File

@@ -1,10 +0,0 @@
const fs = require('fs');
module.exports = {
category: 'Examples',
name: 'Webhooks',
data:
`\`\`\`js
${fs.readFileSync('./docs/custom/examples/webhook.js').toString('utf-8')}
\`\`\``,
};

View File

@@ -1,7 +0,0 @@
const fs = require('fs');
module.exports = {
category: 'General',
name: 'Welcome',
data: fs.readFileSync('./docs/custom/documents/welcome.md').toString('utf-8'),
};

View File

@@ -47,10 +47,10 @@ The ShardingManager and any voice-related functionality is unavailable in these
* [York's v9 upgrade guide](https://yorkaargh.wordpress.com/2016/09/03/updating-discord-js-bots/)
## Links
* [Website](http://discord.js.org/)
* [Website](https://discord.js.org/)
* [Discord.js server](https://discord.gg/bRCvFy9)
* [Discord API server](https://discord.gg/rV4BwdK)
* [Documentation](http://discord.js.org/#/docs)
* [Documentation](https://discord.js.org/#/docs)
* [Legacy (v8) documentation](http://discordjs.readthedocs.io/en/8.2.0/docs_client.html)
* [Examples](https://github.com/hydrabolt/discord.js/tree/master/docs/custom/examples)
* [GitHub](https://github.com/hydrabolt/discord.js)

View File

@@ -1,4 +0,0 @@
{
"GEN_VERSION": 14,
"COMPRESS": false
}

View File

@@ -1,101 +0,0 @@
/* eslint-disable no-console */
const DocumentedClass = require('./types/DocumentedClass');
const DocumentedInterface = require('./types/DocumentedInterface');
const DocumentedTypeDef = require('./types/DocumentedTypeDef');
const DocumentedConstructor = require('./types/DocumentedConstructor');
const DocumentedMember = require('./types/DocumentedMember');
const DocumentedFunction = require('./types/DocumentedFunction');
const DocumentedEvent = require('./types/DocumentedEvent');
const GEN_VERSION = require('./config').GEN_VERSION;
class Documentation {
constructor(items, custom) {
this.classes = new Map();
this.interfaces = new Map();
this.typedefs = new Map();
this.custom = custom;
this.parse(items);
}
registerRoots(data) {
for (const item of data) {
switch (item.kind) {
case 'class':
this.classes.set(item.name, new DocumentedClass(this, item));
break;
case 'interface':
this.interfaces.set(item.name, new DocumentedInterface(this, item));
break;
case 'typedef':
this.typedefs.set(item.name, new DocumentedTypeDef(this, item));
break;
default:
break;
}
}
}
findParent(item) {
if (['constructor', 'member', 'function', 'event'].includes(item.kind)) {
let val = this.classes.get(item.memberof);
if (val) return val;
val = this.interfaces.get(item.memberof);
if (val) return val;
}
return null;
}
parse(items) {
this.registerRoots(items.filter(item => ['class', 'interface', 'typedef'].includes(item.kind)));
const members = items.filter(item => !['class', 'interface', 'typedef'].includes(item.kind));
const unknowns = new Map();
for (const member of members) {
let item;
switch (member.kind) {
case 'constructor':
item = new DocumentedConstructor(this, member);
break;
case 'member':
item = new DocumentedMember(this, member);
break;
case 'function':
item = new DocumentedFunction(this, member);
break;
case 'event':
item = new DocumentedEvent(this, member);
break;
default:
unknowns.set(member.kind, member);
continue;
}
const parent = this.findParent(member);
if (!parent) {
console.warn(`- "${member.name || member.directData.name}" has no accessible parent.`);
continue;
}
parent.add(item);
}
for (const [key, val] of unknowns) {
console.warn(`- Unknown documentation kind "${key}" - \n${JSON.stringify(val)}\n`);
}
}
serialize() {
const meta = {
version: GEN_VERSION,
date: Date.now(),
};
const serialized = {
meta,
classes: Array.from(this.classes.values()).map(c => c.serialize()),
interfaces: Array.from(this.interfaces.values()).map(i => i.serialize()),
typedefs: Array.from(this.typedefs.values()).map(t => t.serialize()),
custom: this.custom,
};
return serialized;
}
}
module.exports = Documentation;

View File

@@ -1,33 +0,0 @@
#!/usr/bin/env node
/* eslint-disable no-console */
const fs = require('fs');
const jsdoc2md = require('jsdoc-to-markdown');
const Documentation = require('./documentation');
const custom = require('../custom/index');
const config = require('./config');
process.on('unhandledRejection', console.error);
console.log(`Using format version ${config.GEN_VERSION}.`);
console.log('Parsing JSDocs in source files...');
jsdoc2md.getTemplateData({ files: [`./src/*.js`, `./src/**/*.js`] }).then(data => {
console.log(`${data.length} items found.`);
const documentation = new Documentation(data, custom);
console.log('Serializing...');
let output = JSON.stringify(documentation.serialize(), null, 0);
if (config.compress) {
console.log('Compressing...');
output = require('zlib').deflateSync(output).toString('utf8');
}
if (!process.argv.slice(2).includes('test')) {
console.log('Writing to docs.json...');
fs.writeFileSync('./docs/docs.json', output);
}
console.log('Done!');
process.exit(0);
}).catch(console.error);

View File

@@ -1,80 +0,0 @@
const DocumentedItem = require('./DocumentedItem');
const DocumentedItemMeta = require('./DocumentedItemMeta');
const DocumentedConstructor = require('./DocumentedConstructor');
const DocumentedFunction = require('./DocumentedFunction');
const DocumentedMember = require('./DocumentedMember');
const DocumentedEvent = require('./DocumentedEvent');
/*
{ id: 'VoiceChannel',
longname: 'VoiceChannel',
name: 'VoiceChannel',
scope: 'global',
kind: 'class',
augments: [ 'GuildChannel' ],
description: 'Represents a Server Voice Channel on Discord.',
meta:
{ lineno: 7,
filename: 'VoiceChannel.js',
path: 'src/structures' },
order: 232 }
*/
class DocumentedClass extends DocumentedItem {
constructor(docParent, data) {
super(docParent, data);
this.props = new Map();
this.methods = new Map();
this.events = new Map();
}
add(item) {
if (item instanceof DocumentedConstructor) {
if (this.classConstructor) {
throw new Error(`Doc ${this.directData.name} already has constructor - ${this.directData.classConstructor}`);
}
this.classConstructor = item;
} else if (item instanceof DocumentedFunction) {
if (this.methods.get(item.directData.name)) {
throw new Error(`Doc ${this.directData.name} already has method ${item.directData.name}`);
}
this.methods.set(item.directData.name, item);
} else if (item instanceof DocumentedMember) {
if (this.props.get(item.directData.name)) {
throw new Error(`Doc ${this.directData.name} already has prop ${item.directData.name}`);
}
this.props.set(item.directData.name, item);
} else if (item instanceof DocumentedEvent) {
if (this.events.get(item.directData.name)) {
throw new Error(`Doc ${this.directData.name} already has event ${item.directData.name}`);
}
this.events.set(item.directData.name, item);
}
}
registerMetaInfo(data) {
super.registerMetaInfo(data);
this.directData = data;
this.directData.meta = new DocumentedItemMeta(this, data.meta);
}
serialize() {
super.serialize();
const { id, name, description, meta, augments, access } = this.directData;
const serialized = {
id,
name,
description,
meta: meta.serialize(),
extends: augments,
access,
};
if (this.classConstructor) serialized.classConstructor = this.classConstructor.serialize();
serialized.methods = Array.from(this.methods.values()).map(m => m.serialize());
serialized.properties = Array.from(this.props.values()).map(p => p.serialize());
serialized.events = Array.from(this.events.values()).map(e => e.serialize());
return serialized;
}
}
module.exports = DocumentedClass;

View File

@@ -1,42 +0,0 @@
const DocumentedItem = require('./DocumentedItem');
const DocumentedParam = require('./DocumentedParam');
/*
{ id: 'Client()',
longname: 'Client',
name: 'Client',
kind: 'constructor',
description: 'Creates an instance of Client.',
memberof: 'Client',
params:
[ { type: [Object],
optional: true,
description: 'options to pass to the client',
name: 'options' } ],
order: 10 }
*/
class DocumentedConstructor extends DocumentedItem {
registerMetaInfo(data) {
super.registerMetaInfo(data);
this.directData = data;
const newParams = [];
for (const param of data.params) newParams.push(new DocumentedParam(this, param));
this.directData.params = newParams;
}
serialize() {
super.serialize();
const { id, name, description, memberof, access, params } = this.directData;
return {
id,
name,
description,
memberof,
access,
params: params.map(p => p.serialize()),
};
}
}
module.exports = DocumentedConstructor;

View File

@@ -1,76 +0,0 @@
const DocumentedItem = require('./DocumentedItem');
const DocumentedItemMeta = require('./DocumentedItemMeta');
const DocumentedParam = require('./DocumentedParam');
/*
{
"id":"Client#event:guildMemberRolesUpdate",
"longname":"Client#event:guildMemberRolesUpdate",
"name":"guildMemberRolesUpdate",
"scope":"instance",
"kind":"event",
"description":"Emitted whenever a Guild Member's Roles change - i.e. new role or removed role",
"memberof":"Client",
"params":[
{
"type":{
"names":[
"Guild"
]
},
"description":"the guild that the update affects",
"name":"guild"
},
{
"type":{
"names":[
"Array.<Role>"
]
},
"description":"the roles before the update",
"name":"oldRoles"
},
{
"type":{
"names":[
"Guild"
]
},
"description":"the roles after the update",
"name":"newRoles"
}
],
"meta":{
"lineno":91,
"filename":"Guild.js",
"path":"src/structures"
},
"order":110
}
*/
class DocumentedEvent extends DocumentedItem {
registerMetaInfo(data) {
this.directData = data;
this.directData.meta = new DocumentedItemMeta(this, data.meta);
const newParams = [];
data.params = data.params || [];
for (const param of data.params) newParams.push(new DocumentedParam(this, param));
this.directData.params = newParams;
}
serialize() {
super.serialize();
const { id, name, description, memberof, meta, params } = this.directData;
return {
id,
name,
description,
memberof,
meta: meta.serialize(),
params: params.map(p => p.serialize()),
};
}
}
module.exports = DocumentedEvent;

View File

@@ -1,88 +0,0 @@
const DocumentedItem = require('./DocumentedItem');
const DocumentedItemMeta = require('./DocumentedItemMeta');
const DocumentedVarType = require('./DocumentedVarType');
const DocumentedParam = require('./DocumentedParam');
/*
{
"id":"ClientUser#sendTTSMessage",
"longname":"ClientUser#sendTTSMessage",
"name":"sendTTSMessage",
"scope":"instance",
"kind":"function",
"inherits":"User#sendTTSMessage",
"inherited":true,
"implements":[
"TextBasedChannel#sendTTSMessage"
],
"description":"Send a text-to-speech message to this channel",
"memberof":"ClientUser",
"params":[
{
"type":{
"names":[
"String"
]
},
"description":"the content to send",
"name":"content"
}
],
"examples":[
"// send a TTS message..."
],
"returns":[
{
"type":{
"names":[
"Promise.<Message>"
]
}
}
],
"meta":{
"lineno":38,
"filename":"TextBasedChannel.js",
"path":src/structures/interface"
},
"order":293
}
*/
class DocumentedFunction extends DocumentedItem {
registerMetaInfo(data) {
super.registerMetaInfo(data);
this.directData = data;
this.directData.meta = new DocumentedItemMeta(this, data.meta);
this.directData.returns = new DocumentedVarType(this, data.returns ? data.returns[0].type : {
names: ['void'],
});
const newParams = [];
for (const param of data.params) newParams.push(new DocumentedParam(this, param));
this.directData.params = newParams;
}
serialize() {
super.serialize();
const {
id, name, description, memberof, examples, inherits, inherited, meta, returns, params, access,
} = this.directData;
const serialized = {
id,
access,
name,
description,
memberof,
examples,
inherits,
inherited,
meta: meta.serialize(),
returns: returns.serialize(),
params: params.map(p => p.serialize()),
};
serialized.implements = this.directData.implements;
return serialized;
}
}
module.exports = DocumentedFunction;

View File

@@ -1,32 +0,0 @@
const DocumentedClass = require('./DocumentedClass');
/*
{ id: 'TextBasedChannel',
longname: 'TextBasedChannel',
name: 'TextBasedChannel',
scope: 'global',
kind: 'interface',
classdesc: 'Interface for classes that have text-channel-like features',
params: [],
meta:
{ lineno: 5,
filename: 'TextBasedChannel.js',
path: 'src/structures/interface' },
order: 175 }
*/
class DocumentedInterface extends DocumentedClass {
registerMetaInfo(data) {
super.registerMetaInfo(data);
this.directData = data;
// this.directData.meta = new DocumentedItemMeta(this, data.meta);
}
serialize() {
const serialized = super.serialize();
serialized.description = this.directData.classdesc;
return serialized;
}
}
module.exports = DocumentedInterface;

View File

@@ -1,17 +0,0 @@
class DocumentedItem {
constructor(parent, info) {
this.parent = parent;
this.directData = {};
this.registerMetaInfo(info);
}
registerMetaInfo() {
return;
}
serialize() {
return;
}
}
module.exports = DocumentedItem;

View File

@@ -1,27 +0,0 @@
const DocumentedItem = require('./DocumentedItem');
const cwd = `${process.cwd()}\\`.replace(/\\/g, '/');
const backToForward = /\\/g;
/*
{ lineno: 7,
filename: 'VoiceChannel.js',
path: 'src/structures' },
*/
class DocumentedItemMeta extends DocumentedItem {
registerMetaInfo(data) {
super.registerMetaInfo(data);
this.directData.line = data.lineno;
this.directData.file = data.filename;
this.directData.path = data.path.replace(backToForward, '/').replace(cwd, '');
}
serialize() {
super.serialize();
const { line, file, path } = this.directData;
return { line, file, path };
}
}
module.exports = DocumentedItemMeta;

View File

@@ -1,56 +0,0 @@
const DocumentedItem = require('./DocumentedItem');
const DocumentedItemMeta = require('./DocumentedItemMeta');
const DocumentedVarType = require('./DocumentedVarType');
const DocumentedParam = require('./DocumentedParam');
/*
{ id: 'Client#rest',
longname: 'Client#rest',
name: 'rest',
scope: 'instance',
kind: 'member',
description: 'The REST manager of the client',
memberof: 'Client',
type: { names: [ 'RESTManager' ] },
access: 'private',
meta:
{ lineno: 32,
filename: 'Client.js',
path: 'src/client' },
order: 11 }
*/
class DocumentedMember extends DocumentedItem {
registerMetaInfo(data) {
super.registerMetaInfo(data);
this.directData = data;
this.directData.meta = new DocumentedItemMeta(this, data.meta);
this.directData.type = new DocumentedVarType(this, data.type);
if (data.properties) {
const newProps = [];
for (const param of data.properties) {
newProps.push(new DocumentedParam(this, param));
}
this.directData.properties = newProps;
} else {
data.properties = [];
}
}
serialize() {
super.serialize();
const { id, name, description, memberof, type, access, meta, properties } = this.directData;
return {
id,
name,
description,
memberof,
type: type.serialize(),
access,
meta: meta.serialize(),
props: properties.map(p => p.serialize()),
};
}
}
module.exports = DocumentedMember;

View File

@@ -1,36 +0,0 @@
const DocumentedItem = require('./DocumentedItem');
const DocumentedVarType = require('./DocumentedVarType');
/*
{
"type":{
"names":[
"Guild"
]
},
"description":"the roles after the update",
"name":"newRoles"
}
*/
class DocumentedParam extends DocumentedItem {
registerMetaInfo(data) {
super.registerMetaInfo(data);
this.directData = data;
this.directData.type = new DocumentedVarType(this, data.type);
}
serialize() {
super.serialize();
const { name, description, type, optional, defaultvalue } = this.directData;
return {
name,
description,
optional,
default: defaultvalue,
type: type.serialize(),
};
}
}
module.exports = DocumentedParam;

View File

@@ -1,48 +0,0 @@
const DocumentedItem = require('./DocumentedItem');
const DocumentedItemMeta = require('./DocumentedItemMeta');
const DocumentedVarType = require('./DocumentedVarType');
const DocumentedParam = require('./DocumentedParam');
/*
{ id: 'StringResolvable',
longname: 'StringResolvable',
name: 'StringResolvable',
scope: 'global',
kind: 'typedef',
description: 'Data that can be resolved to give a String...',
type: { names: [ 'String', 'Array', 'Object' ] },
meta:
{ lineno: 142,
filename: 'ClientDataResolver.js',
path: 'src/client' },
order: 37 }
*/
class DocumentedTypeDef extends DocumentedItem {
registerMetaInfo(data) {
super.registerMetaInfo(data);
this.props = new Map();
this.directData = data;
this.directData.meta = new DocumentedItemMeta(this, data.meta);
this.directData.type = new DocumentedVarType(this, data.type);
data.properties = data.properties || [];
for (const prop of data.properties) this.props.set(prop.name, new DocumentedParam(this, prop));
}
serialize() {
super.serialize();
const { id, name, description, type, access, meta } = this.directData;
const serialized = {
id,
name,
description,
type: type.serialize(),
access,
meta: meta.serialize(),
};
serialized.properties = Array.from(this.props.values()).map(p => p.serialize());
return serialized;
}
}
module.exports = DocumentedTypeDef;

View File

@@ -1,45 +0,0 @@
const DocumentedItem = require('./DocumentedItem');
/*
{
"names":[
"String"
]
}
*/
const regex = /([\w]+)([^\w]+)/;
const regexG = /([\w]+)([^\w]+)/g;
class DocumentedVarType extends DocumentedItem {
registerMetaInfo(data) {
super.registerMetaInfo(data);
this.directData = data;
}
serialize() {
super.serialize();
const names = [];
for (const name of this.directData.names) names.push(splitVarName(name));
return {
types: names,
};
}
}
function splitVarName(str) {
if (str === '*') return ['*', ''];
const matches = str.match(regexG);
const output = [];
if (matches) {
for (const match of matches) {
const groups = match.match(regex);
output.push([groups[1], groups[2]]);
}
} else {
output.push([str.match(/(\w+)/g)[0], '']);
}
return output;
}
module.exports = DocumentedVarType;

View File

@@ -4,9 +4,9 @@
"description": "A powerful library for interacting with the Discord API",
"main": "./src/index",
"scripts": {
"test": "eslint src && node docs/generator test",
"docs": "node docs/generator",
"test-docs": "node docs/generator test",
"test": "eslint src && docgen --source src --custom docs",
"docs": "docgen --source src --custom docs --output docs/docs.json",
"test-docs": "docgen --source src --custom docs",
"lint": "eslint src",
"web-dist": "node ./node_modules/parallel-webpack/bin/run.js"
},
@@ -39,6 +39,7 @@
},
"devDependencies": {
"bufferutil": "^1.2.1",
"discord.js-docgen": "github:Gawdl3y/discord.js-docgen",
"eslint": "^3.10.0",
"jsdoc-to-markdown": "^2.0.0",
"json-loader": "^0.5.4",