diff --git a/packages/builders/.eslintrc.json b/packages/builders/.eslintrc.json index 99ef7cec8..6115ee5c0 100644 --- a/packages/builders/.eslintrc.json +++ b/packages/builders/.eslintrc.json @@ -1,3 +1,7 @@ { - "extends": "../../.eslintrc.json" + "extends": "../../.eslintrc.json", + "plugins": ["eslint-plugin-tsdoc"], + "rules": { + "tsdoc/syntax": "warn" + } } diff --git a/packages/builders/package.json b/packages/builders/package.json index 527569ffa..b4ebcac34 100644 --- a/packages/builders/package.json +++ b/packages/builders/package.json @@ -74,6 +74,7 @@ "eslint-config-prettier": "^8.5.0", "eslint-import-resolver-typescript": "^3.4.1", "eslint-plugin-import": "^2.26.0", + "eslint-plugin-tsdoc": "^0.2.16", "prettier": "^2.7.1", "rollup-plugin-typescript2": "0.32.1", "typescript": "^4.7.4", diff --git a/packages/builders/src/components/ActionRow.ts b/packages/builders/src/components/ActionRow.ts index 5580d3f89..245fa1dc4 100644 --- a/packages/builders/src/components/ActionRow.ts +++ b/packages/builders/src/components/ActionRow.ts @@ -59,7 +59,7 @@ export class ActionRowBuilder extends ComponentBu } /** - * {@inheritDoc JSONEncodable.toJSON} + * {@inheritDoc ComponentBuilder.toJSON} */ public toJSON(): APIActionRowComponent> { // eslint-disable-next-line @typescript-eslint/consistent-type-assertions diff --git a/packages/builders/src/components/Component.ts b/packages/builders/src/components/Component.ts index 1775a6d69..b9f85674a 100644 --- a/packages/builders/src/components/Component.ts +++ b/packages/builders/src/components/Component.ts @@ -23,7 +23,11 @@ export abstract class ComponentBuilder< public readonly data: Partial; /** - * {@inheritDoc JSONEncodable.toJSON} + * Serializes this component to an API-compatible JSON object + * + * @remarks + * This method runs validations on the data before serializing it. + * As such, it may throw an error if the data is invalid. */ public abstract toJSON(): AnyAPIActionRowComponent; diff --git a/packages/builders/src/components/button/Button.ts b/packages/builders/src/components/button/Button.ts index 853667b5e..63ed26090 100644 --- a/packages/builders/src/components/button/Button.ts +++ b/packages/builders/src/components/button/Button.ts @@ -21,6 +21,35 @@ import { ComponentBuilder } from '../Component'; * Represents a button component */ export class ButtonBuilder extends ComponentBuilder { + /** + * Creates a new button from API data + * @param data - The API data to create this button with + * + * @example + * Creating a button from an API data object + * ```ts + * const button = new ButtonBuilder({ + * style: 'primary', + * label: 'Click Me', + * emoji: { + * name: ':smile:', + * id: '12345678901234567890123456789012', + * }, + * custom_id: '12345678901234567890123456789012', + * }); + * ``` + * + * @example + * Creating a button using setters and API data + * ```ts + * const button = new ButtonBuilder({ + * style: 'primary', + * label: 'Click Me', + * }) + * .setEmoji({ name: ':smile:', id: '12345678901234567890123456789012' }) + * .setCustomId('12345678901234567890123456789012'); + * ``` + */ public constructor(data?: Partial) { super({ type: ComponentType.Button, ...data }); } @@ -38,6 +67,10 @@ export class ButtonBuilder extends ComponentBuilder { /** * Sets the URL for this button * + * @remarks + * This method is only available to buttons using the `Link` button style. + * Only three types of URL schemes are currently supported: `https://`, `http://` and `discord://` + * * @param url - The URL to open when this button is clicked */ public setURL(url: string) { @@ -48,6 +81,9 @@ export class ButtonBuilder extends ComponentBuilder { /** * Sets the custom id for this button * + * @remarks + * This method is only applicable to buttons that are not using the `Link` button style. + * * @param customId - The custom id to use for this button */ public setCustomId(customId: string) { @@ -86,7 +122,7 @@ export class ButtonBuilder extends ComponentBuilder { } /** - * {@inheritDoc JSONEncodable.toJSON} + * {@inheritDoc ComponentBuilder.toJSON} */ public toJSON(): APIButtonComponent { validateRequiredButtonParameters( diff --git a/packages/builders/src/components/selectMenu/SelectMenu.ts b/packages/builders/src/components/selectMenu/SelectMenu.ts index 2eccd4692..55751ee70 100644 --- a/packages/builders/src/components/selectMenu/SelectMenu.ts +++ b/packages/builders/src/components/selectMenu/SelectMenu.ts @@ -117,7 +117,7 @@ export class SelectMenuBuilder extends ComponentBuilder } /** - * {@inheritDoc JSONEncodable.toJSON} + * {@inheritDoc ComponentBuilder.toJSON} */ public toJSON(): APISelectMenuComponent { validateRequiredSelectMenuParameters(this.options, this.data.custom_id); diff --git a/packages/builders/src/components/selectMenu/SelectMenuOption.ts b/packages/builders/src/components/selectMenu/SelectMenuOption.ts index 452b46a83..3dba43869 100644 --- a/packages/builders/src/components/selectMenu/SelectMenuOption.ts +++ b/packages/builders/src/components/selectMenu/SelectMenuOption.ts @@ -65,7 +65,7 @@ export class SelectMenuOptionBuilder implements JSONEncodable): this { fields = normalizeArray(fields); @@ -120,9 +120,9 @@ export class EmbedBuilder { * embed.spliceFields(-1, 1); * ``` * - * @param index The index to start at - * @param deleteCount The number of fields to remove - * @param fields The replacing field objects + * @param index - The index to start at + * @param deleteCount - The number of fields to remove + * @param fields - The replacing field objects */ public spliceFields(index: number, deleteCount: number, ...fields: APIEmbedField[]): this { // Ensure adding these fields won't exceed the 25 field limit @@ -144,7 +144,7 @@ export class EmbedBuilder { * * You can set a maximum of 25 fields. * - * @param fields The fields to set + * @param fields - The fields to set */ public setFields(...fields: RestOrArray) { this.spliceFields(0, this.data.fields?.length ?? 0, ...normalizeArray(fields)); @@ -154,7 +154,7 @@ export class EmbedBuilder { /** * Sets the author of this embed * - * @param options The options for the author + * @param options - The options for the author */ public setAuthor(options: EmbedAuthorOptions | null): this { @@ -173,7 +173,7 @@ export class EmbedBuilder { /** * Sets the color of this embed * - * @param color The color of the embed + * @param color - The color of the embed */ public setColor(color: number | RGBTuple | null): this { // Data assertions @@ -191,7 +191,7 @@ export class EmbedBuilder { /** * Sets the description of this embed * - * @param description The description + * @param description - The description */ public setDescription(description: string | null): this { // Data assertions @@ -204,7 +204,7 @@ export class EmbedBuilder { /** * Sets the footer of this embed * - * @param options The options for the footer + * @param options - The options for the footer */ public setFooter(options: EmbedFooterOptions | null): this { if (options === null) { @@ -222,7 +222,7 @@ export class EmbedBuilder { /** * Sets the image of this embed * - * @param url The URL of the image + * @param url - The URL of the image */ public setImage(url: string | null): this { // Data assertions @@ -235,7 +235,7 @@ export class EmbedBuilder { /** * Sets the thumbnail of this embed * - * @param url The URL of the thumbnail + * @param url - The URL of the thumbnail */ public setThumbnail(url: string | null): this { // Data assertions @@ -248,7 +248,7 @@ export class EmbedBuilder { /** * Sets the timestamp of this embed * - * @param timestamp The timestamp or date + * @param timestamp - The timestamp or date */ public setTimestamp(timestamp: number | Date | null = Date.now()): this { // Data assertions @@ -261,7 +261,7 @@ export class EmbedBuilder { /** * Sets the title of this embed * - * @param title The title + * @param title - The title */ public setTitle(title: string | null): this { // Data assertions @@ -274,7 +274,7 @@ export class EmbedBuilder { /** * Sets the URL of this embed * - * @param url The URL + * @param url - The URL */ public setURL(url: string | null): this { // Data assertions diff --git a/packages/collection/.eslintrc.json b/packages/collection/.eslintrc.json index 99ef7cec8..6115ee5c0 100644 --- a/packages/collection/.eslintrc.json +++ b/packages/collection/.eslintrc.json @@ -1,3 +1,7 @@ { - "extends": "../../.eslintrc.json" + "extends": "../../.eslintrc.json", + "plugins": ["eslint-plugin-tsdoc"], + "rules": { + "tsdoc/syntax": "warn" + } } diff --git a/packages/collection/package.json b/packages/collection/package.json index bb98fa1d1..ce17f3d0f 100644 --- a/packages/collection/package.json +++ b/packages/collection/package.json @@ -63,6 +63,7 @@ "eslint-config-prettier": "^8.5.0", "eslint-import-resolver-typescript": "^3.4.1", "eslint-plugin-import": "^2.26.0", + "eslint-plugin-tsdoc": "^0.2.16", "prettier": "^2.7.1", "rollup-plugin-typescript2": "0.32.1", "typescript": "^4.7.4", diff --git a/packages/proxy/.eslintrc.json b/packages/proxy/.eslintrc.json index 99ef7cec8..6115ee5c0 100644 --- a/packages/proxy/.eslintrc.json +++ b/packages/proxy/.eslintrc.json @@ -1,3 +1,7 @@ { - "extends": "../../.eslintrc.json" + "extends": "../../.eslintrc.json", + "plugins": ["eslint-plugin-tsdoc"], + "rules": { + "tsdoc/syntax": "warn" + } } diff --git a/packages/rest/.eslintrc.json b/packages/rest/.eslintrc.json index 99ef7cec8..6115ee5c0 100644 --- a/packages/rest/.eslintrc.json +++ b/packages/rest/.eslintrc.json @@ -1,3 +1,7 @@ { - "extends": "../../.eslintrc.json" + "extends": "../../.eslintrc.json", + "plugins": ["eslint-plugin-tsdoc"], + "rules": { + "tsdoc/syntax": "warn" + } } diff --git a/packages/rest/package.json b/packages/rest/package.json index 61875f2f8..5387dd4d2 100644 --- a/packages/rest/package.json +++ b/packages/rest/package.json @@ -74,6 +74,7 @@ "eslint-config-prettier": "^8.5.0", "eslint-import-resolver-typescript": "^3.4.1", "eslint-plugin-import": "^2.26.0", + "eslint-plugin-tsdoc": "^0.2.16", "prettier": "^2.7.1", "rollup-plugin-typescript2": "0.32.1", "typescript": "^4.7.4", diff --git a/packages/rest/src/lib/REST.ts b/packages/rest/src/lib/REST.ts index 356b077e2..adb148a48 100644 --- a/packages/rest/src/lib/REST.ts +++ b/packages/rest/src/lib/REST.ts @@ -91,7 +91,7 @@ export interface RESTOptions { /** * Extra information to add to the user agent * - * @defaultValue ``Node.js ${process.version}`` + * @defaultValue `Node.js ${process.version}` */ userAgentAppendix: string; /** diff --git a/packages/rest/src/lib/RequestManager.ts b/packages/rest/src/lib/RequestManager.ts index 52ef3a0c0..3ef43edc0 100644 --- a/packages/rest/src/lib/RequestManager.ts +++ b/packages/rest/src/lib/RequestManager.ts @@ -65,7 +65,7 @@ export interface RequestData { */ body?: BodyInit | unknown; /** - * The {@link https://undici.nodejs.org/#/docs/api/Agent Agent} to use for the request. + * The {@link https://undici.nodejs.org/#/docs/api/Agent | Agent} to use for the request. */ dispatcher?: Agent; /** @@ -174,7 +174,7 @@ export interface RequestManager { */ export class RequestManager extends EventEmitter { /** - * The {@link https://undici.nodejs.org/#/docs/api/Agent Agent} for all requests + * The {@link https://undici.nodejs.org/#/docs/api/Agent | Agent} for all requests * performed by this manager. */ public agent: Dispatcher | null = null; @@ -342,7 +342,7 @@ export class RequestManager extends EventEmitter { * @param hash - The hash for the route * @param majorParameter - The major parameter for this handler * - * @private + * @internal */ private createHandler(hash: string, majorParameter: string) { // Create the async request queue to handle requests @@ -487,7 +487,7 @@ export class RequestManager extends EventEmitter { * @param endpoint - The raw endpoint to generalize * @param method - The HTTP method this endpoint is called without * - * @private + * @internal */ private static generateRouteData(endpoint: RouteLike, method: RequestMethod): RouteData { const majorIdMatch = /^\/(?:channels|guilds|webhooks)\/(\d{16,19})/.exec(endpoint); diff --git a/packages/rest/src/lib/handlers/IHandler.ts b/packages/rest/src/lib/handlers/IHandler.ts index 840dcccbb..c5370f931 100644 --- a/packages/rest/src/lib/handlers/IHandler.ts +++ b/packages/rest/src/lib/handlers/IHandler.ts @@ -3,13 +3,27 @@ import type { RequestOptions } from '../REST'; import type { HandlerRequestData, RouteData } from '../RequestManager'; export interface IHandler { + /** + * Queues a request to be sent + * + * @param routeId - The generalized api route with literal ids for major parameters + * @param url - The url to do the request on + * @param options - All the information needed to make a request + * @param requestData - Extra data from the user's request needed for errors and additional processing + */ queueRequest: ( routeId: RouteData, url: string, options: RequestOptions, requestData: HandlerRequestData, ) => Promise; + /** + * If the bucket is currently inactive (no pending requests) + */ // eslint-disable-next-line @typescript-eslint/method-signature-style -- This is meant to be a getter returning a bool get inactive(): boolean; + /** + * The unique id of the handler + */ readonly id: string; } diff --git a/packages/rest/src/lib/handlers/SequentialHandler.ts b/packages/rest/src/lib/handlers/SequentialHandler.ts index c7afe833d..b53b8ed8c 100644 --- a/packages/rest/src/lib/handlers/SequentialHandler.ts +++ b/packages/rest/src/lib/handlers/SequentialHandler.ts @@ -30,7 +30,7 @@ const enum QueueType { */ export class SequentialHandler implements IHandler { /** - * The unique id of the handler + * {@inheritDoc IHandler.id} */ public readonly id: string; @@ -87,7 +87,7 @@ export class SequentialHandler implements IHandler { } /** - * If the bucket is currently inactive (no pending requests) + * {@inheritDoc IHandler.inactive} */ public get inactive(): boolean { return ( @@ -161,12 +161,7 @@ export class SequentialHandler implements IHandler { } /** - * Queues a request to be sent - * - * @param routeId - The generalized api route with literal ids for major parameters - * @param url - The url to do the request on - * @param options - All the information needed to make a request - * @param requestData - Extra data from the user's request needed for errors and additional processing + * {@inheritDoc IHandler.queueRequest} */ public async queueRequest( routeId: RouteData, diff --git a/packages/voice/.eslintrc.json b/packages/voice/.eslintrc.json index f07d57ea2..e63740acf 100644 --- a/packages/voice/.eslintrc.json +++ b/packages/voice/.eslintrc.json @@ -1,5 +1,9 @@ { "extends": "../../.eslintrc.json", + "plugins": ["eslint-plugin-tsdoc"], + "rules": { + "tsdoc/syntax": "warn" + }, "parserOptions": { "project": "./tsconfig.eslint.json", "extraFileExtensions": [".mjs"] diff --git a/packages/voice/package.json b/packages/voice/package.json index 6c3e6c54f..0eca57056 100644 --- a/packages/voice/package.json +++ b/packages/voice/package.json @@ -75,6 +75,7 @@ "eslint-config-prettier": "^8.5.0", "eslint-import-resolver-typescript": "^3.4.1", "eslint-plugin-import": "^2.26.0", + "eslint-plugin-tsdoc": "^0.2.16", "jest": "^28.1.3", "jest-websocket-mock": "^2.4.0", "mock-socket": "^9.1.5", diff --git a/packages/voice/src/VoiceConnection.ts b/packages/voice/src/VoiceConnection.ts index 7efad7486..eb76482c9 100644 --- a/packages/voice/src/VoiceConnection.ts +++ b/packages/voice/src/VoiceConnection.ts @@ -165,22 +165,22 @@ export type VoiceConnectionState = export interface VoiceConnection extends EventEmitter { /** * Emitted when there is an error emitted from the voice connection - * @event + * @eventProperty */ on(event: 'error', listener: (error: Error) => void): this; /** * Emitted debugging information about the voice connection - * @event + * @eventProperty */ on(event: 'debug', listener: (message: string) => void): this; /** * Emitted when the state of the voice connection changes - * @event + * @eventProperty */ on(event: 'stateChange', listener: (oldState: VoiceConnectionState, newState: VoiceConnectionState) => void): this; /** * Emitted when the state of the voice connection changes to a specific status - * @event + * @eventProperty */ on( event: T, diff --git a/packages/voice/src/audio/AudioPlayer.ts b/packages/voice/src/audio/AudioPlayer.ts index f6a82fd19..25d73361c 100644 --- a/packages/voice/src/audio/AudioPlayer.ts +++ b/packages/voice/src/audio/AudioPlayer.ts @@ -154,27 +154,27 @@ export type AudioPlayerState = export interface AudioPlayer extends EventEmitter { /** * Emitted when there is an error emitted from the audio resource played by the audio player - * @event + * @eventProperty */ on(event: 'error', listener: (error: AudioPlayerError) => void): this; /** * Emitted debugging information about the audio player - * @event + * @eventProperty */ on(event: 'debug', listener: (message: string) => void): this; /** * Emitted when the state of the audio player changes - * @event + * @eventProperty */ on(event: 'stateChange', listener: (oldState: AudioPlayerState, newState: AudioPlayerState) => void): this; /** * Emitted when the audio player is subscribed to a voice connection - * @event + * @eventProperty */ on(event: 'subscribe' | 'unsubscribe', listener: (subscription: PlayerSubscription) => void): this; /** * Emitted when the status of state changes to a specific status - * @event + * @eventProperty */ on( event: T, diff --git a/packages/voice/src/audio/AudioResource.ts b/packages/voice/src/audio/AudioResource.ts index 616401947..61b1d9cc8 100644 --- a/packages/voice/src/audio/AudioResource.ts +++ b/packages/voice/src/audio/AudioResource.ts @@ -7,7 +7,7 @@ import { noop } from '../util/util'; /** * Options that are set when creating a new audio resource. * - * @template T - the type for the metadata (if any) of the audio resource + * @typeParam T - the type for the metadata (if any) of the audio resource */ export interface CreateAudioResourceOptions { /** @@ -38,7 +38,7 @@ export interface CreateAudioResourceOptions { /** * Represents an audio resource that can be played by an audio player. * - * @template T - the type for the metadata (if any) of the audio resource + * @typeParam T - the type for the metadata (if any) of the audio resource */ export class AudioResource { /** @@ -204,7 +204,7 @@ export function inferStreamType(stream: Readable): { * @param input - The resource to play * @param options - Configurable options for creating the resource * - * @template T - the type for the metadata (if any) of the audio resource + * @typeParam T - the type for the metadata (if any) of the audio resource */ export function createAudioResource( input: string | Readable, @@ -228,7 +228,7 @@ export function createAudioResource( * @param input - The resource to play * @param options - Configurable options for creating the resource * - * @template T - the type for the metadata (if any) of the audio resource + * @typeParam T - the type for the metadata (if any) of the audio resource */ export function createAudioResource( input: string | Readable, @@ -248,7 +248,7 @@ export function createAudioResource( * @param input - The resource to play * @param options - Configurable options for creating the resource * - * @template T - the type for the metadata (if any) of the audio resource + * @typeParam T - the type for the metadata (if any) of the audio resource */ export function createAudioResource( input: string | Readable, diff --git a/packages/voice/src/networking/Networking.ts b/packages/voice/src/networking/Networking.ts index 946b8ccf3..7af99ba2d 100644 --- a/packages/voice/src/networking/Networking.ts +++ b/packages/voice/src/networking/Networking.ts @@ -155,7 +155,7 @@ export interface Networking extends EventEmitter { /** * Debug event for Networking. * - * @event + * @eventProperty */ on(event: 'debug', listener: (message: string) => void): this; on(event: 'error', listener: (error: Error) => void): this; diff --git a/packages/voice/src/networking/VoiceWebSocket.ts b/packages/voice/src/networking/VoiceWebSocket.ts index 1e4445114..1b9ad77ae 100644 --- a/packages/voice/src/networking/VoiceWebSocket.ts +++ b/packages/voice/src/networking/VoiceWebSocket.ts @@ -10,13 +10,13 @@ export interface VoiceWebSocket extends EventEmitter { /** * Debug event for VoiceWebSocket. * - * @event + * @eventProperty */ on(event: 'debug', listener: (message: string) => void): this; /** * Packet event. * - * @event + * @eventProperty */ on(event: 'packet', listener: (packet: any) => void): this; } diff --git a/packages/voice/src/receive/SpeakingMap.ts b/packages/voice/src/receive/SpeakingMap.ts index 7e807c019..b1049d764 100644 --- a/packages/voice/src/receive/SpeakingMap.ts +++ b/packages/voice/src/receive/SpeakingMap.ts @@ -4,13 +4,13 @@ import { EventEmitter } from 'node:events'; export interface SpeakingMap extends EventEmitter { /** * Emitted when a user starts speaking. - * @event + * @eventProperty */ on(event: 'start', listener: (userId: string) => void): this; /** * Emitted when a user ends speaking. - * @event + * @eventProperty */ on(event: 'end', listener: (userId: string) => void): this; } diff --git a/packages/website/src/DocModel/ApiNodeJSONEncoder.ts b/packages/website/src/DocModel/ApiNodeJSONEncoder.ts new file mode 100644 index 000000000..526f91912 --- /dev/null +++ b/packages/website/src/DocModel/ApiNodeJSONEncoder.ts @@ -0,0 +1,381 @@ +import { + ApiModel, + ApiDeclaredItem, + ApiPropertyItem, + ApiMethod, + ApiParameterListMixin, + ApiTypeParameterListMixin, + ApiClass, + ApiFunction, + ApiItemKind, + ApiTypeAlias, + ApiEnum, + ApiInterface, + ApiMethodSignature, + ApiPropertySignature, + ApiVariable, + ApiItem, + ApiConstructor, + ApiItemContainerMixin, +} from '@microsoft/api-extractor-model'; +import { generateTypeParamData } from './TypeParameterMixin'; +import { Visibility } from './Visibility'; +import { createCommentNode } from './comment'; +import type { DocBlockJSON } from './comment/CommentBlock'; +import type { AnyDocNodeJSON } from './comment/CommentNode'; +import { DocNodeContainerJSON, nodeContainer } from './comment/CommentNodeContainer'; +import { + generatePath, + genParameter, + genReference, + genToken, + resolveName, + TokenDocumentation, +} from '~/util/parse.server'; + +export interface ReferenceData { + name: string; + path: string; +} + +export interface InheritanceData { + parentName: string; + path: string; + parentKey: string; +} + +export interface ApiInheritableJSON { + inheritanceData: InheritanceData | null; +} + +export interface ApiItemJSON { + kind: string; + name: string; + referenceData: ReferenceData; + excerpt: string; + excerptTokens: TokenDocumentation[]; + remarks: DocNodeContainerJSON | null; + summary: DocNodeContainerJSON | null; + deprecated: DocNodeContainerJSON | null; + comment: AnyDocNodeJSON | null; + containerKey: string; + path: string[]; +} + +export interface ApiPropertyItemJSON extends ApiItemJSON, ApiInheritableJSON { + propertyTypeTokens: TokenDocumentation[]; + readonly: boolean; + optional: boolean; +} + +export interface ApiTypeParameterListJSON { + typeParameters: ApiTypeParameterJSON[]; +} + +export interface ApiTypeParameterJSON { + name: string; + constraintTokens: TokenDocumentation[]; + defaultTokens: TokenDocumentation[]; + optional: boolean; + commentBlock: DocBlockJSON | null; +} + +export interface ApiParameterListJSON { + parameters: ApiParameterJSON[]; +} + +export interface ApiMethodSignatureJSON + extends ApiItemJSON, + ApiTypeParameterListJSON, + ApiParameterListJSON, + ApiInheritableJSON { + returnTypeTokens: TokenDocumentation[]; + optional: boolean; + overloadIndex: number; +} + +export interface ApiMethodJSON extends ApiMethodSignatureJSON { + static: boolean; + visibility: Visibility; +} + +export interface ApiParameterJSON { + name: string; + isOptional: boolean; + tokens: TokenDocumentation[]; + paramCommentBlock: DocBlockJSON | null; +} + +export interface ApiClassJSON extends ApiItemJSON, ApiTypeParameterListJSON { + constructor: ApiConstructorJSON | null; + properties: ApiPropertyItemJSON[]; + methods: ApiMethodJSON[]; + extendsTokens: TokenDocumentation[]; + implementsTokens: TokenDocumentation[][]; +} + +export interface ApiTypeAliasJSON extends ApiItemJSON, ApiTypeParameterListJSON { + typeTokens: TokenDocumentation[]; +} + +export interface EnumMemberData { + name: string; + initializerTokens: TokenDocumentation[]; + summary: DocNodeContainerJSON | null; +} + +export interface ApiEnumJSON extends ApiItemJSON { + members: EnumMemberData[]; +} + +export interface ApiInterfaceJSON extends ApiItemJSON, ApiTypeParameterListJSON { + properties: ApiPropertyItemJSON[]; + methods: ApiMethodSignatureJSON[]; + extendsTokens: TokenDocumentation[][] | null; +} + +export interface ApiVariableJSON extends ApiItemJSON { + typeTokens: TokenDocumentation[]; + readonly: boolean; +} + +export interface ApiFunctionJSON extends ApiItemJSON, ApiTypeParameterListJSON, ApiParameterListJSON { + returnTypeTokens: TokenDocumentation[]; + overloadIndex: number; +} + +export interface ApiConstructorJSON extends ApiItemJSON, ApiParameterListJSON { + protected: boolean; +} + +// eslint-disable-next-line @typescript-eslint/no-extraneous-class +export class ApiNodeJSONEncoder { + public static encode(model: ApiModel, node: ApiItem) { + if (!(node instanceof ApiDeclaredItem)) { + throw new Error(`Cannot serialize node of type ${node.kind}`); + } + + switch (node.kind) { + case ApiItemKind.Class: + return this.encodeClass(model, node as ApiClass); + case ApiItemKind.Function: + return this.encodeFunction(model, node as ApiFunction); + case ApiItemKind.Interface: + return this.encodeInterface(model, node as ApiInterface); + case ApiItemKind.TypeAlias: + return this.encodeTypeAlias(model, node as ApiTypeAlias); + case ApiItemKind.Enum: + return this.encodeEnum(model, node as ApiEnum); + case ApiItemKind.Variable: + return this.encodeVariable(model, node as ApiVariable); + default: + throw new Error(`Unknown API item kind: ${node.kind}`); + } + } + + public static encodeItem(model: ApiModel, item: ApiDeclaredItem): ApiItemJSON { + const path = []; + for (const _item of item.getHierarchy()) { + switch (_item.kind) { + case 'None': + case 'EntryPoint': + case 'Model': + break; + default: + path.push(resolveName(_item)); + } + } + + return { + kind: item.kind, + name: resolveName(item), + referenceData: genReference(item), + excerpt: item.excerpt.text, + excerptTokens: item.excerpt.spannedTokens.map((token) => genToken(model, token)), + remarks: item.tsdocComment?.remarksBlock + ? (createCommentNode(item.tsdocComment.remarksBlock, model, item.parent) as DocNodeContainerJSON) + : null, + summary: item.tsdocComment?.summarySection + ? (createCommentNode(item.tsdocComment.summarySection, model, item.parent) as DocNodeContainerJSON) + : null, + deprecated: item.tsdocComment?.deprecatedBlock + ? (createCommentNode(item.tsdocComment.deprecatedBlock, model, item.parent) as DocNodeContainerJSON) + : null, + path, + containerKey: item.containerKey, + comment: item.tsdocComment ? createCommentNode(item.tsdocComment, model, item.parent) : null, + }; + } + + public static encodeParameterList( + model: ApiModel, + item: ApiParameterListMixin & ApiDeclaredItem, + ): { parameters: ApiParameterJSON[] } { + return { + parameters: item.parameters.map((param) => genParameter(model, param)), + }; + } + + public static encodeTypeParameterList(model: ApiModel, item: ApiTypeParameterListMixin & ApiDeclaredItem) { + return { + typeParameters: item.typeParameters.map((param) => generateTypeParamData(model, param, item.parent)), + }; + } + + public static encodeProperty( + model: ApiModel, + item: ApiPropertyItem, + parent: ApiItemContainerMixin, + ): ApiPropertyItemJSON { + return { + ...this.encodeItem(model, item), + ...this.encodeInheritanceData(item, parent), + propertyTypeTokens: item.propertyTypeExcerpt.spannedTokens.map((token) => genToken(model, token)), + readonly: item.isReadonly, + optional: item.isOptional, + }; + } + + public static encodeInheritanceData(item: ApiDeclaredItem, parent: ApiItemContainerMixin): ApiInheritableJSON { + return { + inheritanceData: + item.parent && item.parent.containerKey !== parent.containerKey + ? { + parentKey: item.parent.containerKey, + parentName: item.parent.displayName, + path: generatePath(item.parent.getHierarchy()), + } + : null, + }; + } + + public static encodeFunction(model: ApiModel, item: ApiFunction) { + return { + ...this.encodeItem(model, item), + ...this.encodeParameterList(model, item), + ...this.encodeTypeParameterList(model, item), + returnTypeTokens: item.returnTypeExcerpt.spannedTokens.map((token) => genToken(model, token)), + overloadIndex: item.overloadIndex, + }; + } + + public static encodeMethodSignature( + model: ApiModel, + item: ApiMethodSignature, + parent: ApiItemContainerMixin, + ): ApiMethodSignatureJSON { + return { + ...this.encodeFunction(model, item), + ...this.encodeInheritanceData(item, parent), + optional: item.isOptional, + }; + } + + public static encodeMethod(model: ApiModel, item: ApiMethod, parent: ApiItemContainerMixin): ApiMethodJSON { + return { + ...this.encodeMethodSignature(model, item, parent), + static: item.isStatic, + visibility: item.isProtected ? Visibility.Protected : Visibility.Public, + }; + } + + public static encodeClass(model: ApiModel, item: ApiClass): ApiClassJSON { + const extendsExcerpt = item.extendsType?.excerpt; + + const methods: ApiMethodJSON[] = []; + const properties: ApiPropertyItemJSON[] = []; + + let constructor: ApiConstructor | undefined; + + for (const member of item.findMembersWithInheritance().items) { + switch (member.kind) { + case ApiItemKind.Method: + methods.push(this.encodeMethod(model, member as ApiMethod, item)); + break; + case ApiItemKind.Property: + properties.push(this.encodeProperty(model, member as ApiPropertyItem, item)); + break; + case ApiItemKind.Constructor: + constructor = member as ApiConstructor; + break; + default: + break; + } + } + + return { + ...this.encodeItem(model, item), + ...this.encodeTypeParameterList(model, item), + constructor: constructor ? this.encodeConstructor(model, constructor) : null, + extendsTokens: extendsExcerpt ? extendsExcerpt.spannedTokens.map((token) => genToken(model, token)) : [], + implementsTokens: item.implementsTypes.map((excerpt) => + excerpt.excerpt.spannedTokens.map((token) => genToken(model, token)), + ), + methods, + properties, + }; + } + + public static encodeTypeAlias(model: ApiModel, item: ApiTypeAlias): ApiTypeAliasJSON { + return { + ...this.encodeItem(model, item), + ...this.encodeTypeParameterList(model, item), + typeTokens: item.typeExcerpt.spannedTokens.map((token) => genToken(model, token)), + }; + } + + public static encodeEnum(model: ApiModel, item: ApiEnum): ApiEnumJSON { + return { + ...this.encodeItem(model, item), + members: item.members.map((member) => ({ + name: member.name, + initializerTokens: member.initializerExcerpt?.spannedTokens.map((token) => genToken(model, token)) ?? [], + summary: member.tsdocComment ? nodeContainer(member.tsdocComment.summarySection, model, member) : null, + })), + }; + } + + public static encodeInterface(model: ApiModel, item: ApiInterface): ApiInterfaceJSON { + const methods: ApiMethodSignatureJSON[] = []; + const properties: ApiPropertyItemJSON[] = []; + + for (const member of item.findMembersWithInheritance().items) { + switch (member.kind) { + case ApiItemKind.MethodSignature: + methods.push(this.encodeMethodSignature(model, member as ApiMethodSignature, item)); + break; + case ApiItemKind.PropertySignature: + properties.push(this.encodeProperty(model, member as ApiPropertySignature, item)); + break; + default: + break; + } + } + + return { + ...this.encodeItem(model, item), + ...this.encodeTypeParameterList(model, item), + extendsTokens: item.extendsTypes.map((excerpt) => + excerpt.excerpt.spannedTokens.map((token) => genToken(model, token)), + ), + methods, + properties, + }; + } + + public static encodeVariable(model: ApiModel, item: ApiVariable): ApiVariableJSON { + return { + ...this.encodeItem(model, item), + typeTokens: item.variableTypeExcerpt.spannedTokens.map((token) => genToken(model, token)), + readonly: item.isReadonly, + }; + } + + public static encodeConstructor(model: ApiModel, item: ApiConstructor): ApiConstructorJSON { + return { + ...this.encodeItem(model, item), + ...this.encodeParameterList(model, item), + protected: item.isProtected, + }; + } +} diff --git a/packages/website/src/DocModel/DocClass.ts b/packages/website/src/DocModel/DocClass.ts deleted file mode 100644 index 0403e1e2e..000000000 --- a/packages/website/src/DocModel/DocClass.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { - type ApiClass, - type ApiModel, - ApiItemKind, - type ApiMethod, - type ApiPropertyItem, -} from '@microsoft/api-extractor-model'; -import { DocItem } from './DocItem'; -import { DocMethod } from './DocMethod'; -import { DocProperty } from './DocProperty'; -import { TypeParameterMixin } from './TypeParameterMixin'; -import { type TokenDocumentation, genToken } from '~/util/parse.server'; - -export class DocClass extends TypeParameterMixin(DocItem) { - public readonly extendsTokens: TokenDocumentation[] | null; - public readonly implementsTokens: TokenDocumentation[][]; - public readonly methods: DocMethod[] = []; - public readonly properties: DocProperty[] = []; - - public constructor(model: ApiModel, item: ApiClass) { - super(model, item); - const extendsExcerpt = item.extendsType?.excerpt; - - this.extendsTokens = extendsExcerpt - ? extendsExcerpt.spannedTokens.map((token) => genToken(this.model, token)) - : null; - - this.implementsTokens = item.implementsTypes.map((excerpt) => - excerpt.excerpt.spannedTokens.map((token) => genToken(this.model, token)), - ); - - for (const member of item.findMembersWithInheritance().items) { - switch (member.kind) { - case ApiItemKind.Method: { - const method = member as ApiMethod; - - if (method.parent?.containerKey !== this.containerKey) { - this.methods.push(new DocMethod(this.model, method, true)); - break; - } - this.methods.push(new DocMethod(this.model, method)); - break; - } - case ApiItemKind.Property: { - const property = member as ApiPropertyItem; - - if (property.parent?.containerKey !== this.containerKey) { - this.properties.push(new DocProperty(this.model, property, true)); - break; - } - - this.properties.push(new DocProperty(this.model, property)); - break; - } - default: - break; - } - } - } - - public override toJSON() { - return { - ...super.toJSON(), - extendsTokens: this.extendsTokens, - implementsTokens: this.implementsTokens, - methods: this.methods.map((method) => method.toJSON()), - properties: this.properties.map((prop) => prop.toJSON()), - }; - } -} diff --git a/packages/website/src/DocModel/DocEnum.ts b/packages/website/src/DocModel/DocEnum.ts deleted file mode 100644 index c2b7fcb69..000000000 --- a/packages/website/src/DocModel/DocEnum.ts +++ /dev/null @@ -1,31 +0,0 @@ -import type { ApiEnum, ApiModel } from '@microsoft/api-extractor-model'; -import { DocItem } from './DocItem'; -import { nodeContainer } from './comment/CommentNodeContainer'; -import { genToken, TokenDocumentation } from '~/util/parse.server'; - -export interface EnumMemberData { - name: string; - initializerTokens: TokenDocumentation[]; - summary: ReturnType['summary']; -} - -export class DocEnum extends DocItem { - public readonly members: EnumMemberData[] = []; - - public constructor(model: ApiModel, item: ApiEnum) { - super(model, item); - - this.members = item.members.map((member) => ({ - name: member.name, - initializerTokens: member.initializerExcerpt?.spannedTokens.map((token) => genToken(this.model, token)) ?? [], - summary: member.tsdocComment ? nodeContainer(member.tsdocComment.summarySection, model, member) : null, - })); - } - - public override toJSON() { - return { - ...super.toJSON(), - members: this.members, - }; - } -} diff --git a/packages/website/src/DocModel/DocFunction.ts b/packages/website/src/DocModel/DocFunction.ts deleted file mode 100644 index 03731e2af..000000000 --- a/packages/website/src/DocModel/DocFunction.ts +++ /dev/null @@ -1,26 +0,0 @@ -import type { ApiFunction, ApiModel, ApiParameterListMixin } from '@microsoft/api-extractor-model'; -import { DocItem } from './DocItem'; -import { TypeParameterMixin } from './TypeParameterMixin'; -import { type TokenDocumentation, genToken, genParameter, ParameterDocumentation } from '~/util/parse.server'; - -export class DocFunction extends TypeParameterMixin(DocItem) { - public readonly returnTypeTokens: TokenDocumentation[]; - public readonly overloadIndex: number; - public readonly parameters: ParameterDocumentation[]; - - public constructor(model: ApiModel, item: ApiFunction) { - super(model, item); - this.returnTypeTokens = item.returnTypeExcerpt.spannedTokens.map((token) => genToken(this.model, token)); - this.overloadIndex = item.overloadIndex; - this.parameters = (item as ApiParameterListMixin).parameters.map((param) => genParameter(this.model, param)); - } - - public override toJSON() { - return { - ...super.toJSON(), - parameters: this.parameters, - returnTypeTokens: this.returnTypeTokens, - overloadIndex: this.overloadIndex, - }; - } -} diff --git a/packages/website/src/DocModel/DocInterface.ts b/packages/website/src/DocModel/DocInterface.ts deleted file mode 100644 index 88058b1cf..000000000 --- a/packages/website/src/DocModel/DocInterface.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { DocItem } from './DocItem'; -import { DocMethodSignature } from './DocMethodSignature'; -import { DocProperty } from './DocProperty'; -import { TypeParameterMixin } from './TypeParameterMixin'; -import { - ApiInterface, - ApiItemKind, - ApiMethodSignature, - ApiModel, - ApiPropertySignature, -} from '~/util/api-extractor.server'; -import { type TokenDocumentation, genToken } from '~/util/parse.server'; - -export class DocInterface extends TypeParameterMixin(DocItem) { - public readonly extendsTokens: TokenDocumentation[][] | null; - public readonly methods: DocMethodSignature[] = []; - public readonly properties: DocProperty[] = []; - - public constructor(model: ApiModel, item: ApiInterface) { - super(model, item); - - this.extendsTokens = item.extendsTypes.map((excerpt) => - excerpt.excerpt.spannedTokens.map((token) => genToken(this.model, token)), - ); - - for (const member of item.findMembersWithInheritance().items) { - switch (member.kind) { - case ApiItemKind.MethodSignature: { - const method = member as ApiMethodSignature; - - if (method.parent?.containerKey !== this.containerKey) { - this.methods.push(new DocMethodSignature(this.model, method, true)); - break; - } - this.methods.push(new DocMethodSignature(this.model, method)); - break; - } - case ApiItemKind.PropertySignature: { - const property = member as ApiPropertySignature; - - if (property.parent?.containerKey !== this.containerKey) { - this.properties.push(new DocProperty(this.model, property, true)); - break; - } - - this.properties.push(new DocProperty(this.model, property)); - break; - } - default: - break; - } - } - } - - public override toJSON() { - return { - ...super.toJSON(), - extendsTokens: this.extendsTokens, - methods: this.methods.map((method) => method.toJSON()), - properties: this.properties.map((prop) => prop.toJSON()), - }; - } -} diff --git a/packages/website/src/DocModel/DocItem.ts b/packages/website/src/DocModel/DocItem.ts deleted file mode 100644 index c6e6c5afe..000000000 --- a/packages/website/src/DocModel/DocItem.ts +++ /dev/null @@ -1,76 +0,0 @@ -import type { ApiModel, ApiDeclaredItem } from '@microsoft/api-extractor-model'; -import { createCommentNode } from './comment'; -import type { AnyDocNodeJSON } from './comment/CommentNode'; -import type { DocNodeContainerJSON } from './comment/CommentNodeContainer'; -import type { ReferenceData } from '~/util/model.server'; -import { resolveName, genReference, TokenDocumentation, genToken } from '~/util/parse.server'; - -export type DocItemConstructor = new (...args: any[]) => T; - -export class DocItem { - public readonly item: T; - public readonly name: string; - public readonly referenceData: ReferenceData; - public readonly model: ApiModel; - public readonly excerpt: string; - public readonly excerptTokens: TokenDocumentation[] = []; - public readonly kind: string; - public readonly remarks: DocNodeContainerJSON | null; - public readonly summary: DocNodeContainerJSON | null; - public readonly deprecated: DocNodeContainerJSON | null; - public readonly containerKey: string; - public readonly comment: AnyDocNodeJSON | null; - - public constructor(model: ApiModel, item: T) { - this.item = item; - this.kind = item.kind; - this.model = model; - this.name = resolveName(item); - this.referenceData = genReference(item); - this.excerpt = item.excerpt.text; - this.excerptTokens = item.excerpt.spannedTokens.map((token) => genToken(model, token)); - this.remarks = item.tsdocComment?.remarksBlock - ? (createCommentNode(item.tsdocComment.remarksBlock, model, item.parent) as DocNodeContainerJSON) - : null; - this.summary = item.tsdocComment?.summarySection - ? (createCommentNode(item.tsdocComment.summarySection, model, item.parent) as DocNodeContainerJSON) - : null; - this.deprecated = item.tsdocComment?.deprecatedBlock - ? (createCommentNode(item.tsdocComment.deprecatedBlock, model, item.parent) as DocNodeContainerJSON) - : null; - this.containerKey = item.containerKey; - this.comment = item.tsdocComment ? createCommentNode(item.tsdocComment, model, item.parent) : null; - } - - public get path() { - const path = []; - for (const item of this.item.getHierarchy()) { - switch (item.kind) { - case 'None': - case 'EntryPoint': - case 'Model': - break; - default: - path.push(resolveName(item)); - } - } - - return path; - } - - public toJSON() { - return { - name: this.name, - referenceData: this.referenceData, - summary: this.summary, - excerpt: this.excerpt, - excerptTokens: this.excerptTokens, - kind: this.kind, - remarks: this.remarks, - deprecated: this.deprecated, - path: this.path, - containerKey: this.containerKey, - comment: this.comment, - }; - } -} diff --git a/packages/website/src/DocModel/DocMethod.ts b/packages/website/src/DocModel/DocMethod.ts deleted file mode 100644 index 9a6e8dd35..000000000 --- a/packages/website/src/DocModel/DocMethod.ts +++ /dev/null @@ -1,40 +0,0 @@ -import type { ApiMethod, ApiModel } from '@microsoft/api-extractor-model'; -import { DocFunction } from './DocFunction'; -import { Visibility } from './Visibility'; -import { generatePath } from '~/util/parse.server'; - -export interface InheritanceData { - parentName: string; - path: string; -} - -export class DocMethod extends DocFunction { - public readonly static: boolean; - public readonly optional: boolean; - public readonly visibility: Visibility; - public readonly inheritanceData: InheritanceData | null; - - public constructor(model: ApiModel, item: ApiMethod, inherited = false) { - super(model, item); - this.static = item.isStatic; - this.optional = item.isOptional; - this.visibility = item.isProtected ? Visibility.Protected : Visibility.Public; - this.inheritanceData = - inherited && item.parent - ? { - parentName: item.parent.displayName, - path: generatePath(item.parent.getHierarchy()), - } - : null; - } - - public override toJSON() { - return { - ...super.toJSON(), - static: this.static, - optional: this.optional, - visibility: this.visibility, - inheritanceData: this.inheritanceData, - }; - } -} diff --git a/packages/website/src/DocModel/DocMethodSignature.ts b/packages/website/src/DocModel/DocMethodSignature.ts deleted file mode 100644 index 0a8268a9a..000000000 --- a/packages/website/src/DocModel/DocMethodSignature.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type { ApiMethodSignature, ApiModel } from '@microsoft/api-extractor-model'; -import { DocFunction } from './DocFunction'; -import type { InheritanceData } from './DocMethod'; -import { generatePath } from '~/util/parse.server'; - -export class DocMethodSignature extends DocFunction { - public readonly optional: boolean; - public readonly inheritanceData: InheritanceData | null; - - public constructor(model: ApiModel, item: ApiMethodSignature, inherited = false) { - super(model, item); - this.optional = item.isOptional; - this.inheritanceData = - inherited && item.parent - ? { - parentName: item.parent.displayName, - path: generatePath(item.parent.getHierarchy()), - } - : null; - } - - public override toJSON() { - return { - ...super.toJSON(), - optional: this.optional, - inheritanceData: this.inheritanceData, - }; - } -} diff --git a/packages/website/src/DocModel/DocProperty.ts b/packages/website/src/DocModel/DocProperty.ts deleted file mode 100644 index 8a2389b07..000000000 --- a/packages/website/src/DocModel/DocProperty.ts +++ /dev/null @@ -1,35 +0,0 @@ -import type { ApiPropertyItem, ApiModel, ApiPropertySignature } from '@microsoft/api-extractor-model'; -import { DocItem } from './DocItem'; -import type { InheritanceData } from './DocMethod'; -import { type TokenDocumentation, genToken, generatePath } from '~/util/parse.server'; - -export class DocProperty extends DocItem { - public readonly propertyTypeTokens: TokenDocumentation[]; - public readonly readonly: boolean; - public readonly optional: boolean; - public readonly inheritanceData: InheritanceData | null; - - public constructor(model: ApiModel, item: ApiPropertyItem | ApiPropertySignature, inherited = false) { - super(model, item); - this.propertyTypeTokens = item.propertyTypeExcerpt.spannedTokens.map((token) => genToken(this.model, token)); - this.readonly = item.isReadonly; - this.optional = item.isOptional; - this.inheritanceData = - inherited && item.parent - ? { - parentName: item.parent.displayName, - path: generatePath(item.parent.getHierarchy()), - } - : null; - } - - public override toJSON() { - return { - ...super.toJSON(), - propertyTypeTokens: this.propertyTypeTokens, - readonly: this.readonly, - optional: this.optional, - inheritanceData: this.inheritanceData, - }; - } -} diff --git a/packages/website/src/DocModel/DocTypeAlias.ts b/packages/website/src/DocModel/DocTypeAlias.ts deleted file mode 100644 index 7101176cc..000000000 --- a/packages/website/src/DocModel/DocTypeAlias.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type { ApiModel, ApiTypeAlias } from '@microsoft/api-extractor-model'; -import { DocItem } from './DocItem'; -import { TypeParameterMixin } from './TypeParameterMixin'; -import { type TokenDocumentation, genToken } from '~/util/parse.server'; - -export class DocTypeAlias extends TypeParameterMixin(DocItem) { - public readonly typeTokens: TokenDocumentation[]; - - public constructor(model: ApiModel, item: ApiTypeAlias) { - super(model, item); - this.typeTokens = item.typeExcerpt.spannedTokens.map((token) => genToken(model, token)); - } - - public override toJSON() { - return { - ...super.toJSON(), - typeTokens: this.typeTokens, - }; - } -} diff --git a/packages/website/src/DocModel/DocVariable.ts b/packages/website/src/DocModel/DocVariable.ts deleted file mode 100644 index 2cf946bfe..000000000 --- a/packages/website/src/DocModel/DocVariable.ts +++ /dev/null @@ -1,22 +0,0 @@ -import type { ApiModel, ApiVariable } from '@microsoft/api-extractor-model'; -import { DocItem } from './DocItem'; -import { genToken, TokenDocumentation } from '~/util/parse.server'; - -export class DocVariable extends DocItem { - public readonly typeTokens: TokenDocumentation[] = []; - public readonly readonly: boolean; - - public constructor(model: ApiModel, item: ApiVariable) { - super(model, item); - this.typeTokens = item.variableTypeExcerpt.spannedTokens.map((token) => genToken(model, token)); - this.readonly = item.isReadonly; - } - - public override toJSON() { - return { - ...super.toJSON(), - typeTokens: this.typeTokens, - readonly: this.readonly, - }; - } -} diff --git a/packages/website/src/DocModel/TypeParameterMixin.ts b/packages/website/src/DocModel/TypeParameterMixin.ts index adaf0b5d5..74fb155ac 100644 --- a/packages/website/src/DocModel/TypeParameterMixin.ts +++ b/packages/website/src/DocModel/TypeParameterMixin.ts @@ -1,5 +1,4 @@ -import type { ApiItem, ApiModel, ApiTypeParameterListMixin, TypeParameter } from '@microsoft/api-extractor-model'; -import type { DocItemConstructor } from './DocItem'; +import type { ApiItem, ApiModel, TypeParameter } from '@microsoft/api-extractor-model'; import { block, DocBlockJSON } from './comment/CommentBlock'; import { genToken, TokenDocumentation } from '~/util/parse.server'; @@ -27,24 +26,3 @@ export function generateTypeParamData( commentBlock: typeParam.tsdocTypeParamBlock ? block(typeParam.tsdocTypeParamBlock, model, parentItem) : null, }; } - -export function TypeParameterMixin(Base: TBase) { - return class Mixed extends Base { - public readonly typeParameters: TypeParameterData[] = []; - - public constructor(...args: any[]); - public constructor(model: ApiModel, item: ApiItem) { - super(model, item); - this.typeParameters = (item as ApiTypeParameterListMixin).typeParameters.map((typeParam) => - generateTypeParamData(this.model, typeParam, item.parent), - ); - } - - public override toJSON() { - return { - ...super.toJSON(), - typeParameterData: this.typeParameters, - }; - } - }; -} diff --git a/packages/website/src/components/CodeListing.tsx b/packages/website/src/components/CodeListing.tsx index 462007588..be6744eef 100644 --- a/packages/website/src/components/CodeListing.tsx +++ b/packages/website/src/components/CodeListing.tsx @@ -3,8 +3,7 @@ import type { ReactNode } from 'react'; import { HyperlinkedText } from './HyperlinkedText'; import { InheritanceText } from './InheritanceText'; import { TSDoc } from './tsdoc/TSDoc'; -import type { DocItem } from '~/DocModel/DocItem'; -import type { InheritanceData } from '~/DocModel/DocMethod'; +import type { ApiItemJSON, InheritanceData } from '~/DocModel/ApiNodeJSONEncoder'; import type { AnyDocNodeJSON } from '~/DocModel/comment/CommentNode'; import type { TokenDocumentation } from '~/util/parse.server'; @@ -30,7 +29,7 @@ export function CodeListing({ typeTokens: TokenDocumentation[]; readonly?: boolean; optional?: boolean; - summary?: ReturnType['summary']; + summary?: ApiItemJSON['summary']; comment?: AnyDocNodeJSON | null; children?: ReactNode; deprecation?: AnyDocNodeJSON | null; diff --git a/packages/website/src/components/DocContainer.tsx b/packages/website/src/components/DocContainer.tsx index 335126473..7802ecc63 100644 --- a/packages/website/src/components/DocContainer.tsx +++ b/packages/website/src/components/DocContainer.tsx @@ -9,8 +9,7 @@ import { Section } from './Section'; import { TableOfContentsItems } from './TableOfContentsItems'; import { TypeParamTable } from './TypeParamTable'; import { TSDoc } from './tsdoc/TSDoc'; -import type { DocClass } from '~/DocModel/DocClass'; -import type { DocItem } from '~/DocModel/DocItem'; +import type { ApiClassJSON, ApiItemJSON } from '~/DocModel/ApiNodeJSONEncoder'; import type { TypeParameterData } from '~/DocModel/TypeParameterMixin'; import type { AnyDocNodeJSON } from '~/DocModel/comment/CommentNode'; import { generateIcon } from '~/util/icon'; @@ -20,13 +19,13 @@ export interface DocContainerProps { name: string; kind: string; excerpt: string; - summary?: ReturnType['summary']; + summary?: ApiItemJSON['summary']; children?: ReactNode; extendsTokens?: TokenDocumentation[] | null; implementsTokens?: TokenDocumentation[][]; typeParams?: TypeParameterData[]; comment?: AnyDocNodeJSON | null; - methods?: ReturnType['methods'] | null; + methods?: ApiClassJSON['methods'] | null; } export function DocContainer({ diff --git a/packages/website/src/components/InheritanceText.tsx b/packages/website/src/components/InheritanceText.tsx index 655b98568..6f2fb999b 100644 --- a/packages/website/src/components/InheritanceText.tsx +++ b/packages/website/src/components/InheritanceText.tsx @@ -1,6 +1,6 @@ import { Anchor, Text } from '@mantine/core'; import Link from 'next/link'; -import type { InheritanceData } from '~/DocModel/DocMethod'; +import type { InheritanceData } from '~/DocModel/ApiNodeJSONEncoder'; export function InheritanceText({ data }: { data: InheritanceData }) { return ( diff --git a/packages/website/src/components/MethodItem.tsx b/packages/website/src/components/MethodItem.tsx index 3200de490..8b3dd7be7 100644 --- a/packages/website/src/components/MethodItem.tsx +++ b/packages/website/src/components/MethodItem.tsx @@ -3,11 +3,10 @@ import { HyperlinkedText } from './HyperlinkedText'; import { InheritanceText } from './InheritanceText'; import { ParameterTable } from './ParameterTable'; import { TSDoc } from './tsdoc/TSDoc'; -import type { DocMethod } from '~/DocModel/DocMethod'; -import type { DocMethodSignature } from '~/DocModel/DocMethodSignature'; +import type { ApiMethodJSON, ApiMethodSignatureJSON } from '~/DocModel/ApiNodeJSONEncoder'; import { Visibility } from '~/DocModel/Visibility'; -type MethodResolvable = ReturnType | ReturnType; +type MethodResolvable = ApiMethodJSON | ApiMethodSignatureJSON; function getShorthandName(data: MethodResolvable) { return `${data.name}${data.optional ? '?' : ''}(${data.parameters.reduce((prev, cur, index) => { @@ -20,7 +19,8 @@ function getShorthandName(data: MethodResolvable) { } export function MethodItem({ data }: { data: MethodResolvable }) { - const method = data as ReturnType; + const method = data as ApiMethodJSON; + return ( 1 ? `:${data.overloadIndex}` : ''}`} diff --git a/packages/website/src/components/MethodList.tsx b/packages/website/src/components/MethodList.tsx index 69204a622..e4d140fef 100644 --- a/packages/website/src/components/MethodList.tsx +++ b/packages/website/src/components/MethodList.tsx @@ -1,14 +1,9 @@ import { Divider, Stack } from '@mantine/core'; import { Fragment } from 'react'; import { MethodItem } from './MethodItem'; -import type { DocMethod } from '~/DocModel/DocMethod'; -import type { DocMethodSignature } from '~/DocModel/DocMethodSignature'; +import type { ApiMethodJSON, ApiMethodSignatureJSON } from '~/DocModel/ApiNodeJSONEncoder'; -export function MethodList({ - data, -}: { - data: (ReturnType | ReturnType)[]; -}) { +export function MethodList({ data }: { data: (ApiMethodJSON | ApiMethodSignatureJSON)[] }) { return ( {data.map((method) => ( diff --git a/packages/website/src/components/PropertyList.tsx b/packages/website/src/components/PropertyList.tsx index 3188312db..7397df375 100644 --- a/packages/website/src/components/PropertyList.tsx +++ b/packages/website/src/components/PropertyList.tsx @@ -1,8 +1,8 @@ import { Stack } from '@mantine/core'; import { CodeListing } from './CodeListing'; -import type { DocProperty } from '~/DocModel/DocProperty'; +import type { ApiPropertyItemJSON } from '~/DocModel/ApiNodeJSONEncoder'; -export function PropertyList({ data }: { data: ReturnType[] }) { +export function PropertyList({ data }: { data: ApiPropertyItemJSON[] }) { return ( {data.map((prop) => ( diff --git a/packages/website/src/components/Sections.tsx b/packages/website/src/components/Sections.tsx index 0ab792c05..f190681a6 100644 --- a/packages/website/src/components/Sections.tsx +++ b/packages/website/src/components/Sections.tsx @@ -1,18 +1,16 @@ +import { Stack, Group, Badge, Title } from '@mantine/core'; import { useMediaQuery } from '@mantine/hooks'; import { VscSymbolConstant, VscSymbolMethod, VscSymbolProperty } from 'react-icons/vsc'; + import { MethodList } from './MethodList'; import { ParameterTable } from './ParameterTable'; import { PropertyList } from './PropertyList'; import { Section } from './Section'; -import type { DocClass } from '~/DocModel/DocClass'; -import type { DocInterface } from '~/DocModel/DocInterface'; +import { TSDoc } from './tsdoc/TSDoc'; +import type { ApiClassJSON, ApiConstructorJSON, ApiInterfaceJSON } from '~/DocModel/ApiNodeJSONEncoder'; import type { ParameterDocumentation } from '~/util/parse.server'; -export function PropertiesSection({ - data, -}: { - data: ReturnType['properties'] | ReturnType['properties']; -}) { +export function PropertiesSection({ data }: { data: ApiClassJSON['properties'] | ApiInterfaceJSON['properties'] }) { const matches = useMediaQuery('(max-width: 768px)', true, { getInitialValueInEffect: false }); return data.length ? ( @@ -22,11 +20,7 @@ export function PropertiesSection({ ) : null; } -export function MethodsSection({ - data, -}: { - data: ReturnType['methods'] | ReturnType['methods']; -}) { +export function MethodsSection({ data }: { data: ApiClassJSON['methods'] | ApiInterfaceJSON['methods'] }) { const matches = useMediaQuery('(max-width: 768px)', true, { getInitialValueInEffect: false }); return data.length ? ( @@ -45,3 +39,48 @@ export function ParametersSection({ data }: { data: ParameterDocumentation[] }) ) : null; } + +export function ConstructorSection({ data }: { data: ApiConstructorJSON }) { + const matches = useMediaQuery('(max-width: 768px)', true, { getInitialValueInEffect: false }); + + function getShorthandName(): string { + return `constructor(${data.parameters.reduce((prev, cur, index) => { + if (index === 0) { + return `${prev}${cur.isOptional ? `[${cur.name}]` : cur.name}`; + } + + return `${prev}, ${cur.isOptional ? `[${cur.name}]` : cur.name}`; + }, '')})`; + } + + return data.parameters.length ? ( +
} padded dense={matches}> + + + + + {data.deprecated ? ( + + Deprecated + + ) : null} + {data.protected ? Protected : null} + + {getShorthandName()} + + + + + + + {data.deprecated ? : null} + {data.summary ? : null} + {data.remarks ? : null} + {data.comment ? : null} + {data.parameters.length ? : null} + + + +
+ ) : null; +} diff --git a/packages/website/src/components/SidebarLayout.tsx b/packages/website/src/components/SidebarLayout.tsx index 211f796ca..ce480adb1 100644 --- a/packages/website/src/components/SidebarLayout.tsx +++ b/packages/website/src/components/SidebarLayout.tsx @@ -25,7 +25,7 @@ import { type PropsWithChildren, useState } from 'react'; import { VscChevronDown, VscPackage } from 'react-icons/vsc'; import { WiDaySunny, WiNightClear } from 'react-icons/wi'; import { SidebarItems } from './SidebarItems'; -import type { DocItem } from '~/DocModel/DocItem'; +import type { ApiItemJSON } from '~/DocModel/ApiNodeJSONEncoder'; import type { findMember } from '~/util/model.server'; import type { getMembers } from '~/util/parse.server'; @@ -36,7 +36,7 @@ export interface SidebarLayoutProps { member: ReturnType; }; - selectedMember?: ReturnType | undefined; + selectedMember?: ApiItemJSON | undefined; } export type Members = SidebarLayoutProps['data']['members']; diff --git a/packages/website/src/components/TableOfContentsItems.tsx b/packages/website/src/components/TableOfContentsItems.tsx index ccece300c..07b855216 100644 --- a/packages/website/src/components/TableOfContentsItems.tsx +++ b/packages/website/src/components/TableOfContentsItems.tsx @@ -1,7 +1,6 @@ import { createStyles, Group, Text, Box } from '@mantine/core'; import { VscListSelection } from 'react-icons/vsc'; -import type { DocClass } from '~/DocModel/DocClass'; -import type { DocInterface } from '~/DocModel/DocInterface'; +import type { ApiClassJSON, ApiInterfaceJSON } from '~/DocModel/ApiNodeJSONEncoder'; const useStyles = createStyles((theme) => ({ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment @@ -25,11 +24,7 @@ const useStyles = createStyles((theme) => ({ }, })); -export function TableOfContentsItems({ - members, -}: { - members: ReturnType['methods'] | ReturnType['methods']; -}) { +export function TableOfContentsItems({ members }: { members: ApiClassJSON['methods'] | ApiInterfaceJSON['methods'] }) { const { classes } = useStyles(); const items = members.map((member) => { diff --git a/packages/website/src/components/model/Class.tsx b/packages/website/src/components/model/Class.tsx index 6a93fa1b7..27ffaeb51 100644 --- a/packages/website/src/components/model/Class.tsx +++ b/packages/website/src/components/model/Class.tsx @@ -1,20 +1,21 @@ import { DocContainer } from '../DocContainer'; -import { MethodsSection, PropertiesSection } from '../Sections'; -import type { DocClass } from '~/DocModel/DocClass'; +import { ConstructorSection, MethodsSection, PropertiesSection } from '../Sections'; +import type { ApiClassJSON } from '~/DocModel/ApiNodeJSONEncoder'; -export function Class({ data }: { data: ReturnType }) { +export function Class({ data }: { data: ApiClassJSON }) { return ( + {data.constructor ? : null} diff --git a/packages/website/src/components/model/Enum.tsx b/packages/website/src/components/model/Enum.tsx index dd68db93d..3dcaaff79 100644 --- a/packages/website/src/components/model/Enum.tsx +++ b/packages/website/src/components/model/Enum.tsx @@ -4,9 +4,9 @@ import { VscSymbolEnumMember } from 'react-icons/vsc'; import { CodeListing, CodeListingSeparatorType } from '../CodeListing'; import { DocContainer } from '../DocContainer'; import { Section } from '../Section'; -import type { DocEnum } from '~/DocModel/DocEnum'; +import type { ApiEnumJSON } from '~/DocModel/ApiNodeJSONEncoder'; -export function Enum({ data }: { data: ReturnType }) { +export function Enum({ data }: { data: ApiEnumJSON }) { const matches = useMediaQuery('(max-width: 768px)', true, { getInitialValueInEffect: false }); return ( diff --git a/packages/website/src/components/model/Function.tsx b/packages/website/src/components/model/Function.tsx index 382b2866c..3314e3283 100644 --- a/packages/website/src/components/model/Function.tsx +++ b/packages/website/src/components/model/Function.tsx @@ -1,15 +1,15 @@ import { DocContainer } from '../DocContainer'; import { ParametersSection } from '../Sections'; -import type { DocFunction } from '~/DocModel/DocFunction'; +import type { ApiFunctionJSON } from '~/DocModel/ApiNodeJSONEncoder'; -export function Function({ data }: { data: ReturnType }) { +export function Function({ data }: { data: ApiFunctionJSON }) { return ( 1 ? ` (${data.overloadIndex})` : ''}`} kind={data.kind} excerpt={data.excerpt} summary={data.summary} - typeParams={data.typeParameterData} + typeParams={data.typeParameters} > diff --git a/packages/website/src/components/model/Interface.tsx b/packages/website/src/components/model/Interface.tsx index 8410b43b1..e689d906d 100644 --- a/packages/website/src/components/model/Interface.tsx +++ b/packages/website/src/components/model/Interface.tsx @@ -1,15 +1,15 @@ import { DocContainer } from '../DocContainer'; import { MethodsSection, PropertiesSection } from '../Sections'; -import type { DocInterface } from '~/DocModel/DocInterface'; +import type { ApiInterfaceJSON } from '~/DocModel/ApiNodeJSONEncoder'; -export function Interface({ data }: { data: ReturnType }) { +export function Interface({ data }: { data: ApiInterfaceJSON }) { return ( diff --git a/packages/website/src/components/model/TypeAlias.tsx b/packages/website/src/components/model/TypeAlias.tsx index 10aa14fe4..f2e1ee4e5 100644 --- a/packages/website/src/components/model/TypeAlias.tsx +++ b/packages/website/src/components/model/TypeAlias.tsx @@ -1,14 +1,14 @@ import { DocContainer } from '../DocContainer'; -import type { DocTypeAlias } from '~/DocModel/DocTypeAlias'; +import type { ApiTypeAliasJSON } from '~/DocModel/ApiNodeJSONEncoder'; -export function TypeAlias({ data }: { data: ReturnType }) { +export function TypeAlias({ data }: { data: ApiTypeAliasJSON }) { return ( ); } diff --git a/packages/website/src/components/model/Variable.tsx b/packages/website/src/components/model/Variable.tsx index 3cc45824a..65b1fabc7 100644 --- a/packages/website/src/components/model/Variable.tsx +++ b/packages/website/src/components/model/Variable.tsx @@ -1,6 +1,6 @@ import { DocContainer } from '../DocContainer'; -import type { DocVariable } from '~/DocModel/DocVariable'; +import type { ApiVariableJSON } from '~/DocModel/ApiNodeJSONEncoder'; -export function Variable({ data }: { data: ReturnType }) { +export function Variable({ data }: { data: ApiVariableJSON }) { return ; } diff --git a/packages/website/src/contexts/member.tsx b/packages/website/src/contexts/member.tsx index 2c3d9ffa4..d45059596 100644 --- a/packages/website/src/contexts/member.tsx +++ b/packages/website/src/contexts/member.tsx @@ -1,14 +1,12 @@ import { createContext } from 'react'; -import type { DocItem } from '~/DocModel/DocItem'; +import type { ApiItemJSON } from '~/DocModel/ApiNodeJSONEncoder'; -export type DocItemJSON = ReturnType; - -export const MemberContext = createContext(undefined); +export const MemberContext = createContext(undefined); export const MemberProvider = ({ member, children, }: { - member: DocItemJSON | undefined; + member: ApiItemJSON | undefined; children: React.ReactNode; }) => {children}; diff --git a/packages/website/src/pages/docs/[...slug].tsx b/packages/website/src/pages/docs/[...slug].tsx index ba7d9537b..6cdef84c8 100644 --- a/packages/website/src/pages/docs/[...slug].tsx +++ b/packages/website/src/pages/docs/[...slug].tsx @@ -4,12 +4,14 @@ import { join } from 'node:path'; import { Box } from '@mantine/core'; import { ApiFunction } from '@microsoft/api-extractor-model'; import type { GetStaticPaths, GetStaticProps } from 'next/types'; -import type { DocClass } from '~/DocModel/DocClass'; -import type { DocEnum } from '~/DocModel/DocEnum'; -import type { DocFunction } from '~/DocModel/DocFunction'; -import type { DocInterface } from '~/DocModel/DocInterface'; -import type { DocTypeAlias } from '~/DocModel/DocTypeAlias'; -import type { DocVariable } from '~/DocModel/DocVariable'; +import type { + ApiClassJSON, + ApiEnumJSON, + ApiFunctionJSON, + ApiInterfaceJSON, + ApiTypeAliasJSON, + ApiVariableJSON, +} from '~/DocModel/ApiNodeJSONEncoder'; import { SidebarLayout, type SidebarLayoutProps } from '~/components/SidebarLayout'; import { Class } from '~/components/model/Class'; import { Enum } from '~/components/model/Enum'; @@ -110,8 +112,7 @@ export const getStaticProps: GetStaticProps = async ({ params }) => { packageName, data: { members: pkg ? getMembers(pkg) : [], - member: - memberName && containerKey ? findMemberByKey(model, packageName, containerKey)?.toJSON() ?? null : null, + member: memberName && containerKey ? findMemberByKey(model, packageName, containerKey) ?? null : null, }, }, }; @@ -128,17 +129,17 @@ const member = (props: any) => { // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access switch (props.kind) { case 'Class': - return } />; + return ; case 'Function': - return } />; + return ; case 'Interface': - return } />; + return ; case 'TypeAlias': - return } />; + return ; case 'Variable': - return } />; + return ; case 'Enum': - return } />; + return ; default: return Cannot render that item type; } diff --git a/packages/website/src/util/model.server.ts b/packages/website/src/util/model.server.ts index d6da14a18..b96b9e7c9 100644 --- a/packages/website/src/util/model.server.ts +++ b/packages/website/src/util/model.server.ts @@ -1,52 +1,6 @@ -import { - ApiClass, - ApiDeclaredItem, - ApiEntryPoint, - ApiEnum, - ApiFunction, - ApiInterface, - ApiItem, - ApiItemKind, - ApiModel, - ApiTypeAlias, - ApiVariable, -} from '@microsoft/api-extractor-model'; +import type { ApiEntryPoint, ApiModel } from '@microsoft/api-extractor-model'; import { findPackage } from './parse.server'; -import { DocClass } from '../DocModel/DocClass'; -import { DocEnum } from '../DocModel/DocEnum'; -import { DocFunction } from '../DocModel/DocFunction'; -import { DocInterface } from '../DocModel/DocInterface'; -import { DocItem } from '../DocModel/DocItem'; -import { DocTypeAlias } from '../DocModel/DocTypeAlias'; -import { DocVariable } from '../DocModel/DocVariable'; - -export interface ReferenceData { - name: string; - path: string; -} - -function createDocItem(model: ApiModel, member: ApiItem) { - if (!(member instanceof ApiDeclaredItem)) { - return undefined; - } - - switch (member.kind) { - case ApiItemKind.Class: - return new DocClass(model, member as ApiClass); - case ApiItemKind.Function: - return new DocFunction(model, member as ApiFunction); - case ApiItemKind.Interface: - return new DocInterface(model, member as ApiInterface); - case ApiItemKind.TypeAlias: - return new DocTypeAlias(model, member as ApiTypeAlias); - case ApiItemKind.Variable: - return new DocVariable(model, member as ApiVariable); - case ApiItemKind.Enum: - return new DocEnum(model, member as ApiEnum); - default: - return new DocItem(model, member); - } -} +import { ApiNodeJSONEncoder } from '~/DocModel/ApiNodeJSONEncoder'; export function findMemberByKey(model: ApiModel, packageName: string, containerKey: string) { const pkg = findPackage(model, packageName)!; @@ -56,10 +10,14 @@ export function findMemberByKey(model: ApiModel, packageName: string, containerK return undefined; } - return createDocItem(model, member); + return ApiNodeJSONEncoder.encode(model, member); } -export function findMember(model: ApiModel, packageName: string, memberName: string): DocItem | undefined { +export function findMember( + model: ApiModel, + packageName: string, + memberName: string, +): ReturnType | undefined { const pkg = findPackage(model, packageName)!; const member = (pkg.members[0] as ApiEntryPoint).findMembersByName(memberName)[0]; @@ -67,5 +25,5 @@ export function findMember(model: ApiModel, packageName: string, memberName: str return undefined; } - return createDocItem(model, member); + return ApiNodeJSONEncoder.encode(model, member); } diff --git a/packages/ws/.eslintrc.json b/packages/ws/.eslintrc.json index 99ef7cec8..6115ee5c0 100644 --- a/packages/ws/.eslintrc.json +++ b/packages/ws/.eslintrc.json @@ -1,3 +1,7 @@ { - "extends": "../../.eslintrc.json" + "extends": "../../.eslintrc.json", + "plugins": ["eslint-plugin-tsdoc"], + "rules": { + "tsdoc/syntax": "warn" + } } diff --git a/packages/ws/package.json b/packages/ws/package.json index 252809969..2b05956a4 100644 --- a/packages/ws/package.json +++ b/packages/ws/package.json @@ -74,6 +74,7 @@ "eslint-config-prettier": "^8.5.0", "eslint-import-resolver-typescript": "^3.4.1", "eslint-plugin-import": "^2.26.0", + "eslint-plugin-tsdoc": "^0.2.16", "mock-socket": "^9.1.5", "prettier": "^2.7.1", "rollup-plugin-typescript2": "0.32.1", diff --git a/packages/ws/src/strategies/sharding/SimpleShardingStrategy.ts b/packages/ws/src/strategies/sharding/SimpleShardingStrategy.ts index 1bffc4303..c6c6b6bbe 100644 --- a/packages/ws/src/strategies/sharding/SimpleShardingStrategy.ts +++ b/packages/ws/src/strategies/sharding/SimpleShardingStrategy.ts @@ -21,6 +21,9 @@ export class SimpleShardingStrategy implements IShardingStrategy { this.throttler = new IdentifyThrottler(manager); } + /** + * {@inheritDoc IShardingStrategy.spawn} + */ public async spawn(shardIds: number[]) { const strategyOptions = await managerToFetchingStrategyOptions(this.manager); for (const shardId of shardIds) { @@ -34,6 +37,9 @@ export class SimpleShardingStrategy implements IShardingStrategy { } } + /** + * {@inheritDoc IShardingStrategy.connect} + */ public async connect() { const promises = []; @@ -45,6 +51,9 @@ export class SimpleShardingStrategy implements IShardingStrategy { await Promise.all(promises); } + /** + * {@inheritDoc IShardingStrategy.destroy} + */ public async destroy(options?: Omit) { const promises = []; @@ -56,6 +65,9 @@ export class SimpleShardingStrategy implements IShardingStrategy { this.shards.clear(); } + /** + * {@inheritDoc IShardingStrategy.send} + */ public send(shardId: number, payload: GatewaySendPayload) { const shard = this.shards.get(shardId); if (!shard) throw new Error(`Shard ${shardId} not found`); diff --git a/packages/ws/src/strategies/sharding/WorkerShardingStrategy.ts b/packages/ws/src/strategies/sharding/WorkerShardingStrategy.ts index 5add1955c..e15c4a5dd 100644 --- a/packages/ws/src/strategies/sharding/WorkerShardingStrategy.ts +++ b/packages/ws/src/strategies/sharding/WorkerShardingStrategy.ts @@ -73,6 +73,9 @@ export class WorkerShardingStrategy implements IShardingStrategy { this.options = options; } + /** + * {@inheritDoc IShardingStrategy.spawn} + */ public async spawn(shardIds: number[]) { const shardsPerWorker = this.options.shardsPerWorker === 'all' ? shardIds.length : this.options.shardsPerWorker; const strategyOptions = await managerToFetchingStrategyOptions(this.manager); @@ -106,6 +109,9 @@ export class WorkerShardingStrategy implements IShardingStrategy { } } + /** + * {@inheritDoc IShardingStrategy.connect} + */ public async connect() { const promises = []; @@ -125,6 +131,9 @@ export class WorkerShardingStrategy implements IShardingStrategy { await Promise.all(promises); } + /** + * {@inheritDoc IShardingStrategy.destroy} + */ public async destroy(options: Omit = {}) { const promises = []; @@ -147,6 +156,9 @@ export class WorkerShardingStrategy implements IShardingStrategy { await Promise.all(promises); } + /** + * {@inheritDoc IShardingStrategy.send} + */ public send(shardId: number, data: GatewaySendPayload) { const worker = this.#workerByShardId.get(shardId); if (!worker) { diff --git a/packages/ws/src/ws/WebSocketManager.ts b/packages/ws/src/ws/WebSocketManager.ts index 52a28ce5b..9a7877a09 100644 --- a/packages/ws/src/ws/WebSocketManager.ts +++ b/packages/ws/src/ws/WebSocketManager.ts @@ -203,7 +203,7 @@ export class WebSocketManager extends AsyncEventEmitter { /** * Fetches the gateway information from Discord - or returns it from cache if available - * @param force Whether to ignore the cache and force a fresh fetch + * @param force - Whether to ignore the cache and force a fresh fetch */ public async fetchGatewayInformation(force = false) { if (this.gatewayInformation) { @@ -222,7 +222,7 @@ export class WebSocketManager extends AsyncEventEmitter { /** * Updates your total shard count on-the-fly, spawning shards as needed - * @param shardCount The new shard count to use + * @param shardCount - The new shard count to use */ public async updateShardCount(shardCount: number | null) { await this.strategy.destroy({ reason: 'User is adjusting their shards' }); diff --git a/yarn.lock b/yarn.lock index 7f03f5385..64ece8df1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1745,6 +1745,7 @@ __metadata: eslint-config-prettier: ^8.5.0 eslint-import-resolver-typescript: ^3.4.1 eslint-plugin-import: ^2.26.0 + eslint-plugin-tsdoc: ^0.2.16 fast-deep-equal: ^3.1.3 prettier: ^2.7.1 rollup-plugin-typescript2: 0.32.1 @@ -1773,6 +1774,7 @@ __metadata: eslint-config-prettier: ^8.5.0 eslint-import-resolver-typescript: ^3.4.1 eslint-plugin-import: ^2.26.0 + eslint-plugin-tsdoc: ^0.2.16 prettier: ^2.7.1 rollup-plugin-typescript2: 0.32.1 typescript: ^4.7.4 @@ -1900,6 +1902,7 @@ __metadata: eslint-config-prettier: ^8.5.0 eslint-import-resolver-typescript: ^3.4.1 eslint-plugin-import: ^2.26.0 + eslint-plugin-tsdoc: ^0.2.16 file-type: ^17.1.6 prettier: ^2.7.1 rollup-plugin-typescript2: 0.32.1 @@ -1956,6 +1959,7 @@ __metadata: eslint-config-prettier: ^8.5.0 eslint-import-resolver-typescript: ^3.4.1 eslint-plugin-import: ^2.26.0 + eslint-plugin-tsdoc: ^0.2.16 jest: ^28.1.3 jest-websocket-mock: ^2.4.0 mock-socket: ^9.1.5 @@ -2043,6 +2047,7 @@ __metadata: eslint-config-prettier: ^8.5.0 eslint-import-resolver-typescript: ^3.4.1 eslint-plugin-import: ^2.26.0 + eslint-plugin-tsdoc: ^0.2.16 mock-socket: ^9.1.5 prettier: ^2.7.1 rollup-plugin-typescript2: 0.32.1 @@ -7925,6 +7930,16 @@ __metadata: languageName: node linkType: hard +"eslint-plugin-tsdoc@npm:^0.2.16": + version: 0.2.16 + resolution: "eslint-plugin-tsdoc@npm:0.2.16" + dependencies: + "@microsoft/tsdoc": 0.14.1 + "@microsoft/tsdoc-config": 0.16.1 + checksum: 37ca88b060b90223aa938656d267eead4291d5859e790f95eb8271eb8f315c16010e500fac4ef535710350e36d7394cecb7e61fbb3635568066008e3425dcac7 + languageName: node + linkType: hard + "eslint-rule-docs@npm:^1.1.5": version: 1.1.235 resolution: "eslint-rule-docs@npm:1.1.235"