mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-12 01:23:31 +01:00
feat: @discordjs/structures (#10900)
* chore: init /structures * feat: base structure * feat: initial structures design attempt * refactor(Structure): use unknown to store in kData * feat(Structure): add Invite refactor(Structure): patch to _patch * refactor: symbol names and override location * fix: don't possibly return 0 if discord borks Co-authored-by: Synbulat Biishev <signin@syjalo.dev> * refactor: use getter value instead of api Co-authored-by: Synbulat Biishev <signin@syjalo.dev> * refactor: cache createdTimestamp value Co-authored-by: Qjuh <76154676+Qjuh@users.noreply.github.com> * docs: better docs for what's done so far * feat: add Mixin * refactor(User): remove bitfield getters and add displayName * feat(structures): add Connection * feat(structures): add Channel base * refactor(Mixin): trace prototype chain, allow construction * fix(structures): fix mixin behavior * fix(structures): data optimization call behavior from perf testing * feat: channel mixins * chore: update deps * feat: channels and mixins * chore: more typeguard tests * fix: tests and some other issues * feat: add ChannelWebhookMixin * fix: more tests * chore: tests and docs * chore: docs * fix: remove unneccessary omitted * chore: apply code suggestions * refactor: change how extended invite works * fix: type imports * Apply suggestions from code review Co-authored-by: Almeida <github@almeidx.dev> * fix: tests * chore: add jsdoc * refactor: apply code suggestions * fix: don't instantiate sub-structures * fix: don't do null default twice * chore: use formatters, add _cache * chore: lockfile * chore: move MixinTypes to declaratiion file * fix: tests * fix: don't include source d.ts files for docs * feat: bitfields * feat: more bitfields * refactor: remove DirectoryChannel structure * chore: apply suggestions from code review * chore: remove unused import * refactor: use symbol for mixin toJSON, remove _ prefix * chore: apply suggestions from code review * refactor: remove bitfield casts * refactor: remove special case for threadchannel types * fix: apply code review suggestions * refactor: bitfields always store bigint * fix: tests * chore: apply suggestions from code review * fix: lint * refactor: conditional structuredClone * Apply suggestions from code review Co-authored-by: ckohen <chaikohen@gmail.com> * fix: code review errors * fix: lint * chore: bump dtypes * Update packages/structures/cliff.toml Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com> * docs: link to VideoQualityMode * chore: typo in comment * chore: small nits in docs links * chore: small nits * docs: forgot one * chore: update template * chore: typos and things * chore: apply suggestions from code review * fix: tests and typeguards * chore: don't clone appliedTags * refactor: use a symbol for patch method * fix: add missing readonly * chore: remove todo comment * refactor: use symbol for clone * fix: add constraint to DataType * chore: apply suggestions * fix: dtypes bump * chore: fix comment * chore: add todo comment * chore: mark bitfield as todo chore: mark bit field as todo and edit readme --------- Co-authored-by: ckohen <chaikohen@gmail.com> Co-authored-by: Synbulat Biishev <signin@syjalo.dev> Co-authored-by: Almeida <github@almeidx.dev> Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
This commit is contained in:
40
packages/structures/src/users/AvatarDecorationData.ts
Normal file
40
packages/structures/src/users/AvatarDecorationData.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import type { APIAvatarDecorationData } from 'discord-api-types/v10';
|
||||
import { Structure } from '../Structure.js';
|
||||
import { kData } from '../utils/symbols.js';
|
||||
import type { Partialize } from '../utils/types.js';
|
||||
|
||||
/**
|
||||
* Represents metadata of an avatar decoration of a User.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
*/
|
||||
export class AvatarDecorationData<Omitted extends keyof APIAvatarDecorationData | '' = ''> extends Structure<
|
||||
APIAvatarDecorationData,
|
||||
Omitted
|
||||
> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each Connection
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<APIAvatarDecorationData> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the connection
|
||||
*/
|
||||
public constructor(data: Partialize<APIAvatarDecorationData, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The id of the SKU this avatar decoration is part of.
|
||||
*/
|
||||
public get skuId() {
|
||||
return this[kData].sku_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The asset of this avatar decoration.
|
||||
*/
|
||||
public get asset() {
|
||||
return this[kData].asset;
|
||||
}
|
||||
}
|
||||
95
packages/structures/src/users/Connection.ts
Normal file
95
packages/structures/src/users/Connection.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
import type { APIConnection } from 'discord-api-types/v10';
|
||||
import { Structure } from '../Structure.js';
|
||||
import { kData, kPatch } from '../utils/symbols.js';
|
||||
import type { Partialize } from '../utils/types.js';
|
||||
|
||||
/**
|
||||
* Represents a user's connection on Discord.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
*/
|
||||
export class Connection<Omitted extends keyof APIConnection | '' = ''> extends Structure<APIConnection, Omitted> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each Connection
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<APIConnection> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the connection
|
||||
*/
|
||||
public constructor(data: Partialize<APIConnection, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc Structure.[kPatch]}
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public override [kPatch](data: Partial<APIConnection>) {
|
||||
return super[kPatch](data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The id of the connection account
|
||||
*/
|
||||
public get id() {
|
||||
return this[kData].id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The username of the connection account
|
||||
*/
|
||||
public get name() {
|
||||
return this[kData].name;
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of service this connection is for
|
||||
*/
|
||||
public get type() {
|
||||
return this[kData].type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the connection is revoked
|
||||
*/
|
||||
public get revoked() {
|
||||
return this[kData].revoked ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the connection is verified
|
||||
*/
|
||||
public get verified() {
|
||||
return this[kData].verified;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether friend sync is enabled for this connection
|
||||
*/
|
||||
public get friendSync() {
|
||||
return this[kData].friend_sync;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether activities related to this connection are shown in the users presence
|
||||
*/
|
||||
public get showActivity() {
|
||||
return this[kData].show_activity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this connection has an Oauth2 token for console voice transfer
|
||||
*/
|
||||
public get twoWayLink() {
|
||||
return this[kData].two_way_link;
|
||||
}
|
||||
|
||||
/**
|
||||
* The visibility state for this connection
|
||||
*/
|
||||
public get visibility() {
|
||||
return this[kData].visibility;
|
||||
}
|
||||
}
|
||||
180
packages/structures/src/users/User.ts
Normal file
180
packages/structures/src/users/User.ts
Normal file
@@ -0,0 +1,180 @@
|
||||
import { DiscordSnowflake } from '@sapphire/snowflake';
|
||||
import type { APIUser } from 'discord-api-types/v10';
|
||||
import { Structure } from '../Structure.js';
|
||||
import { kData, kPatch } from '../utils/symbols.js';
|
||||
import { isIdSet } from '../utils/type-guards.js';
|
||||
import type { Partialize } from '../utils/types.js';
|
||||
|
||||
/**
|
||||
* Represents any user on Discord.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
* @remarks has a substructure `AvatarDecorationData`, which needs to be instantiated and stored by an extending class using it
|
||||
*/
|
||||
export class User<Omitted extends keyof APIUser | '' = ''> extends Structure<APIUser, Omitted> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each User
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<APIUser> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the user
|
||||
*/
|
||||
public constructor(data: Partialize<APIUser, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc Structure.[kPatch]}
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public override [kPatch](data: Partial<APIUser>) {
|
||||
return super[kPatch](data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The user's id
|
||||
*/
|
||||
public get id() {
|
||||
return this[kData].id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The username of the user
|
||||
*/
|
||||
public get username() {
|
||||
return this[kData].username;
|
||||
}
|
||||
|
||||
/**
|
||||
* The user's 4 digit tag, if a bot
|
||||
*/
|
||||
public get discriminator() {
|
||||
return this[kData].discriminator;
|
||||
}
|
||||
|
||||
/**
|
||||
* The user's display name, the application name for bots
|
||||
*/
|
||||
public get globalName() {
|
||||
return this[kData].global_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* The name displayed in the client for this user when no nickname is set
|
||||
*/
|
||||
public get displayName() {
|
||||
return this.globalName ?? this.username;
|
||||
}
|
||||
|
||||
/**
|
||||
* The user avatar's hash
|
||||
*/
|
||||
public get avatar() {
|
||||
return this[kData].avatar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the user is a bot
|
||||
*/
|
||||
public get bot() {
|
||||
return this[kData].bot ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the user is an Official Discord System user
|
||||
*/
|
||||
public get system() {
|
||||
return this[kData].system ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the user has mfa enabled
|
||||
*
|
||||
* @remarks This property is only set when the user was fetched with an OAuth2 token and the `identify` scope
|
||||
*/
|
||||
public get mfaEnabled() {
|
||||
return this[kData].mfa_enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* The user's banner hash
|
||||
*
|
||||
* @remarks This property is only set when the user was manually fetched
|
||||
*/
|
||||
public get banner() {
|
||||
return this[kData].banner;
|
||||
}
|
||||
|
||||
/**
|
||||
* The base 10 accent color of the user's banner
|
||||
*
|
||||
* @remarks This property is only set when the user was manually fetched
|
||||
*/
|
||||
public get accentColor() {
|
||||
return this[kData].accent_color;
|
||||
}
|
||||
|
||||
/**
|
||||
* The user's primary Discord language
|
||||
*
|
||||
* @remarks This property is only set when the user was fetched with an Oauth2 token and the `identify` scope
|
||||
*/
|
||||
public get locale() {
|
||||
return this[kData].locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the email on the user's account has been verified
|
||||
*
|
||||
* @remarks This property is only set when the user was fetched with an OAuth2 token and the `email` scope
|
||||
*/
|
||||
public get verified() {
|
||||
return this[kData].verified;
|
||||
}
|
||||
|
||||
/**
|
||||
* The user's email
|
||||
*
|
||||
* @remarks This property is only set when the user was fetched with an OAuth2 token and the `email` scope
|
||||
*/
|
||||
public get email() {
|
||||
return this[kData].email;
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of nitro subscription on the user's account
|
||||
*
|
||||
* @remarks This property is only set when the user was fetched with an OAuth2 token and the `identify` scope
|
||||
*/
|
||||
public get premiumType() {
|
||||
return this[kData].premium_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* The timestamp the user was created at
|
||||
*/
|
||||
public get createdTimestamp() {
|
||||
return isIdSet(this.id) ? DiscordSnowflake.timestampFrom(this.id) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The time the user was created at
|
||||
*/
|
||||
public get createdAt() {
|
||||
const createdTimestamp = this.createdTimestamp;
|
||||
return createdTimestamp ? new Date(createdTimestamp) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The hexadecimal version of the user accent color, with a leading hash
|
||||
*
|
||||
* @remarks This property is only set when the user was manually fetched
|
||||
*/
|
||||
public get hexAccentColor() {
|
||||
const accentColor = this.accentColor;
|
||||
if (typeof accentColor !== 'number') return accentColor;
|
||||
return `#${accentColor.toString(16).padStart(6, '0')}`;
|
||||
}
|
||||
}
|
||||
3
packages/structures/src/users/index.ts
Normal file
3
packages/structures/src/users/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from './AvatarDecorationData.js';
|
||||
export * from './User.js';
|
||||
export * from './Connection.js';
|
||||
Reference in New Issue
Block a user