initial commit
This commit is contained in:
76
fluxer_api/src/models/Application.ts
Normal file
76
fluxer_api/src/models/Application.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {ApplicationID, UserID} from '~/BrandedTypes';
|
||||
import type {ApplicationRow} from '~/database/types/OAuth2Types';
|
||||
|
||||
export class Application {
|
||||
readonly applicationId: ApplicationID;
|
||||
readonly ownerUserId: UserID;
|
||||
readonly name: string;
|
||||
readonly botUserId: UserID | null;
|
||||
readonly botIsPublic: boolean;
|
||||
readonly oauth2RedirectUris: Set<string>;
|
||||
readonly clientSecretHash: string | null;
|
||||
readonly botTokenHash: string | null;
|
||||
readonly botTokenPreview: string | null;
|
||||
readonly botTokenCreatedAt: Date | null;
|
||||
readonly clientSecretCreatedAt: Date | null;
|
||||
readonly version: number;
|
||||
|
||||
constructor(row: ApplicationRow) {
|
||||
this.applicationId = row.application_id;
|
||||
this.ownerUserId = row.owner_user_id;
|
||||
this.name = row.name;
|
||||
this.botUserId = row.bot_user_id;
|
||||
this.botIsPublic = row.bot_is_public ?? row.bot_user_id !== null;
|
||||
this.oauth2RedirectUris = row.oauth2_redirect_uris ?? new Set<string>();
|
||||
this.clientSecretHash = row.client_secret_hash;
|
||||
this.botTokenHash = row.bot_token_hash;
|
||||
this.botTokenPreview = row.bot_token_preview;
|
||||
this.botTokenCreatedAt = row.bot_token_created_at;
|
||||
this.clientSecretCreatedAt = row.client_secret_created_at;
|
||||
this.version = row.version ?? 1;
|
||||
}
|
||||
|
||||
toRow(): ApplicationRow {
|
||||
return {
|
||||
application_id: this.applicationId,
|
||||
owner_user_id: this.ownerUserId,
|
||||
name: this.name,
|
||||
bot_user_id: this.botUserId,
|
||||
bot_is_public: this.botIsPublic,
|
||||
oauth2_redirect_uris: this.oauth2RedirectUris,
|
||||
client_secret_hash: this.clientSecretHash,
|
||||
bot_token_hash: this.botTokenHash,
|
||||
bot_token_preview: this.botTokenPreview,
|
||||
bot_token_created_at: this.botTokenCreatedAt,
|
||||
client_secret_created_at: this.clientSecretCreatedAt,
|
||||
version: this.version,
|
||||
};
|
||||
}
|
||||
|
||||
hasBotUser(): boolean {
|
||||
return this.botUserId !== null;
|
||||
}
|
||||
|
||||
getBotUserId(): UserID | null {
|
||||
return this.botUserId;
|
||||
}
|
||||
}
|
||||
71
fluxer_api/src/models/Attachment.ts
Normal file
71
fluxer_api/src/models/Attachment.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {MessageAttachment} from '~/database/CassandraTypes';
|
||||
import type {AttachmentID} from '../BrandedTypes';
|
||||
|
||||
export class Attachment {
|
||||
readonly id: AttachmentID;
|
||||
readonly filename: string;
|
||||
readonly size: bigint;
|
||||
readonly title: string | null;
|
||||
readonly description: string | null;
|
||||
readonly width: number | null;
|
||||
readonly height: number | null;
|
||||
readonly contentType: string;
|
||||
readonly contentHash: string | null;
|
||||
readonly placeholder: string | null;
|
||||
readonly flags: number;
|
||||
readonly duration: number | null;
|
||||
readonly nsfw: boolean | null;
|
||||
|
||||
constructor(attachment: MessageAttachment) {
|
||||
this.id = attachment.attachment_id;
|
||||
this.filename = attachment.filename;
|
||||
this.size = attachment.size;
|
||||
this.title = attachment.title ?? null;
|
||||
this.description = attachment.description ?? null;
|
||||
this.width = attachment.width ?? null;
|
||||
this.height = attachment.height ?? null;
|
||||
this.contentType = attachment.content_type;
|
||||
this.contentHash = attachment.content_hash ?? null;
|
||||
this.placeholder = attachment.placeholder ?? null;
|
||||
this.flags = attachment.flags ?? 0;
|
||||
this.duration = attachment.duration ?? null;
|
||||
this.nsfw = attachment.nsfw ?? null;
|
||||
}
|
||||
|
||||
toMessageAttachment(): MessageAttachment {
|
||||
return {
|
||||
attachment_id: this.id,
|
||||
filename: this.filename,
|
||||
size: this.size,
|
||||
title: this.title,
|
||||
description: this.description,
|
||||
width: this.width,
|
||||
height: this.height,
|
||||
content_type: this.contentType,
|
||||
content_hash: this.contentHash,
|
||||
placeholder: this.placeholder,
|
||||
flags: this.flags,
|
||||
duration: this.duration,
|
||||
nsfw: this.nsfw,
|
||||
};
|
||||
}
|
||||
}
|
||||
62
fluxer_api/src/models/AuthSession.ts
Normal file
62
fluxer_api/src/models/AuthSession.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {AuthSessionRow} from '~/database/CassandraTypes';
|
||||
import type {UserID} from '../BrandedTypes';
|
||||
|
||||
export class AuthSession {
|
||||
readonly userId: UserID;
|
||||
readonly sessionIdHash: Buffer;
|
||||
readonly createdAt: Date;
|
||||
readonly approximateLastUsedAt: Date;
|
||||
readonly clientIp: string;
|
||||
readonly clientOs: string;
|
||||
readonly clientPlatform: string;
|
||||
readonly clientCountry: string | null;
|
||||
readonly clientLocation: string | null;
|
||||
readonly version: number;
|
||||
|
||||
constructor(row: AuthSessionRow) {
|
||||
this.userId = row.user_id;
|
||||
this.sessionIdHash = row.session_id_hash;
|
||||
this.createdAt = row.created_at;
|
||||
this.approximateLastUsedAt = row.approx_last_used_at;
|
||||
this.clientIp = row.client_ip;
|
||||
this.clientOs = row.client_os;
|
||||
this.clientPlatform = row.client_platform;
|
||||
this.clientCountry = row.client_country ?? null;
|
||||
this.clientLocation = row.client_location ?? null;
|
||||
this.version = row.version;
|
||||
}
|
||||
|
||||
toRow(): AuthSessionRow {
|
||||
return {
|
||||
user_id: this.userId,
|
||||
session_id_hash: this.sessionIdHash,
|
||||
created_at: this.createdAt,
|
||||
approx_last_used_at: this.approximateLastUsedAt,
|
||||
client_ip: this.clientIp,
|
||||
client_os: this.clientOs,
|
||||
client_platform: this.clientPlatform,
|
||||
client_country: this.clientCountry,
|
||||
client_location: this.clientLocation,
|
||||
version: this.version,
|
||||
};
|
||||
}
|
||||
}
|
||||
51
fluxer_api/src/models/BetaCode.ts
Normal file
51
fluxer_api/src/models/BetaCode.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {BetaCodeRow} from '~/database/CassandraTypes';
|
||||
import type {UserID} from '../BrandedTypes';
|
||||
import {createBetaCode} from '../BrandedTypes';
|
||||
|
||||
export class BetaCode {
|
||||
readonly code: string;
|
||||
readonly creatorId: UserID;
|
||||
readonly createdAt: Date;
|
||||
readonly redeemerId: UserID | null;
|
||||
readonly redeemedAt: Date | null;
|
||||
readonly version: number;
|
||||
|
||||
constructor(row: BetaCodeRow) {
|
||||
this.code = row.code;
|
||||
this.creatorId = row.creator_id;
|
||||
this.createdAt = row.created_at;
|
||||
this.redeemerId = row.redeemer_id ?? null;
|
||||
this.redeemedAt = row.redeemed_at ?? null;
|
||||
this.version = row.version;
|
||||
}
|
||||
|
||||
toRow(): BetaCodeRow {
|
||||
return {
|
||||
code: createBetaCode(this.code),
|
||||
creator_id: this.creatorId,
|
||||
created_at: this.createdAt,
|
||||
redeemer_id: this.redeemerId,
|
||||
redeemed_at: this.redeemedAt,
|
||||
version: this.version,
|
||||
};
|
||||
}
|
||||
}
|
||||
38
fluxer_api/src/models/CallInfo.ts
Normal file
38
fluxer_api/src/models/CallInfo.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {MessageCall} from '~/database/CassandraTypes';
|
||||
import type {UserID} from '../BrandedTypes';
|
||||
|
||||
export class CallInfo {
|
||||
readonly participantIds: Set<UserID>;
|
||||
readonly endedTimestamp: Date | null;
|
||||
|
||||
constructor(call: MessageCall) {
|
||||
this.participantIds = call.participant_ids ?? new Set();
|
||||
this.endedTimestamp = call.ended_timestamp ?? null;
|
||||
}
|
||||
|
||||
toMessageCall(): MessageCall {
|
||||
return {
|
||||
participant_ids: this.participantIds.size > 0 ? this.participantIds : null,
|
||||
ended_timestamp: this.endedTimestamp,
|
||||
};
|
||||
}
|
||||
}
|
||||
117
fluxer_api/src/models/Channel.ts
Normal file
117
fluxer_api/src/models/Channel.ts
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {ChannelRow, PermissionOverwrite} from '~/database/CassandraTypes';
|
||||
import type {ChannelID, GuildID, MessageID, RoleID, UserID} from '../BrandedTypes';
|
||||
import {ChannelPermissionOverwrite} from './ChannelPermissionOverwrite';
|
||||
|
||||
export class Channel {
|
||||
readonly id: ChannelID;
|
||||
readonly guildId: GuildID | null;
|
||||
readonly type: number;
|
||||
readonly name: string | null;
|
||||
readonly topic: string | null;
|
||||
readonly iconHash: string | null;
|
||||
readonly url: string | null;
|
||||
readonly parentId: ChannelID | null;
|
||||
readonly position: number;
|
||||
readonly ownerId: UserID | null;
|
||||
readonly recipientIds: Set<UserID>;
|
||||
readonly isNsfw: boolean;
|
||||
readonly rateLimitPerUser: number;
|
||||
readonly bitrate: number | null;
|
||||
readonly userLimit: number | null;
|
||||
readonly rtcRegion: string | null;
|
||||
readonly lastMessageId: MessageID | null;
|
||||
readonly lastPinTimestamp: Date | null;
|
||||
readonly permissionOverwrites: Map<RoleID | UserID, ChannelPermissionOverwrite>;
|
||||
readonly nicknames: Map<string, string>;
|
||||
readonly isSoftDeleted: boolean;
|
||||
readonly indexedAt: Date | null;
|
||||
readonly version: number;
|
||||
|
||||
constructor(row: ChannelRow) {
|
||||
this.id = row.channel_id;
|
||||
this.guildId = row.guild_id ?? null;
|
||||
this.type = row.type;
|
||||
this.name = row.name ?? null;
|
||||
this.topic = row.topic ?? null;
|
||||
this.iconHash = row.icon_hash ?? null;
|
||||
this.url = row.url ?? null;
|
||||
this.parentId = row.parent_id ?? null;
|
||||
this.position = row.position ?? 0;
|
||||
this.ownerId = row.owner_id ?? null;
|
||||
this.recipientIds = row.recipient_ids ?? new Set();
|
||||
this.isNsfw = row.nsfw ?? false;
|
||||
this.rateLimitPerUser = row.rate_limit_per_user ?? 0;
|
||||
this.bitrate = row.bitrate ?? 0;
|
||||
this.userLimit = row.user_limit ?? 0;
|
||||
this.rtcRegion = row.rtc_region ?? null;
|
||||
this.lastMessageId = row.last_message_id ?? null;
|
||||
this.lastPinTimestamp = row.last_pin_timestamp ?? null;
|
||||
this.permissionOverwrites = new Map();
|
||||
if (row.permission_overwrites) {
|
||||
for (const [id, overwrite] of row.permission_overwrites) {
|
||||
this.permissionOverwrites.set(id, new ChannelPermissionOverwrite(overwrite));
|
||||
}
|
||||
}
|
||||
this.nicknames = row.nicks ?? new Map();
|
||||
this.isSoftDeleted = row.soft_deleted;
|
||||
this.indexedAt = row.indexed_at ?? null;
|
||||
this.version = row.version;
|
||||
}
|
||||
|
||||
toRow(): ChannelRow {
|
||||
const permOverwritesMap: Map<UserID | RoleID, PermissionOverwrite> | null =
|
||||
this.permissionOverwrites.size > 0
|
||||
? new Map(
|
||||
Array.from(this.permissionOverwrites.entries()).map(([id, overwrite]) => [
|
||||
id,
|
||||
overwrite.toPermissionOverwrite(),
|
||||
]),
|
||||
)
|
||||
: null;
|
||||
|
||||
return {
|
||||
channel_id: this.id,
|
||||
guild_id: this.guildId,
|
||||
type: this.type,
|
||||
name: this.name,
|
||||
topic: this.topic,
|
||||
icon_hash: this.iconHash,
|
||||
url: this.url,
|
||||
parent_id: this.parentId,
|
||||
position: this.position,
|
||||
owner_id: this.ownerId,
|
||||
recipient_ids: this.recipientIds.size > 0 ? this.recipientIds : null,
|
||||
nsfw: this.isNsfw,
|
||||
rate_limit_per_user: this.rateLimitPerUser,
|
||||
bitrate: this.bitrate,
|
||||
user_limit: this.userLimit,
|
||||
rtc_region: this.rtcRegion,
|
||||
last_message_id: this.lastMessageId,
|
||||
last_pin_timestamp: this.lastPinTimestamp,
|
||||
permission_overwrites: permOverwritesMap,
|
||||
nicks: this.nicknames.size > 0 ? this.nicknames : null,
|
||||
soft_deleted: this.isSoftDeleted,
|
||||
indexed_at: this.indexedAt,
|
||||
version: this.version,
|
||||
};
|
||||
}
|
||||
}
|
||||
40
fluxer_api/src/models/ChannelPermissionOverwrite.ts
Normal file
40
fluxer_api/src/models/ChannelPermissionOverwrite.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {PermissionOverwrite} from '~/database/CassandraTypes';
|
||||
|
||||
export class ChannelPermissionOverwrite {
|
||||
readonly type: number;
|
||||
readonly allow: bigint;
|
||||
readonly deny: bigint;
|
||||
|
||||
constructor(overwrite: PermissionOverwrite) {
|
||||
this.type = overwrite.type;
|
||||
this.allow = overwrite.allow_ ?? 0n;
|
||||
this.deny = overwrite.deny_ ?? 0n;
|
||||
}
|
||||
|
||||
toPermissionOverwrite(): PermissionOverwrite {
|
||||
return {
|
||||
type: this.type,
|
||||
allow_: this.allow,
|
||||
deny_: this.deny,
|
||||
};
|
||||
}
|
||||
}
|
||||
42
fluxer_api/src/models/EmailRevertToken.ts
Normal file
42
fluxer_api/src/models/EmailRevertToken.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {EmailRevertTokenRow} from '~/database/CassandraTypes';
|
||||
import type {UserID} from '../BrandedTypes';
|
||||
import {createEmailRevertToken} from '../BrandedTypes';
|
||||
|
||||
export class EmailRevertToken {
|
||||
readonly token: string;
|
||||
readonly userId: UserID;
|
||||
readonly email: string;
|
||||
|
||||
constructor(row: EmailRevertTokenRow) {
|
||||
this.token = row.token_;
|
||||
this.userId = row.user_id;
|
||||
this.email = row.email;
|
||||
}
|
||||
|
||||
toRow(): EmailRevertTokenRow {
|
||||
return {
|
||||
token_: createEmailRevertToken(this.token),
|
||||
user_id: this.userId,
|
||||
email: this.email,
|
||||
};
|
||||
}
|
||||
}
|
||||
42
fluxer_api/src/models/EmailVerificationToken.ts
Normal file
42
fluxer_api/src/models/EmailVerificationToken.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {EmailVerificationTokenRow} from '~/database/CassandraTypes';
|
||||
import type {UserID} from '../BrandedTypes';
|
||||
import {createEmailVerificationToken} from '../BrandedTypes';
|
||||
|
||||
export class EmailVerificationToken {
|
||||
readonly token: string;
|
||||
readonly userId: UserID;
|
||||
readonly email: string;
|
||||
|
||||
constructor(row: EmailVerificationTokenRow) {
|
||||
this.token = row.token_;
|
||||
this.userId = row.user_id;
|
||||
this.email = row.email;
|
||||
}
|
||||
|
||||
toRow(): EmailVerificationTokenRow {
|
||||
return {
|
||||
token_: createEmailVerificationToken(this.token),
|
||||
user_id: this.userId,
|
||||
email: this.email,
|
||||
};
|
||||
}
|
||||
}
|
||||
78
fluxer_api/src/models/Embed.ts
Normal file
78
fluxer_api/src/models/Embed.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {MessageEmbed} from '~/database/CassandraTypes';
|
||||
import {EmbedAuthor} from './EmbedAuthor';
|
||||
import {EmbedField} from './EmbedField';
|
||||
import {EmbedFooter} from './EmbedFooter';
|
||||
import {EmbedMedia} from './EmbedMedia';
|
||||
import {EmbedProvider} from './EmbedProvider';
|
||||
|
||||
export class Embed {
|
||||
readonly type: string | null;
|
||||
readonly title: string | null;
|
||||
readonly description: string | null;
|
||||
readonly url: string | null;
|
||||
readonly timestamp: Date | null;
|
||||
readonly color: number | null;
|
||||
readonly author: EmbedAuthor | null;
|
||||
readonly provider: EmbedProvider | null;
|
||||
readonly thumbnail: EmbedMedia | null;
|
||||
readonly image: EmbedMedia | null;
|
||||
readonly video: EmbedMedia | null;
|
||||
readonly footer: EmbedFooter | null;
|
||||
readonly fields: Array<EmbedField>;
|
||||
readonly nsfw: boolean | null;
|
||||
|
||||
constructor(embed: MessageEmbed) {
|
||||
this.type = embed.type ?? null;
|
||||
this.title = embed.title ?? null;
|
||||
this.description = embed.description ?? null;
|
||||
this.url = embed.url ?? null;
|
||||
this.timestamp = embed.timestamp ?? null;
|
||||
this.color = embed.color ?? null;
|
||||
this.author = embed.author ? new EmbedAuthor(embed.author) : null;
|
||||
this.provider = embed.provider ? new EmbedProvider(embed.provider) : null;
|
||||
this.thumbnail = embed.thumbnail ? new EmbedMedia(embed.thumbnail) : null;
|
||||
this.image = embed.image ? new EmbedMedia(embed.image) : null;
|
||||
this.video = embed.video ? new EmbedMedia(embed.video) : null;
|
||||
this.footer = embed.footer ? new EmbedFooter(embed.footer) : null;
|
||||
this.fields = (embed.fields ?? []).map((field) => new EmbedField(field));
|
||||
this.nsfw = embed.nsfw ?? null;
|
||||
}
|
||||
|
||||
toMessageEmbed(): MessageEmbed {
|
||||
return {
|
||||
type: this.type,
|
||||
title: this.title,
|
||||
description: this.description,
|
||||
url: this.url,
|
||||
timestamp: this.timestamp,
|
||||
color: this.color,
|
||||
author: this.author?.toMessageEmbedAuthor() ?? null,
|
||||
provider: this.provider?.toMessageEmbedProvider() ?? null,
|
||||
thumbnail: this.thumbnail?.toMessageEmbedMedia() ?? null,
|
||||
image: this.image?.toMessageEmbedMedia() ?? null,
|
||||
video: this.video?.toMessageEmbedMedia() ?? null,
|
||||
footer: this.footer?.toMessageEmbedFooter() ?? null,
|
||||
fields: this.fields.length > 0 ? this.fields.map((field) => field.toMessageEmbedField()) : null,
|
||||
nsfw: this.nsfw,
|
||||
};
|
||||
}
|
||||
}
|
||||
40
fluxer_api/src/models/EmbedAuthor.ts
Normal file
40
fluxer_api/src/models/EmbedAuthor.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {MessageEmbedAuthor} from '~/database/CassandraTypes';
|
||||
|
||||
export class EmbedAuthor {
|
||||
readonly name: string | null;
|
||||
readonly url: string | null;
|
||||
readonly iconUrl: string | null;
|
||||
|
||||
constructor(author: MessageEmbedAuthor) {
|
||||
this.name = author.name ?? null;
|
||||
this.url = author.url ?? null;
|
||||
this.iconUrl = author.icon_url ?? null;
|
||||
}
|
||||
|
||||
toMessageEmbedAuthor(): MessageEmbedAuthor {
|
||||
return {
|
||||
name: this.name,
|
||||
url: this.url,
|
||||
icon_url: this.iconUrl,
|
||||
};
|
||||
}
|
||||
}
|
||||
40
fluxer_api/src/models/EmbedField.ts
Normal file
40
fluxer_api/src/models/EmbedField.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {MessageEmbedField} from '~/database/CassandraTypes';
|
||||
|
||||
export class EmbedField {
|
||||
readonly name: string;
|
||||
readonly value: string;
|
||||
readonly inline: boolean;
|
||||
|
||||
constructor(field: MessageEmbedField) {
|
||||
this.name = field.name ?? '';
|
||||
this.value = field.value ?? '';
|
||||
this.inline = field.inline ?? false;
|
||||
}
|
||||
|
||||
toMessageEmbedField(): MessageEmbedField {
|
||||
return {
|
||||
name: this.name || null,
|
||||
value: this.value || null,
|
||||
inline: this.inline,
|
||||
};
|
||||
}
|
||||
}
|
||||
37
fluxer_api/src/models/EmbedFooter.ts
Normal file
37
fluxer_api/src/models/EmbedFooter.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {MessageEmbedFooter} from '~/database/CassandraTypes';
|
||||
|
||||
export class EmbedFooter {
|
||||
readonly text: string | null;
|
||||
readonly iconUrl: string | null;
|
||||
|
||||
constructor(footer: MessageEmbedFooter) {
|
||||
this.text = footer.text ?? null;
|
||||
this.iconUrl = footer.icon_url ?? null;
|
||||
}
|
||||
|
||||
toMessageEmbedFooter(): MessageEmbedFooter {
|
||||
return {
|
||||
text: this.text,
|
||||
icon_url: this.iconUrl,
|
||||
};
|
||||
}
|
||||
}
|
||||
58
fluxer_api/src/models/EmbedMedia.ts
Normal file
58
fluxer_api/src/models/EmbedMedia.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {MessageEmbedMedia} from '~/database/CassandraTypes';
|
||||
|
||||
export class EmbedMedia {
|
||||
readonly url: string | null;
|
||||
readonly width: number | null;
|
||||
readonly height: number | null;
|
||||
readonly description: string | null;
|
||||
readonly contentType: string | null;
|
||||
readonly contentHash: string | null;
|
||||
readonly placeholder: string | null;
|
||||
readonly flags: number;
|
||||
readonly duration: number | null;
|
||||
|
||||
constructor(media: MessageEmbedMedia) {
|
||||
this.url = media.url ?? null;
|
||||
this.width = media.width ?? null;
|
||||
this.height = media.height ?? null;
|
||||
this.description = media.description ?? null;
|
||||
this.contentType = media.content_type ?? null;
|
||||
this.contentHash = media.content_hash ?? null;
|
||||
this.placeholder = media.placeholder ?? null;
|
||||
this.flags = media.flags ?? 0;
|
||||
this.duration = media.duration ?? null;
|
||||
}
|
||||
|
||||
toMessageEmbedMedia(): MessageEmbedMedia {
|
||||
return {
|
||||
url: this.url,
|
||||
width: this.width,
|
||||
height: this.height,
|
||||
description: this.description,
|
||||
content_type: this.contentType,
|
||||
content_hash: this.contentHash,
|
||||
placeholder: this.placeholder,
|
||||
flags: this.flags,
|
||||
duration: this.duration,
|
||||
};
|
||||
}
|
||||
}
|
||||
37
fluxer_api/src/models/EmbedProvider.ts
Normal file
37
fluxer_api/src/models/EmbedProvider.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {MessageEmbedProvider} from '~/database/CassandraTypes';
|
||||
|
||||
export class EmbedProvider {
|
||||
readonly name: string | null;
|
||||
readonly url: string | null;
|
||||
|
||||
constructor(provider: MessageEmbedProvider) {
|
||||
this.name = provider.name ?? null;
|
||||
this.url = provider.url ?? null;
|
||||
}
|
||||
|
||||
toMessageEmbedProvider(): MessageEmbedProvider {
|
||||
return {
|
||||
name: this.name,
|
||||
url: this.url,
|
||||
};
|
||||
}
|
||||
}
|
||||
58
fluxer_api/src/models/ExpressionPack.ts
Normal file
58
fluxer_api/src/models/ExpressionPack.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {ExpressionPackRow} from '~/database/CassandraTypes';
|
||||
import type {GuildID, UserID} from '../BrandedTypes';
|
||||
|
||||
export type ExpressionPackType = 'emoji' | 'sticker';
|
||||
|
||||
export class ExpressionPack {
|
||||
readonly id: GuildID;
|
||||
readonly type: ExpressionPackType;
|
||||
readonly creatorId: UserID;
|
||||
readonly name: string;
|
||||
readonly description: string | null;
|
||||
readonly createdAt: Date;
|
||||
readonly updatedAt: Date;
|
||||
readonly version: number;
|
||||
|
||||
constructor(row: ExpressionPackRow) {
|
||||
this.id = row.pack_id;
|
||||
this.type = row.pack_type as ExpressionPackType;
|
||||
this.creatorId = row.creator_id;
|
||||
this.name = row.name;
|
||||
this.description = row.description ?? null;
|
||||
this.createdAt = row.created_at;
|
||||
this.updatedAt = row.updated_at;
|
||||
this.version = row.version;
|
||||
}
|
||||
|
||||
toRow(): ExpressionPackRow {
|
||||
return {
|
||||
pack_id: this.id,
|
||||
pack_type: this.type,
|
||||
creator_id: this.creatorId,
|
||||
name: this.name,
|
||||
description: this.description,
|
||||
created_at: this.createdAt,
|
||||
updated_at: this.updatedAt,
|
||||
version: this.version,
|
||||
};
|
||||
}
|
||||
}
|
||||
88
fluxer_api/src/models/FavoriteMeme.ts
Normal file
88
fluxer_api/src/models/FavoriteMeme.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {FavoriteMemeRow} from '~/database/CassandraTypes';
|
||||
import {extractTimestamp} from '~/utils/SnowflakeUtils';
|
||||
import {type AttachmentID, type MemeID, type UserID, userIdToChannelId} from '../BrandedTypes';
|
||||
|
||||
export class FavoriteMeme {
|
||||
readonly id: MemeID;
|
||||
readonly userId: UserID;
|
||||
readonly name: string;
|
||||
readonly altText: string | null;
|
||||
readonly tags: Array<string>;
|
||||
readonly attachmentId: AttachmentID;
|
||||
readonly filename: string;
|
||||
readonly contentType: string;
|
||||
readonly contentHash: string | null;
|
||||
readonly size: bigint;
|
||||
readonly width: number | null;
|
||||
readonly height: number | null;
|
||||
readonly duration: number | null;
|
||||
readonly isGifv: boolean;
|
||||
readonly tenorId: string | null;
|
||||
readonly createdAt: Date;
|
||||
readonly version: number;
|
||||
|
||||
constructor(row: FavoriteMemeRow) {
|
||||
this.id = row.meme_id;
|
||||
this.userId = row.user_id;
|
||||
this.name = row.name;
|
||||
this.altText = row.alt_text ?? null;
|
||||
this.tags = row.tags ?? [];
|
||||
this.attachmentId = row.attachment_id;
|
||||
this.filename = row.filename;
|
||||
this.contentType = row.content_type;
|
||||
this.contentHash = row.content_hash ?? null;
|
||||
this.size = row.size;
|
||||
this.width = row.width ?? null;
|
||||
this.height = row.height ?? null;
|
||||
this.duration = row.duration ?? null;
|
||||
this.isGifv = row.is_gifv ?? false;
|
||||
this.tenorId = row.tenor_id_str ?? null;
|
||||
this.createdAt = new Date(extractTimestamp(this.id));
|
||||
this.version = row.version;
|
||||
}
|
||||
|
||||
toRow(): FavoriteMemeRow {
|
||||
return {
|
||||
user_id: this.userId,
|
||||
meme_id: this.id,
|
||||
name: this.name,
|
||||
alt_text: this.altText,
|
||||
tags: this.tags.length > 0 ? this.tags : null,
|
||||
attachment_id: this.attachmentId,
|
||||
filename: this.filename,
|
||||
content_type: this.contentType,
|
||||
content_hash: this.contentHash,
|
||||
size: this.size,
|
||||
width: this.width,
|
||||
height: this.height,
|
||||
duration: this.duration,
|
||||
is_gifv: this.isGifv,
|
||||
tenor_id_str: this.tenorId,
|
||||
version: this.version,
|
||||
};
|
||||
}
|
||||
|
||||
get storageKey(): string {
|
||||
const channelId = userIdToChannelId(this.userId);
|
||||
return `attachments/${channelId}/${this.attachmentId}/${this.filename}`;
|
||||
}
|
||||
}
|
||||
62
fluxer_api/src/models/GiftCode.ts
Normal file
62
fluxer_api/src/models/GiftCode.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {GiftCodeRow} from '~/database/CassandraTypes';
|
||||
import type {UserID} from '../BrandedTypes';
|
||||
|
||||
export class GiftCode {
|
||||
readonly code: string;
|
||||
readonly durationMonths: number;
|
||||
readonly createdAt: Date;
|
||||
readonly createdByUserId: UserID;
|
||||
readonly redeemedAt: Date | null;
|
||||
readonly redeemedByUserId: UserID | null;
|
||||
readonly stripePaymentIntentId: string | null;
|
||||
readonly visionarySequenceNumber: number | null;
|
||||
readonly checkoutSessionId: string | null;
|
||||
readonly version: number;
|
||||
|
||||
constructor(row: GiftCodeRow) {
|
||||
this.code = row.code;
|
||||
this.durationMonths = row.duration_months;
|
||||
this.createdAt = row.created_at;
|
||||
this.createdByUserId = row.created_by_user_id as UserID;
|
||||
this.redeemedAt = row.redeemed_at ?? null;
|
||||
this.redeemedByUserId = row.redeemed_by_user_id ? (row.redeemed_by_user_id as UserID) : null;
|
||||
this.stripePaymentIntentId = row.stripe_payment_intent_id ?? null;
|
||||
this.visionarySequenceNumber = row.visionary_sequence_number ?? null;
|
||||
this.checkoutSessionId = row.checkout_session_id ?? null;
|
||||
this.version = row.version;
|
||||
}
|
||||
|
||||
toRow(): GiftCodeRow {
|
||||
return {
|
||||
code: this.code,
|
||||
duration_months: this.durationMonths,
|
||||
created_at: this.createdAt,
|
||||
created_by_user_id: this.createdByUserId,
|
||||
redeemed_at: this.redeemedAt,
|
||||
redeemed_by_user_id: this.redeemedByUserId,
|
||||
stripe_payment_intent_id: this.stripePaymentIntentId,
|
||||
visionary_sequence_number: this.visionarySequenceNumber,
|
||||
checkout_session_id: this.checkoutSessionId,
|
||||
version: this.version,
|
||||
};
|
||||
}
|
||||
}
|
||||
123
fluxer_api/src/models/Guild.ts
Normal file
123
fluxer_api/src/models/Guild.ts
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {GuildSplashCardAlignment, type GuildSplashCardAlignmentValue} from '~/constants/Guild';
|
||||
import type {GuildRow} from '~/database/CassandraTypes';
|
||||
import type {ChannelID, GuildID, UserID, VanityURLCode} from '../BrandedTypes';
|
||||
|
||||
export class Guild {
|
||||
readonly id: GuildID;
|
||||
readonly ownerId: UserID;
|
||||
readonly name: string;
|
||||
readonly vanityUrlCode: VanityURLCode | null;
|
||||
readonly iconHash: string | null;
|
||||
readonly bannerHash: string | null;
|
||||
readonly bannerWidth: number | null;
|
||||
readonly bannerHeight: number | null;
|
||||
readonly splashHash: string | null;
|
||||
readonly splashWidth: number | null;
|
||||
readonly splashHeight: number | null;
|
||||
readonly splashCardAlignment: GuildSplashCardAlignmentValue;
|
||||
readonly embedSplashHash: string | null;
|
||||
readonly embedSplashWidth: number | null;
|
||||
readonly embedSplashHeight: number | null;
|
||||
readonly features: Set<string>;
|
||||
readonly verificationLevel: number;
|
||||
readonly mfaLevel: number;
|
||||
readonly nsfwLevel: number;
|
||||
readonly explicitContentFilter: number;
|
||||
readonly defaultMessageNotifications: number;
|
||||
readonly systemChannelId: ChannelID | null;
|
||||
readonly systemChannelFlags: number;
|
||||
readonly rulesChannelId: ChannelID | null;
|
||||
readonly afkChannelId: ChannelID | null;
|
||||
readonly afkTimeout: number;
|
||||
readonly disabledOperations: number;
|
||||
readonly memberCount: number;
|
||||
readonly auditLogsIndexedAt: Date | null;
|
||||
readonly version: number;
|
||||
|
||||
constructor(row: GuildRow) {
|
||||
this.id = row.guild_id;
|
||||
this.ownerId = row.owner_id;
|
||||
this.name = row.name;
|
||||
this.vanityUrlCode = row.vanity_url_code ?? null;
|
||||
this.iconHash = row.icon_hash ?? null;
|
||||
this.bannerHash = row.banner_hash ?? null;
|
||||
this.bannerWidth = row.banner_width ?? null;
|
||||
this.bannerHeight = row.banner_height ?? null;
|
||||
this.splashHash = row.splash_hash ?? null;
|
||||
this.splashWidth = row.splash_width ?? null;
|
||||
this.splashHeight = row.splash_height ?? null;
|
||||
this.splashCardAlignment = row.splash_card_alignment ?? GuildSplashCardAlignment.CENTER;
|
||||
this.embedSplashHash = row.embed_splash_hash ?? null;
|
||||
this.embedSplashWidth = row.embed_splash_width ?? null;
|
||||
this.embedSplashHeight = row.embed_splash_height ?? null;
|
||||
this.features = row.features ?? new Set();
|
||||
this.verificationLevel = row.verification_level ?? 0;
|
||||
this.mfaLevel = row.mfa_level ?? 0;
|
||||
this.nsfwLevel = row.nsfw_level ?? 0;
|
||||
this.explicitContentFilter = row.explicit_content_filter ?? 0;
|
||||
this.defaultMessageNotifications = row.default_message_notifications ?? 0;
|
||||
this.systemChannelId = row.system_channel_id ?? null;
|
||||
this.systemChannelFlags = row.system_channel_flags ?? 0;
|
||||
this.rulesChannelId = row.rules_channel_id ?? null;
|
||||
this.afkChannelId = row.afk_channel_id ?? null;
|
||||
this.afkTimeout = row.afk_timeout ?? 0;
|
||||
this.disabledOperations = row.disabled_operations ?? 0;
|
||||
this.memberCount = row.member_count ?? 0;
|
||||
this.auditLogsIndexedAt = row.audit_logs_indexed_at ?? null;
|
||||
this.version = row.version;
|
||||
}
|
||||
|
||||
toRow(): GuildRow {
|
||||
return {
|
||||
guild_id: this.id,
|
||||
owner_id: this.ownerId,
|
||||
name: this.name,
|
||||
vanity_url_code: this.vanityUrlCode,
|
||||
icon_hash: this.iconHash,
|
||||
banner_hash: this.bannerHash,
|
||||
banner_width: this.bannerWidth,
|
||||
banner_height: this.bannerHeight,
|
||||
splash_hash: this.splashHash,
|
||||
splash_width: this.splashWidth,
|
||||
splash_height: this.splashHeight,
|
||||
splash_card_alignment: this.splashCardAlignment,
|
||||
embed_splash_hash: this.embedSplashHash,
|
||||
embed_splash_width: this.embedSplashWidth,
|
||||
embed_splash_height: this.embedSplashHeight,
|
||||
features: this.features.size > 0 ? this.features : null,
|
||||
verification_level: this.verificationLevel,
|
||||
mfa_level: this.mfaLevel,
|
||||
nsfw_level: this.nsfwLevel,
|
||||
explicit_content_filter: this.explicitContentFilter,
|
||||
default_message_notifications: this.defaultMessageNotifications,
|
||||
system_channel_id: this.systemChannelId,
|
||||
system_channel_flags: this.systemChannelFlags,
|
||||
rules_channel_id: this.rulesChannelId,
|
||||
afk_channel_id: this.afkChannelId,
|
||||
afk_timeout: this.afkTimeout,
|
||||
disabled_operations: this.disabledOperations,
|
||||
member_count: this.memberCount,
|
||||
audit_logs_indexed_at: this.auditLogsIndexedAt,
|
||||
version: this.version,
|
||||
};
|
||||
}
|
||||
}
|
||||
68
fluxer_api/src/models/GuildAuditLog.ts
Normal file
68
fluxer_api/src/models/GuildAuditLog.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {GuildAuditLogRow} from '~/database/CassandraTypes';
|
||||
import type {GuildAuditLogChange} from '~/guild/GuildAuditLogTypes';
|
||||
import type {GuildID, UserID} from '../BrandedTypes';
|
||||
import {extractTimestamp} from '../utils/SnowflakeUtils';
|
||||
|
||||
export class GuildAuditLog {
|
||||
readonly guildId: GuildID;
|
||||
readonly logId: bigint;
|
||||
readonly userId: UserID;
|
||||
readonly targetId: string | null;
|
||||
readonly actionType: number;
|
||||
readonly reason: string | null;
|
||||
readonly options: Map<string, string>;
|
||||
readonly changes: GuildAuditLogChange | null;
|
||||
readonly createdAt: Date;
|
||||
|
||||
constructor(row: GuildAuditLogRow) {
|
||||
this.guildId = row.guild_id;
|
||||
this.logId = row.log_id;
|
||||
this.userId = row.user_id;
|
||||
this.targetId = row.target_id ?? null;
|
||||
this.actionType = row.action_type;
|
||||
this.reason = row.reason ?? null;
|
||||
this.options = row.options ?? new Map();
|
||||
this.changes = row.changes ? this.safeParseChanges(row.changes) : null;
|
||||
this.createdAt = new Date(extractTimestamp(this.logId));
|
||||
}
|
||||
|
||||
toRow(): GuildAuditLogRow {
|
||||
return {
|
||||
guild_id: this.guildId,
|
||||
log_id: this.logId,
|
||||
user_id: this.userId,
|
||||
target_id: this.targetId,
|
||||
action_type: this.actionType,
|
||||
reason: this.reason,
|
||||
options: this.options.size > 0 ? this.options : null,
|
||||
changes: this.changes ? JSON.stringify(this.changes) : null,
|
||||
};
|
||||
}
|
||||
|
||||
private safeParseChanges(raw: string): GuildAuditLogChange | null {
|
||||
try {
|
||||
return JSON.parse(raw) as GuildAuditLogChange;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
53
fluxer_api/src/models/GuildBan.ts
Normal file
53
fluxer_api/src/models/GuildBan.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {GuildBanRow} from '~/database/CassandraTypes';
|
||||
import type {GuildID, UserID} from '../BrandedTypes';
|
||||
|
||||
export class GuildBan {
|
||||
readonly guildId: GuildID;
|
||||
readonly userId: UserID;
|
||||
readonly moderatorId: UserID;
|
||||
readonly bannedAt: Date;
|
||||
readonly expiresAt: Date | null;
|
||||
readonly reason: string | null;
|
||||
readonly ipAddress: string | null;
|
||||
|
||||
constructor(row: GuildBanRow) {
|
||||
this.guildId = row.guild_id;
|
||||
this.userId = row.user_id;
|
||||
this.moderatorId = row.moderator_id;
|
||||
this.bannedAt = row.banned_at;
|
||||
this.expiresAt = row.expires_at ?? null;
|
||||
this.reason = row.reason ?? null;
|
||||
this.ipAddress = row.ip ?? null;
|
||||
}
|
||||
|
||||
toRow(): GuildBanRow {
|
||||
return {
|
||||
guild_id: this.guildId,
|
||||
user_id: this.userId,
|
||||
moderator_id: this.moderatorId,
|
||||
banned_at: this.bannedAt,
|
||||
expires_at: this.expiresAt,
|
||||
reason: this.reason,
|
||||
ip: this.ipAddress,
|
||||
};
|
||||
}
|
||||
}
|
||||
44
fluxer_api/src/models/GuildChannelOverride.ts
Normal file
44
fluxer_api/src/models/GuildChannelOverride.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {ChannelOverride} from '~/database/CassandraTypes';
|
||||
import {MuteConfiguration} from './MuteConfiguration';
|
||||
|
||||
export class GuildChannelOverride {
|
||||
readonly collapsed: boolean;
|
||||
readonly messageNotifications: number | null;
|
||||
readonly muted: boolean;
|
||||
readonly muteConfig: MuteConfiguration | null;
|
||||
|
||||
constructor(override: ChannelOverride) {
|
||||
this.collapsed = override.collapsed ?? false;
|
||||
this.messageNotifications = override.message_notifications ?? null;
|
||||
this.muted = override.muted ?? false;
|
||||
this.muteConfig = override.mute_config ? new MuteConfiguration(override.mute_config) : null;
|
||||
}
|
||||
|
||||
toChannelOverride(): ChannelOverride {
|
||||
return {
|
||||
collapsed: this.collapsed,
|
||||
message_notifications: this.messageNotifications,
|
||||
muted: this.muted,
|
||||
mute_config: this.muteConfig?.toMuteConfig() ?? null,
|
||||
};
|
||||
}
|
||||
}
|
||||
50
fluxer_api/src/models/GuildEmoji.ts
Normal file
50
fluxer_api/src/models/GuildEmoji.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {GuildEmojiRow} from '~/database/CassandraTypes';
|
||||
import type {EmojiID, GuildID, UserID} from '../BrandedTypes';
|
||||
|
||||
export class GuildEmoji {
|
||||
readonly guildId: GuildID;
|
||||
readonly id: EmojiID;
|
||||
readonly name: string;
|
||||
readonly creatorId: UserID;
|
||||
readonly isAnimated: boolean;
|
||||
readonly version: number;
|
||||
|
||||
constructor(row: GuildEmojiRow) {
|
||||
this.guildId = row.guild_id;
|
||||
this.id = row.emoji_id;
|
||||
this.name = row.name;
|
||||
this.creatorId = row.creator_id;
|
||||
this.isAnimated = row.animated ?? false;
|
||||
this.version = row.version;
|
||||
}
|
||||
|
||||
toRow(): GuildEmojiRow {
|
||||
return {
|
||||
guild_id: this.guildId,
|
||||
emoji_id: this.id,
|
||||
name: this.name,
|
||||
creator_id: this.creatorId,
|
||||
animated: this.isAnimated,
|
||||
version: this.version,
|
||||
};
|
||||
}
|
||||
}
|
||||
105
fluxer_api/src/models/GuildMember.ts
Normal file
105
fluxer_api/src/models/GuildMember.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {GuildMemberRow} from '~/database/CassandraTypes';
|
||||
import type {GuildID, InviteCode, RoleID, UserID} from '../BrandedTypes';
|
||||
import {GuildMemberProfileFlags} from '../constants/Guild';
|
||||
|
||||
export class GuildMember {
|
||||
readonly guildId: GuildID;
|
||||
readonly userId: UserID;
|
||||
readonly joinedAt: Date;
|
||||
readonly nickname: string | null;
|
||||
readonly avatarHash: string | null;
|
||||
readonly bannerHash: string | null;
|
||||
readonly bio: string | null;
|
||||
readonly pronouns: string | null;
|
||||
readonly accentColor: number | null;
|
||||
readonly joinSourceType: number | null;
|
||||
readonly sourceInviteCode: InviteCode | null;
|
||||
readonly inviterId: UserID | null;
|
||||
readonly isDeaf: boolean;
|
||||
readonly isMute: boolean;
|
||||
readonly communicationDisabledUntil: Date | null;
|
||||
readonly roleIds: Set<RoleID>;
|
||||
readonly isPremiumSanitized: boolean;
|
||||
readonly isTemporary: boolean;
|
||||
readonly profileFlags: number;
|
||||
readonly version: number;
|
||||
|
||||
constructor(row: GuildMemberRow) {
|
||||
this.guildId = row.guild_id;
|
||||
this.userId = row.user_id;
|
||||
this.joinedAt = row.joined_at;
|
||||
this.nickname = row.nick ?? null;
|
||||
this.avatarHash = row.avatar_hash ?? null;
|
||||
this.bannerHash = row.banner_hash ?? null;
|
||||
this.bio = row.bio ?? null;
|
||||
this.pronouns = row.pronouns ?? null;
|
||||
this.accentColor = row.accent_color ?? null;
|
||||
this.joinSourceType = row.join_source_type ?? null;
|
||||
this.sourceInviteCode = row.source_invite_code ?? null;
|
||||
this.inviterId = row.inviter_id ?? null;
|
||||
this.isDeaf = row.deaf ?? false;
|
||||
this.isMute = row.mute ?? false;
|
||||
this.communicationDisabledUntil = row.communication_disabled_until ?? null;
|
||||
this.roleIds = row.role_ids ?? new Set();
|
||||
this.isPremiumSanitized = row.is_premium_sanitized ?? false;
|
||||
this.isTemporary = row.temporary ?? false;
|
||||
this.profileFlags = row.profile_flags ?? 0;
|
||||
this.version = row.version;
|
||||
}
|
||||
|
||||
hasProfileFlag(flag: number): boolean {
|
||||
return (this.profileFlags & flag) === flag;
|
||||
}
|
||||
|
||||
isAvatarUnset(): boolean {
|
||||
return this.hasProfileFlag(GuildMemberProfileFlags.AVATAR_UNSET);
|
||||
}
|
||||
|
||||
isBannerUnset(): boolean {
|
||||
return this.hasProfileFlag(GuildMemberProfileFlags.BANNER_UNSET);
|
||||
}
|
||||
|
||||
toRow(): GuildMemberRow {
|
||||
return {
|
||||
guild_id: this.guildId,
|
||||
user_id: this.userId,
|
||||
joined_at: this.joinedAt,
|
||||
nick: this.nickname,
|
||||
avatar_hash: this.avatarHash,
|
||||
banner_hash: this.bannerHash,
|
||||
bio: this.bio,
|
||||
pronouns: this.pronouns,
|
||||
accent_color: this.accentColor,
|
||||
join_source_type: this.joinSourceType,
|
||||
source_invite_code: this.sourceInviteCode,
|
||||
inviter_id: this.inviterId,
|
||||
deaf: this.isDeaf,
|
||||
mute: this.isMute,
|
||||
communication_disabled_until: this.communicationDisabledUntil,
|
||||
role_ids: this.roleIds.size > 0 ? this.roleIds : null,
|
||||
is_premium_sanitized: this.isPremiumSanitized,
|
||||
temporary: this.isTemporary,
|
||||
profile_flags: this.profileFlags || null,
|
||||
version: this.version,
|
||||
};
|
||||
}
|
||||
}
|
||||
72
fluxer_api/src/models/GuildRole.ts
Normal file
72
fluxer_api/src/models/GuildRole.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {GuildRoleRow} from '~/database/CassandraTypes';
|
||||
import type {GuildID, RoleID} from '../BrandedTypes';
|
||||
|
||||
export class GuildRole {
|
||||
readonly guildId: GuildID;
|
||||
readonly id: RoleID;
|
||||
readonly name: string;
|
||||
readonly permissions: bigint;
|
||||
readonly position: number;
|
||||
readonly hoistPosition: number | null;
|
||||
readonly color: number;
|
||||
readonly iconHash: string | null;
|
||||
readonly unicodeEmoji: string | null;
|
||||
readonly isHoisted: boolean;
|
||||
readonly isMentionable: boolean;
|
||||
readonly version: number;
|
||||
|
||||
constructor(row: GuildRoleRow) {
|
||||
this.guildId = row.guild_id;
|
||||
this.id = row.role_id;
|
||||
this.name = row.name;
|
||||
this.permissions = row.permissions;
|
||||
this.position = row.position;
|
||||
this.hoistPosition = row.hoist_position ?? null;
|
||||
this.color = row.color ?? 0;
|
||||
this.iconHash = row.icon_hash ?? null;
|
||||
this.unicodeEmoji = row.unicode_emoji ?? null;
|
||||
this.isHoisted = row.hoist ?? false;
|
||||
this.isMentionable = row.mentionable ?? false;
|
||||
this.version = row.version;
|
||||
}
|
||||
|
||||
get effectiveHoistPosition(): number {
|
||||
return this.hoistPosition ?? this.position;
|
||||
}
|
||||
|
||||
toRow(): GuildRoleRow {
|
||||
return {
|
||||
guild_id: this.guildId,
|
||||
role_id: this.id,
|
||||
name: this.name,
|
||||
permissions: this.permissions,
|
||||
position: this.position,
|
||||
hoist_position: this.hoistPosition,
|
||||
color: this.color,
|
||||
icon_hash: this.iconHash,
|
||||
unicode_emoji: this.unicodeEmoji,
|
||||
hoist: this.isHoisted,
|
||||
mentionable: this.isMentionable,
|
||||
version: this.version,
|
||||
};
|
||||
}
|
||||
}
|
||||
56
fluxer_api/src/models/GuildSticker.ts
Normal file
56
fluxer_api/src/models/GuildSticker.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {GuildStickerRow} from '~/database/CassandraTypes';
|
||||
import type {GuildID, StickerID, UserID} from '../BrandedTypes';
|
||||
|
||||
export class GuildSticker {
|
||||
readonly guildId: GuildID;
|
||||
readonly id: StickerID;
|
||||
readonly name: string;
|
||||
readonly description: string | null;
|
||||
readonly formatType: number;
|
||||
readonly tags: Array<string>;
|
||||
readonly creatorId: UserID;
|
||||
readonly version: number;
|
||||
|
||||
constructor(row: GuildStickerRow) {
|
||||
this.guildId = row.guild_id;
|
||||
this.id = row.sticker_id;
|
||||
this.name = row.name;
|
||||
this.description = row.description ?? null;
|
||||
this.formatType = row.format_type;
|
||||
this.tags = row.tags ?? [];
|
||||
this.creatorId = row.creator_id;
|
||||
this.version = row.version;
|
||||
}
|
||||
|
||||
toRow(): GuildStickerRow {
|
||||
return {
|
||||
guild_id: this.guildId,
|
||||
sticker_id: this.id,
|
||||
name: this.name,
|
||||
description: this.description,
|
||||
format_type: this.formatType,
|
||||
tags: this.tags.length > 0 ? this.tags : null,
|
||||
creator_id: this.creatorId,
|
||||
version: this.version,
|
||||
};
|
||||
}
|
||||
}
|
||||
65
fluxer_api/src/models/Invite.ts
Normal file
65
fluxer_api/src/models/Invite.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {InviteRow} from '~/database/CassandraTypes';
|
||||
import type {ChannelID, GuildID, InviteCode, UserID} from '../BrandedTypes';
|
||||
|
||||
export class Invite {
|
||||
readonly code: InviteCode;
|
||||
readonly type: number;
|
||||
readonly guildId: GuildID | null;
|
||||
readonly channelId: ChannelID | null;
|
||||
readonly inviterId: UserID | null;
|
||||
readonly createdAt: Date;
|
||||
readonly uses: number;
|
||||
readonly maxUses: number;
|
||||
readonly maxAge: number;
|
||||
readonly temporary: boolean;
|
||||
readonly version: number;
|
||||
|
||||
constructor(row: InviteRow) {
|
||||
this.code = row.code;
|
||||
this.type = row.type;
|
||||
this.guildId = row.guild_id ?? null;
|
||||
this.channelId = row.channel_id ?? null;
|
||||
this.inviterId = row.inviter_id ?? null;
|
||||
this.createdAt = row.created_at;
|
||||
this.uses = row.uses ?? 0;
|
||||
this.maxUses = row.max_uses ?? 0;
|
||||
this.maxAge = row.max_age ?? 0;
|
||||
this.temporary = row.temporary ?? false;
|
||||
this.version = row.version;
|
||||
}
|
||||
|
||||
toRow(): InviteRow {
|
||||
return {
|
||||
code: this.code,
|
||||
type: this.type,
|
||||
guild_id: this.guildId,
|
||||
channel_id: this.channelId,
|
||||
inviter_id: this.inviterId,
|
||||
created_at: this.createdAt,
|
||||
uses: this.uses,
|
||||
max_uses: this.maxUses,
|
||||
max_age: this.maxAge,
|
||||
temporary: this.temporary,
|
||||
version: this.version,
|
||||
};
|
||||
}
|
||||
}
|
||||
111
fluxer_api/src/models/Message.ts
Normal file
111
fluxer_api/src/models/Message.ts
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {MessageRow} from '~/database/CassandraTypes';
|
||||
import type {ChannelID, MessageID, RoleID, UserID, WebhookID} from '../BrandedTypes';
|
||||
import {Attachment} from './Attachment';
|
||||
import {CallInfo} from './CallInfo';
|
||||
import {Embed} from './Embed';
|
||||
import {MessageRef} from './MessageRef';
|
||||
import {MessageSnapshot} from './MessageSnapshot';
|
||||
import {StickerItem} from './StickerItem';
|
||||
|
||||
export class Message {
|
||||
readonly channelId: ChannelID;
|
||||
readonly bucket: number;
|
||||
readonly id: MessageID;
|
||||
readonly authorId: UserID | null;
|
||||
readonly type: number;
|
||||
readonly webhookId: WebhookID | null;
|
||||
readonly webhookName: string | null;
|
||||
readonly webhookAvatarHash: string | null;
|
||||
readonly content: string | null;
|
||||
readonly editedTimestamp: Date | null;
|
||||
readonly pinnedTimestamp: Date | null;
|
||||
readonly flags: number;
|
||||
readonly mentionEveryone: boolean;
|
||||
readonly mentionedUserIds: Set<UserID>;
|
||||
readonly mentionedRoleIds: Set<RoleID>;
|
||||
readonly mentionedChannelIds: Set<ChannelID>;
|
||||
readonly attachments: Array<Attachment>;
|
||||
readonly embeds: Array<Embed>;
|
||||
readonly stickers: Array<StickerItem>;
|
||||
readonly reference: MessageRef | null;
|
||||
readonly messageSnapshots: Array<MessageSnapshot>;
|
||||
readonly call: CallInfo | null;
|
||||
readonly hasReaction: boolean | null;
|
||||
readonly version: number;
|
||||
|
||||
constructor(row: MessageRow) {
|
||||
this.channelId = row.channel_id;
|
||||
this.bucket = row.bucket;
|
||||
this.id = row.message_id;
|
||||
this.authorId = row.author_id ?? null;
|
||||
this.type = row.type;
|
||||
this.webhookId = row.webhook_id ?? null;
|
||||
this.webhookName = row.webhook_name ?? null;
|
||||
this.webhookAvatarHash = row.webhook_avatar_hash ?? null;
|
||||
this.content = row.content ?? null;
|
||||
this.editedTimestamp = row.edited_timestamp ?? null;
|
||||
this.pinnedTimestamp = row.pinned_timestamp ?? null;
|
||||
this.flags = row.flags ?? 0;
|
||||
this.mentionEveryone = row.mention_everyone ?? false;
|
||||
this.mentionedUserIds = row.mention_users ?? new Set();
|
||||
this.mentionedRoleIds = row.mention_roles ?? new Set();
|
||||
this.mentionedChannelIds = row.mention_channels ?? new Set();
|
||||
this.attachments = (row.attachments ?? []).map((att) => new Attachment(att));
|
||||
this.embeds = (row.embeds ?? []).map((embed) => new Embed(embed));
|
||||
this.stickers = (row.sticker_items ?? []).map((sticker) => new StickerItem(sticker));
|
||||
this.reference = row.message_reference ? new MessageRef(row.message_reference) : null;
|
||||
this.messageSnapshots = (row.message_snapshots ?? []).map((snapshot) => new MessageSnapshot(snapshot));
|
||||
this.call = row.call ? new CallInfo(row.call) : null;
|
||||
this.hasReaction = row.has_reaction ?? null;
|
||||
this.version = row.version;
|
||||
}
|
||||
|
||||
toRow(): MessageRow {
|
||||
return {
|
||||
channel_id: this.channelId,
|
||||
bucket: this.bucket,
|
||||
message_id: this.id,
|
||||
author_id: this.authorId,
|
||||
type: this.type,
|
||||
webhook_id: this.webhookId,
|
||||
webhook_name: this.webhookName,
|
||||
webhook_avatar_hash: this.webhookAvatarHash,
|
||||
content: this.content,
|
||||
edited_timestamp: this.editedTimestamp,
|
||||
pinned_timestamp: this.pinnedTimestamp,
|
||||
flags: this.flags,
|
||||
mention_everyone: this.mentionEveryone,
|
||||
mention_users: this.mentionedUserIds.size > 0 ? this.mentionedUserIds : null,
|
||||
mention_roles: this.mentionedRoleIds.size > 0 ? this.mentionedRoleIds : null,
|
||||
mention_channels: this.mentionedChannelIds.size > 0 ? this.mentionedChannelIds : null,
|
||||
attachments: this.attachments.length > 0 ? this.attachments.map((att) => att.toMessageAttachment()) : null,
|
||||
embeds: this.embeds.length > 0 ? this.embeds.map((embed) => embed.toMessageEmbed()) : null,
|
||||
sticker_items: this.stickers.length > 0 ? this.stickers.map((sticker) => sticker.toMessageStickerItem()) : null,
|
||||
message_reference: this.reference?.toMessageReference() ?? null,
|
||||
message_snapshots:
|
||||
this.messageSnapshots.length > 0 ? this.messageSnapshots.map((snapshot) => snapshot.toMessageSnapshot()) : null,
|
||||
call: this.call?.toMessageCall() ?? null,
|
||||
has_reaction: this.hasReaction ?? null,
|
||||
version: this.version,
|
||||
};
|
||||
}
|
||||
}
|
||||
53
fluxer_api/src/models/MessageReaction.ts
Normal file
53
fluxer_api/src/models/MessageReaction.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {MessageReactionRow} from '~/database/CassandraTypes';
|
||||
import type {ChannelID, EmojiID, MessageID, UserID} from '../BrandedTypes';
|
||||
|
||||
export class MessageReaction {
|
||||
readonly channelId: ChannelID;
|
||||
readonly bucket: number;
|
||||
readonly messageId: MessageID;
|
||||
readonly userId: UserID;
|
||||
readonly emojiId: EmojiID;
|
||||
readonly emojiName: string;
|
||||
readonly isEmojiAnimated: boolean;
|
||||
|
||||
constructor(row: MessageReactionRow) {
|
||||
this.channelId = row.channel_id;
|
||||
this.bucket = row.bucket;
|
||||
this.messageId = row.message_id;
|
||||
this.userId = row.user_id;
|
||||
this.emojiId = row.emoji_id;
|
||||
this.emojiName = row.emoji_name;
|
||||
this.isEmojiAnimated = row.emoji_animated ?? false;
|
||||
}
|
||||
|
||||
toRow(): MessageReactionRow {
|
||||
return {
|
||||
channel_id: this.channelId,
|
||||
bucket: this.bucket,
|
||||
message_id: this.messageId,
|
||||
user_id: this.userId,
|
||||
emoji_id: this.emojiId,
|
||||
emoji_name: this.emojiName,
|
||||
emoji_animated: this.isEmojiAnimated,
|
||||
};
|
||||
}
|
||||
}
|
||||
44
fluxer_api/src/models/MessageRef.ts
Normal file
44
fluxer_api/src/models/MessageRef.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {MessageReference} from '~/database/CassandraTypes';
|
||||
import type {ChannelID, GuildID, MessageID} from '../BrandedTypes';
|
||||
|
||||
export class MessageRef {
|
||||
readonly channelId: ChannelID;
|
||||
readonly messageId: MessageID;
|
||||
readonly guildId: GuildID | null;
|
||||
readonly type: number;
|
||||
|
||||
constructor(ref: MessageReference) {
|
||||
this.channelId = ref.channel_id;
|
||||
this.messageId = ref.message_id;
|
||||
this.guildId = ref.guild_id ?? null;
|
||||
this.type = ref.type;
|
||||
}
|
||||
|
||||
toMessageReference(): MessageReference {
|
||||
return {
|
||||
channel_id: this.channelId,
|
||||
message_id: this.messageId,
|
||||
guild_id: this.guildId,
|
||||
type: this.type,
|
||||
};
|
||||
}
|
||||
}
|
||||
68
fluxer_api/src/models/MessageSnapshot.ts
Normal file
68
fluxer_api/src/models/MessageSnapshot.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {MessageSnapshot as CassandraMessageSnapshot} from '~/database/CassandraTypes';
|
||||
import type {ChannelID, RoleID, UserID} from '../BrandedTypes';
|
||||
import {Attachment} from './Attachment';
|
||||
import {Embed} from './Embed';
|
||||
import {StickerItem} from './StickerItem';
|
||||
|
||||
export class MessageSnapshot {
|
||||
readonly content: string | null;
|
||||
readonly timestamp: Date;
|
||||
readonly editedTimestamp: Date | null;
|
||||
readonly mentionedUserIds: Set<UserID>;
|
||||
readonly mentionedRoleIds: Set<RoleID>;
|
||||
readonly mentionedChannelIds: Set<ChannelID>;
|
||||
readonly attachments: Array<Attachment>;
|
||||
readonly embeds: Array<Embed>;
|
||||
readonly stickers: Array<StickerItem>;
|
||||
readonly type: number;
|
||||
readonly flags: number;
|
||||
|
||||
constructor(snapshot: CassandraMessageSnapshot) {
|
||||
this.content = snapshot.content ?? null;
|
||||
this.timestamp = snapshot.timestamp;
|
||||
this.editedTimestamp = snapshot.edited_timestamp ?? null;
|
||||
this.mentionedUserIds = snapshot.mention_users ?? new Set();
|
||||
this.mentionedRoleIds = snapshot.mention_roles ?? new Set();
|
||||
this.mentionedChannelIds = snapshot.mention_channels ?? new Set();
|
||||
this.attachments = (snapshot.attachments ?? []).map((att) => new Attachment(att));
|
||||
this.embeds = (snapshot.embeds ?? []).map((embed) => new Embed(embed));
|
||||
this.stickers = (snapshot.sticker_items ?? []).map((sticker) => new StickerItem(sticker));
|
||||
this.type = snapshot.type;
|
||||
this.flags = snapshot.flags;
|
||||
}
|
||||
|
||||
toMessageSnapshot(): CassandraMessageSnapshot {
|
||||
return {
|
||||
content: this.content,
|
||||
timestamp: this.timestamp,
|
||||
edited_timestamp: this.editedTimestamp,
|
||||
mention_users: this.mentionedUserIds.size > 0 ? this.mentionedUserIds : null,
|
||||
mention_roles: this.mentionedRoleIds.size > 0 ? this.mentionedRoleIds : null,
|
||||
mention_channels: this.mentionedChannelIds.size > 0 ? this.mentionedChannelIds : null,
|
||||
attachments: this.attachments.length > 0 ? this.attachments.map((att) => att.toMessageAttachment()) : null,
|
||||
embeds: this.embeds.length > 0 ? this.embeds.map((embed) => embed.toMessageEmbed()) : null,
|
||||
sticker_items: this.stickers.length > 0 ? this.stickers.map((sticker) => sticker.toMessageStickerItem()) : null,
|
||||
type: this.type,
|
||||
flags: this.flags,
|
||||
};
|
||||
}
|
||||
}
|
||||
42
fluxer_api/src/models/MfaBackupCode.ts
Normal file
42
fluxer_api/src/models/MfaBackupCode.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {MfaBackupCodeRow} from '~/database/CassandraTypes';
|
||||
import type {UserID} from '../BrandedTypes';
|
||||
import {createMfaBackupCode} from '../BrandedTypes';
|
||||
|
||||
export class MfaBackupCode {
|
||||
readonly userId: UserID;
|
||||
readonly code: string;
|
||||
readonly consumed: boolean;
|
||||
|
||||
constructor(row: MfaBackupCodeRow) {
|
||||
this.userId = row.user_id;
|
||||
this.code = row.code;
|
||||
this.consumed = row.consumed ?? false;
|
||||
}
|
||||
|
||||
toRow(): MfaBackupCodeRow {
|
||||
return {
|
||||
user_id: this.userId,
|
||||
code: createMfaBackupCode(this.code),
|
||||
consumed: this.consumed,
|
||||
};
|
||||
}
|
||||
}
|
||||
37
fluxer_api/src/models/MuteConfiguration.ts
Normal file
37
fluxer_api/src/models/MuteConfiguration.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {MuteConfig} from '~/database/CassandraTypes';
|
||||
|
||||
export class MuteConfiguration {
|
||||
readonly endTime: Date | null;
|
||||
readonly selectedTimeWindow: number | null;
|
||||
|
||||
constructor(config: MuteConfig) {
|
||||
this.endTime = config.end_time ?? null;
|
||||
this.selectedTimeWindow = config.selected_time_window ?? null;
|
||||
}
|
||||
|
||||
toMuteConfig(): MuteConfig {
|
||||
return {
|
||||
end_time: this.endTime,
|
||||
selected_time_window: this.selectedTimeWindow,
|
||||
};
|
||||
}
|
||||
}
|
||||
51
fluxer_api/src/models/OAuth2AccessToken.ts
Normal file
51
fluxer_api/src/models/OAuth2AccessToken.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {ApplicationID, UserID} from '~/BrandedTypes';
|
||||
import type {OAuth2AccessTokenRow} from '~/database/types/OAuth2Types';
|
||||
|
||||
export class OAuth2AccessToken {
|
||||
readonly token: string;
|
||||
readonly applicationId: ApplicationID;
|
||||
readonly userId: UserID | null;
|
||||
readonly scope: Set<string>;
|
||||
readonly createdAt: Date;
|
||||
|
||||
constructor(row: OAuth2AccessTokenRow) {
|
||||
this.token = row.token_;
|
||||
this.applicationId = row.application_id;
|
||||
this.userId = row.user_id;
|
||||
this.scope = row.scope;
|
||||
this.createdAt = row.created_at;
|
||||
}
|
||||
|
||||
toRow(): OAuth2AccessTokenRow {
|
||||
return {
|
||||
token_: this.token,
|
||||
application_id: this.applicationId,
|
||||
user_id: this.userId,
|
||||
scope: this.scope,
|
||||
created_at: this.createdAt,
|
||||
};
|
||||
}
|
||||
|
||||
hasScope(scope: string): boolean {
|
||||
return this.scope.has(scope);
|
||||
}
|
||||
}
|
||||
57
fluxer_api/src/models/OAuth2AuthorizationCode.ts
Normal file
57
fluxer_api/src/models/OAuth2AuthorizationCode.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {ApplicationID, UserID} from '~/BrandedTypes';
|
||||
import type {OAuth2AuthorizationCodeRow} from '~/database/types/OAuth2Types';
|
||||
|
||||
export class OAuth2AuthorizationCode {
|
||||
readonly code: string;
|
||||
readonly applicationId: ApplicationID;
|
||||
readonly userId: UserID;
|
||||
readonly redirectUri: string;
|
||||
readonly scope: Set<string>;
|
||||
readonly nonce: string | null;
|
||||
readonly createdAt: Date;
|
||||
|
||||
constructor(row: OAuth2AuthorizationCodeRow) {
|
||||
this.code = row.code;
|
||||
this.applicationId = row.application_id;
|
||||
this.userId = row.user_id;
|
||||
this.redirectUri = row.redirect_uri;
|
||||
this.scope = row.scope;
|
||||
this.nonce = row.nonce;
|
||||
this.createdAt = row.created_at;
|
||||
}
|
||||
|
||||
toRow(): OAuth2AuthorizationCodeRow {
|
||||
return {
|
||||
code: this.code,
|
||||
application_id: this.applicationId,
|
||||
user_id: this.userId,
|
||||
redirect_uri: this.redirectUri,
|
||||
scope: this.scope,
|
||||
nonce: this.nonce,
|
||||
created_at: this.createdAt,
|
||||
};
|
||||
}
|
||||
|
||||
hasScope(scope: string): boolean {
|
||||
return this.scope.has(scope);
|
||||
}
|
||||
}
|
||||
51
fluxer_api/src/models/OAuth2RefreshToken.ts
Normal file
51
fluxer_api/src/models/OAuth2RefreshToken.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {ApplicationID, UserID} from '~/BrandedTypes';
|
||||
import type {OAuth2RefreshTokenRow} from '~/database/types/OAuth2Types';
|
||||
|
||||
export class OAuth2RefreshToken {
|
||||
readonly token: string;
|
||||
readonly applicationId: ApplicationID;
|
||||
readonly userId: UserID;
|
||||
readonly scope: Set<string>;
|
||||
readonly createdAt: Date;
|
||||
|
||||
constructor(row: OAuth2RefreshTokenRow) {
|
||||
this.token = row.token_;
|
||||
this.applicationId = row.application_id;
|
||||
this.userId = row.user_id;
|
||||
this.scope = row.scope;
|
||||
this.createdAt = row.created_at;
|
||||
}
|
||||
|
||||
toRow(): OAuth2RefreshTokenRow {
|
||||
return {
|
||||
token_: this.token,
|
||||
application_id: this.applicationId,
|
||||
user_id: this.userId,
|
||||
scope: this.scope,
|
||||
created_at: this.createdAt,
|
||||
};
|
||||
}
|
||||
|
||||
hasScope(scope: string): boolean {
|
||||
return this.scope.has(scope);
|
||||
}
|
||||
}
|
||||
42
fluxer_api/src/models/PasswordResetToken.ts
Normal file
42
fluxer_api/src/models/PasswordResetToken.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {PasswordResetTokenRow} from '~/database/CassandraTypes';
|
||||
import type {UserID} from '../BrandedTypes';
|
||||
import {createPasswordResetToken} from '../BrandedTypes';
|
||||
|
||||
export class PasswordResetToken {
|
||||
readonly token: string;
|
||||
readonly userId: UserID;
|
||||
readonly email: string;
|
||||
|
||||
constructor(row: PasswordResetTokenRow) {
|
||||
this.token = row.token_;
|
||||
this.userId = row.user_id;
|
||||
this.email = row.email;
|
||||
}
|
||||
|
||||
toRow(): PasswordResetTokenRow {
|
||||
return {
|
||||
token_: createPasswordResetToken(this.token),
|
||||
user_id: this.userId,
|
||||
email: this.email,
|
||||
};
|
||||
}
|
||||
}
|
||||
80
fluxer_api/src/models/Payment.ts
Normal file
80
fluxer_api/src/models/Payment.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {PaymentRow} from '~/database/CassandraTypes';
|
||||
import type {UserID} from '../BrandedTypes';
|
||||
|
||||
export class Payment {
|
||||
readonly checkoutSessionId: string;
|
||||
readonly userId: UserID;
|
||||
readonly stripeCustomerId: string | null;
|
||||
readonly paymentIntentId: string | null;
|
||||
readonly subscriptionId: string | null;
|
||||
readonly invoiceId: string | null;
|
||||
readonly priceId: string | null;
|
||||
readonly productType: string | null;
|
||||
readonly amountCents: number;
|
||||
readonly currency: string;
|
||||
readonly status: string;
|
||||
readonly isGift: boolean;
|
||||
readonly giftCode: string | null;
|
||||
readonly createdAt: Date;
|
||||
readonly completedAt: Date | null;
|
||||
readonly version: number;
|
||||
|
||||
constructor(row: PaymentRow) {
|
||||
this.checkoutSessionId = row.checkout_session_id;
|
||||
this.userId = row.user_id as UserID;
|
||||
this.stripeCustomerId = row.stripe_customer_id ?? null;
|
||||
this.paymentIntentId = row.payment_intent_id ?? null;
|
||||
this.subscriptionId = row.subscription_id ?? null;
|
||||
this.invoiceId = row.invoice_id ?? null;
|
||||
this.priceId = row.price_id ?? null;
|
||||
this.productType = row.product_type ?? null;
|
||||
this.amountCents = row.amount_cents;
|
||||
this.currency = row.currency;
|
||||
this.status = row.status;
|
||||
this.isGift = row.is_gift;
|
||||
this.giftCode = row.gift_code ?? null;
|
||||
this.createdAt = row.created_at;
|
||||
this.completedAt = row.completed_at ?? null;
|
||||
this.version = row.version;
|
||||
}
|
||||
|
||||
toRow(): PaymentRow {
|
||||
return {
|
||||
checkout_session_id: this.checkoutSessionId,
|
||||
user_id: this.userId,
|
||||
stripe_customer_id: this.stripeCustomerId,
|
||||
payment_intent_id: this.paymentIntentId,
|
||||
subscription_id: this.subscriptionId,
|
||||
invoice_id: this.invoiceId,
|
||||
price_id: this.priceId,
|
||||
product_type: this.productType,
|
||||
amount_cents: this.amountCents,
|
||||
currency: this.currency,
|
||||
status: this.status,
|
||||
is_gift: this.isGift,
|
||||
gift_code: this.giftCode,
|
||||
created_at: this.createdAt,
|
||||
completed_at: this.completedAt,
|
||||
version: this.version,
|
||||
};
|
||||
}
|
||||
}
|
||||
41
fluxer_api/src/models/PrivateChannel.ts
Normal file
41
fluxer_api/src/models/PrivateChannel.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {PrivateChannelRow} from '~/database/CassandraTypes';
|
||||
import type {ChannelID, UserID} from '../BrandedTypes';
|
||||
|
||||
export class PrivateChannel {
|
||||
readonly userId: UserID;
|
||||
readonly channelId: ChannelID;
|
||||
readonly isGroupDM: boolean;
|
||||
|
||||
constructor(row: PrivateChannelRow) {
|
||||
this.userId = row.user_id;
|
||||
this.channelId = row.channel_id;
|
||||
this.isGroupDM = row.is_gdm ?? false;
|
||||
}
|
||||
|
||||
toRow(): PrivateChannelRow {
|
||||
return {
|
||||
user_id: this.userId,
|
||||
channel_id: this.channelId,
|
||||
is_gdm: this.isGroupDM,
|
||||
};
|
||||
}
|
||||
}
|
||||
50
fluxer_api/src/models/PushSubscription.ts
Normal file
50
fluxer_api/src/models/PushSubscription.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {PushSubscriptionRow} from '~/database/CassandraTypes';
|
||||
import type {UserID} from '../BrandedTypes';
|
||||
|
||||
export class PushSubscription {
|
||||
readonly userId: UserID;
|
||||
readonly subscriptionId: string;
|
||||
readonly endpoint: string;
|
||||
readonly p256dhKey: string;
|
||||
readonly authKey: string;
|
||||
readonly userAgent: string | null;
|
||||
|
||||
constructor(row: PushSubscriptionRow) {
|
||||
this.userId = row.user_id;
|
||||
this.subscriptionId = row.subscription_id;
|
||||
this.endpoint = row.endpoint;
|
||||
this.p256dhKey = row.p256dh_key;
|
||||
this.authKey = row.auth_key;
|
||||
this.userAgent = row.user_agent ?? null;
|
||||
}
|
||||
|
||||
toRow(): PushSubscriptionRow {
|
||||
return {
|
||||
user_id: this.userId,
|
||||
subscription_id: this.subscriptionId,
|
||||
endpoint: this.endpoint,
|
||||
p256dh_key: this.p256dhKey,
|
||||
auth_key: this.authKey,
|
||||
user_agent: this.userAgent,
|
||||
};
|
||||
}
|
||||
}
|
||||
47
fluxer_api/src/models/ReadState.ts
Normal file
47
fluxer_api/src/models/ReadState.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {ReadStateRow} from '~/database/CassandraTypes';
|
||||
import type {ChannelID, MessageID, UserID} from '../BrandedTypes';
|
||||
|
||||
export class ReadState {
|
||||
readonly userId: UserID;
|
||||
readonly channelId: ChannelID;
|
||||
readonly lastMessageId: MessageID | null;
|
||||
readonly mentionCount: number;
|
||||
readonly lastPinTimestamp: Date | null;
|
||||
|
||||
constructor(row: ReadStateRow) {
|
||||
this.userId = row.user_id;
|
||||
this.channelId = row.channel_id;
|
||||
this.lastMessageId = row.message_id ?? null;
|
||||
this.mentionCount = row.mention_count ?? 0;
|
||||
this.lastPinTimestamp = row.last_pin_timestamp ?? null;
|
||||
}
|
||||
|
||||
toRow(): ReadStateRow {
|
||||
return {
|
||||
user_id: this.userId,
|
||||
channel_id: this.channelId,
|
||||
message_id: this.lastMessageId,
|
||||
mention_count: this.mentionCount,
|
||||
last_pin_timestamp: this.lastPinTimestamp,
|
||||
};
|
||||
}
|
||||
}
|
||||
50
fluxer_api/src/models/RecentMention.ts
Normal file
50
fluxer_api/src/models/RecentMention.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {RecentMentionRow} from '~/database/CassandraTypes';
|
||||
import type {ChannelID, GuildID, MessageID, UserID} from '../BrandedTypes';
|
||||
|
||||
export class RecentMention {
|
||||
readonly userId: UserID;
|
||||
readonly channelId: ChannelID;
|
||||
readonly messageId: MessageID;
|
||||
readonly guildId: GuildID;
|
||||
readonly isEveryone: boolean;
|
||||
readonly isRole: boolean;
|
||||
|
||||
constructor(row: RecentMentionRow) {
|
||||
this.userId = row.user_id;
|
||||
this.channelId = row.channel_id;
|
||||
this.messageId = row.message_id;
|
||||
this.guildId = row.guild_id;
|
||||
this.isEveryone = row.is_everyone;
|
||||
this.isRole = row.is_role;
|
||||
}
|
||||
|
||||
toRow(): RecentMentionRow {
|
||||
return {
|
||||
user_id: this.userId,
|
||||
channel_id: this.channelId,
|
||||
message_id: this.messageId,
|
||||
guild_id: this.guildId,
|
||||
is_everyone: this.isEveryone,
|
||||
is_role: this.isRole,
|
||||
};
|
||||
}
|
||||
}
|
||||
50
fluxer_api/src/models/Relationship.ts
Normal file
50
fluxer_api/src/models/Relationship.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {RelationshipRow} from '~/database/CassandraTypes';
|
||||
import type {UserID} from '../BrandedTypes';
|
||||
|
||||
export class Relationship {
|
||||
readonly sourceUserId: UserID;
|
||||
readonly targetUserId: UserID;
|
||||
readonly type: number;
|
||||
readonly nickname: string | null;
|
||||
readonly since: Date | null;
|
||||
readonly version: number;
|
||||
|
||||
constructor(row: RelationshipRow) {
|
||||
this.sourceUserId = row.source_user_id;
|
||||
this.targetUserId = row.target_user_id;
|
||||
this.type = row.type;
|
||||
this.nickname = row.nickname ?? null;
|
||||
this.since = row.since ?? null;
|
||||
this.version = row.version;
|
||||
}
|
||||
|
||||
toRow(): RelationshipRow {
|
||||
return {
|
||||
source_user_id: this.sourceUserId,
|
||||
target_user_id: this.targetUserId,
|
||||
type: this.type,
|
||||
nickname: this.nickname,
|
||||
since: this.since,
|
||||
version: this.version,
|
||||
};
|
||||
}
|
||||
}
|
||||
44
fluxer_api/src/models/SavedMessage.ts
Normal file
44
fluxer_api/src/models/SavedMessage.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {SavedMessageRow} from '~/database/CassandraTypes';
|
||||
import type {ChannelID, MessageID, UserID} from '../BrandedTypes';
|
||||
|
||||
export class SavedMessage {
|
||||
readonly userId: UserID;
|
||||
readonly channelId: ChannelID;
|
||||
readonly messageId: MessageID;
|
||||
readonly savedAt: Date;
|
||||
|
||||
constructor(row: SavedMessageRow) {
|
||||
this.userId = row.user_id;
|
||||
this.channelId = row.channel_id;
|
||||
this.messageId = row.message_id;
|
||||
this.savedAt = row.saved_at;
|
||||
}
|
||||
|
||||
toRow(): SavedMessageRow {
|
||||
return {
|
||||
user_id: this.userId,
|
||||
channel_id: this.channelId,
|
||||
message_id: this.messageId,
|
||||
saved_at: this.savedAt,
|
||||
};
|
||||
}
|
||||
}
|
||||
198
fluxer_api/src/models/ScheduledMessage.ts
Normal file
198
fluxer_api/src/models/ScheduledMessage.ts
Normal file
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {ChannelID, MessageID, UserID} from '~/BrandedTypes';
|
||||
import type {AttachmentRequestData} from '~/channel/AttachmentDTOs';
|
||||
import type {AllowedMentionsRequest, MessageRequest} from '~/channel/ChannelModel';
|
||||
import type {ScheduledMessageRow} from '~/database/CassandraTypes';
|
||||
|
||||
export type ScheduledMessageStatus = 'pending' | 'invalid';
|
||||
|
||||
export interface ScheduledMessageReference {
|
||||
message_id: string;
|
||||
channel_id?: string;
|
||||
guild_id?: string;
|
||||
type?: number;
|
||||
}
|
||||
|
||||
export interface ScheduledAllowedMentions {
|
||||
parse?: AllowedMentionsRequest['parse'];
|
||||
users?: Array<string>;
|
||||
roles?: Array<string>;
|
||||
replied_user?: boolean;
|
||||
}
|
||||
|
||||
export interface ScheduledMessagePayload {
|
||||
content?: string | null;
|
||||
embeds?: MessageRequest['embeds'];
|
||||
attachments?: Array<AttachmentRequestData>;
|
||||
message_reference?: ScheduledMessageReference;
|
||||
allowed_mentions?: ScheduledAllowedMentions;
|
||||
flags?: number;
|
||||
nonce?: string;
|
||||
favorite_meme_id?: string;
|
||||
sticker_ids?: Array<string>;
|
||||
tts?: boolean;
|
||||
}
|
||||
|
||||
export interface ScheduledMessageResponse {
|
||||
id: string;
|
||||
channel_id: string;
|
||||
scheduled_at: string;
|
||||
scheduled_local_at: string;
|
||||
timezone: string;
|
||||
status: ScheduledMessageStatus;
|
||||
status_reason: string | null;
|
||||
payload: ScheduledMessagePayload;
|
||||
created_at: string;
|
||||
invalidated_at: string | null;
|
||||
}
|
||||
|
||||
export class ScheduledMessage {
|
||||
readonly userId: UserID;
|
||||
readonly id: MessageID;
|
||||
readonly channelId: ChannelID;
|
||||
readonly scheduledAt: Date;
|
||||
readonly scheduledLocalAt: string;
|
||||
readonly timezone: string;
|
||||
readonly payload: ScheduledMessagePayload;
|
||||
readonly status: ScheduledMessageStatus;
|
||||
readonly statusReason: string | null;
|
||||
readonly createdAt: Date;
|
||||
readonly invalidatedAt: Date | null;
|
||||
|
||||
constructor(params: {
|
||||
userId: UserID;
|
||||
id: MessageID;
|
||||
channelId: ChannelID;
|
||||
scheduledAt: Date;
|
||||
scheduledLocalAt: string;
|
||||
timezone: string;
|
||||
payload: ScheduledMessagePayload;
|
||||
status?: ScheduledMessageStatus;
|
||||
statusReason?: string | null;
|
||||
createdAt?: Date;
|
||||
invalidatedAt?: Date | null;
|
||||
}) {
|
||||
this.userId = params.userId;
|
||||
this.id = params.id;
|
||||
this.channelId = params.channelId;
|
||||
this.scheduledAt = params.scheduledAt;
|
||||
this.scheduledLocalAt = params.scheduledLocalAt;
|
||||
this.timezone = params.timezone;
|
||||
this.payload = params.payload;
|
||||
this.status = params.status ?? 'pending';
|
||||
this.statusReason = params.statusReason ?? null;
|
||||
this.createdAt = params.createdAt ?? new Date();
|
||||
this.invalidatedAt = params.invalidatedAt ?? null;
|
||||
}
|
||||
|
||||
static fromRow(row: ScheduledMessageRow): ScheduledMessage {
|
||||
return new ScheduledMessage({
|
||||
userId: row.user_id,
|
||||
id: row.scheduled_message_id,
|
||||
channelId: row.channel_id,
|
||||
scheduledAt: row.scheduled_at,
|
||||
scheduledLocalAt: row.scheduled_local_at,
|
||||
timezone: row.timezone,
|
||||
payload: parsePayload(row.payload),
|
||||
status: toStatus(row.status),
|
||||
statusReason: row.status_reason,
|
||||
createdAt: row.created_at,
|
||||
invalidatedAt: row.invalidated_at,
|
||||
});
|
||||
}
|
||||
|
||||
toRow(): ScheduledMessageRow {
|
||||
return {
|
||||
user_id: this.userId,
|
||||
scheduled_message_id: this.id,
|
||||
channel_id: this.channelId,
|
||||
payload: JSON.stringify(this.payload),
|
||||
scheduled_at: this.scheduledAt,
|
||||
scheduled_local_at: this.scheduledLocalAt,
|
||||
timezone: this.timezone,
|
||||
status: this.status,
|
||||
status_reason: this.statusReason,
|
||||
created_at: this.createdAt,
|
||||
invalidated_at: this.invalidatedAt,
|
||||
};
|
||||
}
|
||||
|
||||
toResponse(): ScheduledMessageResponse {
|
||||
return {
|
||||
id: this.id.toString(),
|
||||
channel_id: this.channelId.toString(),
|
||||
scheduled_at: this.scheduledAt.toISOString(),
|
||||
scheduled_local_at: this.scheduledLocalAt,
|
||||
timezone: this.timezone,
|
||||
status: this.status,
|
||||
status_reason: this.statusReason,
|
||||
payload: this.payload,
|
||||
created_at: this.createdAt.toISOString(),
|
||||
invalidated_at: this.invalidatedAt?.toISOString() ?? null,
|
||||
};
|
||||
}
|
||||
|
||||
parseToMessageRequest(): MessageRequest {
|
||||
return hydrateMessageRequest(this.payload);
|
||||
}
|
||||
}
|
||||
|
||||
function parsePayload(payload: string): ScheduledMessagePayload {
|
||||
try {
|
||||
return JSON.parse(payload) as ScheduledMessagePayload;
|
||||
} catch (_error) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
function toStatus(value: string): ScheduledMessageStatus {
|
||||
return value === 'invalid' ? 'invalid' : 'pending';
|
||||
}
|
||||
|
||||
function hydrateMessageRequest(payload: ScheduledMessagePayload): MessageRequest {
|
||||
const message: MessageRequest = {
|
||||
content: payload.content,
|
||||
embeds: payload.embeds ?? [],
|
||||
attachments: payload.attachments,
|
||||
message_reference: payload.message_reference
|
||||
? {
|
||||
...payload.message_reference,
|
||||
message_id: BigInt(payload.message_reference.message_id),
|
||||
channel_id: payload.message_reference.channel_id ? BigInt(payload.message_reference.channel_id) : undefined,
|
||||
guild_id: payload.message_reference.guild_id ? BigInt(payload.message_reference.guild_id) : undefined,
|
||||
}
|
||||
: undefined,
|
||||
allowed_mentions: payload.allowed_mentions
|
||||
? {
|
||||
parse: payload.allowed_mentions.parse,
|
||||
users: payload.allowed_mentions.users?.map((value) => BigInt(value)),
|
||||
roles: payload.allowed_mentions.roles?.map((value) => BigInt(value)),
|
||||
replied_user: payload.allowed_mentions.replied_user,
|
||||
}
|
||||
: undefined,
|
||||
flags: payload.flags,
|
||||
nonce: payload.nonce,
|
||||
favorite_meme_id: payload.favorite_meme_id ? BigInt(payload.favorite_meme_id) : undefined,
|
||||
sticker_ids: payload.sticker_ids?.map((value) => BigInt(value)),
|
||||
tts: payload.tts,
|
||||
};
|
||||
return message;
|
||||
}
|
||||
41
fluxer_api/src/models/StickerItem.ts
Normal file
41
fluxer_api/src/models/StickerItem.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {MessageStickerItem} from '~/database/CassandraTypes';
|
||||
import type {StickerID} from '../BrandedTypes';
|
||||
|
||||
export class StickerItem {
|
||||
readonly id: StickerID;
|
||||
readonly name: string;
|
||||
readonly formatType: number;
|
||||
|
||||
constructor(sticker: MessageStickerItem) {
|
||||
this.id = sticker.sticker_id;
|
||||
this.name = sticker.name;
|
||||
this.formatType = sticker.format_type;
|
||||
}
|
||||
|
||||
toMessageStickerItem(): MessageStickerItem {
|
||||
return {
|
||||
sticker_id: this.id,
|
||||
name: this.name,
|
||||
format_type: this.formatType,
|
||||
};
|
||||
}
|
||||
}
|
||||
204
fluxer_api/src/models/User.ts
Normal file
204
fluxer_api/src/models/User.ts
Normal file
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {types} from 'cassandra-driver';
|
||||
import type {UserRow} from '~/database/CassandraTypes';
|
||||
import type {UserID} from '../BrandedTypes';
|
||||
import {checkIsPremium} from '../user/UserHelpers';
|
||||
|
||||
export class User {
|
||||
readonly id: UserID;
|
||||
readonly username: string;
|
||||
readonly discriminator: number;
|
||||
readonly globalName: string | null;
|
||||
readonly isBot: boolean;
|
||||
readonly isSystem: boolean;
|
||||
readonly email: string | null;
|
||||
readonly emailVerified: boolean;
|
||||
readonly emailBounced: boolean;
|
||||
readonly phone: string | null;
|
||||
readonly passwordHash: string | null;
|
||||
readonly passwordLastChangedAt: Date | null;
|
||||
readonly totpSecret: string | null;
|
||||
readonly authenticatorTypes: Set<number>;
|
||||
readonly avatarHash: string | null;
|
||||
readonly avatarColor: number | null;
|
||||
readonly bannerHash: string | null;
|
||||
readonly bannerColor: number | null;
|
||||
readonly bio: string | null;
|
||||
readonly pronouns: string | null;
|
||||
readonly accentColor: number | null;
|
||||
readonly dateOfBirth: string | null;
|
||||
readonly locale: string | null;
|
||||
readonly flags: bigint;
|
||||
readonly premiumType: number | null;
|
||||
readonly premiumSince: Date | null;
|
||||
readonly premiumUntil: Date | null;
|
||||
readonly premiumWillCancel: boolean;
|
||||
readonly premiumBillingCycle: string | null;
|
||||
readonly premiumLifetimeSequence: number | null;
|
||||
readonly stripeSubscriptionId: string | null;
|
||||
readonly stripeCustomerId: string | null;
|
||||
readonly hasEverPurchased: boolean;
|
||||
readonly suspiciousActivityFlags: number;
|
||||
readonly termsAgreedAt: Date | null;
|
||||
readonly privacyAgreedAt: Date | null;
|
||||
readonly lastActiveAt: Date | null;
|
||||
readonly lastActiveIp: string | null;
|
||||
readonly tempBannedUntil: Date | null;
|
||||
readonly pendingBulkMessageDeletionAt: Date | null;
|
||||
readonly pendingBulkMessageDeletionChannelCount: number | null;
|
||||
readonly pendingBulkMessageDeletionMessageCount: number | null;
|
||||
readonly pendingDeletionAt: Date | null;
|
||||
readonly deletionReasonCode: number | null;
|
||||
readonly deletionPublicReason: string | null;
|
||||
readonly deletionAuditLogReason: string | null;
|
||||
readonly acls: Set<string>;
|
||||
readonly firstRefundAt: Date | null;
|
||||
readonly betaCodeAllowance: number;
|
||||
readonly betaCodeLastResetAt: Date | null;
|
||||
readonly giftInventoryServerSeq: number | null;
|
||||
readonly giftInventoryClientSeq: number | null;
|
||||
readonly premiumOnboardingDismissedAt: Date | null;
|
||||
readonly version: number;
|
||||
|
||||
constructor(row: UserRow) {
|
||||
this.id = row.user_id;
|
||||
this.username = row.username;
|
||||
this.discriminator = row.discriminator;
|
||||
this.globalName = row.global_name ?? null;
|
||||
this.isBot = row.bot ?? false;
|
||||
this.isSystem = row.system ?? false;
|
||||
this.email = row.email ?? null;
|
||||
this.emailVerified = row.email_verified ?? false;
|
||||
this.emailBounced = row.email_bounced ?? false;
|
||||
this.phone = row.phone ?? null;
|
||||
this.passwordHash = row.password_hash ?? null;
|
||||
this.passwordLastChangedAt = row.password_last_changed_at ?? null;
|
||||
this.totpSecret = row.totp_secret ?? null;
|
||||
this.authenticatorTypes = row.authenticator_types ?? new Set();
|
||||
this.avatarHash = row.avatar_hash ?? null;
|
||||
this.avatarColor = row.avatar_color ?? null;
|
||||
this.bannerHash = row.banner_hash ?? null;
|
||||
this.bannerColor = row.banner_color ?? null;
|
||||
this.bio = row.bio ?? null;
|
||||
this.pronouns = row.pronouns ?? null;
|
||||
this.accentColor = row.accent_color ?? null;
|
||||
this.dateOfBirth = row.date_of_birth ? row.date_of_birth.toString() : null;
|
||||
this.locale = row.locale ?? null;
|
||||
this.flags = row.flags ?? 0n;
|
||||
this.premiumType = row.premium_type ?? null;
|
||||
this.premiumSince = row.premium_since ?? null;
|
||||
this.premiumUntil = row.premium_until ?? null;
|
||||
this.premiumWillCancel = row.premium_will_cancel ?? false;
|
||||
this.premiumBillingCycle = row.premium_billing_cycle ?? null;
|
||||
this.premiumLifetimeSequence = row.premium_lifetime_sequence ?? null;
|
||||
this.stripeSubscriptionId = row.stripe_subscription_id ?? null;
|
||||
this.stripeCustomerId = row.stripe_customer_id ?? null;
|
||||
this.hasEverPurchased = row.has_ever_purchased ?? false;
|
||||
this.suspiciousActivityFlags = row.suspicious_activity_flags ?? 0;
|
||||
this.termsAgreedAt = row.terms_agreed_at ?? null;
|
||||
this.privacyAgreedAt = row.privacy_agreed_at ?? null;
|
||||
this.lastActiveAt = row.last_active_at ?? null;
|
||||
this.lastActiveIp = row.last_active_ip ?? null;
|
||||
this.tempBannedUntil = row.temp_banned_until ?? null;
|
||||
this.pendingBulkMessageDeletionAt = row.pending_bulk_message_deletion_at ?? null;
|
||||
this.pendingBulkMessageDeletionChannelCount = row.pending_bulk_message_deletion_channel_count ?? null;
|
||||
this.pendingBulkMessageDeletionMessageCount = row.pending_bulk_message_deletion_message_count ?? null;
|
||||
this.pendingDeletionAt = row.pending_deletion_at ?? null;
|
||||
this.deletionReasonCode = row.deletion_reason_code ?? null;
|
||||
this.deletionPublicReason = row.deletion_public_reason ?? null;
|
||||
this.deletionAuditLogReason = row.deletion_audit_log_reason ?? null;
|
||||
this.acls = row.acls ?? new Set();
|
||||
this.firstRefundAt = row.first_refund_at ?? null;
|
||||
this.betaCodeAllowance = row.beta_code_allowance ?? 0;
|
||||
this.betaCodeLastResetAt = row.beta_code_last_reset_at ?? null;
|
||||
this.giftInventoryServerSeq = row.gift_inventory_server_seq ?? null;
|
||||
this.giftInventoryClientSeq = row.gift_inventory_client_seq ?? null;
|
||||
this.premiumOnboardingDismissedAt = row.premium_onboarding_dismissed_at ?? null;
|
||||
this.version = row.version;
|
||||
}
|
||||
|
||||
isPremium(): boolean {
|
||||
return checkIsPremium(this);
|
||||
}
|
||||
|
||||
canUseGlobalExpressions(): boolean {
|
||||
return this.isPremium() || this.isBot;
|
||||
}
|
||||
|
||||
toRow(): UserRow {
|
||||
return {
|
||||
user_id: this.id,
|
||||
username: this.username,
|
||||
discriminator: this.discriminator,
|
||||
global_name: this.globalName,
|
||||
bot: this.isBot,
|
||||
system: this.isSystem,
|
||||
email: this.email,
|
||||
email_verified: this.emailVerified,
|
||||
email_bounced: this.emailBounced,
|
||||
phone: this.phone,
|
||||
password_hash: this.passwordHash,
|
||||
password_last_changed_at: this.passwordLastChangedAt,
|
||||
totp_secret: this.totpSecret,
|
||||
authenticator_types: this.authenticatorTypes.size > 0 ? this.authenticatorTypes : null,
|
||||
avatar_hash: this.avatarHash,
|
||||
avatar_color: this.avatarColor,
|
||||
banner_hash: this.bannerHash,
|
||||
banner_color: this.bannerColor,
|
||||
bio: this.bio,
|
||||
pronouns: this.pronouns,
|
||||
accent_color: this.accentColor,
|
||||
date_of_birth: this.dateOfBirth ? types.LocalDate.fromString(this.dateOfBirth) : null,
|
||||
locale: this.locale,
|
||||
flags: this.flags,
|
||||
premium_type: this.premiumType,
|
||||
premium_since: this.premiumSince,
|
||||
premium_until: this.premiumUntil,
|
||||
premium_will_cancel: this.premiumWillCancel,
|
||||
premium_billing_cycle: this.premiumBillingCycle,
|
||||
premium_lifetime_sequence: this.premiumLifetimeSequence,
|
||||
stripe_subscription_id: this.stripeSubscriptionId,
|
||||
stripe_customer_id: this.stripeCustomerId,
|
||||
has_ever_purchased: this.hasEverPurchased,
|
||||
suspicious_activity_flags: this.suspiciousActivityFlags,
|
||||
terms_agreed_at: this.termsAgreedAt,
|
||||
privacy_agreed_at: this.privacyAgreedAt,
|
||||
last_active_at: this.lastActiveAt,
|
||||
last_active_ip: this.lastActiveIp,
|
||||
temp_banned_until: this.tempBannedUntil,
|
||||
pending_bulk_message_deletion_at: this.pendingBulkMessageDeletionAt,
|
||||
pending_bulk_message_deletion_channel_count: this.pendingBulkMessageDeletionChannelCount,
|
||||
pending_bulk_message_deletion_message_count: this.pendingBulkMessageDeletionMessageCount,
|
||||
pending_deletion_at: this.pendingDeletionAt,
|
||||
deletion_reason_code: this.deletionReasonCode,
|
||||
deletion_public_reason: this.deletionPublicReason,
|
||||
deletion_audit_log_reason: this.deletionAuditLogReason,
|
||||
acls: this.acls.size > 0 ? this.acls : null,
|
||||
first_refund_at: this.firstRefundAt,
|
||||
beta_code_allowance: this.betaCodeAllowance,
|
||||
beta_code_last_reset_at: this.betaCodeLastResetAt,
|
||||
gift_inventory_server_seq: this.giftInventoryServerSeq,
|
||||
gift_inventory_client_seq: this.giftInventoryClientSeq,
|
||||
premium_onboarding_dismissed_at: this.premiumOnboardingDismissedAt,
|
||||
version: this.version,
|
||||
};
|
||||
}
|
||||
}
|
||||
51
fluxer_api/src/models/UserCustomStatus.ts
Normal file
51
fluxer_api/src/models/UserCustomStatus.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {CustomStatus} from '~/database/CassandraTypes';
|
||||
import type {EmojiID} from '../BrandedTypes';
|
||||
|
||||
export class UserCustomStatus {
|
||||
readonly text: string | null;
|
||||
readonly emojiId: EmojiID | null;
|
||||
readonly emojiName: string | null;
|
||||
readonly emojiAnimated: boolean;
|
||||
readonly expiresAt: Date | null;
|
||||
|
||||
constructor(status: CustomStatus) {
|
||||
this.text = status.text ?? null;
|
||||
this.emojiId = status.emoji_id ?? null;
|
||||
this.emojiName = status.emoji_name ?? null;
|
||||
this.emojiAnimated = status.emoji_animated ?? false;
|
||||
this.expiresAt = status.expires_at ?? null;
|
||||
}
|
||||
|
||||
toCustomStatus(): CustomStatus {
|
||||
return {
|
||||
text: this.text,
|
||||
emoji_id: this.emojiId,
|
||||
emoji_name: this.emojiName,
|
||||
emoji_animated: this.emojiAnimated,
|
||||
expires_at: this.expiresAt,
|
||||
};
|
||||
}
|
||||
|
||||
isExpired(referenceTime: Date = new Date()): boolean {
|
||||
return this.expiresAt !== null && this.expiresAt.getTime() <= referenceTime.getTime();
|
||||
}
|
||||
}
|
||||
44
fluxer_api/src/models/UserGuildFolder.ts
Normal file
44
fluxer_api/src/models/UserGuildFolder.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {GuildFolder} from '~/database/CassandraTypes';
|
||||
import type {GuildID} from '../BrandedTypes';
|
||||
|
||||
export class UserGuildFolder {
|
||||
readonly folderId: number;
|
||||
readonly name: string | null;
|
||||
readonly color: number | null;
|
||||
readonly guildIds: Array<GuildID>;
|
||||
|
||||
constructor(folder: GuildFolder) {
|
||||
this.folderId = folder.folder_id;
|
||||
this.name = folder.name ?? null;
|
||||
this.color = folder.color ?? null;
|
||||
this.guildIds = folder.guild_ids ?? [];
|
||||
}
|
||||
|
||||
toGuildFolder(): GuildFolder {
|
||||
return {
|
||||
folder_id: this.folderId,
|
||||
name: this.name,
|
||||
color: this.color,
|
||||
guild_ids: this.guildIds.length > 0 ? this.guildIds : null,
|
||||
};
|
||||
}
|
||||
}
|
||||
79
fluxer_api/src/models/UserGuildSettings.ts
Normal file
79
fluxer_api/src/models/UserGuildSettings.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {ChannelOverride, UserGuildSettingsRow} from '~/database/CassandraTypes';
|
||||
import type {ChannelID, GuildID, UserID} from '../BrandedTypes';
|
||||
import {GuildChannelOverride} from './GuildChannelOverride';
|
||||
import {MuteConfiguration} from './MuteConfiguration';
|
||||
|
||||
export class UserGuildSettings {
|
||||
readonly userId: UserID;
|
||||
readonly guildId: GuildID;
|
||||
readonly messageNotifications: number | null;
|
||||
readonly muted: boolean;
|
||||
readonly muteConfig: MuteConfiguration | null;
|
||||
readonly mobilePush: boolean;
|
||||
readonly suppressEveryone: boolean;
|
||||
readonly suppressRoles: boolean;
|
||||
readonly hideMutedChannels: boolean;
|
||||
readonly channelOverrides: Map<ChannelID, GuildChannelOverride>;
|
||||
readonly version: number;
|
||||
|
||||
constructor(row: UserGuildSettingsRow) {
|
||||
this.userId = row.user_id;
|
||||
this.guildId = row.guild_id;
|
||||
this.messageNotifications = row.message_notifications ?? null;
|
||||
this.muted = row.muted ?? false;
|
||||
this.muteConfig = row.mute_config ? new MuteConfiguration(row.mute_config) : null;
|
||||
this.mobilePush = row.mobile_push ?? false;
|
||||
this.suppressEveryone = row.suppress_everyone ?? false;
|
||||
this.suppressRoles = row.suppress_roles ?? false;
|
||||
this.hideMutedChannels = row.hide_muted_channels ?? false;
|
||||
this.channelOverrides = new Map();
|
||||
if (row.channel_overrides) {
|
||||
for (const [channelId, override] of row.channel_overrides) {
|
||||
this.channelOverrides.set(channelId, new GuildChannelOverride(override));
|
||||
}
|
||||
}
|
||||
this.version = row.version;
|
||||
}
|
||||
|
||||
toRow(): UserGuildSettingsRow {
|
||||
const channelOverridesMap: Map<ChannelID, ChannelOverride> | null =
|
||||
this.channelOverrides.size > 0
|
||||
? new Map(
|
||||
Array.from(this.channelOverrides.entries()).map(([id, override]) => [id, override.toChannelOverride()]),
|
||||
)
|
||||
: null;
|
||||
|
||||
return {
|
||||
user_id: this.userId,
|
||||
guild_id: this.guildId,
|
||||
message_notifications: this.messageNotifications,
|
||||
muted: this.muted,
|
||||
mute_config: this.muteConfig?.toMuteConfig() ?? null,
|
||||
mobile_push: this.mobilePush,
|
||||
suppress_everyone: this.suppressEveryone,
|
||||
suppress_roles: this.suppressRoles,
|
||||
hide_muted_channels: this.hideMutedChannels,
|
||||
channel_overrides: channelOverridesMap,
|
||||
version: this.version,
|
||||
};
|
||||
}
|
||||
}
|
||||
44
fluxer_api/src/models/UserNote.ts
Normal file
44
fluxer_api/src/models/UserNote.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {NoteRow} from '~/database/CassandraTypes';
|
||||
import type {UserID} from '../BrandedTypes';
|
||||
|
||||
export class UserNote {
|
||||
readonly sourceUserId: UserID;
|
||||
readonly targetUserId: UserID;
|
||||
readonly note: string;
|
||||
readonly version: number;
|
||||
|
||||
constructor(row: NoteRow) {
|
||||
this.sourceUserId = row.source_user_id;
|
||||
this.targetUserId = row.target_user_id;
|
||||
this.note = row.note;
|
||||
this.version = row.version;
|
||||
}
|
||||
|
||||
toRow(): NoteRow {
|
||||
return {
|
||||
source_user_id: this.sourceUserId,
|
||||
target_user_id: this.targetUserId,
|
||||
note: this.note,
|
||||
version: this.version,
|
||||
};
|
||||
}
|
||||
}
|
||||
178
fluxer_api/src/models/UserSettings.ts
Normal file
178
fluxer_api/src/models/UserSettings.ts
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {UserSettingsRow} from '~/database/CassandraTypes';
|
||||
import type {GuildID, UserID} from '../BrandedTypes';
|
||||
import {Config} from '../Config';
|
||||
import {
|
||||
FriendSourceFlags,
|
||||
GroupDmAddPermissionFlags,
|
||||
IncomingCallFlags,
|
||||
RenderSpoilers,
|
||||
StickerAnimationOptions,
|
||||
ThemeTypes,
|
||||
UserExplicitContentFilterTypes,
|
||||
} from '../Constants';
|
||||
import {UserCustomStatus} from './UserCustomStatus';
|
||||
import {UserGuildFolder} from './UserGuildFolder';
|
||||
|
||||
export class UserSettings {
|
||||
readonly userId: UserID;
|
||||
readonly locale: string;
|
||||
readonly theme: string;
|
||||
readonly status: string;
|
||||
readonly statusResetsAt: Date | null;
|
||||
readonly statusResetsTo: string | null;
|
||||
readonly customStatus: UserCustomStatus | null;
|
||||
readonly developerMode: boolean;
|
||||
readonly compactMessageDisplay: boolean;
|
||||
readonly animateEmoji: boolean;
|
||||
readonly animateStickers: number;
|
||||
readonly gifAutoPlay: boolean;
|
||||
readonly renderEmbeds: boolean;
|
||||
readonly renderReactions: boolean;
|
||||
readonly renderSpoilers: number;
|
||||
readonly inlineAttachmentMedia: boolean;
|
||||
readonly inlineEmbedMedia: boolean;
|
||||
readonly explicitContentFilter: number;
|
||||
readonly friendSourceFlags: number;
|
||||
readonly incomingCallFlags: number;
|
||||
readonly groupDmAddPermissionFlags: number;
|
||||
readonly defaultGuildsRestricted: boolean;
|
||||
readonly restrictedGuilds: Set<GuildID>;
|
||||
readonly guildPositions: Array<GuildID>;
|
||||
readonly guildFolders: Array<UserGuildFolder>;
|
||||
readonly afkTimeout: number;
|
||||
readonly timeFormat: number;
|
||||
readonly version: number;
|
||||
|
||||
constructor(row: UserSettingsRow) {
|
||||
this.userId = row.user_id;
|
||||
this.locale = row.locale;
|
||||
this.theme = row.theme;
|
||||
this.status = row.status;
|
||||
this.statusResetsAt = row.status_resets_at ?? null;
|
||||
this.statusResetsTo = row.status_resets_to ?? null;
|
||||
this.customStatus = row.custom_status ? new UserCustomStatus(row.custom_status) : null;
|
||||
this.developerMode = row.developer_mode ?? false;
|
||||
this.compactMessageDisplay = row.message_display_compact ?? false;
|
||||
this.animateEmoji = row.animate_emoji ?? false;
|
||||
this.animateStickers = row.animate_stickers ?? 0;
|
||||
this.gifAutoPlay = row.gif_auto_play ?? false;
|
||||
this.renderEmbeds = row.render_embeds ?? false;
|
||||
this.renderReactions = row.render_reactions ?? false;
|
||||
this.renderSpoilers = row.render_spoilers ?? 0;
|
||||
this.inlineAttachmentMedia = row.inline_attachment_media ?? false;
|
||||
this.inlineEmbedMedia = row.inline_embed_media ?? false;
|
||||
this.explicitContentFilter = row.explicit_content_filter ?? 0;
|
||||
this.friendSourceFlags = row.friend_source_flags ?? 0;
|
||||
this.incomingCallFlags = row.incoming_call_flags ?? 0;
|
||||
this.groupDmAddPermissionFlags = row.group_dm_add_permission_flags ?? 0;
|
||||
this.defaultGuildsRestricted = row.default_guilds_restricted ?? false;
|
||||
this.restrictedGuilds = row.restricted_guilds ?? new Set();
|
||||
this.guildPositions = row.guild_positions ?? [];
|
||||
this.guildFolders = (row.guild_folders ?? []).map((folder) => new UserGuildFolder(folder));
|
||||
this.afkTimeout = row.afk_timeout ?? 600;
|
||||
this.timeFormat = row.time_format ?? 0;
|
||||
this.version = row.version;
|
||||
}
|
||||
|
||||
toRow(): UserSettingsRow {
|
||||
return {
|
||||
user_id: this.userId,
|
||||
locale: this.locale,
|
||||
theme: this.theme,
|
||||
status: this.status,
|
||||
status_resets_at: this.statusResetsAt,
|
||||
status_resets_to: this.statusResetsTo,
|
||||
custom_status: this.customStatus?.toCustomStatus() ?? null,
|
||||
developer_mode: this.developerMode,
|
||||
message_display_compact: this.compactMessageDisplay,
|
||||
animate_emoji: this.animateEmoji,
|
||||
animate_stickers: this.animateStickers,
|
||||
gif_auto_play: this.gifAutoPlay,
|
||||
render_embeds: this.renderEmbeds,
|
||||
render_reactions: this.renderReactions,
|
||||
render_spoilers: this.renderSpoilers,
|
||||
inline_attachment_media: this.inlineAttachmentMedia,
|
||||
inline_embed_media: this.inlineEmbedMedia,
|
||||
explicit_content_filter: this.explicitContentFilter,
|
||||
friend_source_flags: this.friendSourceFlags,
|
||||
incoming_call_flags: this.incomingCallFlags,
|
||||
group_dm_add_permission_flags: this.groupDmAddPermissionFlags,
|
||||
default_guilds_restricted: this.defaultGuildsRestricted,
|
||||
restricted_guilds: this.restrictedGuilds.size > 0 ? this.restrictedGuilds : null,
|
||||
guild_positions: this.guildPositions.length > 0 ? this.guildPositions : null,
|
||||
guild_folders: this.guildFolders.length > 0 ? this.guildFolders.map((folder) => folder.toGuildFolder()) : null,
|
||||
afk_timeout: this.afkTimeout,
|
||||
time_format: this.timeFormat,
|
||||
version: this.version,
|
||||
};
|
||||
}
|
||||
|
||||
static getDefaultUserSettings({
|
||||
userId,
|
||||
locale,
|
||||
isAdult,
|
||||
}: {
|
||||
userId: UserID;
|
||||
locale: string;
|
||||
isAdult: boolean;
|
||||
}): UserSettingsRow {
|
||||
let explicitContentFilter: number = UserExplicitContentFilterTypes.NON_FRIENDS;
|
||||
if (isAdult) {
|
||||
explicitContentFilter = UserExplicitContentFilterTypes.FRIENDS_AND_NON_FRIENDS;
|
||||
}
|
||||
let friendSourceFlags: number = FriendSourceFlags.MUTUAL_FRIENDS | FriendSourceFlags.MUTUAL_GUILDS;
|
||||
if (isAdult) {
|
||||
friendSourceFlags |= FriendSourceFlags.NO_RELATION;
|
||||
}
|
||||
|
||||
return {
|
||||
user_id: userId,
|
||||
locale,
|
||||
theme: ThemeTypes.SYSTEM,
|
||||
status: 'online',
|
||||
status_resets_at: null,
|
||||
status_resets_to: null,
|
||||
custom_status: null,
|
||||
developer_mode: Config.nodeEnv === 'development',
|
||||
message_display_compact: false,
|
||||
animate_emoji: true,
|
||||
animate_stickers: StickerAnimationOptions.ALWAYS_ANIMATE,
|
||||
gif_auto_play: true,
|
||||
render_embeds: true,
|
||||
render_reactions: true,
|
||||
render_spoilers: RenderSpoilers.ON_CLICK,
|
||||
inline_attachment_media: true,
|
||||
inline_embed_media: true,
|
||||
explicit_content_filter: explicitContentFilter,
|
||||
friend_source_flags: friendSourceFlags,
|
||||
incoming_call_flags: IncomingCallFlags.FRIENDS_ONLY,
|
||||
group_dm_add_permission_flags: GroupDmAddPermissionFlags.FRIENDS_ONLY,
|
||||
default_guilds_restricted: false,
|
||||
restricted_guilds: new Set(),
|
||||
guild_positions: [],
|
||||
guild_folders: [],
|
||||
afk_timeout: 600,
|
||||
time_format: 0,
|
||||
version: 1,
|
||||
};
|
||||
}
|
||||
}
|
||||
42
fluxer_api/src/models/VisionarySlot.ts
Normal file
42
fluxer_api/src/models/VisionarySlot.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {VisionarySlotRow} from '~/database/CassandraTypes';
|
||||
import type {UserID} from '../BrandedTypes';
|
||||
|
||||
export class VisionarySlot {
|
||||
readonly slotIndex: number;
|
||||
readonly userId: UserID | null;
|
||||
|
||||
constructor(row: VisionarySlotRow) {
|
||||
this.slotIndex = row.slot_index;
|
||||
this.userId = row.user_id;
|
||||
}
|
||||
|
||||
toRow(): VisionarySlotRow {
|
||||
return {
|
||||
slot_index: this.slotIndex,
|
||||
user_id: this.userId,
|
||||
};
|
||||
}
|
||||
|
||||
isReserved(): boolean {
|
||||
return this.userId !== null;
|
||||
}
|
||||
}
|
||||
57
fluxer_api/src/models/WebAuthnCredential.ts
Normal file
57
fluxer_api/src/models/WebAuthnCredential.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {WebAuthnCredentialRow} from '~/database/CassandraTypes';
|
||||
import type {UserID} from '../BrandedTypes';
|
||||
|
||||
export class WebAuthnCredential {
|
||||
readonly credentialId: string;
|
||||
readonly publicKey: Buffer;
|
||||
readonly counter: bigint;
|
||||
readonly transports: Set<string> | null;
|
||||
readonly name: string;
|
||||
readonly createdAt: Date;
|
||||
readonly lastUsedAt: Date | null;
|
||||
readonly version: number;
|
||||
|
||||
constructor(row: WebAuthnCredentialRow) {
|
||||
this.credentialId = row.credential_id;
|
||||
this.publicKey = row.public_key;
|
||||
this.counter = row.counter;
|
||||
this.transports = row.transports ?? null;
|
||||
this.name = row.name;
|
||||
this.createdAt = row.created_at;
|
||||
this.lastUsedAt = row.last_used_at ?? null;
|
||||
this.version = row.version;
|
||||
}
|
||||
|
||||
toRow(userId: UserID): WebAuthnCredentialRow {
|
||||
return {
|
||||
user_id: userId,
|
||||
credential_id: this.credentialId,
|
||||
public_key: this.publicKey,
|
||||
counter: this.counter,
|
||||
transports: this.transports,
|
||||
name: this.name,
|
||||
created_at: this.createdAt,
|
||||
last_used_at: this.lastUsedAt,
|
||||
version: this.version,
|
||||
};
|
||||
}
|
||||
}
|
||||
59
fluxer_api/src/models/Webhook.ts
Normal file
59
fluxer_api/src/models/Webhook.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type {WebhookRow} from '~/database/CassandraTypes';
|
||||
import type {ChannelID, GuildID, UserID, WebhookID, WebhookToken} from '../BrandedTypes';
|
||||
|
||||
export class Webhook {
|
||||
readonly id: WebhookID;
|
||||
readonly token: WebhookToken;
|
||||
readonly type: number;
|
||||
readonly guildId: GuildID | null;
|
||||
readonly channelId: ChannelID | null;
|
||||
readonly creatorId: UserID | null;
|
||||
readonly name: string;
|
||||
readonly avatarHash: string | null;
|
||||
readonly version: number;
|
||||
|
||||
constructor(row: WebhookRow) {
|
||||
this.id = row.webhook_id;
|
||||
this.token = row.webhook_token;
|
||||
this.type = row.type;
|
||||
this.guildId = row.guild_id ?? null;
|
||||
this.channelId = row.channel_id ?? null;
|
||||
this.creatorId = row.creator_id ?? null;
|
||||
this.name = row.name;
|
||||
this.avatarHash = row.avatar_hash ?? null;
|
||||
this.version = row.version;
|
||||
}
|
||||
|
||||
toRow(): WebhookRow {
|
||||
return {
|
||||
webhook_id: this.id,
|
||||
webhook_token: this.token,
|
||||
type: this.type,
|
||||
guild_id: this.guildId,
|
||||
channel_id: this.channelId,
|
||||
creator_id: this.creatorId,
|
||||
name: this.name,
|
||||
avatar_hash: this.avatarHash,
|
||||
version: this.version,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user