mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-14 02:23:31 +01:00
build: package api-extractor and -model (#9920)
* fix(ExceptText): don't display import("d..-types/v10"). in return type
* Squashed 'packages/api-extractor-model/' content from commit 39ecb196c
git-subtree-dir: packages/api-extractor-model
git-subtree-split: 39ecb196ca210bdf84ba6c9cadb1bb93571849d7
* Squashed 'packages/api-extractor/' content from commit 341ad6c51
git-subtree-dir: packages/api-extractor
git-subtree-split: 341ad6c51b01656d4f73b74ad4bdb3095f9262c4
* feat(api-extractor): add api-extractor and -model
* fix: package.json docs script
* fix(SourcLink): use <> instead of function syntax
* fix: make packages private
* fix: rest params showing in docs, added labels
* fix: missed two files
* fix: cpy-cli & pnpm-lock
* fix: increase icon size
* fix: icon size again
This commit is contained in:
225
packages/api-extractor-model/src/items/ApiDeclaredItem.ts
Normal file
225
packages/api-extractor-model/src/items/ApiDeclaredItem.ts
Normal file
@@ -0,0 +1,225 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
||||
// See LICENSE in the project root for license information.
|
||||
|
||||
import { DeclarationReference } from '@microsoft/tsdoc/lib-commonjs/beta/DeclarationReference.js';
|
||||
import { Excerpt, ExcerptToken, type IExcerptTokenRange, type IExcerptToken } from '../mixins/Excerpt.js';
|
||||
import type { DeserializerContext } from '../model/DeserializerContext.js';
|
||||
import { SourceLocation } from '../model/SourceLocation.js';
|
||||
import { ApiDocumentedItem, type IApiDocumentedItemJson, type IApiDocumentedItemOptions } from './ApiDocumentedItem.js';
|
||||
import type { ApiItem } from './ApiItem.js';
|
||||
|
||||
/**
|
||||
* Constructor options for {@link ApiDeclaredItem}.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export interface IApiDeclaredItemOptions extends IApiDocumentedItemOptions {
|
||||
excerptTokens: IExcerptToken[];
|
||||
fileColumn?: number | undefined;
|
||||
fileLine?: number | undefined;
|
||||
fileUrlPath?: string | undefined;
|
||||
}
|
||||
|
||||
export interface IApiDeclaredItemJson extends IApiDocumentedItemJson {
|
||||
excerptTokens: IExcerptToken[];
|
||||
fileColumn?: number;
|
||||
fileLine?: number;
|
||||
fileUrlPath?: string | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* The base class for API items that have an associated source code excerpt containing a TypeScript declaration.
|
||||
*
|
||||
* @remarks
|
||||
*
|
||||
* This is part of the {@link ApiModel} hierarchy of classes, which are serializable representations of
|
||||
* API declarations.
|
||||
*
|
||||
* Most `ApiItem` subclasses have declarations and thus extend `ApiDeclaredItem`. Counterexamples include
|
||||
* `ApiModel` and `ApiPackage`, which do not have any corresponding TypeScript source code.
|
||||
* @public
|
||||
*/
|
||||
|
||||
export class ApiDeclaredItem extends ApiDocumentedItem {
|
||||
private readonly _excerptTokens: ExcerptToken[];
|
||||
|
||||
private readonly _excerpt: Excerpt;
|
||||
|
||||
private readonly _fileUrlPath?: string | undefined;
|
||||
|
||||
private readonly _fileLine?: number | undefined;
|
||||
|
||||
private readonly _fileColumn?: number | undefined;
|
||||
|
||||
private _sourceLocation?: SourceLocation;
|
||||
|
||||
public constructor(options: IApiDeclaredItemOptions) {
|
||||
super(options);
|
||||
|
||||
this._excerptTokens = options.excerptTokens.map((token) => {
|
||||
const canonicalReference: DeclarationReference | undefined =
|
||||
token.canonicalReference === undefined ? undefined : DeclarationReference.parse(token.canonicalReference);
|
||||
return new ExcerptToken(token.kind, token.text, canonicalReference);
|
||||
});
|
||||
this._excerpt = new Excerpt(this.excerptTokens, { startIndex: 0, endIndex: this.excerptTokens.length });
|
||||
this._fileUrlPath = options.fileUrlPath;
|
||||
this._fileLine = options.fileLine;
|
||||
this._fileColumn = options.fileColumn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public static override onDeserializeInto(
|
||||
options: Partial<IApiDeclaredItemOptions>,
|
||||
context: DeserializerContext,
|
||||
jsonObject: IApiDeclaredItemJson,
|
||||
): void {
|
||||
super.onDeserializeInto(options, context, jsonObject);
|
||||
|
||||
options.excerptTokens = jsonObject.excerptTokens;
|
||||
options.fileUrlPath = jsonObject.fileUrlPath;
|
||||
options.fileLine = jsonObject.fileLine;
|
||||
options.fileColumn = jsonObject.fileColumn;
|
||||
}
|
||||
|
||||
/**
|
||||
* The source code excerpt where the API item is declared.
|
||||
*/
|
||||
public get excerpt(): Excerpt {
|
||||
return this._excerpt;
|
||||
}
|
||||
|
||||
/**
|
||||
* The individual source code tokens that comprise the main excerpt.
|
||||
*/
|
||||
public get excerptTokens(): readonly ExcerptToken[] {
|
||||
return this._excerptTokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* The file URL path relative to the `projectFolder` and `projectFolderURL` fields
|
||||
* as defined in the `api-extractor.json` config. Is `undefined` if the path is
|
||||
* the same as the parent API item's.
|
||||
*/
|
||||
public get fileUrlPath(): string | undefined {
|
||||
return this._fileUrlPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* The line in the `fileUrlPath` where the API item is declared.
|
||||
*/
|
||||
public get fileLine(): number | undefined {
|
||||
return this._fileLine;
|
||||
}
|
||||
|
||||
/**
|
||||
* The column in the `fileUrlPath` where the API item is declared.
|
||||
*/
|
||||
public get fileColumn(): number | undefined {
|
||||
return this._fileColumn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the source location where the API item is declared.
|
||||
*/
|
||||
public get sourceLocation(): SourceLocation {
|
||||
if (!this._sourceLocation) {
|
||||
this._sourceLocation = this._buildSourceLocation();
|
||||
}
|
||||
|
||||
return this._sourceLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the API item has certain important modifier tags such as `@sealed`, `@virtual`, or `@override`,
|
||||
* this prepends them as a doc comment above the excerpt.
|
||||
*/
|
||||
public getExcerptWithModifiers(): string {
|
||||
const excerpt: string = this.excerpt.text;
|
||||
const modifierTags: string[] = [];
|
||||
|
||||
if (excerpt.length > 0 && this instanceof ApiDocumentedItem) {
|
||||
if (this.tsdocComment) {
|
||||
if (this.tsdocComment.modifierTagSet.isSealed()) {
|
||||
modifierTags.push('@sealed');
|
||||
}
|
||||
|
||||
if (this.tsdocComment.modifierTagSet.isVirtual()) {
|
||||
modifierTags.push('@virtual');
|
||||
}
|
||||
|
||||
if (this.tsdocComment.modifierTagSet.isOverride()) {
|
||||
modifierTags.push('@override');
|
||||
}
|
||||
}
|
||||
|
||||
if (modifierTags.length > 0) {
|
||||
return '/** ' + modifierTags.join(' ') + ' */\n' + excerpt;
|
||||
}
|
||||
}
|
||||
|
||||
return excerpt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public override serializeInto(jsonObject: Partial<IApiDeclaredItemJson>): void {
|
||||
super.serializeInto(jsonObject);
|
||||
jsonObject.excerptTokens = this.excerptTokens.map((x) => {
|
||||
const excerptToken: IExcerptToken = { kind: x.kind, text: x.text };
|
||||
if (x.canonicalReference !== undefined) {
|
||||
excerptToken.canonicalReference = x.canonicalReference.toString();
|
||||
}
|
||||
|
||||
return excerptToken;
|
||||
});
|
||||
|
||||
// Only serialize this API item's file URL path if it exists and it's different from its parent's
|
||||
// (a little optimization to keep the doc model succinct).
|
||||
if (
|
||||
this.fileUrlPath &&
|
||||
(!(this.parent instanceof ApiDeclaredItem) || this.fileUrlPath !== this.parent.fileUrlPath)
|
||||
) {
|
||||
jsonObject.fileUrlPath = this.fileUrlPath;
|
||||
}
|
||||
|
||||
if (this.fileLine) {
|
||||
jsonObject.fileLine = this.fileLine;
|
||||
}
|
||||
|
||||
if (this.fileColumn) {
|
||||
jsonObject.fileColumn = this.fileColumn;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@link Excerpt} corresponding to the provided token range.
|
||||
*/
|
||||
public buildExcerpt(tokenRange: IExcerptTokenRange): Excerpt {
|
||||
return new Excerpt(this.excerptTokens, tokenRange);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the cached object used by the `sourceLocation` property.
|
||||
*/
|
||||
private _buildSourceLocation(): SourceLocation {
|
||||
const projectFolderUrl: string | undefined = this.getAssociatedPackage()?.projectFolderUrl;
|
||||
|
||||
let fileUrlPath: string | undefined;
|
||||
for (let current: ApiItem | undefined = this; current !== undefined; current = current.parent) {
|
||||
if (current instanceof ApiDeclaredItem && current.fileUrlPath) {
|
||||
fileUrlPath = current.fileUrlPath;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return new SourceLocation({
|
||||
projectFolderUrl,
|
||||
fileUrlPath,
|
||||
sourceFileColumn: this.fileColumn,
|
||||
sourceFileLine: this.fileLine,
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user