mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-19 05:55:34 +09:00
feat(expressions): remove the unfinished packs feature (#2250)
This commit is contained in:
1 parent
0eef611b6d
commit
b8f8d8d859
159 files changed
+42
-6863
No files matched your search
@@ -1,16 +1,10 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import {
|
||||
ChannelIdParam,
|
||||
GuildIdParam,
|
||||
InviteCodeParam,
|
||||
PackIdParam,
|
||||
} from '@fluxer/schema/src/domains/common/CommonParamSchemas';
|
||||
import {ChannelIdParam, GuildIdParam, InviteCodeParam} from '@fluxer/schema/src/domains/common/CommonParamSchemas';
|
||||
import {
|
||||
ChannelInviteCreateRequest,
|
||||
InviteMetadataResponseSchema,
|
||||
InviteResponseSchema,
|
||||
PackInviteCreateRequest,
|
||||
} from '@fluxer/schema/src/domains/invite/InviteSchemas';
|
||||
import {z} from 'zod';
|
||||
import {createChannelID, createGuildID, createInviteCode} from '../BrandedTypes';
|
||||
@@ -30,7 +24,7 @@ export function InviteController(app: HonoApp) {
|
||||
operationId: 'get_invite',
|
||||
summary: 'Get invite information',
|
||||
description:
|
||||
'Fetches detailed information about an invite using its code, including the guild, channel, or pack it belongs to and metadata such as expiration and usage limits. This endpoint does not require authentication and does not consume the invite.',
|
||||
'Fetches detailed information about an invite using its code, including the guild or channel it belongs to and metadata such as expiration and usage limits. This endpoint does not require authentication and does not consume the invite.',
|
||||
responseSchema: InviteResponseSchema,
|
||||
statusCode: 200,
|
||||
security: [],
|
||||
@@ -53,7 +47,7 @@ export function InviteController(app: HonoApp) {
|
||||
operationId: 'accept_invite',
|
||||
summary: 'Accept invite',
|
||||
description:
|
||||
'Accepts an invite using its code, adding the authenticated user to the corresponding guild, pack, or other entity. The invite usage count is incremented, and if it reaches its maximum usage limit or expiration, the invite is automatically revoked. Returns the accepted invite details.',
|
||||
'Accepts an invite using its code, adding the authenticated user to the corresponding guild or other entity. The invite usage count is incremented, and if it reaches its maximum usage limit or expiration, the invite is automatically revoked. Returns the accepted invite details.',
|
||||
responseSchema: InviteResponseSchema,
|
||||
statusCode: 200,
|
||||
security: ['bearerToken', 'sessionToken'],
|
||||
@@ -77,7 +71,7 @@ export function InviteController(app: HonoApp) {
|
||||
operationId: 'delete_invite',
|
||||
summary: 'Delete invite',
|
||||
description:
|
||||
'Permanently deletes an invite by its code, preventing any further usage. The authenticated user must have permission to manage invites for the guild, channel, or pack associated with the invite. This action can be logged in the audit log if an X-Audit-Log-Reason header is provided.',
|
||||
'Permanently deletes an invite by its code, preventing any further usage. The authenticated user must have permission to manage invites for the guild or channel associated with the invite. This action can be logged in the audit log if an X-Audit-Log-Reason header is provided.',
|
||||
responseSchema: null,
|
||||
statusCode: 204,
|
||||
security: ['botToken', 'bearerToken', 'sessionToken'],
|
||||
@@ -171,60 +165,4 @@ export function InviteController(app: HonoApp) {
|
||||
return ctx.json(await inviteRequestService.listGuildInvites({userId, guildId, requestCache}));
|
||||
},
|
||||
);
|
||||
app.get(
|
||||
'/packs/:pack_id/invites',
|
||||
RateLimitMiddleware(RateLimitConfigs.PACKS_INVITES_LIST),
|
||||
LoginRequired,
|
||||
DefaultUserOnly,
|
||||
Validator('param', PackIdParam),
|
||||
OpenAPI({
|
||||
operationId: 'list_pack_invites',
|
||||
summary: 'List pack invites',
|
||||
description:
|
||||
'Retrieves all currently active invites for the specified pack, including invite codes, creators, expiration times, and usage statistics. The authenticated user must have permission to manage invites for the pack and must be a default (non-bot) user. Returns an array of invite metadata objects.',
|
||||
responseSchema: z.array(InviteMetadataResponseSchema),
|
||||
statusCode: 200,
|
||||
security: ['bearerToken', 'sessionToken'],
|
||||
tags: ['Invites'],
|
||||
}),
|
||||
async (ctx) => {
|
||||
const userId = ctx.get('user').id;
|
||||
const packId = createGuildID(ctx.req.valid('param').pack_id);
|
||||
const inviteRequestService = ctx.get('inviteRequestService');
|
||||
const requestCache = ctx.get('requestCache');
|
||||
return ctx.json(await inviteRequestService.listPackInvites({userId, packId, requestCache}));
|
||||
},
|
||||
);
|
||||
app.post(
|
||||
'/packs/:pack_id/invites',
|
||||
RateLimitMiddleware(RateLimitConfigs.PACKS_INVITES_CREATE),
|
||||
LoginRequired,
|
||||
DefaultUserOnly,
|
||||
Validator('param', PackIdParam),
|
||||
Validator('json', PackInviteCreateRequest),
|
||||
OpenAPI({
|
||||
operationId: 'create_pack_invite',
|
||||
summary: 'Create pack invite',
|
||||
description:
|
||||
'Creates a new invite for the specified pack with optional parameters such as maximum age and maximum uses. The authenticated user must have permission to create invites for the pack and must be a default (non-bot) user. Returns the created invite with full metadata including usage statistics.',
|
||||
responseSchema: InviteMetadataResponseSchema,
|
||||
statusCode: 200,
|
||||
security: ['bearerToken', 'sessionToken'],
|
||||
tags: ['Invites'],
|
||||
}),
|
||||
async (ctx) => {
|
||||
const userId = ctx.get('user').id;
|
||||
const packId = createGuildID(ctx.req.valid('param').pack_id);
|
||||
const inviteRequestService = ctx.get('inviteRequestService');
|
||||
const requestCache = ctx.get('requestCache');
|
||||
return ctx.json(
|
||||
await inviteRequestService.createPackInvite({
|
||||
inviterId: userId,
|
||||
packId,
|
||||
requestCache,
|
||||
data: ctx.req.valid('json'),
|
||||
}),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
import {InviteTypes} from '@fluxer/constants/src/ChannelConstants';
|
||||
import {UnknownInviteError} from '@fluxer/errors/src/domains/invite/UnknownInviteError';
|
||||
import {UnknownPackError} from '@fluxer/errors/src/domains/pack/UnknownPackError';
|
||||
import type {ChannelPartialResponse} from '@fluxer/schema/src/domains/channel/ChannelSchemas';
|
||||
import type {GuildPartialResponse} from '@fluxer/schema/src/domains/guild/GuildResponseSchemas';
|
||||
import type {
|
||||
@@ -10,8 +9,6 @@ import type {
|
||||
GroupDmInviteResponse,
|
||||
GuildInviteMetadataResponse,
|
||||
GuildInviteResponse,
|
||||
PackInviteMetadataResponse,
|
||||
PackInviteResponse,
|
||||
} from '@fluxer/schema/src/domains/invite/InviteSchemas';
|
||||
import type {z} from 'zod';
|
||||
import type {ChannelID, GuildID} from '../BrandedTypes';
|
||||
@@ -20,8 +17,6 @@ import type {UserCacheService} from '../infrastructure/UserCacheService';
|
||||
import type {RequestCache} from '../middleware/RequestCacheMiddleware';
|
||||
import type {Channel} from '../models/Channel';
|
||||
import type {Invite} from '../models/Invite';
|
||||
import {mapPackToSummary} from '../pack/PackModel';
|
||||
import type {PackRepository} from '../pack/PackRepository';
|
||||
import {getCachedUserPartialResponse, getCachedUserPartialResponses} from '../user/UserCacheHelpers';
|
||||
|
||||
interface MapInviteToGuildInviteResponseParams {
|
||||
@@ -216,67 +211,3 @@ export async function mapInviteToGroupDmInviteMetadataResponse({
|
||||
max_uses: invite.maxUses,
|
||||
};
|
||||
}
|
||||
|
||||
interface MapInviteToPackInviteResponseParams {
|
||||
invite: Invite;
|
||||
userCacheService: UserCacheService;
|
||||
requestCache: RequestCache;
|
||||
packRepository: PackRepository;
|
||||
}
|
||||
|
||||
const buildPackInviteBase = async ({
|
||||
invite,
|
||||
userCacheService,
|
||||
requestCache,
|
||||
packRepository,
|
||||
}: MapInviteToPackInviteResponseParams): Promise<z.infer<typeof PackInviteResponse>> => {
|
||||
if (!invite.guildId) {
|
||||
throw new UnknownPackError();
|
||||
}
|
||||
const pack = await packRepository.getPack(invite.guildId);
|
||||
if (!pack) {
|
||||
throw new UnknownPackError();
|
||||
}
|
||||
const creator = await getCachedUserPartialResponse({
|
||||
userId: pack.creatorId,
|
||||
userCacheService,
|
||||
requestCache,
|
||||
});
|
||||
const inviter = invite.inviterId
|
||||
? await getCachedUserPartialResponse({
|
||||
userId: invite.inviterId,
|
||||
userCacheService,
|
||||
requestCache,
|
||||
})
|
||||
: null;
|
||||
const expiresAt = invite.maxAge > 0 ? new Date(invite.createdAt.getTime() + invite.maxAge * 1000) : null;
|
||||
return {
|
||||
code: invite.code,
|
||||
type: invite.type as typeof InviteTypes.EMOJI_PACK | typeof InviteTypes.STICKER_PACK,
|
||||
pack: {
|
||||
...mapPackToSummary(pack),
|
||||
creator,
|
||||
},
|
||||
inviter,
|
||||
expires_at: expiresAt?.toISOString() ?? null,
|
||||
temporary: invite.temporary,
|
||||
};
|
||||
};
|
||||
|
||||
export async function mapInviteToPackInviteResponse(
|
||||
params: MapInviteToPackInviteResponseParams,
|
||||
): Promise<z.infer<typeof PackInviteResponse>> {
|
||||
return buildPackInviteBase(params);
|
||||
}
|
||||
|
||||
export async function mapInviteToPackInviteMetadataResponse(
|
||||
params: MapInviteToPackInviteResponseParams,
|
||||
): Promise<z.infer<typeof PackInviteMetadataResponse>> {
|
||||
const baseResponse = await buildPackInviteBase(params);
|
||||
return {
|
||||
...baseResponse,
|
||||
created_at: params.invite.createdAt.toISOString(),
|
||||
uses: params.invite.uses,
|
||||
max_uses: params.invite.maxUses,
|
||||
};
|
||||
}
|
||||
@@ -1,14 +1,12 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import {InviteTypes} from '@fluxer/constants/src/ChannelConstants';
|
||||
import {UnknownPackError} from '@fluxer/errors/src/domains/pack/UnknownPackError';
|
||||
import type {ChannelPartialResponse} from '@fluxer/schema/src/domains/channel/ChannelSchemas';
|
||||
import type {GuildPartialResponse} from '@fluxer/schema/src/domains/guild/GuildResponseSchemas';
|
||||
import type {
|
||||
ChannelInviteCreateRequest,
|
||||
InviteMetadataResponseSchema,
|
||||
InviteResponseSchema,
|
||||
PackInviteCreateRequest,
|
||||
} from '@fluxer/schema/src/domains/invite/InviteSchemas';
|
||||
import type {ChannelID, GuildID, InviteCode, UserID} from '../BrandedTypes';
|
||||
import {mapChannelToPartialResponse} from '../channel/ChannelMappers';
|
||||
@@ -19,14 +17,11 @@ import type {UserCacheService} from '../infrastructure/UserCacheService';
|
||||
import type {RequestCache} from '../middleware/RequestCacheMiddleware';
|
||||
import type {Channel} from '../models/Channel';
|
||||
import type {Invite} from '../models/Invite';
|
||||
import type {PackRepository} from '../pack/PackRepository';
|
||||
import {
|
||||
mapInviteToGroupDmInviteMetadataResponse,
|
||||
mapInviteToGroupDmInviteResponse,
|
||||
mapInviteToGuildInviteMetadataResponse,
|
||||
mapInviteToGuildInviteResponse,
|
||||
mapInviteToPackInviteMetadataResponse,
|
||||
mapInviteToPackInviteResponse,
|
||||
} from './InviteModel';
|
||||
import type {InviteService} from './InviteService';
|
||||
|
||||
@@ -41,7 +36,6 @@ interface MappingHelpers {
|
||||
memberCount: number;
|
||||
presenceCount: number;
|
||||
}>;
|
||||
packRepository: PackRepository;
|
||||
gatewayService: IGatewayService;
|
||||
}
|
||||
|
||||
@@ -51,7 +45,6 @@ export class InviteRequestService {
|
||||
private readonly channelService: ChannelService,
|
||||
private readonly guildService: GuildService,
|
||||
private readonly gatewayService: IGatewayService,
|
||||
private readonly packRepository: PackRepository,
|
||||
private readonly userCacheService: UserCacheService,
|
||||
) {}
|
||||
|
||||
@@ -127,43 +120,6 @@ export class InviteRequestService {
|
||||
return this.mapInviteList(invites, params.requestCache);
|
||||
}
|
||||
|
||||
async listPackInvites(params: {
|
||||
userId: UserID;
|
||||
packId: GuildID;
|
||||
requestCache: RequestCache;
|
||||
}): Promise<Array<InviteMetadataResponseSchema>> {
|
||||
const invites = await this.inviteService.getPackInvitesSorted({
|
||||
userId: params.userId,
|
||||
packId: params.packId,
|
||||
});
|
||||
return this.mapInviteList(invites, params.requestCache);
|
||||
}
|
||||
|
||||
async createPackInvite(params: {
|
||||
inviterId: UserID;
|
||||
packId: GuildID;
|
||||
requestCache: RequestCache;
|
||||
data: PackInviteCreateRequest;
|
||||
}): Promise<InviteMetadataResponseSchema> {
|
||||
const pack = await this.packRepository.getPack(params.packId);
|
||||
if (!pack) {
|
||||
throw new UnknownPackError();
|
||||
}
|
||||
const {invite, isNew} = await this.inviteService.createPackInvite({
|
||||
inviterId: params.inviterId,
|
||||
packId: params.packId,
|
||||
packType: pack.type,
|
||||
maxUses: params.data.max_uses ?? 0,
|
||||
maxAge: params.data.max_age ?? 0,
|
||||
unique: params.data.unique ?? false,
|
||||
});
|
||||
const inviteData = await this.mapInviteMetadataResponse(invite, params.requestCache);
|
||||
if (isNew) {
|
||||
await this.inviteService.dispatchInviteCreate(invite, inviteData);
|
||||
}
|
||||
return inviteData;
|
||||
}
|
||||
|
||||
private createMappingHelpers(requestCache: RequestCache): MappingHelpers {
|
||||
return {
|
||||
userCacheService: this.userCacheService,
|
||||
@@ -176,7 +132,6 @@ export class InviteRequestService {
|
||||
await this.channelService.channelData.operations.getChannelMemberCount(channelId),
|
||||
getGuildResponse: async (guildId: GuildID) => await this.guildService.data.getPublicGuildData(guildId),
|
||||
getGuildCounts: async (guildId: GuildID) => await this.gatewayService.getGuildCounts(guildId),
|
||||
packRepository: this.packRepository,
|
||||
gatewayService: this.gatewayService,
|
||||
};
|
||||
}
|
||||
@@ -186,9 +141,6 @@ export class InviteRequestService {
|
||||
if (invite.type === InviteTypes.GROUP_DM) {
|
||||
return mapInviteToGroupDmInviteResponse({invite, ...helpers});
|
||||
}
|
||||
if (invite.type === InviteTypes.EMOJI_PACK || invite.type === InviteTypes.STICKER_PACK) {
|
||||
return mapInviteToPackInviteResponse({invite, ...helpers});
|
||||
}
|
||||
return mapInviteToGuildInviteResponse({invite, ...helpers});
|
||||
}
|
||||
|
||||
@@ -200,9 +152,6 @@ export class InviteRequestService {
|
||||
if (invite.type === InviteTypes.GROUP_DM) {
|
||||
return mapInviteToGroupDmInviteMetadataResponse({invite, ...helpers});
|
||||
}
|
||||
if (invite.type === InviteTypes.EMOJI_PACK || invite.type === InviteTypes.STICKER_PACK) {
|
||||
return mapInviteToPackInviteMetadataResponse({invite, ...helpers});
|
||||
}
|
||||
return mapInviteToGuildInviteMetadataResponse({invite, ...helpers});
|
||||
}
|
||||
|
||||
|
||||
@@ -12,12 +12,9 @@ import {MaxGuildInvitesError} from '@fluxer/errors/src/domains/guild/MaxGuildInv
|
||||
import {InvitesDisabledError} from '@fluxer/errors/src/domains/invite/InvitesDisabledError';
|
||||
import {TemporaryInviteRequiresPresenceError} from '@fluxer/errors/src/domains/invite/TemporaryInviteRequiresPresenceError';
|
||||
import {UnknownInviteError} from '@fluxer/errors/src/domains/invite/UnknownInviteError';
|
||||
import {PackAccessDeniedError} from '@fluxer/errors/src/domains/pack/PackAccessDeniedError';
|
||||
import {UnknownPackError} from '@fluxer/errors/src/domains/pack/UnknownPackError';
|
||||
import type {
|
||||
GroupDmInviteMetadataResponse,
|
||||
GuildInviteMetadataResponse,
|
||||
PackInviteMetadataResponse,
|
||||
} from '@fluxer/schema/src/domains/invite/InviteSchemas';
|
||||
import type {ApiContext} from '../ApiContext';
|
||||
import type {ChannelID, GuildID, InviteCode, UserID} from '../BrandedTypes';
|
||||
@@ -32,8 +29,6 @@ import {createLimitMatchContext} from '../limits/LimitMatchContextBuilder';
|
||||
import type {RequestCache} from '../middleware/RequestCacheMiddleware';
|
||||
import type {Channel} from '../models/Channel';
|
||||
import {Invite} from '../models/Invite';
|
||||
import type {PackRepository, PackType} from '../pack/PackRepository';
|
||||
import type {PackService} from '../pack/PackService';
|
||||
import * as RandomUtils from '../utils/RandomUtils';
|
||||
import type {IInviteRepository} from './IInviteRepository';
|
||||
|
||||
@@ -56,15 +51,6 @@ interface CreateInviteParams {
|
||||
temporary?: boolean;
|
||||
}
|
||||
|
||||
interface CreatePackInviteParams {
|
||||
inviterId: UserID;
|
||||
packId: GuildID;
|
||||
packType: PackType;
|
||||
maxUses: number;
|
||||
maxAge: number;
|
||||
unique: boolean;
|
||||
}
|
||||
|
||||
interface AcceptInviteParams {
|
||||
userId: UserID;
|
||||
inviteCode: InviteCode;
|
||||
@@ -108,11 +94,6 @@ interface ReusableInviteCriteria {
|
||||
type?: number;
|
||||
}
|
||||
|
||||
const PACK_TYPE_TO_INVITE_TYPE: Record<PackType, number> = {
|
||||
emoji: InviteTypes.EMOJI_PACK,
|
||||
sticker: InviteTypes.STICKER_PACK,
|
||||
};
|
||||
|
||||
export class InviteService {
|
||||
constructor(
|
||||
private readonly apiContext: ApiContext,
|
||||
@@ -120,8 +101,6 @@ export class InviteService {
|
||||
private guildService: GuildService,
|
||||
private channelService: ChannelService,
|
||||
private readonly guildAuditLogService: GuildAuditLogService,
|
||||
private readonly packRepository: PackRepository,
|
||||
private readonly packService: PackService,
|
||||
private readonly limitConfigService: LimitConfigService,
|
||||
) {}
|
||||
|
||||
@@ -255,51 +234,6 @@ export class InviteService {
|
||||
return {invite: newInvite, isNew: true};
|
||||
}
|
||||
|
||||
async createPackInvite({inviterId, packId, packType, maxUses, maxAge, unique}: CreatePackInviteParams): Promise<{
|
||||
invite: Invite;
|
||||
isNew: boolean;
|
||||
}> {
|
||||
const pack = await this.packRepository.getPack(packId);
|
||||
if (!pack) {
|
||||
throw new UnknownPackError();
|
||||
}
|
||||
if (pack.creatorId !== inviterId) {
|
||||
throw new PackAccessDeniedError();
|
||||
}
|
||||
if (pack.type !== packType) {
|
||||
throw new PackAccessDeniedError();
|
||||
}
|
||||
const allInvites = await this.inviteRepository.listGuildInvites(packId);
|
||||
const inviteType = PACK_TYPE_TO_INVITE_TYPE[packType];
|
||||
if (!unique) {
|
||||
const existingInvite = this.findReusableInvite(allInvites, {
|
||||
inviterId,
|
||||
maxUses,
|
||||
maxAge,
|
||||
type: inviteType,
|
||||
});
|
||||
if (existingInvite) {
|
||||
return {invite: existingInvite, isNew: false};
|
||||
}
|
||||
}
|
||||
const packInviteLimit = this.resolveInviteLimit(null);
|
||||
if (allInvites.length >= packInviteLimit) {
|
||||
throw new MaxGuildInvitesError(packInviteLimit);
|
||||
}
|
||||
const newInvite = await this.inviteRepository.create({
|
||||
code: this.createRandomInviteCode(),
|
||||
type: inviteType,
|
||||
guild_id: packId,
|
||||
channel_id: null,
|
||||
inviter_id: inviterId,
|
||||
uses: 0,
|
||||
max_uses: maxUses,
|
||||
max_age: maxAge,
|
||||
temporary: false,
|
||||
});
|
||||
return {invite: newInvite, isNew: true};
|
||||
}
|
||||
|
||||
async acceptInvite({userId, inviteCode, requestCache}: AcceptInviteParams): Promise<Invite> {
|
||||
const invite = await this.findInviteWithLowercaseFallback(inviteCode);
|
||||
if (!invite) throw new UnknownInviteError();
|
||||
@@ -334,11 +268,6 @@ export class InviteService {
|
||||
});
|
||||
return this.incrementInviteUses(invite, {deleteWhenExhausted: true});
|
||||
}
|
||||
if (invite.type === InviteTypes.EMOJI_PACK || invite.type === InviteTypes.STICKER_PACK) {
|
||||
if (!invite.guildId) throw new UnknownInviteError();
|
||||
await this.packService.installPack(userId, invite.guildId);
|
||||
return this.incrementInviteUses(invite, {deleteWhenExhausted: true});
|
||||
}
|
||||
if (!invite.guildId) throw new UnknownInviteError();
|
||||
const guild = await this.guildService.data.getGuildSystem(invite.guildId);
|
||||
if ((guild.disabledOperations & GuildOperations.INSTANT_INVITES) !== 0) {
|
||||
@@ -433,18 +362,6 @@ export class InviteService {
|
||||
async deleteInvite({userId, inviteCode}: DeleteInviteParams, auditLogReason?: string | null): Promise<void> {
|
||||
const invite = await this.findInviteWithLowercaseFallback(inviteCode);
|
||||
if (!invite) throw new UnknownInviteError();
|
||||
if (invite.type === InviteTypes.EMOJI_PACK || invite.type === InviteTypes.STICKER_PACK) {
|
||||
if (!invite.guildId) throw new UnknownInviteError();
|
||||
const pack = await this.packRepository.getPack(invite.guildId);
|
||||
if (!pack) {
|
||||
throw new UnknownPackError();
|
||||
}
|
||||
if (pack.creatorId !== userId) {
|
||||
throw new PackAccessDeniedError();
|
||||
}
|
||||
await this.inviteRepository.delete(invite.code);
|
||||
return;
|
||||
}
|
||||
if (invite.type === InviteTypes.GROUP_DM) {
|
||||
if (!invite.channelId) throw new UnknownInviteError();
|
||||
const channel = await this.channelService.channelData.operations.getChannel({
|
||||
@@ -497,25 +414,9 @@ export class InviteService {
|
||||
return invites.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
||||
}
|
||||
|
||||
async getPackInvitesSorted(params: {userId: UserID; packId: GuildID}): Promise<Array<Invite>> {
|
||||
const {userId, packId} = params;
|
||||
const pack = await this.packRepository.getPack(packId);
|
||||
if (!pack) {
|
||||
throw new UnknownPackError();
|
||||
}
|
||||
if (pack.creatorId !== userId) {
|
||||
throw new PackAccessDeniedError();
|
||||
}
|
||||
const invites = await this.inviteRepository.listGuildInvites(packId);
|
||||
const inviteType = PACK_TYPE_TO_INVITE_TYPE[pack.type];
|
||||
return invites
|
||||
.filter((invite) => invite.type === inviteType)
|
||||
.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
||||
}
|
||||
|
||||
async dispatchInviteCreate(
|
||||
invite: Invite,
|
||||
inviteData: GuildInviteMetadataResponse | GroupDmInviteMetadataResponse | PackInviteMetadataResponse,
|
||||
inviteData: GuildInviteMetadataResponse | GroupDmInviteMetadataResponse,
|
||||
): Promise<void> {
|
||||
if (invite.guildId && invite.type === InviteTypes.GUILD) {
|
||||
await this.apiContext.services.gateway.dispatchGuild({
|
||||
|
||||
Reference in new issue
Block a user