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 extends Structure { /** * The template used for removing data from the raw data stored for each User */ public static override readonly DataTemplate: Partial = {}; /** * @param data - The raw data received from the API for the user */ public constructor(data: Partialize) { super(data); } /** * {@inheritDoc Structure.[kPatch]} * * @internal */ public override [kPatch](data: Partial) { 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')}`; } }