feat(website): show union members of type aliases (#10001)

* feat(website): show union members of type aliases

* refactor: suggestions from code review

* Apply suggestions from code review

---------

Co-authored-by: Noel <buechler.noel@outlook.com>
This commit is contained in:
Qjuh
2023-12-01 02:19:07 +01:00
committed by GitHub
parent b229240731
commit a44ada661f
3 changed files with 125 additions and 48 deletions

View File

@@ -0,0 +1,36 @@
import { Excerpt, type ApiTypeAlias, type ExcerptToken } from '@discordjs/api-extractor-model';
import { VscSymbolArray } from '@react-icons/all-files/vsc/VscSymbolArray';
import { useMemo } from 'react';
import { ExcerptText } from '~/components/ExcerptText';
import { DocumentationSection } from './DocumentationSection';
export type UnionMember = ExcerptToken[];
export function UnionMembersSection({
item,
members,
}: {
readonly item: ApiTypeAlias;
readonly members: UnionMember[];
}) {
const unionMembers = useMemo(
() =>
members.map((member, idx) => (
<div className="flex flex-row place-items-center gap-4" key={`union-${idx}`}>
<span className="break-all font-mono space-y-2">
<ExcerptText
excerpt={new Excerpt(member, { startIndex: 0, endIndex: member.length })}
apiPackage={item.getAssociatedPackage()!}
/>
</span>
</div>
)),
[item, members],
);
return (
<DocumentationSection icon={<VscSymbolArray size={20} />} padded title="Union Members">
<div className="flex flex-col gap-4">{unionMembers}</div>
</DocumentationSection>
);
}

View File

@@ -1,10 +1,59 @@
import type { ApiTypeAlias } from '@discordjs/api-extractor-model';
import { ExcerptTokenKind, type ApiTypeAlias, ExcerptToken } from '@discordjs/api-extractor-model';
import { useMemo } from 'react';
import { SyntaxHighlighter } from '../SyntaxHighlighter';
import { Documentation } from '../documentation/Documentation';
import { Header } from '../documentation/Header';
import { SummarySection } from '../documentation/section/SummarySection';
import { UnionMembersSection } from '../documentation/section/UnionMembersSection';
export function TypeAlias({ item }: { readonly item: ApiTypeAlias }) {
const union = useMemo(() => {
const union: ExcerptToken[][] = [];
let currentUnionMember: ExcerptToken[] = [];
let depth = 0;
for (const token of item.typeExcerpt.spannedTokens) {
if (token.text.includes('?')) {
return [];
}
if (token.text.includes('<')) {
depth++;
}
if (token.text.includes('>')) {
depth--;
}
if (token.text.trim() === '|' && depth === 0) {
if (currentUnionMember.length) {
union.push(currentUnionMember);
currentUnionMember = [];
}
} else if (depth === 0 && token.kind === ExcerptTokenKind.Content && token.text.includes('|')) {
for (const [idx, tokenpart] of token.text.split('|').entries()) {
if (currentUnionMember.length && depth === 0 && idx === 0) {
currentUnionMember.push(new ExcerptToken(ExcerptTokenKind.Content, tokenpart));
union.push(currentUnionMember);
currentUnionMember = [];
} else if (currentUnionMember.length && depth === 0) {
union.push(currentUnionMember);
currentUnionMember = [new ExcerptToken(ExcerptTokenKind.Content, tokenpart)];
} else if (tokenpart.length) {
currentUnionMember.push(new ExcerptToken(ExcerptTokenKind.Content, tokenpart));
}
}
} else {
currentUnionMember.push(token);
}
}
if (currentUnionMember.length && union.length) {
union.push(currentUnionMember);
}
return union;
}, [item]);
return (
<Documentation>
<Header
@@ -16,6 +65,7 @@ export function TypeAlias({ item }: { readonly item: ApiTypeAlias }) {
{/* @ts-expect-error async component */}
<SyntaxHighlighter code={item.excerpt.text} />
<SummarySection item={item} />
{union.length ? <UnionMembersSection item={item} members={union} /> : null}
</Documentation>
);
}

View File

@@ -859,9 +859,9 @@ export interface IconData {
proxyIconURL?: string;
}
export type EmbedAuthorData = Omit<APIEmbedAuthor, 'icon_url' | 'proxy_icon_url'> & IconData;
export interface EmbedAuthorData extends Omit<APIEmbedAuthor, 'icon_url' | 'proxy_icon_url'>, IconData {}
export type EmbedFooterData = Omit<APIEmbedFooter, 'icon_url' | 'proxy_icon_url'> & IconData;
export interface EmbedFooterData extends Omit<APIEmbedFooter, 'icon_url' | 'proxy_icon_url'>, IconData {}
export interface EmbedAssetData extends Omit<APIEmbedImage, 'proxy_url'> {
proxyURL?: string;
@@ -1989,29 +1989,29 @@ export class LimitedCollection<Key, Value> extends Collection<Key, Value> {
export type MessageComponentType = Exclude<ComponentType, ComponentType.TextInput | ComponentType.ActionRow>;
export type MessageCollectorOptionsParams<
export interface MessageCollectorOptionsParams<
ComponentType extends MessageComponentType,
Cached extends boolean = boolean,
> = {
> extends MessageComponentCollectorOptions<MappedInteractionTypes<Cached>[ComponentType]> {
componentType?: ComponentType;
} & MessageComponentCollectorOptions<MappedInteractionTypes<Cached>[ComponentType]>;
}
export type MessageChannelCollectorOptionsParams<
export interface MessageChannelCollectorOptionsParams<
ComponentType extends MessageComponentType,
Cached extends boolean = boolean,
> = {
> extends MessageChannelComponentCollectorOptions<MappedInteractionTypes<Cached>[ComponentType]> {
componentType?: ComponentType;
} & MessageChannelComponentCollectorOptions<MappedInteractionTypes<Cached>[ComponentType]>;
}
export type AwaitMessageCollectorOptionsParams<
export interface AwaitMessageCollectorOptionsParams<
ComponentType extends MessageComponentType,
Cached extends boolean = boolean,
> = {
> extends Pick<
InteractionCollectorOptions<MappedInteractionTypes<Cached>[ComponentType]>,
keyof AwaitMessageComponentOptions<any>
> {
componentType?: ComponentType;
} & Pick<
InteractionCollectorOptions<MappedInteractionTypes<Cached>[ComponentType]>,
keyof AwaitMessageComponentOptions<any>
>;
}
export interface StringMappedInteractionTypes<Cached extends CacheType = CacheType> {
Button: ButtonInteraction<Cached>;
@@ -2437,7 +2437,9 @@ export interface GuildForumTag {
emoji: GuildForumTagEmoji | null;
}
export type GuildForumTagData = Partial<GuildForumTag> & { name: string };
export interface GuildForumTagData extends Partial<GuildForumTag> {
name: string;
}
export interface DefaultReactionEmoji {
id: Snowflake | null;
@@ -3974,7 +3976,7 @@ export class ChannelManager extends CachedManager<Snowflake, Channel, ChannelRes
public fetch(id: Snowflake, options?: FetchChannelOptions): Promise<Channel | null>;
}
export type FetchGuildApplicationCommandFetchOptions = Omit<FetchApplicationCommandOptions, 'guildId'>;
export interface FetchGuildApplicationCommandFetchOptions extends Omit<FetchApplicationCommandOptions, 'guildId'> {}
export class GuildApplicationCommandManager extends ApplicationCommandManager<ApplicationCommand, {}, Guild> {
private constructor(guild: Guild, iterable?: Iterable<RawApplicationCommandData>);
@@ -4421,7 +4423,7 @@ export interface WebhookFields extends PartialWebhookFields {
//#region Typedefs
export type ActivitiesOptions = Omit<ActivityOptions, 'shardId'>;
export interface ActivitiesOptions extends Omit<ActivityOptions, 'shardId'> {}
export interface ActivityOptions {
name: string;
@@ -4776,22 +4778,16 @@ export interface AutoModerationTriggerMetadata {
mentionRaidProtectionEnabled: boolean;
}
export type AwaitMessageComponentOptions<Interaction extends CollectedMessageInteraction> = Omit<
MessageComponentCollectorOptions<Interaction>,
'max' | 'maxComponents' | 'maxUsers'
>;
export interface AwaitMessageComponentOptions<Interaction extends CollectedMessageInteraction>
extends Omit<MessageComponentCollectorOptions<Interaction>, 'max' | 'maxComponents' | 'maxUsers'> {}
export type ModalSubmitInteractionCollectorOptions<Interaction extends ModalSubmitInteraction> = Omit<
InteractionCollectorOptions<Interaction>,
'channel' | 'message' | 'guild' | 'interactionType'
>;
export interface ModalSubmitInteractionCollectorOptions<Interaction extends ModalSubmitInteraction>
extends Omit<InteractionCollectorOptions<Interaction>, 'channel' | 'message' | 'guild' | 'interactionType'> {}
export type AwaitModalSubmitOptions<Interaction extends ModalSubmitInteraction> = Omit<
ModalSubmitInteractionCollectorOptions<Interaction>,
'max' | 'maxComponents' | 'maxUsers'
> & {
export interface AwaitModalSubmitOptions<Interaction extends ModalSubmitInteraction>
extends Omit<ModalSubmitInteractionCollectorOptions<Interaction>, 'max' | 'maxComponents' | 'maxUsers'> {
time: number;
};
}
export interface AwaitMessagesOptions extends MessageCollectorOptions {
errors?: string[];
@@ -5114,14 +5110,14 @@ export interface CommandInteractionResolvedData<Cached extends CacheType = Cache
attachments?: Collection<Snowflake, Attachment>;
}
export type AutocompleteFocusedOption = Pick<CommandInteractionOption, 'name'> & {
export interface AutocompleteFocusedOption extends Pick<CommandInteractionOption, 'name'> {
focused: true;
type:
| ApplicationCommandOptionType.String
| ApplicationCommandOptionType.Integer
| ApplicationCommandOptionType.Number;
value: string;
};
}
export declare const Colors: {
Default: 0x000000;
@@ -5913,7 +5909,7 @@ export interface InteractionDeferReplyOptions {
fetchReply?: boolean;
}
export type InteractionDeferUpdateOptions = Omit<InteractionDeferReplyOptions, 'ephemeral'>;
export interface InteractionDeferUpdateOptions extends Omit<InteractionDeferReplyOptions, 'ephemeral'> {}
export interface InteractionReplyOptions extends BaseMessageOptions {
tts?: boolean;
@@ -6025,15 +6021,11 @@ export type CollectedMessageInteraction<Cached extends CacheType = CacheType> =
ModalSubmitInteraction
>;
export type MessageComponentCollectorOptions<Interaction extends CollectedMessageInteraction> = Omit<
InteractionCollectorOptions<Interaction>,
'channel' | 'message' | 'guild' | 'interactionType'
>;
export interface MessageComponentCollectorOptions<Interaction extends CollectedMessageInteraction>
extends Omit<InteractionCollectorOptions<Interaction>, 'channel' | 'message' | 'guild' | 'interactionType'> {}
export type MessageChannelComponentCollectorOptions<Interaction extends CollectedMessageInteraction> = Omit<
InteractionCollectorOptions<Interaction>,
'channel' | 'guild' | 'interactionType'
>;
export interface MessageChannelComponentCollectorOptions<Interaction extends CollectedMessageInteraction>
extends Omit<InteractionCollectorOptions<Interaction>, 'channel' | 'guild' | 'interactionType'> {}
export interface MessageEvent {
data: WebSocketData;
@@ -6094,8 +6086,9 @@ export interface MessageCreateOptions extends BaseMessageOptions {
>;
}
export type GuildForumThreadMessageCreateOptions = BaseMessageOptions &
Pick<MessageCreateOptions, 'flags' | 'stickers'>;
export interface GuildForumThreadMessageCreateOptions
extends BaseMessageOptions,
Pick<MessageCreateOptions, 'flags' | 'stickers'> {}
export interface MessageEditAttachmentData {
id: Snowflake;
@@ -6215,9 +6208,7 @@ export type PermissionResolvable = BitFieldResolvable<keyof typeof PermissionFla
export type PermissionOverwriteResolvable = UserResolvable | RoleResolvable | PermissionOverwrites;
export type RecursiveArray<ItemType> = ReadonlyArray<ItemType | RecursiveArray<ItemType>>;
export type RecursiveReadonlyArray<ItemType> = ReadonlyArray<ItemType | RecursiveReadonlyArray<ItemType>>;
export interface RecursiveReadonlyArray<ItemType> extends ReadonlyArray<ItemType | RecursiveReadonlyArray<ItemType>> {}
export interface PartialRecipient {
username: string;
@@ -6567,7 +6558,7 @@ export interface WebhookClientDataURL {
url: string;
}
export type WebhookClientOptions = Pick<ClientOptions, 'allowedMentions' | 'rest'>;
export interface WebhookClientOptions extends Pick<ClientOptions, 'allowedMentions' | 'rest'> {}
export interface WebhookDeleteOptions {
token?: string;