mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-18 12:33:30 +01:00
feat: docs for mixin methods, examples (#9960)
This commit is contained in:
@@ -3,7 +3,18 @@
|
|||||||
|
|
||||||
import { existsSync } from 'node:fs';
|
import { existsSync } from 'node:fs';
|
||||||
import * as path from 'node:path';
|
import * as path from 'node:path';
|
||||||
|
import type {
|
||||||
|
IApiMethodOptions,
|
||||||
|
ApiItemContainerMixin,
|
||||||
|
IApiParameterOptions,
|
||||||
|
IExcerptTokenRange,
|
||||||
|
IExcerptTokenRangeWithTypeParameters,
|
||||||
|
IExcerptToken,
|
||||||
|
IApiTypeParameterOptions,
|
||||||
|
IApiPropertyOptions,
|
||||||
|
} from '@discordjs/api-extractor-model';
|
||||||
import {
|
import {
|
||||||
|
ApiItemKind,
|
||||||
ApiModel,
|
ApiModel,
|
||||||
ApiClass,
|
ApiClass,
|
||||||
ApiPackage,
|
ApiPackage,
|
||||||
@@ -13,16 +24,11 @@ import {
|
|||||||
ApiNamespace,
|
ApiNamespace,
|
||||||
ApiInterface,
|
ApiInterface,
|
||||||
ApiPropertySignature,
|
ApiPropertySignature,
|
||||||
type ApiItemContainerMixin,
|
|
||||||
ReleaseTag,
|
ReleaseTag,
|
||||||
ApiProperty,
|
ApiProperty,
|
||||||
ApiMethodSignature,
|
ApiMethodSignature,
|
||||||
type IApiParameterOptions,
|
|
||||||
ApiEnum,
|
ApiEnum,
|
||||||
ApiEnumMember,
|
ApiEnumMember,
|
||||||
type IExcerptTokenRange,
|
|
||||||
type IExcerptTokenRangeWithTypeParameters,
|
|
||||||
type IExcerptToken,
|
|
||||||
ApiConstructor,
|
ApiConstructor,
|
||||||
ApiConstructSignature,
|
ApiConstructSignature,
|
||||||
ApiFunction,
|
ApiFunction,
|
||||||
@@ -30,7 +36,6 @@ import {
|
|||||||
ApiVariable,
|
ApiVariable,
|
||||||
ApiTypeAlias,
|
ApiTypeAlias,
|
||||||
ApiCallSignature,
|
ApiCallSignature,
|
||||||
type IApiTypeParameterOptions,
|
|
||||||
EnumMemberOrder,
|
EnumMemberOrder,
|
||||||
ExcerptTokenKind,
|
ExcerptTokenKind,
|
||||||
Navigation,
|
Navigation,
|
||||||
@@ -214,6 +219,14 @@ function filePathFromJson(meta: DocgenMetaJson): string {
|
|||||||
return `${meta.path.slice('packages/discord.js/'.length)}/${meta.file}`;
|
return `${meta.path.slice('packages/discord.js/'.length)}/${meta.file}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatVarType(type: DocgenVarTypeJson): string {
|
||||||
|
return (Array.isArray(type) ? type : type.types ?? []).map((t1) => t1.map((t2) => t2.join('')).join('')).join(' | ');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getFirstType(type: DocgenVarTypeJson): string {
|
||||||
|
return (Array.isArray(type) ? type[0]?.[0]?.[0] : type.types?.[0]?.[0]?.[0]) ?? 'unknown';
|
||||||
|
}
|
||||||
|
|
||||||
export class ApiModelGenerator {
|
export class ApiModelGenerator {
|
||||||
private readonly _collector: Collector;
|
private readonly _collector: Collector;
|
||||||
|
|
||||||
@@ -433,6 +446,42 @@ export class ApiModelGenerator {
|
|||||||
name: childDeclaration.astSymbol.localName,
|
name: childDeclaration.astSymbol.localName,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const method of (context.parentDocgenJson as DocgenClassJson | DocgenInterfaceJson | undefined)?.methods ??
|
||||||
|
[]) {
|
||||||
|
switch (context.parentApiItem.kind) {
|
||||||
|
case ApiItemKind.Class:
|
||||||
|
this._processApiMethod(null, { ...context, name: method.name });
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ApiItemKind.Interface:
|
||||||
|
this._processApiMethodSignature(null, { ...context, name: method.name });
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
console.log(
|
||||||
|
`Found docgen method not in TS typings for ApiItem of kind ${ApiItemKind[context.parentApiItem.kind]}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const property of (context.parentDocgenJson as DocgenClassJson | DocgenInterfaceJson | undefined)?.props ??
|
||||||
|
[]) {
|
||||||
|
switch (context.parentApiItem.kind) {
|
||||||
|
case ApiItemKind.Class:
|
||||||
|
this._processApiProperty(null, { ...context, name: property.name });
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ApiItemKind.Interface:
|
||||||
|
this._processApiPropertySignature(null, { ...context, name: property.name });
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
console.log(
|
||||||
|
`Found docgen property not in TS typings for ApiItem of kind ${ApiItemKind[context.parentApiItem.kind]}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _processApiCallSignature(astDeclaration: AstDeclaration, context: IProcessAstEntityContext): void {
|
private _processApiCallSignature(astDeclaration: AstDeclaration, context: IProcessAstEntityContext): void {
|
||||||
@@ -955,17 +1004,20 @@ export class ApiModelGenerator {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private _processApiMethod(astDeclaration: AstDeclaration, context: IProcessAstEntityContext): void {
|
private _processApiMethod(astDeclaration: AstDeclaration | null, context: IProcessAstEntityContext): void {
|
||||||
const { name, parentApiItem } = context;
|
const { name, parentApiItem } = context;
|
||||||
const isStatic: boolean = (astDeclaration.modifierFlags & ts.ModifierFlags.Static) !== 0;
|
const parent = context.parentDocgenJson as DocgenClassJson | DocgenInterfaceJson | undefined;
|
||||||
const overloadIndex: number = this._collector.getOverloadIndex(astDeclaration);
|
const jsDoc = parent?.methods?.find((method) => method.name === name);
|
||||||
|
const isStatic: boolean = astDeclaration
|
||||||
|
? (astDeclaration.modifierFlags & ts.ModifierFlags.Static) !== 0
|
||||||
|
: jsDoc?.scope === 'static';
|
||||||
|
const overloadIndex: number = astDeclaration ? this._collector.getOverloadIndex(astDeclaration) : 1;
|
||||||
const containerKey: string = ApiMethod.getContainerKey(name, isStatic, overloadIndex);
|
const containerKey: string = ApiMethod.getContainerKey(name, isStatic, overloadIndex);
|
||||||
|
|
||||||
let apiMethod: ApiMethod | undefined = parentApiItem.tryGetMemberByKey(containerKey) as ApiMethod;
|
let apiMethod: ApiMethod | undefined = parentApiItem.tryGetMemberByKey(containerKey) as ApiMethod;
|
||||||
const parent = context.parentDocgenJson as DocgenClassJson | DocgenInterfaceJson | undefined;
|
|
||||||
const jsDoc = parent?.methods?.find((method) => method.name === name);
|
|
||||||
|
|
||||||
if (apiMethod === undefined) {
|
if (apiMethod === undefined) {
|
||||||
|
if (astDeclaration) {
|
||||||
const methodDeclaration: ts.MethodDeclaration = astDeclaration.declaration as ts.MethodDeclaration;
|
const methodDeclaration: ts.MethodDeclaration = astDeclaration.declaration as ts.MethodDeclaration;
|
||||||
|
|
||||||
const nodesToCapture: IExcerptBuilderNodeToCapture[] = [];
|
const nodesToCapture: IExcerptBuilderNodeToCapture[] = [];
|
||||||
@@ -978,19 +1030,25 @@ export class ApiModelGenerator {
|
|||||||
methodDeclaration.typeParameters,
|
methodDeclaration.typeParameters,
|
||||||
);
|
);
|
||||||
|
|
||||||
const parameters: IApiParameterOptions[] = this._captureParameters(nodesToCapture, methodDeclaration.parameters);
|
const parameters: IApiParameterOptions[] = this._captureParameters(
|
||||||
|
nodesToCapture,
|
||||||
|
methodDeclaration.parameters,
|
||||||
|
);
|
||||||
|
|
||||||
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
|
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
|
||||||
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
|
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
|
||||||
const docComment: tsdoc.DocComment | undefined = jsDoc
|
const docComment: tsdoc.DocComment | undefined = jsDoc
|
||||||
? this._tsDocParser.parseString(
|
? this._tsDocParser.parseString(
|
||||||
`/**\n * ${fixLinkTags(jsDoc.description)}\n${
|
`/**\n * ${fixLinkTags(jsDoc.description)}\n${
|
||||||
jsDoc.params?.map((param) => ` * @param ${param.name} - ${fixLinkTags(param.description)}\n`).join('') ??
|
jsDoc.params
|
||||||
''
|
?.map((param) => ` * @param ${param.name} - ${fixLinkTags(param.description)}\n`)
|
||||||
|
.join('') ?? ''
|
||||||
}${
|
}${
|
||||||
jsDoc.returns?.length && !Array.isArray(jsDoc.returns[0])
|
jsDoc.returns?.length && !Array.isArray(jsDoc.returns[0])
|
||||||
? ` * @returns ${fixLinkTags(jsDoc.returns[0]!.description ?? '')}`
|
? ` * @returns ${fixLinkTags(jsDoc.returns[0]!.description ?? '')}`
|
||||||
: ''
|
: ''
|
||||||
|
}${
|
||||||
|
jsDoc.examples?.map((example) => ` * @example\n * \`\`\`js\n * ${example}\n * \`\`\`\n`).join('') ?? ''
|
||||||
}${
|
}${
|
||||||
jsDoc.deprecated
|
jsDoc.deprecated
|
||||||
? ` * @deprecated ${
|
? ` * @deprecated ${
|
||||||
@@ -1027,14 +1085,17 @@ export class ApiModelGenerator {
|
|||||||
fileLine: jsDoc?.meta.line ?? sourceLocation.sourceFileLine,
|
fileLine: jsDoc?.meta.line ?? sourceLocation.sourceFileLine,
|
||||||
fileColumn: sourceLocation.sourceFileColumn,
|
fileColumn: sourceLocation.sourceFileColumn,
|
||||||
});
|
});
|
||||||
|
} else if (jsDoc) {
|
||||||
|
apiMethod = new ApiMethod(this._mapMethod(jsDoc, parentApiItem.getAssociatedPackage()!.name));
|
||||||
|
}
|
||||||
|
|
||||||
parentApiItem.addMember(apiMethod);
|
parentApiItem.addMember(apiMethod);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _processApiMethodSignature(astDeclaration: AstDeclaration, context: IProcessAstEntityContext): void {
|
private _processApiMethodSignature(astDeclaration: AstDeclaration | null, context: IProcessAstEntityContext): void {
|
||||||
const { name, parentApiItem } = context;
|
const { name, parentApiItem } = context;
|
||||||
const overloadIndex: number = this._collector.getOverloadIndex(astDeclaration);
|
const overloadIndex: number = astDeclaration ? this._collector.getOverloadIndex(astDeclaration) : 1;
|
||||||
const containerKey: string = ApiMethodSignature.getContainerKey(name, overloadIndex);
|
const containerKey: string = ApiMethodSignature.getContainerKey(name, overloadIndex);
|
||||||
|
|
||||||
let apiMethodSignature: ApiMethodSignature | undefined = parentApiItem.tryGetMemberByKey(
|
let apiMethodSignature: ApiMethodSignature | undefined = parentApiItem.tryGetMemberByKey(
|
||||||
@@ -1044,6 +1105,7 @@ export class ApiModelGenerator {
|
|||||||
const jsDoc = parent?.methods?.find((method) => method.name === name);
|
const jsDoc = parent?.methods?.find((method) => method.name === name);
|
||||||
|
|
||||||
if (apiMethodSignature === undefined) {
|
if (apiMethodSignature === undefined) {
|
||||||
|
if (astDeclaration) {
|
||||||
const methodSignature: ts.MethodSignature = astDeclaration.declaration as ts.MethodSignature;
|
const methodSignature: ts.MethodSignature = astDeclaration.declaration as ts.MethodSignature;
|
||||||
|
|
||||||
const nodesToCapture: IExcerptBuilderNodeToCapture[] = [];
|
const nodesToCapture: IExcerptBuilderNodeToCapture[] = [];
|
||||||
@@ -1063,8 +1125,9 @@ export class ApiModelGenerator {
|
|||||||
const docComment: tsdoc.DocComment | undefined = jsDoc
|
const docComment: tsdoc.DocComment | undefined = jsDoc
|
||||||
? this._tsDocParser.parseString(
|
? this._tsDocParser.parseString(
|
||||||
`/**\n * ${fixLinkTags(jsDoc.description)}\n${
|
`/**\n * ${fixLinkTags(jsDoc.description)}\n${
|
||||||
jsDoc.params?.map((param) => ` * @param ${param.name} - ${fixLinkTags(param.description)}\n`).join('') ??
|
jsDoc.params
|
||||||
''
|
?.map((param) => ` * @param ${param.name} - ${fixLinkTags(param.description)}\n`)
|
||||||
|
.join('') ?? ''
|
||||||
}${
|
}${
|
||||||
jsDoc.returns?.length && !Array.isArray(jsDoc.returns[0])
|
jsDoc.returns?.length && !Array.isArray(jsDoc.returns[0])
|
||||||
? ` * @returns ${fixLinkTags(jsDoc.returns[0]!.description ?? '')}`
|
? ` * @returns ${fixLinkTags(jsDoc.returns[0]!.description ?? '')}`
|
||||||
@@ -1096,6 +1159,9 @@ export class ApiModelGenerator {
|
|||||||
fileLine: jsDoc?.meta.line ?? sourceLocation.sourceFileLine,
|
fileLine: jsDoc?.meta.line ?? sourceLocation.sourceFileLine,
|
||||||
fileColumn: sourceLocation.sourceFileColumn,
|
fileColumn: sourceLocation.sourceFileColumn,
|
||||||
});
|
});
|
||||||
|
} else if (jsDoc) {
|
||||||
|
apiMethodSignature = new ApiMethodSignature(this._mapMethod(jsDoc, parentApiItem.getAssociatedPackage()!.name));
|
||||||
|
}
|
||||||
|
|
||||||
parentApiItem.addMember(apiMethodSignature);
|
parentApiItem.addMember(apiMethodSignature);
|
||||||
}
|
}
|
||||||
@@ -1133,16 +1199,21 @@ export class ApiModelGenerator {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private _processApiProperty(astDeclaration: AstDeclaration, context: IProcessAstEntityContext): void {
|
private _processApiProperty(astDeclaration: AstDeclaration | null, context: IProcessAstEntityContext): void {
|
||||||
const { name, parentApiItem } = context;
|
const { name, parentApiItem } = context;
|
||||||
const isStatic: boolean = (astDeclaration.modifierFlags & ts.ModifierFlags.Static) !== 0;
|
const parent = context.parentDocgenJson as DocgenClassJson | DocgenInterfaceJson | DocgenTypedefJson | undefined;
|
||||||
|
const jsDoc = parent?.props?.find((prop) => prop.name === name);
|
||||||
|
const isStatic: boolean = astDeclaration
|
||||||
|
? (astDeclaration.modifierFlags & ts.ModifierFlags.Static) !== 0
|
||||||
|
: parentApiItem.kind === ApiItemKind.Class || parentApiItem.kind === ApiItemKind.Interface
|
||||||
|
? (jsDoc as DocgenPropertyJson).scope === 'static'
|
||||||
|
: false;
|
||||||
const containerKey: string = ApiProperty.getContainerKey(name, isStatic);
|
const containerKey: string = ApiProperty.getContainerKey(name, isStatic);
|
||||||
|
|
||||||
let apiProperty: ApiProperty | undefined = parentApiItem.tryGetMemberByKey(containerKey) as ApiProperty;
|
let apiProperty: ApiProperty | undefined = parentApiItem.tryGetMemberByKey(containerKey) as ApiProperty;
|
||||||
const parent = context.parentDocgenJson as DocgenClassJson | DocgenInterfaceJson | DocgenTypedefJson | undefined;
|
|
||||||
const jsDoc = parent?.props?.find((prop) => prop.name === name);
|
|
||||||
|
|
||||||
if (apiProperty === undefined) {
|
if (apiProperty === undefined) {
|
||||||
|
if (astDeclaration) {
|
||||||
const declaration: ts.Declaration = astDeclaration.declaration;
|
const declaration: ts.Declaration = astDeclaration.declaration;
|
||||||
const nodesToCapture: IExcerptBuilderNodeToCapture[] = [];
|
const nodesToCapture: IExcerptBuilderNodeToCapture[] = [];
|
||||||
|
|
||||||
@@ -1204,6 +1275,14 @@ export class ApiModelGenerator {
|
|||||||
fileLine: jsDoc && 'meta' in jsDoc ? jsDoc.meta.line : sourceLocation.sourceFileLine,
|
fileLine: jsDoc && 'meta' in jsDoc ? jsDoc.meta.line : sourceLocation.sourceFileLine,
|
||||||
fileColumn: sourceLocation.sourceFileColumn,
|
fileColumn: sourceLocation.sourceFileColumn,
|
||||||
});
|
});
|
||||||
|
} else if (parentApiItem.kind === ApiItemKind.Class || parentApiItem.kind === ApiItemKind.Interface) {
|
||||||
|
apiProperty = new ApiProperty(
|
||||||
|
this._mapProp(jsDoc as DocgenPropertyJson, parentApiItem.getAssociatedPackage()!.name),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
console.log(`We got a property in ApiItem of kind ${ApiItemKind[parentApiItem.kind]}`);
|
||||||
|
}
|
||||||
|
|
||||||
parentApiItem.addMember(apiProperty);
|
parentApiItem.addMember(apiProperty);
|
||||||
} else {
|
} else {
|
||||||
// If the property was already declared before (via a merged interface declaration),
|
// If the property was already declared before (via a merged interface declaration),
|
||||||
@@ -1211,7 +1290,7 @@ export class ApiModelGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _processApiPropertySignature(astDeclaration: AstDeclaration, context: IProcessAstEntityContext): void {
|
private _processApiPropertySignature(astDeclaration: AstDeclaration | null, context: IProcessAstEntityContext): void {
|
||||||
const { name, parentApiItem } = context;
|
const { name, parentApiItem } = context;
|
||||||
const containerKey: string = ApiPropertySignature.getContainerKey(name);
|
const containerKey: string = ApiPropertySignature.getContainerKey(name);
|
||||||
|
|
||||||
@@ -1222,6 +1301,7 @@ export class ApiModelGenerator {
|
|||||||
const jsDoc = parent?.props?.find((prop) => prop.name === name);
|
const jsDoc = parent?.props?.find((prop) => prop.name === name);
|
||||||
|
|
||||||
if (apiPropertySignature === undefined) {
|
if (apiPropertySignature === undefined) {
|
||||||
|
if (astDeclaration) {
|
||||||
const propertySignature: ts.PropertySignature = astDeclaration.declaration as ts.PropertySignature;
|
const propertySignature: ts.PropertySignature = astDeclaration.declaration as ts.PropertySignature;
|
||||||
|
|
||||||
const nodesToCapture: IExcerptBuilderNodeToCapture[] = [];
|
const nodesToCapture: IExcerptBuilderNodeToCapture[] = [];
|
||||||
@@ -1257,6 +1337,13 @@ export class ApiModelGenerator {
|
|||||||
fileLine: jsDoc && 'meta' in jsDoc ? jsDoc.meta.line : sourceLocation.sourceFileLine,
|
fileLine: jsDoc && 'meta' in jsDoc ? jsDoc.meta.line : sourceLocation.sourceFileLine,
|
||||||
fileColumn: sourceLocation.sourceFileColumn,
|
fileColumn: sourceLocation.sourceFileColumn,
|
||||||
});
|
});
|
||||||
|
} else if (parentApiItem.kind === ApiItemKind.Class || parentApiItem.kind === ApiItemKind.Interface) {
|
||||||
|
apiPropertySignature = new ApiPropertySignature(
|
||||||
|
this._mapProp(jsDoc as DocgenPropertyJson, parentApiItem.getAssociatedPackage()!.name),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
console.log(`We got a property in ApiItem of kind ${ApiItemKind[parentApiItem.kind]}`);
|
||||||
|
}
|
||||||
|
|
||||||
parentApiItem.addMember(apiPropertySignature);
|
parentApiItem.addMember(apiPropertySignature);
|
||||||
} else {
|
} else {
|
||||||
@@ -1582,9 +1669,11 @@ export class ApiModelGenerator {
|
|||||||
(arr, [type, symbol]) => [
|
(arr, [type, symbol]) => [
|
||||||
...arr,
|
...arr,
|
||||||
{
|
{
|
||||||
kind: ExcerptTokenKind.Reference,
|
kind: type?.includes("'") ? ExcerptTokenKind.Content : ExcerptTokenKind.Reference,
|
||||||
text: type ?? 'unknown',
|
text: type ?? 'unknown',
|
||||||
canonicalReference: DeclarationReference.package(this._apiModel.packages[0]!.name)
|
canonicalReference: type?.includes("'")
|
||||||
|
? undefined
|
||||||
|
: DeclarationReference.package(this._apiModel.packages[0]!.name)
|
||||||
.addNavigationStep(Navigation.Members as any, DeclarationReference.parseComponent(type ?? 'unknown'))
|
.addNavigationStep(Navigation.Members as any, DeclarationReference.parseComponent(type ?? 'unknown'))
|
||||||
.withMeaning(
|
.withMeaning(
|
||||||
lookup[
|
lookup[
|
||||||
@@ -1608,4 +1697,130 @@ export class ApiModelGenerator {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _mapProp(prop: DocgenPropertyJson, _package: string): IApiPropertyOptions {
|
||||||
|
const mappedVarType = this._mapVarType(prop.type);
|
||||||
|
return {
|
||||||
|
name: prop.name,
|
||||||
|
isAbstract: Boolean(prop.abstract),
|
||||||
|
isProtected: prop.access === 'protected',
|
||||||
|
isStatic: prop.scope === 'static',
|
||||||
|
isOptional: Boolean(prop.nullable),
|
||||||
|
isReadonly: Boolean(prop.readonly),
|
||||||
|
docComment: this._tsDocParser.parseString(
|
||||||
|
`/**\n * ${prop.description}\n${prop.see?.map((see) => ` * @see ${see}\n`).join('') ?? ''}${
|
||||||
|
prop.readonly ? ' * @readonly\n' : ''
|
||||||
|
} */`,
|
||||||
|
).docComment,
|
||||||
|
excerptTokens: [
|
||||||
|
{
|
||||||
|
kind: ExcerptTokenKind.Content,
|
||||||
|
text: `${prop.access} ${prop.scope === 'static' ? 'static ' : ''}${prop.readonly ? 'readonly ' : ''}${
|
||||||
|
prop.name
|
||||||
|
} :`,
|
||||||
|
},
|
||||||
|
...mappedVarType,
|
||||||
|
{
|
||||||
|
kind: ExcerptTokenKind.Reference,
|
||||||
|
text: formatVarType(prop.type),
|
||||||
|
canonicalReference: `${_package}!${getFirstType(prop.type)}:class`,
|
||||||
|
},
|
||||||
|
{ kind: ExcerptTokenKind.Content, text: ';' },
|
||||||
|
],
|
||||||
|
propertyTypeTokenRange: { startIndex: 1, endIndex: 1 + mappedVarType.length },
|
||||||
|
releaseTag: prop.access === 'public' ? ReleaseTag.Public : ReleaseTag.Internal,
|
||||||
|
fileLine: prop.meta?.line ?? 0,
|
||||||
|
fileUrlPath: prop.meta ? `${prop.meta.path.slice(`packages/${_package}/`.length)}/${prop.meta.file}` : '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private _mapParam(
|
||||||
|
param: DocgenParamJson,
|
||||||
|
index: number,
|
||||||
|
_package: string,
|
||||||
|
paramTokens: number[],
|
||||||
|
): IApiParameterOptions {
|
||||||
|
return {
|
||||||
|
parameterName: param.name.startsWith('...') ? param.name.slice(3) : param.name,
|
||||||
|
isOptional: Boolean(param.optional),
|
||||||
|
isRest: param.name.startsWith('...'),
|
||||||
|
parameterTypeTokenRange: {
|
||||||
|
startIndex: 1 + index + paramTokens.slice(0, index).reduce((akk, num) => akk + num, 0),
|
||||||
|
endIndex: 1 + index + paramTokens.slice(0, index + 1).reduce((akk, num) => akk + num, 0),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private _mapMethod(method: DocgenMethodJson, _package: string): IApiMethodOptions {
|
||||||
|
const excerptTokens: IExcerptToken[] = [];
|
||||||
|
excerptTokens.push({
|
||||||
|
kind: ExcerptTokenKind.Content,
|
||||||
|
text: `${
|
||||||
|
method.scope === 'global'
|
||||||
|
? `export function ${method.name}(`
|
||||||
|
: `${method.access}${method.scope === 'static' ? ' static' : ''} ${method.name}(`
|
||||||
|
}${
|
||||||
|
method.params?.length
|
||||||
|
? `${method.params[0]!.name}${method.params[0]!.nullable || method.params[0]!.optional ? '?' : ''}`
|
||||||
|
: '): '
|
||||||
|
}`,
|
||||||
|
});
|
||||||
|
const paramTokens: number[] = [];
|
||||||
|
for (let index = 0; index < (method.params?.length ?? 0) - 1; index++) {
|
||||||
|
const newTokens = this._mapVarType(method.params![index]!.type);
|
||||||
|
paramTokens.push(newTokens.length);
|
||||||
|
excerptTokens.push(...newTokens);
|
||||||
|
excerptTokens.push({
|
||||||
|
kind: ExcerptTokenKind.Content,
|
||||||
|
text: `, ${method.params![index + 1]!.name}${
|
||||||
|
method.params![index + 1]!.nullable || method.params![index + 1]!.optional ? '?' : ''
|
||||||
|
}: `,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method.params?.length) {
|
||||||
|
const newTokens = this._mapVarType(method.params[method.params.length - 1]!.type);
|
||||||
|
paramTokens.push(newTokens.length);
|
||||||
|
excerptTokens.push(...newTokens);
|
||||||
|
excerptTokens.push({ kind: ExcerptTokenKind.Content, text: `): ` });
|
||||||
|
}
|
||||||
|
|
||||||
|
const returnTokens = this._mapVarType(method.returns?.[0] ?? []);
|
||||||
|
excerptTokens.push(...returnTokens);
|
||||||
|
|
||||||
|
excerptTokens.push({ kind: ExcerptTokenKind.Content, text: ';' });
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: method.name,
|
||||||
|
isAbstract: Boolean(method.abstract),
|
||||||
|
isOptional: false,
|
||||||
|
isProtected: method.access === 'protected',
|
||||||
|
isStatic: method.scope === 'static',
|
||||||
|
overloadIndex: 1,
|
||||||
|
parameters: method.params?.map((param, index) => this._mapParam(param, index, _package, paramTokens)) ?? [],
|
||||||
|
releaseTag: method.access === 'public' ? ReleaseTag.Public : ReleaseTag.Internal,
|
||||||
|
returnTypeTokenRange: method.returns?.length
|
||||||
|
? method.params?.length
|
||||||
|
? { startIndex: 2 + 2 * method.params.length, endIndex: 3 + 2 * method.params.length }
|
||||||
|
: { startIndex: 1, endIndex: 2 }
|
||||||
|
: { startIndex: 0, endIndex: 0 },
|
||||||
|
typeParameters: [],
|
||||||
|
docComment: this._tsDocParser.parseString(
|
||||||
|
`/**\n * ${method.description}\n${
|
||||||
|
method.params?.map((param) => ` * @param ${param.name} - ${param.description}\n`).join('') ?? ''
|
||||||
|
}${
|
||||||
|
method.returns?.length && !Array.isArray(method.returns[0])
|
||||||
|
? ` * @returns ${method.returns[0]!.description}`
|
||||||
|
: ''
|
||||||
|
}${method.examples?.map((example) => ` * @example\n * \`\`\`js\n * ${example}\n * \`\`\`\n`).join('') ?? ''}${
|
||||||
|
method.deprecated
|
||||||
|
? ` * @deprecated ${typeof method.deprecated === 'boolean' ? 'yes' : method.deprecated}\n`
|
||||||
|
: ''
|
||||||
|
} */`,
|
||||||
|
).docComment,
|
||||||
|
excerptTokens,
|
||||||
|
fileLine: method.meta.line,
|
||||||
|
fileUrlPath: `${method.meta.path.slice(`packages/${_package}/`.length)}/${method.meta.file}`,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user