mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-10 08:33:30 +01:00
* fix(ExceptText): don't display import("d..-types/v10"). in return type
* Squashed 'packages/api-extractor-model/' content from commit 39ecb196c
git-subtree-dir: packages/api-extractor-model
git-subtree-split: 39ecb196ca210bdf84ba6c9cadb1bb93571849d7
* Squashed 'packages/api-extractor/' content from commit 341ad6c51
git-subtree-dir: packages/api-extractor
git-subtree-split: 341ad6c51b01656d4f73b74ad4bdb3095f9262c4
* feat(api-extractor): add api-extractor and -model
* fix: package.json docs script
* fix(SourcLink): use <> instead of function syntax
* fix: make packages private
* fix: rest params showing in docs, added labels
* fix: missed two files
* feat: merge docs.json from docgen and docs.api.json
* fix: cpy-cli & pnpm-lock
* fix: increase icon size
* fix: icon size again
* feat: run both docs on mainlib
* chore: website fixes
* fix: more website fixes
* fix: tests and dev database script
* chore: comment out old docs
* fix: increase max fetch cache
* fix: env should always be a string
* fix: try to reapply patches
* fix: remove prepare for docgen
* fix: temporary cosmetic fixes
* fix: horizontal scroll
* feat: generate index for new docs
---------
Co-authored-by: Noel <buechler.noel@outlook.com>
453 lines
12 KiB
TypeScript
453 lines
12 KiB
TypeScript
import { dirname, join, relative } from 'node:path';
|
|
import type { DeclarationReflection } from 'typedoc';
|
|
import packageFile from '../package.json';
|
|
import type { ChildTypes, Class, Config, CustomDocs, RootTypes } from './interfaces/index.js';
|
|
import { DocumentedClass } from './types/class.js';
|
|
import { DocumentedConstructor } from './types/constructor.js';
|
|
import { DocumentedEvent } from './types/event.js';
|
|
import { DocumentedExternal } from './types/external.js';
|
|
import { DocumentedInterface } from './types/interface.js';
|
|
import { DocumentedMember } from './types/member.js';
|
|
import { DocumentedMethod } from './types/method.js';
|
|
import { DocumentedTypeDef } from './types/typedef.js';
|
|
|
|
export class Documentation {
|
|
public readonly classes = new Map<string, DocumentedClass>();
|
|
|
|
public readonly functions = new Map<string, DocumentedMethod>();
|
|
|
|
public readonly interfaces = new Map<string, DocumentedInterface>();
|
|
|
|
public readonly typedefs = new Map<string, DocumentedTypeDef>();
|
|
|
|
public readonly externals = new Map<string, DocumentedExternal>();
|
|
|
|
public constructor(
|
|
data: DeclarationReflection[] | RootTypes[],
|
|
private readonly config: Config,
|
|
private readonly custom?: Record<string, CustomDocs>,
|
|
) {
|
|
if (config.typescript) {
|
|
const items = data as DeclarationReflection[];
|
|
|
|
for (const item of items) {
|
|
switch (item.kindString) {
|
|
case 'Class': {
|
|
this.classes.set(item.name, new DocumentedClass(item, config));
|
|
if (item.children) {
|
|
this.parse(item.children, item);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case 'Function': {
|
|
this.functions.set(item.name, new DocumentedMethod(item, config));
|
|
break;
|
|
}
|
|
|
|
case 'Interface':
|
|
case 'Type alias':
|
|
case 'Enumeration':
|
|
this.typedefs.set(item.name, new DocumentedTypeDef(item, config));
|
|
if (item.children) {
|
|
this.parse(item.children, item);
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
let items = data as RootTypes[];
|
|
items = items.filter((item) => !item.ignore);
|
|
|
|
for (const item of items) {
|
|
switch (item.kind) {
|
|
case 'class': {
|
|
this.classes.set(item.name, new DocumentedClass(item, config));
|
|
items = items.filter((otherItem) => otherItem.longname !== item.longname || otherItem.kind !== item.kind);
|
|
break;
|
|
}
|
|
|
|
case 'function': {
|
|
if (item.scope === 'global' || !item.memberof) {
|
|
this.functions.set(item.name, new DocumentedMethod(item, config));
|
|
items = items.filter((otherItem) => otherItem.longname !== item.longname);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case 'interface': {
|
|
this.interfaces.set(item.name, new DocumentedInterface(item as unknown as Class, config));
|
|
items = items.filter((otherItem) => otherItem.longname !== item.longname);
|
|
break;
|
|
}
|
|
|
|
case 'typedef': {
|
|
this.typedefs.set(item.name, new DocumentedTypeDef(item, config));
|
|
items = items.filter((otherItem) => otherItem.longname !== item.longname);
|
|
break;
|
|
}
|
|
|
|
case 'external': {
|
|
this.externals.set(item.name, new DocumentedExternal(item, config));
|
|
items = items.filter((otherItem) => otherItem.longname !== item.longname);
|
|
break;
|
|
}
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
this.parse(items as ChildTypes[]);
|
|
}
|
|
}
|
|
|
|
public parse(items: ChildTypes[] | DeclarationReflection[], prop?: DeclarationReflection) {
|
|
if (this.config.typescript) {
|
|
const it = items as DeclarationReflection[];
|
|
|
|
for (const member of it) {
|
|
let item: DocumentedConstructor | DocumentedEvent | DocumentedMember | DocumentedMethod | null = null;
|
|
|
|
switch (member.kindString) {
|
|
case 'Constructor': {
|
|
item = new DocumentedConstructor(member, this.config);
|
|
break;
|
|
}
|
|
|
|
case 'Method': {
|
|
const event = prop?.groups?.find((group) => group.title === 'Events');
|
|
if ((event?.children as unknown as number[])?.includes(member.id)) {
|
|
item = new DocumentedEvent(member, this.config);
|
|
break;
|
|
}
|
|
|
|
item = new DocumentedMethod(member, this.config);
|
|
break;
|
|
}
|
|
|
|
case 'Property': {
|
|
item = new DocumentedMember(member, this.config);
|
|
break;
|
|
}
|
|
|
|
default: {
|
|
console.warn(`- Unknown documentation kind "${member.kindString}" - \n${JSON.stringify(member)}\n`);
|
|
}
|
|
}
|
|
|
|
const parent = this.classes.get(prop!.name) ?? this.interfaces.get(prop!.name);
|
|
if (parent) {
|
|
if (item) {
|
|
parent.add(item);
|
|
} else {
|
|
console.warn(
|
|
`- Documentation item could not be constructed for "${member.name}" - \n${JSON.stringify(member)}\n`,
|
|
);
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
const info = [];
|
|
const name = (member.name || item?.data.name) ?? 'UNKNOWN';
|
|
const meta =
|
|
member.kindString === 'constructor'
|
|
? null
|
|
: {
|
|
file: member.sources?.[0]?.fileName,
|
|
line: member.sources?.[0]?.line,
|
|
path: dirname(member.sources?.[0]?.fileName ?? ''),
|
|
};
|
|
|
|
if (prop!.name) {
|
|
info.push(`member of "${prop!.name}"`);
|
|
}
|
|
|
|
if (meta) {
|
|
info.push(
|
|
`${relative(this.config.root, join(meta.path, meta.file ?? ''))}${meta.line ? `:${meta.line}` : ''}`,
|
|
);
|
|
}
|
|
|
|
console.warn(`- "${name}"${info.length ? ` (${info.join(', ')})` : ''} has no accessible parent.`);
|
|
if (!name && !info.length) {
|
|
console.warn('Raw object:', member);
|
|
}
|
|
}
|
|
} else {
|
|
const it = items as ChildTypes[];
|
|
|
|
for (const member of it) {
|
|
let item: DocumentedConstructor | DocumentedEvent | DocumentedMember | DocumentedMethod | null = null;
|
|
|
|
switch (member.kind) {
|
|
case 'constructor': {
|
|
item = new DocumentedConstructor(member, this.config);
|
|
break;
|
|
}
|
|
|
|
case 'function': {
|
|
item = new DocumentedMethod(member, this.config);
|
|
break;
|
|
}
|
|
|
|
case 'member': {
|
|
item = new DocumentedMember(member, this.config);
|
|
break;
|
|
}
|
|
|
|
case 'event': {
|
|
item = new DocumentedEvent(member, this.config);
|
|
break;
|
|
}
|
|
|
|
default: {
|
|
// @ts-expect-error: This is a valid case
|
|
console.warn(`- Unknown documentation kind "${member.kind}" - \n${JSON.stringify(member)}\n`);
|
|
}
|
|
}
|
|
|
|
const parent = this.classes.get(member.memberof ?? '') ?? this.interfaces.get(member.memberof ?? '');
|
|
if (parent) {
|
|
if (item) {
|
|
parent.add(item);
|
|
} else {
|
|
console.warn(
|
|
`- Documentation item could not be constructed for "${member.name}" - \n${JSON.stringify(member)}\n`,
|
|
);
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
const info = [];
|
|
const name = (member.name || item?.data.name) ?? 'UNKNOWN';
|
|
// @ts-expect-error: Typescript can't infer this
|
|
const memberof = member.memberof ?? item?.data?.memberof;
|
|
const meta =
|
|
member.kind === 'constructor'
|
|
? null
|
|
: { file: member.meta.filename, line: member.meta.lineno, path: member.meta.path };
|
|
|
|
if (memberof) {
|
|
info.push(`member of "${memberof as string}"`);
|
|
}
|
|
|
|
if (meta) {
|
|
info.push(`${relative(this.config.root, join(meta.path, meta.file))}${meta.line ? `:${meta.line}` : ''}`);
|
|
}
|
|
|
|
console.warn(`- "${name}"${info.length ? ` (${info.join(', ')})` : ''} has no accessible parent.`);
|
|
if (!name && !info.length) {
|
|
console.warn('Raw object:', member);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public serialize() {
|
|
return {
|
|
meta: {
|
|
generator: packageFile.version,
|
|
format: Documentation.FORMAT_VERSION,
|
|
date: Date.now(),
|
|
},
|
|
classes: [...this.classes.values()].map((_class) => _class.serialize()),
|
|
functions: [...this.functions.values()].map((_function) => _function.serialize()),
|
|
interfaces: [...this.interfaces.values()].map((_interface) => _interface.serialize()),
|
|
typedefs: [...this.typedefs.values()].map((_typedef) => _typedef.serialize()),
|
|
externals: [...this.externals.values()].map((_external) => _external.serialize()),
|
|
custom: this.custom,
|
|
};
|
|
}
|
|
|
|
public serializeNew() {
|
|
return {
|
|
metadata: {
|
|
toolPackage: '@discordjs/docgen',
|
|
toolVersion: Documentation.FORMAT_VERSION,
|
|
schemaVersion: 1_011,
|
|
oldestForwardsCompatibleVersion: 1_001,
|
|
tsdocConfig: {
|
|
$schema: 'https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json',
|
|
noStandardTags: true,
|
|
tagDefinitions: [
|
|
{
|
|
tagName: '@alpha',
|
|
syntaxKind: 'modifier',
|
|
},
|
|
{
|
|
tagName: '@beta',
|
|
syntaxKind: 'modifier',
|
|
},
|
|
{
|
|
tagName: '@defaultValue',
|
|
syntaxKind: 'block',
|
|
},
|
|
{
|
|
tagName: '@decorator',
|
|
syntaxKind: 'block',
|
|
allowMultiple: true,
|
|
},
|
|
{
|
|
tagName: '@deprecated',
|
|
syntaxKind: 'block',
|
|
},
|
|
{
|
|
tagName: '@eventProperty',
|
|
syntaxKind: 'modifier',
|
|
},
|
|
{
|
|
tagName: '@example',
|
|
syntaxKind: 'block',
|
|
allowMultiple: true,
|
|
},
|
|
{
|
|
tagName: '@experimental',
|
|
syntaxKind: 'modifier',
|
|
},
|
|
{
|
|
tagName: '@inheritDoc',
|
|
syntaxKind: 'inline',
|
|
},
|
|
{
|
|
tagName: '@internal',
|
|
syntaxKind: 'modifier',
|
|
},
|
|
{
|
|
tagName: '@label',
|
|
syntaxKind: 'inline',
|
|
},
|
|
{
|
|
tagName: '@link',
|
|
syntaxKind: 'inline',
|
|
allowMultiple: true,
|
|
},
|
|
{
|
|
tagName: '@override',
|
|
syntaxKind: 'modifier',
|
|
},
|
|
{
|
|
tagName: '@packageDocumentation',
|
|
syntaxKind: 'modifier',
|
|
},
|
|
{
|
|
tagName: '@param',
|
|
syntaxKind: 'block',
|
|
allowMultiple: true,
|
|
},
|
|
{
|
|
tagName: '@privateRemarks',
|
|
syntaxKind: 'block',
|
|
},
|
|
{
|
|
tagName: '@public',
|
|
syntaxKind: 'modifier',
|
|
},
|
|
{
|
|
tagName: '@readonly',
|
|
syntaxKind: 'modifier',
|
|
},
|
|
{
|
|
tagName: '@remarks',
|
|
syntaxKind: 'block',
|
|
},
|
|
{
|
|
tagName: '@returns',
|
|
syntaxKind: 'block',
|
|
},
|
|
{
|
|
tagName: '@sealed',
|
|
syntaxKind: 'modifier',
|
|
},
|
|
{
|
|
tagName: '@see',
|
|
syntaxKind: 'block',
|
|
},
|
|
{
|
|
tagName: '@throws',
|
|
syntaxKind: 'block',
|
|
allowMultiple: true,
|
|
},
|
|
{
|
|
tagName: '@typeParam',
|
|
syntaxKind: 'block',
|
|
allowMultiple: true,
|
|
},
|
|
{
|
|
tagName: '@virtual',
|
|
syntaxKind: 'modifier',
|
|
},
|
|
{
|
|
tagName: '@betaDocumentation',
|
|
syntaxKind: 'modifier',
|
|
},
|
|
{
|
|
tagName: '@internalRemarks',
|
|
syntaxKind: 'block',
|
|
},
|
|
{
|
|
tagName: '@preapproved',
|
|
syntaxKind: 'modifier',
|
|
},
|
|
],
|
|
supportForTags: {
|
|
'@alpha': true,
|
|
'@beta': true,
|
|
'@defaultValue': true,
|
|
'@decorator': true,
|
|
'@deprecated': true,
|
|
'@eventProperty': true,
|
|
'@example': true,
|
|
'@experimental': true,
|
|
'@inheritDoc': true,
|
|
'@internal': true,
|
|
'@label': true,
|
|
'@link': true,
|
|
'@override': true,
|
|
'@packageDocumentation': true,
|
|
'@param': true,
|
|
'@privateRemarks': true,
|
|
'@public': true,
|
|
'@readonly': true,
|
|
'@remarks': true,
|
|
'@returns': true,
|
|
'@sealed': true,
|
|
'@see': true,
|
|
'@throws': true,
|
|
'@typeParam': true,
|
|
'@virtual': true,
|
|
'@betaDocumentation': true,
|
|
'@internalRemarks': true,
|
|
'@preapproved': true,
|
|
},
|
|
reportUnsupportedHtmlElements: false,
|
|
},
|
|
},
|
|
projectFolderUrl: 'https://github.com/discordjs/discord.js/tree/main/packages/discord.js',
|
|
kind: 'Package',
|
|
canonicalReference: 'discord.js!',
|
|
docComment: '',
|
|
name: 'discord.js',
|
|
preserveMemberOrder: false,
|
|
members: [
|
|
...[...this.classes.values()].map((_class) => _class.serialize()),
|
|
...[...this.functions.values()].map((_function) => _function.serialize()),
|
|
...[...this.interfaces.values()].map((_interface) => _interface.serialize()),
|
|
...[...this.typedefs.values()].map((_typedef) => _typedef.serialize()),
|
|
...[...this.externals.values()].map((_external) => _external.serialize()),
|
|
],
|
|
custom: this.custom,
|
|
};
|
|
}
|
|
|
|
public static readonly FORMAT_VERSION = 30;
|
|
}
|