Skip to content

Commit

Permalink
feat(website): show union members of type aliases (#10001)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
Qjuh and iCrawl committed Dec 1, 2023
1 parent b229240 commit a44ada6
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 48 deletions.
Original file line number Diff line number Diff line change
@@ -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>
);
}
52 changes: 51 additions & 1 deletion apps/website/src/components/model/TypeAlias.tsx
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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>
);
}
85 changes: 38 additions & 47 deletions packages/discord.js/typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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>;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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>);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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[];
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down

1 comment on commit a44ada6

@vercel
Copy link

@vercel vercel bot commented on a44ada6 Dec 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.