refactor progress
This commit is contained in:
201
packages/api/src/invite/InviteRepository.tsx
Normal file
201
packages/api/src/invite/InviteRepository.tsx
Normal file
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* 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, GuildID, InviteCode, UserID} from '@fluxer/api/src/BrandedTypes';
|
||||
import {createInviteCode} from '@fluxer/api/src/BrandedTypes';
|
||||
import {BatchBuilder, Db, fetchMany, fetchOne, upsertOne} from '@fluxer/api/src/database/Cassandra';
|
||||
import type {InviteRow} from '@fluxer/api/src/database/types/ChannelTypes';
|
||||
import {IInviteRepository} from '@fluxer/api/src/invite/IInviteRepository';
|
||||
import {Invite} from '@fluxer/api/src/models/Invite';
|
||||
import {Invites, InvitesByChannel, InvitesByGuild} from '@fluxer/api/src/Tables';
|
||||
|
||||
const FETCH_INVITE_BY_CODE_CQL = Invites.selectCql({
|
||||
where: Invites.where.eq('code'),
|
||||
limit: 1,
|
||||
});
|
||||
|
||||
const FETCH_INVITES_BY_CHANNEL_CQL = InvitesByChannel.selectCql({
|
||||
columns: ['code'],
|
||||
where: InvitesByChannel.where.eq('channel_id'),
|
||||
});
|
||||
|
||||
const FETCH_INVITES_BY_GUILD_CQL = InvitesByGuild.selectCql({
|
||||
columns: ['code'],
|
||||
where: InvitesByGuild.where.eq('guild_id'),
|
||||
});
|
||||
|
||||
interface CreateInviteParams {
|
||||
code: InviteCode;
|
||||
type: number;
|
||||
guild_id: GuildID;
|
||||
channel_id?: ChannelID | null;
|
||||
inviter_id?: UserID | null;
|
||||
uses: number;
|
||||
max_uses: number;
|
||||
max_age: number;
|
||||
temporary?: boolean;
|
||||
}
|
||||
|
||||
export class InviteRepository extends IInviteRepository {
|
||||
async findUnique(code: InviteCode): Promise<Invite | null> {
|
||||
const invite = await fetchOne<InviteRow>(FETCH_INVITE_BY_CODE_CQL, {code});
|
||||
return invite ? new Invite(invite) : null;
|
||||
}
|
||||
|
||||
async listChannelInvites(channelId: ChannelID): Promise<Array<Invite>> {
|
||||
const inviteCodes = await fetchMany<{code: string}>(FETCH_INVITES_BY_CHANNEL_CQL, {channel_id: channelId});
|
||||
|
||||
if (inviteCodes.length === 0) return [];
|
||||
|
||||
const invites: Array<Invite> = [];
|
||||
for (const {code} of inviteCodes) {
|
||||
const invite = await this.findUnique(createInviteCode(code));
|
||||
if (invite) invites.push(invite);
|
||||
}
|
||||
|
||||
return invites;
|
||||
}
|
||||
|
||||
async listGuildInvites(guildId: GuildID): Promise<Array<Invite>> {
|
||||
const inviteCodes = await fetchMany<{code: string}>(FETCH_INVITES_BY_GUILD_CQL, {guild_id: guildId});
|
||||
|
||||
if (inviteCodes.length === 0) return [];
|
||||
|
||||
const invites: Array<Invite> = [];
|
||||
for (const {code} of inviteCodes) {
|
||||
const invite = await this.findUnique(createInviteCode(code));
|
||||
if (invite) invites.push(invite);
|
||||
}
|
||||
|
||||
return invites;
|
||||
}
|
||||
|
||||
async create(data: CreateInviteParams): Promise<Invite> {
|
||||
const inviteRow: InviteRow = {
|
||||
code: data.code,
|
||||
type: data.type,
|
||||
guild_id: data.guild_id,
|
||||
channel_id: data.channel_id ?? null,
|
||||
inviter_id: data.inviter_id ?? null,
|
||||
created_at: new Date(),
|
||||
uses: data.uses,
|
||||
max_uses: data.max_uses,
|
||||
max_age: data.max_age,
|
||||
temporary: data.temporary ?? false,
|
||||
version: 1,
|
||||
};
|
||||
|
||||
const batch = new BatchBuilder();
|
||||
|
||||
const hasExpiry = inviteRow.max_age > 0;
|
||||
|
||||
if (hasExpiry) {
|
||||
batch.addPrepared(Invites.insertWithTtlParam(inviteRow, 'max_age'));
|
||||
} else {
|
||||
batch.addPrepared(Invites.insert(inviteRow));
|
||||
}
|
||||
|
||||
if (inviteRow.guild_id) {
|
||||
batch.addPrepared(
|
||||
hasExpiry
|
||||
? InvitesByGuild.insertWithTtl(
|
||||
{
|
||||
guild_id: inviteRow.guild_id,
|
||||
code: inviteRow.code,
|
||||
},
|
||||
inviteRow.max_age,
|
||||
)
|
||||
: InvitesByGuild.insert({
|
||||
guild_id: inviteRow.guild_id,
|
||||
code: inviteRow.code,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if (inviteRow.channel_id) {
|
||||
batch.addPrepared(
|
||||
hasExpiry
|
||||
? InvitesByChannel.insertWithTtl(
|
||||
{
|
||||
channel_id: inviteRow.channel_id,
|
||||
code: inviteRow.code,
|
||||
},
|
||||
inviteRow.max_age,
|
||||
)
|
||||
: InvitesByChannel.insert({
|
||||
channel_id: inviteRow.channel_id,
|
||||
code: inviteRow.code,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
await batch.execute();
|
||||
|
||||
await upsertOne(Invites.upsertAll(inviteRow));
|
||||
if (inviteRow.guild_id) {
|
||||
await upsertOne(
|
||||
InvitesByGuild.upsertAll({
|
||||
guild_id: inviteRow.guild_id,
|
||||
code: inviteRow.code,
|
||||
}),
|
||||
);
|
||||
}
|
||||
if (inviteRow.channel_id) {
|
||||
await upsertOne(
|
||||
InvitesByChannel.upsertAll({
|
||||
channel_id: inviteRow.channel_id,
|
||||
code: inviteRow.code,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
return new Invite(inviteRow);
|
||||
}
|
||||
|
||||
async updateInviteUses(code: InviteCode, uses: number): Promise<void> {
|
||||
await fetchOne(
|
||||
Invites.patchByPk(
|
||||
{code},
|
||||
{
|
||||
uses: Db.set(uses),
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
async delete(code: InviteCode): Promise<void> {
|
||||
const invite = await this.findUnique(code);
|
||||
if (!invite) {
|
||||
return;
|
||||
}
|
||||
|
||||
const batch = new BatchBuilder();
|
||||
batch.addPrepared(Invites.deleteByPk({code}));
|
||||
|
||||
if (invite.guildId) {
|
||||
batch.addPrepared(InvitesByGuild.deleteByPk({guild_id: invite.guildId, code}));
|
||||
}
|
||||
|
||||
if (invite.channelId) {
|
||||
batch.addPrepared(InvitesByChannel.deleteByPk({channel_id: invite.channelId, code}));
|
||||
}
|
||||
|
||||
await batch.execute();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user