mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-15 19:13: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:
173
packages/api-extractor-model/src/mixins/Excerpt.ts
Normal file
173
packages/api-extractor-model/src/mixins/Excerpt.ts
Normal file
@@ -0,0 +1,173 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
||||
// See LICENSE in the project root for license information.
|
||||
|
||||
import type { DeclarationReference } from '@microsoft/tsdoc/lib-commonjs/beta/DeclarationReference';
|
||||
import { Text } from '@rushstack/node-core-library';
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export enum ExcerptTokenKind {
|
||||
/**
|
||||
* Generic text without any special properties
|
||||
*/
|
||||
Content = 'Content',
|
||||
|
||||
/**
|
||||
* A reference to an API declaration
|
||||
*/
|
||||
Reference = 'Reference',
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by {@link Excerpt} to indicate a range of indexes within an array of `ExcerptToken` objects.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export interface IExcerptTokenRange {
|
||||
/**
|
||||
* The index of the last member of the span, plus one.
|
||||
*
|
||||
* @remarks
|
||||
*
|
||||
* If `startIndex` and `endIndex` are the same number, then the span is empty.
|
||||
*/
|
||||
endIndex: number;
|
||||
|
||||
/**
|
||||
* The starting index of the span.
|
||||
*/
|
||||
startIndex: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface IExcerptToken {
|
||||
canonicalReference?: string | undefined;
|
||||
readonly kind: ExcerptTokenKind;
|
||||
text: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a fragment of text belonging to an {@link Excerpt} object.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export class ExcerptToken {
|
||||
private readonly _kind: ExcerptTokenKind;
|
||||
|
||||
private readonly _text: string;
|
||||
|
||||
private readonly _canonicalReference: DeclarationReference | undefined;
|
||||
|
||||
public constructor(kind: ExcerptTokenKind, text: string, canonicalReference?: DeclarationReference) {
|
||||
this._kind = kind;
|
||||
|
||||
// Standardize the newlines across operating systems. Even though this may deviate from the actual
|
||||
// input source file that was parsed, it's useful because the newline gets serialized inside
|
||||
// a string literal in .api.json, which cannot be automatically normalized by Git.
|
||||
this._text = Text.convertToLf(text);
|
||||
this._canonicalReference = canonicalReference;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the kind of token.
|
||||
*/
|
||||
public get kind(): ExcerptTokenKind {
|
||||
return this._kind;
|
||||
}
|
||||
|
||||
/**
|
||||
* The text fragment.
|
||||
*/
|
||||
public get text(): string {
|
||||
return this._text;
|
||||
}
|
||||
|
||||
/**
|
||||
* The hyperlink target for a token whose type is `ExcerptTokenKind.Reference`. For other token types,
|
||||
* this property will be `undefined`.
|
||||
*/
|
||||
public get canonicalReference(): DeclarationReference | undefined {
|
||||
return this._canonicalReference;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The `Excerpt` class is used by {@link ApiDeclaredItem} to represent a TypeScript code fragment that may be
|
||||
* annotated with hyperlinks to declared types (and in the future, source code locations).
|
||||
*
|
||||
* @remarks
|
||||
* API Extractor's .api.json file format stores excerpts compactly as a start/end indexes into an array of tokens.
|
||||
* Every `ApiDeclaredItem` has a "main excerpt" corresponding to the full list of tokens. The declaration may
|
||||
* also have have "captured" excerpts that correspond to subranges of tokens.
|
||||
*
|
||||
* For example, if the main excerpt is:
|
||||
*
|
||||
* ```
|
||||
* function parse(s: string): Vector | undefined;
|
||||
* ```
|
||||
*
|
||||
* ...then this entire signature is the "main excerpt", whereas the function's return type `Vector | undefined` is a
|
||||
* captured excerpt. The `Vector` token might be a hyperlink to that API item.
|
||||
*
|
||||
* An excerpt may be empty (i.e. a token range containing zero tokens). For example, if a function's return value
|
||||
* is not explicitly declared, then the returnTypeExcerpt will be empty. By contrast, a class constructor cannot
|
||||
* have a return value, so ApiConstructor has no returnTypeExcerpt property at all.
|
||||
* @public
|
||||
*/
|
||||
export class Excerpt {
|
||||
/**
|
||||
* The complete list of tokens for the source code fragment that this excerpt is based upon.
|
||||
* If this object is the main excerpt, then it will span all of the tokens; otherwise, it will correspond to
|
||||
* a range within the array.
|
||||
*/
|
||||
public readonly tokens: readonly ExcerptToken[];
|
||||
|
||||
/**
|
||||
* Specifies the excerpt's range within the `tokens` array.
|
||||
*/
|
||||
public readonly tokenRange: Readonly<IExcerptTokenRange>;
|
||||
|
||||
/**
|
||||
* The tokens spanned by this excerpt. It is the range of the `tokens` array as specified by the `tokenRange`
|
||||
* property.
|
||||
*/
|
||||
public readonly spannedTokens: readonly ExcerptToken[];
|
||||
|
||||
private _text: string | undefined;
|
||||
|
||||
public constructor(tokens: readonly ExcerptToken[], tokenRange: IExcerptTokenRange) {
|
||||
this.tokens = tokens;
|
||||
this.tokenRange = tokenRange;
|
||||
|
||||
if (
|
||||
this.tokenRange.startIndex < 0 ||
|
||||
this.tokenRange.endIndex > this.tokens.length ||
|
||||
this.tokenRange.startIndex > this.tokenRange.endIndex
|
||||
) {
|
||||
throw new Error('Invalid token range');
|
||||
}
|
||||
|
||||
this.spannedTokens = this.tokens.slice(this.tokenRange.startIndex, this.tokenRange.endIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* The excerpted text, formed by concatenating the text of the `spannedTokens` strings.
|
||||
*/
|
||||
public get text(): string {
|
||||
if (this._text === undefined) {
|
||||
this._text = this.spannedTokens.map((x) => x.text).join('');
|
||||
}
|
||||
|
||||
return this._text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the excerpt is an empty range.
|
||||
*/
|
||||
public get isEmpty(): boolean {
|
||||
return this.tokenRange.startIndex === this.tokenRange.endIndex;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user