mirror of
https://github.com/stoatchat/javascript-client-sdk.git
synced 2026-07-19 17:13:31 -04:00
refactor: add File class
This commit is contained in:
@@ -348,55 +348,6 @@ export class Client extends EventEmitter<Events> {
|
||||
.replace(RE_SPOILER, "<spoiler>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a URL to a given file with given options.
|
||||
* @param attachment Partial of attachment object
|
||||
* @param options Optional query parameters to modify object
|
||||
* @param allowAnimation Returns GIF if applicable, no operations occur on image
|
||||
* @param fallback Fallback URL
|
||||
* @returns Generated URL or nothing
|
||||
*/
|
||||
createFileURL(
|
||||
attachment?: {
|
||||
tag: string;
|
||||
_id: string;
|
||||
content_type?: string;
|
||||
metadata?: Metadata;
|
||||
},
|
||||
...args: FileArgs
|
||||
) {
|
||||
const [options, allowAnimation, fallback] = args;
|
||||
|
||||
const autumn = this.configuration?.features.autumn;
|
||||
if (!autumn?.enabled) return fallback;
|
||||
if (!attachment) return fallback;
|
||||
|
||||
const { tag, _id, content_type, metadata } = attachment;
|
||||
|
||||
// TODO: server-side
|
||||
if (metadata?.type === "Image") {
|
||||
if (
|
||||
Math.min(metadata.width, metadata.height) <= 0 ||
|
||||
(content_type === "image/gif" &&
|
||||
Math.max(metadata.width, metadata.height) >= 4096)
|
||||
)
|
||||
return fallback;
|
||||
}
|
||||
|
||||
let query = "";
|
||||
if (options) {
|
||||
if (!allowAnimation || content_type !== "image/gif") {
|
||||
query =
|
||||
"?" +
|
||||
Object.keys(options)
|
||||
.map((k) => `${k}=${options[k as keyof FileArgs[0]]}`)
|
||||
.join("&");
|
||||
}
|
||||
}
|
||||
|
||||
return `${autumn.url}/${tag}/${_id}${query}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxy a file through January.
|
||||
* @param url URL to proxy
|
||||
@@ -410,14 +361,3 @@ export class Client extends EventEmitter<Events> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export type FileArgs = [
|
||||
options?: {
|
||||
max_side?: number;
|
||||
size?: number;
|
||||
width?: number;
|
||||
height?: number;
|
||||
},
|
||||
allowAnimation?: boolean,
|
||||
fallback?: string
|
||||
];
|
||||
|
||||
+6
-15
@@ -291,11 +291,8 @@ export class Channel {
|
||||
* URL to the channel icon
|
||||
*/
|
||||
get iconURL() {
|
||||
return this.#collection.client.createFileURL(
|
||||
this.icon ?? this.recipient?.avatar,
|
||||
{
|
||||
max_side: 256,
|
||||
}
|
||||
return (
|
||||
this.icon?.createFileURL({ max_side: 256 }) ?? this.recipient?.avatarURL
|
||||
);
|
||||
}
|
||||
|
||||
@@ -303,22 +300,16 @@ export class Channel {
|
||||
* URL to a small variant of the channel icon
|
||||
*/
|
||||
get smallIconURL() {
|
||||
return this.#collection.client.createFileURL(
|
||||
this.icon ?? this.recipient?.avatar,
|
||||
{
|
||||
max_side: 64,
|
||||
}
|
||||
);
|
||||
return this.icon?.createFileURL({ max_side: 64 });
|
||||
}
|
||||
|
||||
/**
|
||||
* URL to the animated channel icon
|
||||
*/
|
||||
get animatedIconURL() {
|
||||
return this.#collection.client.createFileURL(
|
||||
this.icon ?? this.recipient?.avatar,
|
||||
{ max_side: 256 },
|
||||
true
|
||||
return (
|
||||
this.icon?.createFileURL({ max_side: 256 }, true) ??
|
||||
this.recipient?.animatedAvatarURL
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
import { Metadata } from "revolt-api";
|
||||
|
||||
import { API, Client } from "..";
|
||||
|
||||
/**
|
||||
* Uploaded File
|
||||
*/
|
||||
export class File {
|
||||
#client: Client;
|
||||
|
||||
/**
|
||||
* File Id
|
||||
*/
|
||||
readonly id: string;
|
||||
|
||||
/**
|
||||
* File bucket
|
||||
*/
|
||||
readonly tag: string;
|
||||
|
||||
/**
|
||||
* Original filename
|
||||
*/
|
||||
readonly filename: string;
|
||||
|
||||
/**
|
||||
* Parsed metadata of the file
|
||||
*/
|
||||
readonly metadata: Metadata;
|
||||
|
||||
/**
|
||||
* Raw content type of this file
|
||||
*/
|
||||
readonly contentType: string;
|
||||
|
||||
/**
|
||||
* Size of the file (in bytes)
|
||||
*/
|
||||
readonly size: number;
|
||||
|
||||
/**
|
||||
* Construct file
|
||||
* @param client Client
|
||||
* @param file File
|
||||
*/
|
||||
constructor(client: Client, file: API.File) {
|
||||
this.#client = client;
|
||||
this.id = file._id;
|
||||
this.tag = file.tag;
|
||||
this.filename = file.filename;
|
||||
this.metadata = file.metadata;
|
||||
this.contentType = file.content_type;
|
||||
this.size = file.size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Direct URL to the file
|
||||
*/
|
||||
get url() {
|
||||
return `${this.#client.configuration?.features.autumn}/${this.tag}/${
|
||||
this.id
|
||||
}/${this.filename}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Download URL for the file
|
||||
*/
|
||||
get downloadURL() {
|
||||
return `${this.#client.configuration?.features.autumn}/${
|
||||
this.tag
|
||||
}/download/${this.id}/${this.filename}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Human readable file size
|
||||
*/
|
||||
get humanReadableSize() {
|
||||
if (this.size > 1e6) {
|
||||
return `${(this.size / 1e6).toFixed(2)} MB`;
|
||||
} else if (this.size > 1e3) {
|
||||
return `${(this.size / 1e3).toFixed(2)} KB`;
|
||||
}
|
||||
|
||||
return `${this.size} B`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a URL to a given file with given options.
|
||||
* @param options Optional query parameters to modify object
|
||||
* @param allowAnimation Returns GIF if applicable, no operations occur on image
|
||||
* @returns Generated URL or nothing
|
||||
*/
|
||||
createFileURL(
|
||||
options?: {
|
||||
max_side?: number;
|
||||
size?: number;
|
||||
width?: number;
|
||||
height?: number;
|
||||
},
|
||||
allowAnimation?: boolean
|
||||
) {
|
||||
const autumn = this.#client.configuration?.features.autumn;
|
||||
if (!autumn?.enabled) return;
|
||||
|
||||
// TODO: server-side
|
||||
if (this.metadata.type === "Image") {
|
||||
if (
|
||||
Math.min(this.metadata.width, this.metadata.height) <= 0 ||
|
||||
(this.contentType === "image/gif" &&
|
||||
Math.max(this.metadata.width, this.metadata.height) >= 4096)
|
||||
)
|
||||
return;
|
||||
}
|
||||
|
||||
let query = "";
|
||||
if (options) {
|
||||
if (!allowAnimation || this.contentType !== "image/gif") {
|
||||
query =
|
||||
"?" +
|
||||
Object.keys(options)
|
||||
.map((k) => `${k}=${options[k as keyof typeof options]}`)
|
||||
.join("&");
|
||||
}
|
||||
}
|
||||
|
||||
return `${autumn.url}/${this.tag}/${this.id}${query}`;
|
||||
}
|
||||
}
|
||||
@@ -259,27 +259,21 @@ export class Server {
|
||||
* URL to the server's icon
|
||||
*/
|
||||
get iconURL() {
|
||||
return this.#collection.client.createFileURL(this.icon, { max_side: 256 });
|
||||
return this.icon?.createFileURL({ max_side: 256 });
|
||||
}
|
||||
|
||||
/**
|
||||
* URL to the server's animated icon
|
||||
*/
|
||||
get animatedIconURL() {
|
||||
return this.#collection.client.createFileURL(
|
||||
this.icon,
|
||||
{ max_side: 256 },
|
||||
true
|
||||
);
|
||||
return this.icon?.createFileURL({ max_side: 256 }, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* URL to the server's banner
|
||||
*/
|
||||
get bannerURL() {
|
||||
return this.#collection.client.createFileURL(this.banner, {
|
||||
max_side: 256,
|
||||
});
|
||||
return this.banner?.createFileURL({ max_side: 256 }, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -187,8 +187,7 @@ export class ServerMember {
|
||||
*/
|
||||
get avatarURL() {
|
||||
return (
|
||||
this.#collection.client.createFileURL(this.avatar, { max_side: 256 }) ??
|
||||
this.user?.avatarURL
|
||||
this.avatar?.createFileURL({ max_side: 256 }) ?? this.user?.avatarURL
|
||||
);
|
||||
}
|
||||
|
||||
@@ -197,11 +196,8 @@ export class ServerMember {
|
||||
*/
|
||||
get animatedAvatarURL() {
|
||||
return (
|
||||
this.#collection.client.createFileURL(
|
||||
this.avatar,
|
||||
{ max_side: 256 },
|
||||
true
|
||||
) ?? this.user?.animatedAvatarURL
|
||||
this.avatar?.createFileURL({ max_side: 256 }, true) ??
|
||||
this.user?.animatedAvatarURL
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-7
@@ -112,8 +112,7 @@ export class User {
|
||||
*/
|
||||
get avatarURL() {
|
||||
return (
|
||||
this.#collection.client.createFileURL(this.avatar, { max_side: 256 }) ??
|
||||
this.defaultAvatarURL
|
||||
this.avatar?.createFileURL({ max_side: 256 }) ?? this.defaultAvatarURL
|
||||
);
|
||||
}
|
||||
|
||||
@@ -122,11 +121,8 @@ export class User {
|
||||
*/
|
||||
get animatedAvatarURL() {
|
||||
return (
|
||||
this.#collection.client.createFileURL(
|
||||
this.avatar,
|
||||
{ max_side: 256 },
|
||||
true
|
||||
) ?? this.defaultAvatarURL
|
||||
this.avatar?.createFileURL({ max_side: 256 }, true) ??
|
||||
this.defaultAvatarURL
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,3 +4,5 @@ export { Message } from "./Message";
|
||||
export { Server } from "./Server";
|
||||
export { ServerMember } from "./ServerMember";
|
||||
export { User } from "./User";
|
||||
export { File } from "./File";
|
||||
export { ChannelUnread } from "./ChannelUnread";
|
||||
|
||||
@@ -40,7 +40,7 @@ export class ChannelCollection extends ClassCollection<
|
||||
return this.get(id)!;
|
||||
} else {
|
||||
const instance = new Channel(this, id);
|
||||
this.create(id, "channel", instance, data);
|
||||
this.create(id, "channel", instance, this.client, data);
|
||||
isNew && this.client.emit("channelCreate", instance);
|
||||
return instance;
|
||||
}
|
||||
@@ -55,7 +55,7 @@ export class ChannelCollection extends ClassCollection<
|
||||
return this.get(id)!;
|
||||
} else if (this.client.options.partials) {
|
||||
const instance = new Channel(this, id);
|
||||
this.create(id, "channel", instance, {
|
||||
this.create(id, "channel", instance, this.client, {
|
||||
id,
|
||||
partial: true,
|
||||
});
|
||||
|
||||
@@ -36,7 +36,7 @@ export class ChannelUnreadCollection extends ClassCollection<
|
||||
return this.get(id)!;
|
||||
} else {
|
||||
const instance = new ChannelUnread(this, id);
|
||||
this.create(id, "channelUnread", instance, data);
|
||||
this.create(id, "channelUnread", instance, this.client, data);
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,10 +121,17 @@ export abstract class StoreCollection<T, V> extends Collection<T> {
|
||||
* @param id Id
|
||||
* @param type Type
|
||||
* @param instance Instance
|
||||
* @param context Context
|
||||
* @param data Data
|
||||
*/
|
||||
create(id: string, type: keyof Hydrators, instance: T, data?: unknown) {
|
||||
this.#storage.hydrate(id, type, data);
|
||||
create(
|
||||
id: string,
|
||||
type: keyof Hydrators,
|
||||
instance: T,
|
||||
context: any,
|
||||
data?: unknown
|
||||
) {
|
||||
this.#storage.hydrate(id, type, context, data);
|
||||
this.#objects.set(id, instance);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ export class EmojiCollection extends ClassCollection<Emoji, HydratedEmoji> {
|
||||
return this.get(id)!;
|
||||
} else {
|
||||
const instance = new Emoji(this, id);
|
||||
this.create(id, "emoji", instance, data);
|
||||
this.create(id, "emoji", instance, this.client, data);
|
||||
isNew && this.client.emit("emojiCreate", instance);
|
||||
return instance;
|
||||
}
|
||||
@@ -42,7 +42,7 @@ export class EmojiCollection extends ClassCollection<Emoji, HydratedEmoji> {
|
||||
return this.get(id)!;
|
||||
} else if (this.client.options.partials) {
|
||||
const instance = new Emoji(this, id);
|
||||
this.create(id, "emoji", instance, {
|
||||
this.create(id, "emoji", instance, this.client, {
|
||||
id,
|
||||
});
|
||||
return instance;
|
||||
|
||||
@@ -35,7 +35,7 @@ export class MessageCollection extends ClassCollection<
|
||||
return this.get(id)!;
|
||||
} else {
|
||||
const instance = new Message(this, id);
|
||||
this.create(id, "message", instance, data);
|
||||
this.create(id, "message", instance, this.client, data);
|
||||
isNew && this.client.emit("messageCreate", instance);
|
||||
return instance;
|
||||
}
|
||||
@@ -50,7 +50,7 @@ export class MessageCollection extends ClassCollection<
|
||||
return this.get(id)!;
|
||||
} else if (this.client.options.partials) {
|
||||
const instance = new Message(this, id);
|
||||
this.create(id, "message", instance, {
|
||||
this.create(id, "message", instance, this.client, {
|
||||
id,
|
||||
partial: true,
|
||||
});
|
||||
|
||||
@@ -27,7 +27,7 @@ export class ServerCollection extends ClassCollection<Server, HydratedServer> {
|
||||
return this.get(id)!;
|
||||
} else {
|
||||
const instance = new Server(this, id);
|
||||
this.create(id, "server", instance, data);
|
||||
this.create(id, "server", instance, this.client, data);
|
||||
isNew && this.client.emit("serverCreate", instance);
|
||||
return instance;
|
||||
}
|
||||
@@ -42,7 +42,7 @@ export class ServerCollection extends ClassCollection<Server, HydratedServer> {
|
||||
return this.get(id)!;
|
||||
} else if (this.client.options.partials) {
|
||||
const instance = new Server(this, id);
|
||||
this.create(id, "server", instance, {
|
||||
this.create(id, "server", instance, this.client, {
|
||||
id,
|
||||
partial: true,
|
||||
});
|
||||
|
||||
@@ -52,7 +52,13 @@ export class ServerMemberCollection extends ClassCollection<
|
||||
return this.getByKey(id)!;
|
||||
} else {
|
||||
const instance = new ServerMember(this, id);
|
||||
this.create(id.server + id.user, "serverMember", instance, data);
|
||||
this.create(
|
||||
id.server + id.user,
|
||||
"serverMember",
|
||||
instance,
|
||||
this.client,
|
||||
data
|
||||
);
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
@@ -66,7 +72,7 @@ export class ServerMemberCollection extends ClassCollection<
|
||||
return this.getByKey(id)!;
|
||||
} else if (this.client.options.partials) {
|
||||
const instance = new ServerMember(this, id);
|
||||
this.create(id.server + id.user, "serverMember", instance, {
|
||||
this.create(id.server + id.user, "serverMember", instance, this.client, {
|
||||
id,
|
||||
partial: true,
|
||||
});
|
||||
|
||||
@@ -27,7 +27,7 @@ export class UserCollection extends ClassCollection<User, HydratedUser> {
|
||||
return this.get(id)!;
|
||||
} else {
|
||||
const instance = new User(this, id);
|
||||
this.create(id, "user", instance, data);
|
||||
this.create(id, "user", instance, this.client, data);
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,7 @@ export class UserCollection extends ClassCollection<User, HydratedUser> {
|
||||
return this.get(id)!;
|
||||
} else if (this.client.options.partials) {
|
||||
const instance = new User(this, id);
|
||||
this.create(id, "user", instance, {
|
||||
this.create(id, "user", instance, this.client, {
|
||||
id,
|
||||
partial: true,
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { ReactiveSet } from "@solid-primitives/set";
|
||||
import { Channel as ApiChannel, File, OverrideField } from "revolt-api";
|
||||
import { Channel as ApiChannel, OverrideField } from "revolt-api";
|
||||
|
||||
import { File } from "..";
|
||||
import type { Merge } from "../lib/merge";
|
||||
|
||||
import { Hydrate } from ".";
|
||||
@@ -46,7 +47,7 @@ export const channelHydration: Hydrate<Merge<ApiChannel>, HydratedChannel> = {
|
||||
channelType: (channel) => channel.channel_type,
|
||||
name: (channel) => channel.name,
|
||||
description: (channel) => channel.description!,
|
||||
icon: (channel) => channel.icon!,
|
||||
icon: (channel, ctx) => new File(ctx, channel.icon!),
|
||||
active: (channel) => channel.active || false,
|
||||
typingIds: () => new ReactiveSet(),
|
||||
recipientIds: (channel) => new ReactiveSet(channel.recipients),
|
||||
|
||||
@@ -19,7 +19,7 @@ export type { HydratedUser } from "./user";
|
||||
*/
|
||||
export type MappingFns<Input, Output, Key extends keyof Output> = Record<
|
||||
Key,
|
||||
(value: Input) => Output[Key]
|
||||
(value: Input, context: any) => Output[Key]
|
||||
>;
|
||||
|
||||
/**
|
||||
@@ -44,13 +44,14 @@ export type Hydrate<Input, Output> = {
|
||||
*/
|
||||
function hydrateInternal<Input extends object, Output>(
|
||||
hydration: Hydrate<Input, Output>,
|
||||
input: Input
|
||||
input: Input,
|
||||
context: any
|
||||
): Output {
|
||||
return (Object.keys(input) as (keyof Input)[]).reduce((acc, key) => {
|
||||
let targetKey, value;
|
||||
try {
|
||||
targetKey = hydration.keyMapping[key] ?? key;
|
||||
value = hydration.functions[targetKey as keyof Output](input);
|
||||
value = hydration.functions[targetKey as keyof Output](input, context);
|
||||
} catch (err) {
|
||||
if (key === "type") return acc;
|
||||
console.debug(`Skipping key ${String(key)} during hydration!`);
|
||||
@@ -92,10 +93,12 @@ type ExtractOutput<T> = T extends Hydrate<any, infer O> ? O : never;
|
||||
export function hydrate<T extends keyof Hydrators>(
|
||||
type: T,
|
||||
input: Partial<ExtractInput<Hydrators[T]>>,
|
||||
context: any,
|
||||
initial?: boolean
|
||||
) {
|
||||
return hydrateInternal(
|
||||
hydrators[type] as never,
|
||||
initial ? { ...hydrators[type].initialHydration(), ...input } : input
|
||||
initial ? { ...hydrators[type].initialHydration(), ...input } : input,
|
||||
context
|
||||
) as ExtractOutput<Hydrators[T]>;
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@ import { ReactiveSet } from "@solid-primitives/set";
|
||||
import {
|
||||
Message as ApiMessage,
|
||||
Embed,
|
||||
File,
|
||||
Interactions,
|
||||
Masquerade,
|
||||
SystemMessage,
|
||||
} from "revolt-api";
|
||||
|
||||
import { File } from "..";
|
||||
import type { Merge } from "../lib/merge";
|
||||
|
||||
import { Hydrate } from ".";
|
||||
@@ -47,7 +47,8 @@ export const messageHydration: Hydrate<Merge<ApiMessage>, HydratedMessage> = {
|
||||
authorId: (message) => message.author,
|
||||
content: (message) => message.content!,
|
||||
systemMessage: (message) => message.system!,
|
||||
attachments: (message) => message.attachments!,
|
||||
attachments: (message, ctx) =>
|
||||
message.attachments!.map((file) => new File(ctx, file)),
|
||||
editedAt: (message) => new Date(message.edited!),
|
||||
embeds: (message) => message.embeds!,
|
||||
mentionIds: (message) => message.mentions!,
|
||||
|
||||
@@ -3,11 +3,12 @@ import { ReactiveSet } from "@solid-primitives/set";
|
||||
import {
|
||||
Server as ApiServer,
|
||||
Category,
|
||||
File,
|
||||
Role,
|
||||
SystemMessageChannels,
|
||||
} from "revolt-api";
|
||||
|
||||
import { File } from "..";
|
||||
|
||||
import { Hydrate } from ".";
|
||||
|
||||
export type HydratedServer = {
|
||||
@@ -54,8 +55,8 @@ export const serverHydration: Hydrate<ApiServer, HydratedServer> = {
|
||||
Object.keys(server.roles!).map((id) => [id, server.roles![id]])
|
||||
),
|
||||
defaultPermissions: (server) => server.default_permissions,
|
||||
icon: (server) => server.icon!,
|
||||
banner: (server) => server.banner!,
|
||||
icon: (server, ctx) => new File(ctx, server.icon!),
|
||||
banner: (server, ctx) => new File(ctx, server.banner!),
|
||||
flags: (server) => server.flags!,
|
||||
analytics: (server) => server.analytics || false,
|
||||
discoverable: (server) => server.discoverable || false,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Member as ApiMember, File, MemberCompositeKey } from "revolt-api";
|
||||
import { Member as ApiMember, MemberCompositeKey } from "revolt-api";
|
||||
|
||||
import { File } from "..";
|
||||
import type { Merge } from "../lib/merge";
|
||||
|
||||
import { Hydrate } from ".";
|
||||
@@ -25,7 +26,7 @@ export const serverMemberHydration: Hydrate<
|
||||
id: (member) => member._id,
|
||||
joinedAt: (member) => new Date(member.joined_at),
|
||||
nickname: (member) => member.nickname!,
|
||||
avatar: (member) => member.avatar!,
|
||||
avatar: (member, ctx) => new File(ctx, member.avatar!),
|
||||
roles: (member) => member.roles,
|
||||
timeout: (member) => new Date(member.timeout!),
|
||||
},
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import {
|
||||
User as ApiUser,
|
||||
BotInformation,
|
||||
File,
|
||||
RelationshipStatus,
|
||||
UserStatus,
|
||||
} from "revolt-api";
|
||||
|
||||
import { File } from "..";
|
||||
|
||||
import { Hydrate } from ".";
|
||||
|
||||
export type HydratedUser = {
|
||||
@@ -33,15 +34,15 @@ export const userHydration: Hydrate<ApiUser, HydratedUser> = {
|
||||
username: (user) => user.username,
|
||||
relationship: (user) => user.relationship ?? "None",
|
||||
|
||||
online: (user) => user.online || false,
|
||||
privileged: (user) => user.privileged || false,
|
||||
online: (user) => user.online!,
|
||||
privileged: (user) => user.privileged,
|
||||
|
||||
badges: (user) => user.badges ?? 0,
|
||||
flags: (user) => user.flags ?? 0,
|
||||
|
||||
avatar: (user) => user.avatar! ?? undefined,
|
||||
status: (user) => user.status! ?? undefined,
|
||||
bot: (user) => user.bot! ?? undefined,
|
||||
avatar: (user, ctx) => new File(ctx, user.avatar!),
|
||||
status: (user) => user.status!,
|
||||
bot: (user) => user.bot!,
|
||||
},
|
||||
initialHydration: () => ({
|
||||
relationship: "None",
|
||||
|
||||
@@ -32,11 +32,12 @@ export class ObjectStorage<T> {
|
||||
* Hydrate some data into storage
|
||||
* @param id ID
|
||||
* @param type Hydration type
|
||||
* @param context Context
|
||||
* @param data Input Data
|
||||
*/
|
||||
hydrate(id: string, type: keyof Hydrators, data?: unknown) {
|
||||
hydrate(id: string, type: keyof Hydrators, context: any, data?: unknown) {
|
||||
if (data) {
|
||||
this.set(id, hydrate(type, data as never, true) as T);
|
||||
this.set(id, hydrate(type, data as never, context, true) as T);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user