Skip to content

Commit 3279b40

Browse files
committed
feat(docgen): typescript support
1 parent 1afae90 commit 3279b40

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+955
-321
lines changed

packages/builders/.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ dist/
1919
typings/
2020

2121
docs/**/*
22-
!docs/index.yml
22+
!docs/index.json
2323
!docs/README.md
2424
!docs/examples/
2525
!docs/examples/*.md

packages/builders/docs/index.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[{ "name": "General", "files": [{ "name": "Welcome", "id": "welcome", "path": "../../README.md" }] }]

packages/builders/docs/index.yml

Lines changed: 0 additions & 5 deletions
This file was deleted.

packages/builders/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"build": "tsup",
77
"lint": "prettier --check . && eslint src __tests__ --ext mjs,js,ts",
88
"format": "prettier --write . && eslint src __tests__ --ext mjs,js,ts --fix",
9-
"docs": "typedoc --json docs/typedoc-out.json src/index.ts && ts-docgen -i docs/typedoc-out.json -c docs/index.yml -o docs/docs.json",
9+
"docs": "docgen -i src/index.ts -c docs/index.json -o docs/docs.json --typescript",
1010
"prepublishOnly": "yarn build && yarn lint && yarn test",
1111
"changelog": "git cliff --prepend ./CHANGELOG.md -u -c ./cliff.toml -r ../../ --include-path 'packages/builders/*'",
1212
"release": "cliff-jumper"
@@ -60,6 +60,7 @@
6060
"tslib": "^2.4.0"
6161
},
6262
"devDependencies": {
63+
"@discordjs/docgen": "workspace:^",
6364
"@discordjs/scripts": "workspace:^",
6465
"@favware/cliff-jumper": "^1.8.3",
6566
"@types/node": "^16.11.38",
@@ -71,7 +72,6 @@
7172
"eslint-plugin-import": "^2.26.0",
7273
"prettier": "^2.6.2",
7374
"tsup": "^6.1.0",
74-
"typedoc": "^0.22.17",
7575
"typescript": "^4.7.3"
7676
},
7777
"engines": {

packages/collection/.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pids
1818
dist/
1919
typings/
2020
docs/**/*
21-
!docs/index.yml
21+
!docs/index.json
2222
!docs/README.md
2323

2424
# Miscellaneous

packages/collection/docs/index.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[{ "name": "General", "files": [{ "name": "Welcome", "id": "welcome", "path": "../../README.md" }] }]

packages/collection/docs/index.yml

Lines changed: 0 additions & 5 deletions
This file was deleted.

packages/collection/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"build": "tsup",
77
"lint": "prettier --check . && eslint src __tests__ --ext mjs,js,ts",
88
"format": "prettier --write . && eslint src __tests__ --ext mjs,js,ts --fix",
9-
"docs": "typedoc --json docs/typedoc-out.json src/index.ts && ts-docgen -i docs/typedoc-out.json -c docs/index.yml -o docs/docs.json",
9+
"docs": "docgen -i src/index.ts -c docs/index.json -o docs/docs.json --typescript",
1010
"prepublishOnly": "yarn build && yarn lint && yarn test",
1111
"changelog": "git cliff --prepend ./CHANGELOG.md -u -c ./cliff.toml -r ../../ --include-path 'packages/collection/*'",
1212
"release": "cliff-jumper"
@@ -48,6 +48,7 @@
4848
},
4949
"homepage": "https://discord.js.org",
5050
"devDependencies": {
51+
"@discordjs/docgen": "workspace:^",
5152
"@discordjs/scripts": "workspace:^",
5253
"@favware/cliff-jumper": "^1.8.3",
5354
"@types/node": "^16.11.38",
@@ -59,7 +60,6 @@
5960
"eslint-plugin-import": "^2.26.0",
6061
"prettier": "^2.6.2",
6162
"tsup": "^6.1.0",
62-
"typedoc": "^0.22.17",
6363
"typescript": "^4.7.3"
6464
},
6565
"engines": {

packages/docgen/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,11 @@
4949
},
5050
"homepage": "https://discord.js.org",
5151
"dependencies": {
52-
"@discordjs/collection": "workspace:^",
52+
"@discordjs/collection": "^0.7.0",
5353
"commander": "^9.3.0",
5454
"jsdoc-to-markdown": "^7.1.1",
55-
"tslib": "^2.4.0"
55+
"tslib": "^2.4.0",
56+
"typedoc": "^0.22.17"
5657
},
5758
"devDependencies": {
5859
"@favware/cliff-jumper": "^1.8.3",

packages/docgen/src/documentation.ts

Lines changed: 175 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import { join } from 'node:path';
1+
import { dirname, join } from 'node:path';
22
import { Collection } from '@discordjs/collection';
3+
import type { DeclarationReflection } from 'typedoc';
34
import type { ChildTypes, Class, Config, CustomDocs, RootTypes } from './interfaces/index.js';
45
import { DocumentedClass } from './types/class.js';
56
import { DocumentedConstructor } from './types/constructor.js';
@@ -23,101 +24,199 @@ export class Documentation {
2324
public readonly externals = new Collection<string, DocumentedExternal>();
2425

2526
public constructor(
26-
data: RootTypes[],
27+
data: RootTypes[] | DeclarationReflection[],
2728
private readonly config: Config,
2829
private readonly custom?: Record<string, CustomDocs>,
2930
) {
30-
let items = data;
31-
for (const item of items) {
32-
switch (item.kind) {
33-
case 'class': {
34-
this.classes.set(item.name, new DocumentedClass(item, config));
35-
items = items.filter((i) => i.longname !== item.longname);
36-
break;
37-
}
38-
case 'function': {
39-
if (item.scope === 'global' || !item.memberof) {
31+
if (config.typescript) {
32+
const items = data as DeclarationReflection[];
33+
34+
for (const item of items) {
35+
switch (item.kindString) {
36+
case 'Class': {
37+
this.classes.set(item.name, new DocumentedClass(item, config));
38+
if (item.children) {
39+
this.parse(item.children, item.name);
40+
}
41+
break;
42+
}
43+
44+
case 'Function': {
4045
this.functions.set(item.name, new DocumentedMethod(item, config));
41-
items = items.filter((i) => i.longname !== item.longname);
46+
break;
4247
}
43-
break;
44-
}
45-
case 'interface': {
46-
this.interfaces.set(item.name, new DocumentedInterface(item as unknown as Class, config));
47-
items = items.filter((i) => i.longname !== item.longname);
48-
break;
49-
}
50-
case 'typedef': {
51-
this.typedefs.set(item.name, new DocumentedTypeDef(item, config));
52-
items = items.filter((i) => i.longname !== item.longname);
53-
break;
48+
49+
case 'Interface':
50+
case 'Type alias':
51+
case 'Enumeration':
52+
this.typedefs.set(item.name, new DocumentedTypeDef(item, config));
53+
if (item.children) {
54+
this.parse(item.children, item.name);
55+
}
56+
break;
57+
58+
default:
59+
break;
5460
}
55-
case 'external': {
56-
this.externals.set(item.name, new DocumentedExternal(item, config));
57-
items = items.filter((i) => i.longname !== item.longname);
58-
break;
61+
}
62+
} else {
63+
let items = data as RootTypes[];
64+
65+
for (const item of items) {
66+
switch (item.kind) {
67+
case 'class': {
68+
this.classes.set(item.name, new DocumentedClass(item, config));
69+
items = items.filter((i) => i.longname !== item.longname);
70+
break;
71+
}
72+
case 'function': {
73+
if (item.scope === 'global' || !item.memberof) {
74+
this.functions.set(item.name, new DocumentedMethod(item, config));
75+
items = items.filter((i) => i.longname !== item.longname);
76+
}
77+
break;
78+
}
79+
case 'interface': {
80+
this.interfaces.set(item.name, new DocumentedInterface(item as unknown as Class, config));
81+
items = items.filter((i) => i.longname !== item.longname);
82+
break;
83+
}
84+
case 'typedef': {
85+
this.typedefs.set(item.name, new DocumentedTypeDef(item, config));
86+
items = items.filter((i) => i.longname !== item.longname);
87+
break;
88+
}
89+
case 'external': {
90+
this.externals.set(item.name, new DocumentedExternal(item, config));
91+
items = items.filter((i) => i.longname !== item.longname);
92+
break;
93+
}
94+
default:
95+
break;
5996
}
60-
default:
61-
break;
6297
}
63-
}
6498

65-
this.parse(items as ChildTypes[]);
99+
this.parse(items as ChildTypes[]);
100+
}
66101
}
67102

68-
public parse(items: ChildTypes[]) {
69-
for (const member of items) {
70-
let item: DocumentedMethod | DocumentedConstructor | DocumentedMember | DocumentedEvent | null = null;
103+
public parse(items: ChildTypes[] | DeclarationReflection[], memberOf = '') {
104+
if (this.config.typescript) {
105+
const it = items as DeclarationReflection[];
71106

72-
switch (member.kind) {
73-
case 'constructor': {
74-
item = new DocumentedConstructor(member, this.config);
75-
break;
76-
}
77-
case 'function': {
78-
item = new DocumentedMethod(member, this.config);
79-
break;
80-
}
81-
case 'member': {
82-
item = new DocumentedMember(member, this.config);
83-
break;
84-
}
85-
case 'event': {
86-
item = new DocumentedEvent(member, this.config);
87-
break;
107+
for (const member of it) {
108+
let item: DocumentedMethod | DocumentedConstructor | DocumentedMember | DocumentedEvent | null = null;
109+
110+
switch (member.kindString) {
111+
case 'Constructor': {
112+
item = new DocumentedConstructor(member, this.config);
113+
break;
114+
}
115+
case 'Method': {
116+
item = new DocumentedMethod(member, this.config);
117+
break;
118+
}
119+
case 'Property': {
120+
item = new DocumentedMember(member, this.config);
121+
break;
122+
}
123+
case 'event': {
124+
item = new DocumentedEvent(member, this.config);
125+
break;
126+
}
127+
default: {
128+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
129+
console.warn(`- Unknown documentation kind "${member.kindString}" - \n${JSON.stringify(member)}\n`);
130+
}
88131
}
89-
default: {
90-
// @ts-expect-error
91-
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
92-
console.warn(`- Unknown documentation kind "${member.kind}" - \n${JSON.stringify(member)}\n`);
132+
133+
const parent = this.classes.get(memberOf) ?? this.interfaces.get(memberOf);
134+
if (parent) {
135+
if (item) {
136+
parent.add(item);
137+
} else {
138+
console.warn(
139+
`- Documentation item could not be constructed for "${member.name}" - \n${JSON.stringify(member)}\n`,
140+
);
141+
}
142+
continue;
93143
}
144+
145+
const info = [];
146+
const name = (member.name || item?.data.name) ?? 'UNKNOWN';
147+
const meta =
148+
member.kindString === 'constructor'
149+
? null
150+
: {
151+
file: member.sources?.[0]?.fileName,
152+
line: member.sources?.[0]?.line,
153+
path: dirname(member.sources?.[0]?.fileName ?? ''),
154+
};
155+
156+
if (memberOf) info.push(`member of "${memberOf}"`);
157+
if (meta) info.push(`${join(meta.path, meta.file ?? '')}${meta.line ? `:${meta.line}` : ''}`);
158+
159+
console.warn(`- "${name}"${info.length ? ` (${info.join(', ')})` : ''} has no accessible parent.`);
160+
if (!name && !info.length) console.warn('Raw object:', member);
94161
}
162+
} else {
163+
const it = items as ChildTypes[];
95164

96-
const parent = this.classes.get(member.memberof ?? '') ?? this.interfaces.get(member.memberof ?? '');
97-
if (parent) {
98-
if (item) {
99-
parent.add(item);
100-
} else {
101-
console.warn(
102-
`- Documentation item could not be constructed for "${member.name}" - \n${JSON.stringify(member)}\n`,
103-
);
165+
for (const member of it) {
166+
let item: DocumentedMethod | DocumentedConstructor | DocumentedMember | DocumentedEvent | null = null;
167+
168+
switch (member.kind) {
169+
case 'constructor': {
170+
item = new DocumentedConstructor(member, this.config);
171+
break;
172+
}
173+
case 'function': {
174+
item = new DocumentedMethod(member, this.config);
175+
break;
176+
}
177+
case 'member': {
178+
item = new DocumentedMember(member, this.config);
179+
break;
180+
}
181+
case 'event': {
182+
item = new DocumentedEvent(member, this.config);
183+
break;
184+
}
185+
default: {
186+
// @ts-expect-error
187+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
188+
console.warn(`- Unknown documentation kind "${member.kind}" - \n${JSON.stringify(member)}\n`);
189+
}
104190
}
105-
continue;
106-
}
107191

108-
const info = [];
109-
const name = (member.name || item?.data.name) ?? 'UNKNOWN';
110-
const memberof = member.memberof ?? item?.data.memberof;
111-
const meta =
112-
member.kind === 'constructor'
113-
? null
114-
: { file: member.meta.filename, line: member.meta.lineno, path: member.meta.path };
192+
const parent = this.classes.get(member.memberof ?? '') ?? this.interfaces.get(member.memberof ?? '');
193+
if (parent) {
194+
if (item) {
195+
parent.add(item);
196+
} else {
197+
console.warn(
198+
`- Documentation item could not be constructed for "${member.name}" - \n${JSON.stringify(member)}\n`,
199+
);
200+
}
201+
continue;
202+
}
115203

116-
if (memberof) info.push(`member of "${memberof}"`);
117-
if (meta) info.push(`${join(meta.path, meta.file)}${meta.line ? `:${meta.line}` : ''}`);
204+
const info = [];
205+
const name = (member.name || item?.data.name) ?? 'UNKNOWN';
206+
// @ts-expect-error
207+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unnecessary-condition
208+
const memberof = member.memberof ?? item?.data?.memberof;
209+
const meta =
210+
member.kind === 'constructor'
211+
? null
212+
: { file: member.meta.filename, line: member.meta.lineno, path: member.meta.path };
118213

119-
console.warn(`- "${name}"${info.length ? ` (${info.join(', ')})` : ''} has no accessible parent.`);
120-
if (!name && !info.length) console.warn('Raw object:', member);
214+
if (memberof) info.push(`member of "${memberof as string}"`);
215+
if (meta) info.push(`${join(meta.path, meta.file)}${meta.line ? `:${meta.line}` : ''}`);
216+
217+
console.warn(`- "${name}"${info.length ? ` (${info.join(', ')})` : ''} has no accessible parent.`);
218+
if (!name && !info.length) console.warn('Raw object:', member);
219+
}
121220
}
122221
}
123222

0 commit comments

Comments
 (0)