- Introduced global command channel whitelist and blacklist in the GuildSettings model for improved command access control. - Implemented command gate logic in the command routing to handle channel and role restrictions, providing user feedback for denied commands. - Enhanced the CommandsManager component to support global rules and channel/role selection, improving the user interface for managing command permissions. - Updated localization files to include new keys for global command rules and related messages, ensuring clarity in user interactions.
669 lines
27 KiB
TypeScript
669 lines
27 KiB
TypeScript
import { z } from 'zod';
|
|
import {
|
|
SelfRoleBehaviorSchema,
|
|
SelfRoleEntrySchema,
|
|
SelfRoleModeSchema,
|
|
SuggestionStatusSchema,
|
|
TagResponseTypeSchema,
|
|
TicketModeSchema
|
|
} from './phase4.js';
|
|
import { SocialFeedTypeSchema } from './phase5.js';
|
|
|
|
/**
|
|
* Discord snowflake ID: 17-20 digit numeric string.
|
|
*/
|
|
export const SnowflakeSchema = z.string().regex(/^\d{17,20}$/, 'Invalid Discord ID');
|
|
|
|
/**
|
|
* Optional snowflake field for forms: accepts an empty string (treated as
|
|
* "unset"/cleared) or a valid snowflake. Kept as a plain string (rather than
|
|
* transformed to `undefined`) so that `JSON.stringify` does not silently
|
|
* drop the field when a user clears it in the dashboard - the API layer
|
|
* maps `''` to `null` when persisting.
|
|
*/
|
|
export const OptionalSnowflakeSchema = z.union([z.literal(''), SnowflakeSchema]);
|
|
|
|
function nonEmptyPatch<T extends z.ZodRawShape>(schema: z.ZodObject<T>) {
|
|
return schema.partial().refine((value) => Object.keys(value).length > 0, {
|
|
message: 'At least one field is required'
|
|
});
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Moderation
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const EscalationActionSchema = z.enum(['TIMEOUT', 'KICK', 'BAN']);
|
|
export type EscalationAction = z.infer<typeof EscalationActionSchema>;
|
|
|
|
export const EscalationRuleDashboardSchema = z.object({
|
|
id: z.string().optional(),
|
|
warnCount: z.number().int().positive(),
|
|
action: EscalationActionSchema,
|
|
durationMs: z.number().int().positive().nullable().optional(),
|
|
reason: z.string().max(500).nullable().optional(),
|
|
enabled: z.boolean().default(true)
|
|
});
|
|
export type EscalationRuleDashboard = z.infer<typeof EscalationRuleDashboardSchema>;
|
|
|
|
export const ModerationDashboardSchema = z.object({
|
|
moderationEnabled: z.boolean(),
|
|
escalations: z.array(EscalationRuleDashboardSchema)
|
|
});
|
|
export type ModerationDashboard = z.infer<typeof ModerationDashboardSchema>;
|
|
|
|
export const ModerationDashboardPatchSchema = z
|
|
.object({
|
|
moderationEnabled: z.boolean().optional(),
|
|
escalations: z.array(EscalationRuleDashboardSchema).optional()
|
|
})
|
|
.refine((value) => Object.keys(value).length > 0, { message: 'At least one field is required' });
|
|
export type ModerationDashboardPatch = z.infer<typeof ModerationDashboardPatchSchema>;
|
|
|
|
export const CaseDashboardSchema = z.object({
|
|
id: z.string(),
|
|
caseNumber: z.number().int(),
|
|
targetUserId: z.string(),
|
|
moderatorId: z.string(),
|
|
action: z.string(),
|
|
reason: z.string().nullable(),
|
|
createdAt: z.string(),
|
|
deletedAt: z.string().nullable()
|
|
});
|
|
export type CaseDashboard = z.infer<typeof CaseDashboardSchema>;
|
|
|
|
export const CaseListQuerySchema = z.object({
|
|
search: z.string().trim().max(100).optional(),
|
|
action: z.string().trim().max(50).optional(),
|
|
limit: z.coerce.number().int().positive().max(100).default(25)
|
|
});
|
|
export type CaseListQuery = z.infer<typeof CaseListQuerySchema>;
|
|
|
|
export const WarningDashboardSchema = z.object({
|
|
id: z.string(),
|
|
userId: z.string(),
|
|
moderatorId: z.string(),
|
|
reason: z.string().nullable(),
|
|
caseId: z.string().nullable(),
|
|
createdAt: z.string()
|
|
});
|
|
export type WarningDashboard = z.infer<typeof WarningDashboardSchema>;
|
|
|
|
export const WarningListQuerySchema = z.object({
|
|
userId: SnowflakeSchema.optional()
|
|
});
|
|
export type WarningListQuery = z.infer<typeof WarningListQuerySchema>;
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// AutoMod
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const AntiRaidActionSchema = z.enum(['LOCKDOWN']);
|
|
|
|
export const AutomodConfigDashboardSchema = z.object({
|
|
enabled: z.boolean(),
|
|
antiRaidEnabled: z.boolean(),
|
|
antiRaidJoinThreshold: z.number().int().positive(),
|
|
antiRaidWindowSeconds: z.number().int().positive(),
|
|
antiRaidAction: AntiRaidActionSchema,
|
|
antiNukeEnabled: z.boolean(),
|
|
antiNukeBanThreshold: z.number().int().positive(),
|
|
antiNukeChannelThreshold: z.number().int().positive(),
|
|
antiNukeWindowSeconds: z.number().int().positive(),
|
|
lockdownActive: z.boolean()
|
|
});
|
|
export type AutomodConfigDashboard = z.infer<typeof AutomodConfigDashboardSchema>;
|
|
|
|
export const AutomodConfigDashboardPatchSchema = nonEmptyPatch(AutomodConfigDashboardSchema);
|
|
export type AutomodConfigDashboardPatch = z.infer<typeof AutomodConfigDashboardPatchSchema>;
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Logging
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const LogEventTypeDashboardSchema = z.enum([
|
|
'MESSAGE_EDIT',
|
|
'MESSAGE_DELETE',
|
|
'MESSAGE_BULK_DELETE',
|
|
'MEMBER_JOIN',
|
|
'MEMBER_LEAVE',
|
|
'MEMBER_BAN',
|
|
'MEMBER_UNBAN',
|
|
'MEMBER_UPDATE',
|
|
'CHANNEL_CREATE',
|
|
'CHANNEL_DELETE',
|
|
'CHANNEL_UPDATE',
|
|
'VOICE_JOIN',
|
|
'VOICE_LEAVE',
|
|
'VOICE_MOVE',
|
|
'INVITE_CREATE',
|
|
'EMOJI_CREATE',
|
|
'EMOJI_UPDATE',
|
|
'EMOJI_DELETE',
|
|
'STICKER_CREATE',
|
|
'STICKER_UPDATE',
|
|
'STICKER_DELETE',
|
|
'THREAD_CREATE',
|
|
'THREAD_UPDATE',
|
|
'THREAD_DELETE',
|
|
'GUILD_UPDATE',
|
|
'MOD_ACTION'
|
|
]);
|
|
export type LogEventTypeDashboard = z.infer<typeof LogEventTypeDashboardSchema>;
|
|
|
|
export const LogChannelMappingSchema = z.object({
|
|
eventType: LogEventTypeDashboardSchema,
|
|
channelId: SnowflakeSchema
|
|
});
|
|
export type LogChannelMapping = z.infer<typeof LogChannelMappingSchema>;
|
|
|
|
export const LoggingConfigDashboardSchema = z.object({
|
|
enabled: z.boolean(),
|
|
ignoreBots: z.boolean(),
|
|
ignoredChannelIds: z.array(z.string()),
|
|
ignoredRoleIds: z.array(z.string()),
|
|
retentionDays: z.number().int().min(0).max(3650),
|
|
logChannels: z.array(LogChannelMappingSchema)
|
|
});
|
|
export type LoggingConfigDashboard = z.infer<typeof LoggingConfigDashboardSchema>;
|
|
|
|
export const LoggingConfigDashboardPatchSchema = z
|
|
.object({
|
|
enabled: z.boolean().optional(),
|
|
ignoreBots: z.boolean().optional(),
|
|
ignoredChannelIds: z.array(z.string()).optional(),
|
|
ignoredRoleIds: z.array(z.string()).optional(),
|
|
retentionDays: z.number().int().min(0).max(3650).optional(),
|
|
logChannels: z.array(LogChannelMappingSchema).optional()
|
|
})
|
|
.refine((value) => Object.keys(value).length > 0, { message: 'At least one field is required' });
|
|
export type LoggingConfigDashboardPatch = z.infer<typeof LoggingConfigDashboardPatchSchema>;
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Welcome & Leave
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const WelcomeMessageTypeDashboardSchema = z.enum(['TEXT', 'EMBED', 'IMAGE']);
|
|
|
|
export const WelcomeConfigDashboardSchema = z.object({
|
|
welcomeEnabled: z.boolean(),
|
|
leaveEnabled: z.boolean(),
|
|
welcomeChannelId: OptionalSnowflakeSchema,
|
|
leaveChannelId: OptionalSnowflakeSchema,
|
|
welcomeType: WelcomeMessageTypeDashboardSchema,
|
|
welcomeContent: z.string().max(2000).nullable().optional(),
|
|
welcomeEmbed: z.record(z.string(), z.unknown()).nullable().optional(),
|
|
leaveContent: z.string().max(2000).nullable().optional(),
|
|
leaveEmbed: z.record(z.string(), z.unknown()).nullable().optional(),
|
|
welcomeDmEnabled: z.boolean(),
|
|
welcomeDmContent: z.string().max(2000).nullable().optional(),
|
|
userAutoroleIds: z.array(z.string()),
|
|
botAutoroleIds: z.array(z.string()),
|
|
imageTitle: z.string().max(200).nullable().optional(),
|
|
imageSubtitle: z.string().max(200).nullable().optional()
|
|
});
|
|
export type WelcomeConfigDashboard = z.infer<typeof WelcomeConfigDashboardSchema>;
|
|
|
|
export const WelcomeConfigDashboardPatchSchema = nonEmptyPatch(WelcomeConfigDashboardSchema);
|
|
export type WelcomeConfigDashboardPatch = z.infer<typeof WelcomeConfigDashboardPatchSchema>;
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Verification
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const VerificationModeDashboardSchema = z.enum(['BUTTON', 'CAPTCHA']);
|
|
export const VerificationFailActionDashboardSchema = z.enum(['KICK', 'BAN', 'NONE']);
|
|
|
|
export const VerificationConfigDashboardSchema = z.object({
|
|
enabled: z.boolean(),
|
|
channelId: OptionalSnowflakeSchema,
|
|
verifiedRoleId: OptionalSnowflakeSchema,
|
|
unverifiedRoleId: OptionalSnowflakeSchema,
|
|
mode: VerificationModeDashboardSchema,
|
|
minAccountAgeDays: z.number().int().nonnegative(),
|
|
failAction: VerificationFailActionDashboardSchema
|
|
});
|
|
export type VerificationConfigDashboard = z.infer<typeof VerificationConfigDashboardSchema>;
|
|
|
|
export const VerificationConfigDashboardPatchSchema = nonEmptyPatch(VerificationConfigDashboardSchema);
|
|
export type VerificationConfigDashboardPatch = z.infer<typeof VerificationConfigDashboardPatchSchema>;
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Leveling
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const LevelUpModeDashboardSchema = z.enum(['CHANNEL', 'DM', 'OFF']);
|
|
|
|
export const LevelingConfigDashboardSchema = z.object({
|
|
enabled: z.boolean(),
|
|
textXpMin: z.number().int().positive(),
|
|
textXpMax: z.number().int().positive(),
|
|
textCooldownSeconds: z.number().int().positive(),
|
|
voiceXpPerMinute: z.number().int().nonnegative(),
|
|
noXpChannelIds: z.array(z.string()),
|
|
noXpRoleIds: z.array(z.string()),
|
|
roleMultipliers: z.record(z.string(), z.number().positive()),
|
|
channelMultipliers: z.record(z.string(), z.number().positive()),
|
|
levelUpMode: LevelUpModeDashboardSchema,
|
|
levelUpChannelId: OptionalSnowflakeSchema,
|
|
levelUpMessage: z.string().max(500).nullable().optional(),
|
|
stackRewards: z.boolean(),
|
|
cardAccentColor: z.string().regex(/^#[0-9a-fA-F]{6}$/),
|
|
cardBackgroundColor: z.string().regex(/^#[0-9a-fA-F]{6}$/)
|
|
});
|
|
export type LevelingConfigDashboard = z.infer<typeof LevelingConfigDashboardSchema>;
|
|
|
|
export const LevelingConfigDashboardPatchSchema = nonEmptyPatch(LevelingConfigDashboardSchema);
|
|
export type LevelingConfigDashboardPatch = z.infer<typeof LevelingConfigDashboardPatchSchema>;
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Economy
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const EconomyConfigDashboardSchema = z.object({
|
|
enabled: z.boolean(),
|
|
currencyName: z.string().min(1).max(32),
|
|
currencySymbol: z.string().min(1).max(8),
|
|
dailyAmount: z.number().int().nonnegative(),
|
|
weeklyAmount: z.number().int().nonnegative(),
|
|
workMin: z.number().int().nonnegative(),
|
|
workMax: z.number().int().nonnegative(),
|
|
workCooldownSeconds: z.number().int().positive(),
|
|
startingBalance: z.number().int().nonnegative()
|
|
});
|
|
export type EconomyConfigDashboard = z.infer<typeof EconomyConfigDashboardSchema>;
|
|
|
|
export const EconomyConfigDashboardPatchSchema = nonEmptyPatch(EconomyConfigDashboardSchema);
|
|
export type EconomyConfigDashboardPatch = z.infer<typeof EconomyConfigDashboardPatchSchema>;
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Fun
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const FunConfigDashboardSchema = z.object({
|
|
enabled: z.boolean(),
|
|
mediaEnabled: z.boolean()
|
|
});
|
|
export type FunConfigDashboard = z.infer<typeof FunConfigDashboardSchema>;
|
|
|
|
export const FunConfigDashboardPatchSchema = nonEmptyPatch(FunConfigDashboardSchema);
|
|
export type FunConfigDashboardPatch = z.infer<typeof FunConfigDashboardPatchSchema>;
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Tickets
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const TicketConfigDashboardSchema = z.object({
|
|
enabled: z.boolean(),
|
|
mode: TicketModeSchema,
|
|
categoryId: OptionalSnowflakeSchema,
|
|
logChannelId: OptionalSnowflakeSchema,
|
|
transcriptDm: z.boolean(),
|
|
inactivityHours: z.number().int().positive(),
|
|
ratingEnabled: z.boolean()
|
|
});
|
|
export type TicketConfigDashboard = z.infer<typeof TicketConfigDashboardSchema>;
|
|
|
|
export const TicketConfigDashboardPatchSchema = nonEmptyPatch(TicketConfigDashboardSchema);
|
|
export type TicketConfigDashboardPatch = z.infer<typeof TicketConfigDashboardPatchSchema>;
|
|
|
|
export const TicketCategoryDashboardSchema = z.object({
|
|
id: z.string().optional(),
|
|
name: z.string().min(1).max(100),
|
|
description: z.string().max(500).nullable().optional(),
|
|
emoji: z.string().max(32).nullable().optional(),
|
|
supportRoleIds: z.array(z.string())
|
|
});
|
|
export type TicketCategoryDashboard = z.infer<typeof TicketCategoryDashboardSchema>;
|
|
|
|
export const TicketCategoryDashboardCreateSchema = TicketCategoryDashboardSchema.omit({ id: true });
|
|
export type TicketCategoryDashboardCreate = z.infer<typeof TicketCategoryDashboardCreateSchema>;
|
|
|
|
export const TicketCategoryDashboardUpdateSchema = nonEmptyPatch(TicketCategoryDashboardCreateSchema);
|
|
export type TicketCategoryDashboardUpdate = z.infer<typeof TicketCategoryDashboardUpdateSchema>;
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Giveaways
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const GiveawayDashboardSchema = z.object({
|
|
id: z.string(),
|
|
guildId: z.string(),
|
|
channelId: z.string(),
|
|
messageId: z.string().nullable(),
|
|
prize: z.string(),
|
|
winnerCount: z.number().int(),
|
|
endsAt: z.string(),
|
|
requiredRoleId: z.string().nullable(),
|
|
requiredLevel: z.number().int().nullable(),
|
|
requiredMemberDays: z.number().int().nullable(),
|
|
paused: z.boolean(),
|
|
endedAt: z.string().nullable(),
|
|
winners: z.array(z.string()),
|
|
entrants: z.array(z.string()),
|
|
hostId: z.string(),
|
|
createdAt: z.string()
|
|
});
|
|
export type GiveawayDashboard = z.infer<typeof GiveawayDashboardSchema>;
|
|
|
|
export const GiveawayCreateDashboardSchema = z.object({
|
|
channelId: SnowflakeSchema,
|
|
prize: z.string().min(1).max(200),
|
|
winnerCount: z.number().int().positive().max(50),
|
|
endsAt: z.string().refine((value) => !Number.isNaN(Date.parse(value)), 'Invalid date'),
|
|
requiredRoleId: OptionalSnowflakeSchema.optional(),
|
|
requiredLevel: z.number().int().nonnegative().nullable().optional(),
|
|
requiredMemberDays: z.number().int().nonnegative().nullable().optional()
|
|
});
|
|
export type GiveawayCreateDashboard = z.infer<typeof GiveawayCreateDashboardSchema>;
|
|
|
|
export const GiveawayActionSchema = z.enum(['end', 'pause', 'unpause']);
|
|
export type GiveawayAction = z.infer<typeof GiveawayActionSchema>;
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Self Roles
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const SelfRolePanelDashboardSchema = z.object({
|
|
id: z.string().optional(),
|
|
channelId: SnowflakeSchema,
|
|
title: z.string().min(1).max(200),
|
|
description: z.string().max(1000).nullable().optional(),
|
|
mode: SelfRoleModeSchema,
|
|
behavior: SelfRoleBehaviorSchema,
|
|
roles: z.array(SelfRoleEntrySchema).min(1),
|
|
expiresAt: z.string().nullable().optional()
|
|
});
|
|
export type SelfRolePanelDashboard = z.infer<typeof SelfRolePanelDashboardSchema>;
|
|
|
|
export const SelfRolePanelDashboardCreateSchema = SelfRolePanelDashboardSchema.omit({ id: true });
|
|
export type SelfRolePanelDashboardCreate = z.infer<typeof SelfRolePanelDashboardCreateSchema>;
|
|
|
|
export const SelfRolePanelDashboardUpdateSchema = nonEmptyPatch(SelfRolePanelDashboardCreateSchema);
|
|
export type SelfRolePanelDashboardUpdate = z.infer<typeof SelfRolePanelDashboardUpdateSchema>;
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Tags
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const TagDashboardSchema = z.object({
|
|
id: z.string().optional(),
|
|
name: z.string().min(1).max(50),
|
|
content: z.string().max(2000).nullable().optional(),
|
|
responseType: TagResponseTypeSchema,
|
|
triggerWord: z.string().max(100).nullable().optional(),
|
|
allowedRoleIds: z.array(z.string()),
|
|
allowedChannelIds: z.array(z.string())
|
|
});
|
|
export type TagDashboard = z.infer<typeof TagDashboardSchema>;
|
|
|
|
export const TagDashboardCreateSchema = TagDashboardSchema.omit({ id: true });
|
|
export type TagDashboardCreate = z.infer<typeof TagDashboardCreateSchema>;
|
|
|
|
export const TagDashboardUpdateSchema = nonEmptyPatch(TagDashboardCreateSchema);
|
|
export type TagDashboardUpdate = z.infer<typeof TagDashboardUpdateSchema>;
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Starboard
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const StarboardConfigDashboardSchema = z.object({
|
|
enabled: z.boolean(),
|
|
channelId: OptionalSnowflakeSchema,
|
|
emoji: z.string().min(1).max(32),
|
|
threshold: z.number().int().positive(),
|
|
allowSelfStar: z.boolean(),
|
|
ignoredChannelIds: z.array(z.string())
|
|
});
|
|
export type StarboardConfigDashboard = z.infer<typeof StarboardConfigDashboardSchema>;
|
|
|
|
export const StarboardConfigDashboardPatchSchema = nonEmptyPatch(StarboardConfigDashboardSchema);
|
|
export type StarboardConfigDashboardPatch = z.infer<typeof StarboardConfigDashboardPatchSchema>;
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Suggestions
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const SuggestionConfigDashboardSchema = z.object({
|
|
enabled: z.boolean(),
|
|
openChannelId: OptionalSnowflakeSchema,
|
|
approvedChannelId: OptionalSnowflakeSchema,
|
|
deniedChannelId: OptionalSnowflakeSchema,
|
|
createThread: z.boolean()
|
|
});
|
|
export type SuggestionConfigDashboard = z.infer<typeof SuggestionConfigDashboardSchema>;
|
|
|
|
export const SuggestionConfigDashboardPatchSchema = nonEmptyPatch(SuggestionConfigDashboardSchema);
|
|
export type SuggestionConfigDashboardPatch = z.infer<typeof SuggestionConfigDashboardPatchSchema>;
|
|
|
|
export const SuggestionDashboardSchema = z.object({
|
|
id: z.string(),
|
|
authorId: z.string(),
|
|
content: z.string(),
|
|
status: SuggestionStatusSchema,
|
|
upvotes: z.number().int(),
|
|
downvotes: z.number().int(),
|
|
staffReason: z.string().nullable(),
|
|
createdAt: z.string()
|
|
});
|
|
export type SuggestionDashboard = z.infer<typeof SuggestionDashboardSchema>;
|
|
|
|
export const SuggestionListQuerySchema = z.object({
|
|
status: SuggestionStatusSchema.optional(),
|
|
limit: z.coerce.number().int().positive().max(100).default(25)
|
|
});
|
|
export type SuggestionListQuery = z.infer<typeof SuggestionListQuerySchema>;
|
|
|
|
export const SuggestionActionSchema = z.object({
|
|
status: SuggestionStatusSchema,
|
|
staffReason: z.string().max(500).nullable().optional()
|
|
});
|
|
export type SuggestionAction = z.infer<typeof SuggestionActionSchema>;
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Birthdays
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const BirthdayConfigDashboardSchema = z.object({
|
|
enabled: z.boolean(),
|
|
channelId: OptionalSnowflakeSchema,
|
|
roleId: OptionalSnowflakeSchema,
|
|
message: z.string().max(500).nullable().optional(),
|
|
timezone: z.string().min(1).max(64)
|
|
});
|
|
export type BirthdayConfigDashboard = z.infer<typeof BirthdayConfigDashboardSchema>;
|
|
|
|
export const BirthdayConfigDashboardPatchSchema = nonEmptyPatch(BirthdayConfigDashboardSchema);
|
|
export type BirthdayConfigDashboardPatch = z.infer<typeof BirthdayConfigDashboardPatchSchema>;
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Temp-Voice
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const TempVoiceConfigDashboardSchema = z.object({
|
|
enabled: z.boolean(),
|
|
hubChannelId: OptionalSnowflakeSchema,
|
|
categoryId: OptionalSnowflakeSchema,
|
|
defaultName: z.string().min(1).max(100),
|
|
defaultLimit: z.number().int().nonnegative().max(99)
|
|
});
|
|
export type TempVoiceConfigDashboard = z.infer<typeof TempVoiceConfigDashboardSchema>;
|
|
|
|
export const TempVoiceConfigDashboardPatchSchema = nonEmptyPatch(TempVoiceConfigDashboardSchema);
|
|
export type TempVoiceConfigDashboardPatch = z.infer<typeof TempVoiceConfigDashboardPatchSchema>;
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Server Stats
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const StatsConfigDashboardSchema = z.object({
|
|
enabled: z.boolean(),
|
|
membersChannelId: OptionalSnowflakeSchema,
|
|
onlineChannelId: OptionalSnowflakeSchema,
|
|
boostsChannelId: OptionalSnowflakeSchema,
|
|
membersTemplate: z.string().min(1).max(100),
|
|
onlineTemplate: z.string().min(1).max(100),
|
|
boostsTemplate: z.string().min(1).max(100)
|
|
});
|
|
export type StatsConfigDashboard = z.infer<typeof StatsConfigDashboardSchema>;
|
|
|
|
export const StatsConfigDashboardPatchSchema = nonEmptyPatch(StatsConfigDashboardSchema);
|
|
export type StatsConfigDashboardPatch = z.infer<typeof StatsConfigDashboardPatchSchema>;
|
|
|
|
export const ActivityStatSummarySchema = z.object({
|
|
messageCount: z.number().int().nonnegative(),
|
|
voiceMinutes: z.number().int().nonnegative(),
|
|
activeUserCount: z.number().int().nonnegative()
|
|
});
|
|
export type ActivityStatSummary = z.infer<typeof ActivityStatSummarySchema>;
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Social Feeds
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const SocialFeedDashboardSchema = z.object({
|
|
id: z.string().optional(),
|
|
type: SocialFeedTypeSchema,
|
|
sourceId: z.string().min(1).max(200),
|
|
channelId: SnowflakeSchema,
|
|
rolePingId: OptionalSnowflakeSchema.optional(),
|
|
template: z.string().max(500).nullable().optional(),
|
|
enabled: z.boolean()
|
|
});
|
|
export type SocialFeedDashboard = z.infer<typeof SocialFeedDashboardSchema>;
|
|
|
|
export const SocialFeedDashboardCreateSchema = SocialFeedDashboardSchema.omit({ id: true });
|
|
export type SocialFeedDashboardCreate = z.infer<typeof SocialFeedDashboardCreateSchema>;
|
|
|
|
export const SocialFeedDashboardUpdateSchema = nonEmptyPatch(SocialFeedDashboardCreateSchema);
|
|
export type SocialFeedDashboardUpdate = z.infer<typeof SocialFeedDashboardUpdateSchema>;
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Scheduler
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const ScheduledMessageDashboardSchema = z.object({
|
|
id: z.string(),
|
|
channelId: z.string(),
|
|
creatorId: z.string(),
|
|
content: z.string().nullable(),
|
|
rolePingId: z.string().nullable(),
|
|
cron: z.string().nullable(),
|
|
runAt: z.string().nullable(),
|
|
enabled: z.boolean(),
|
|
createdAt: z.string()
|
|
});
|
|
export type ScheduledMessageDashboard = z.infer<typeof ScheduledMessageDashboardSchema>;
|
|
|
|
export const ScheduledMessageDashboardCreateSchema = z
|
|
.object({
|
|
channelId: SnowflakeSchema,
|
|
content: z.string().max(2000).nullable().optional(),
|
|
rolePingId: OptionalSnowflakeSchema.optional(),
|
|
cron: z.string().min(1).max(100).nullable().optional(),
|
|
runAt: z
|
|
.string()
|
|
.refine((value) => !Number.isNaN(Date.parse(value)), 'Invalid date')
|
|
.nullable()
|
|
.optional()
|
|
})
|
|
.refine((value) => Boolean(value.cron?.trim()) || Boolean(value.runAt), {
|
|
message: 'Either cron or runAt is required'
|
|
})
|
|
.refine((value) => Boolean(value.content?.trim()), {
|
|
message: 'Content is required'
|
|
});
|
|
export type ScheduledMessageDashboardCreate = z.infer<typeof ScheduledMessageDashboardCreateSchema>;
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Guild Backups
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const GuildBackupDashboardSchema = z.object({
|
|
id: z.string(),
|
|
name: z.string(),
|
|
createdById: z.string(),
|
|
createdAt: z.string(),
|
|
roleCount: z.number().int().nonnegative(),
|
|
channelCount: z.number().int().nonnegative()
|
|
});
|
|
export type GuildBackupDashboard = z.infer<typeof GuildBackupDashboardSchema>;
|
|
|
|
export const GuildBackupCreateDashboardSchema = z.object({
|
|
name: z.string().min(1).max(100)
|
|
});
|
|
export type GuildBackupCreateDashboard = z.infer<typeof GuildBackupCreateDashboardSchema>;
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Command Overrides
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const CommandOverrideDashboardSchema = z.object({
|
|
commandName: z.string().min(1).max(100),
|
|
enabled: z.boolean(),
|
|
allowedRoleIds: z.array(SnowflakeSchema),
|
|
deniedRoleIds: z.array(SnowflakeSchema),
|
|
allowedChannelIds: z.array(SnowflakeSchema),
|
|
deniedChannelIds: z.array(SnowflakeSchema),
|
|
cooldownSeconds: z.number().int().nonnegative().nullable()
|
|
});
|
|
export type CommandOverrideDashboard = z.infer<typeof CommandOverrideDashboardSchema>;
|
|
|
|
export const CommandOverrideDashboardUpsertSchema = z.object({
|
|
commandName: z.string().min(1).max(100),
|
|
enabled: z.boolean().default(true),
|
|
allowedRoleIds: z.array(SnowflakeSchema).default([]),
|
|
deniedRoleIds: z.array(SnowflakeSchema).default([]),
|
|
allowedChannelIds: z.array(SnowflakeSchema).default([]),
|
|
deniedChannelIds: z.array(SnowflakeSchema).default([]),
|
|
cooldownSeconds: z.number().int().nonnegative().nullable().optional()
|
|
});
|
|
export type CommandOverrideDashboardUpsert = z.infer<typeof CommandOverrideDashboardUpsertSchema>;
|
|
|
|
export const CommandGlobalRulesSchema = z.object({
|
|
allowedChannelIds: z.array(SnowflakeSchema),
|
|
deniedChannelIds: z.array(SnowflakeSchema)
|
|
});
|
|
export type CommandGlobalRules = z.infer<typeof CommandGlobalRulesSchema>;
|
|
|
|
export const CommandGlobalRulesPatchSchema = CommandGlobalRulesSchema.partial().refine(
|
|
(value) => Object.keys(value).length > 0,
|
|
{ message: 'At least one field is required' }
|
|
);
|
|
export type CommandGlobalRulesPatch = z.infer<typeof CommandGlobalRulesPatchSchema>;
|
|
|
|
export const DiscordChannelOptionSchema = z.object({
|
|
id: SnowflakeSchema,
|
|
name: z.string(),
|
|
type: z.number().int(),
|
|
parentId: SnowflakeSchema.nullable().optional()
|
|
});
|
|
export type DiscordChannelOption = z.infer<typeof DiscordChannelOptionSchema>;
|
|
|
|
export const DiscordRoleOptionSchema = z.object({
|
|
id: SnowflakeSchema,
|
|
name: z.string(),
|
|
color: z.number().int(),
|
|
position: z.number().int()
|
|
});
|
|
export type DiscordRoleOption = z.infer<typeof DiscordRoleOptionSchema>;
|
|
|
|
/**
|
|
* Known slash command names, aggregated from every module's
|
|
* `command-definitions.ts` (`SlashCommandBuilder#setName`). Used by the
|
|
* dashboard's command-management page to list overridable commands without
|
|
* requiring a live bot connection.
|
|
*/
|
|
export const KNOWN_COMMAND_NAMES = [
|
|
'ban', 'unban', 'kick', 'timeout', 'untimeout', 'warn', 'purge', 'slowmode', 'lock', 'unlock',
|
|
'nick', 'case', 'modnote', 'automod', 'welcome', 'verify', 'rank', 'leaderboard', 'xp', 'balance',
|
|
'daily', 'weekly', 'work', 'pay', 'gamble', 'slots', 'blackjack', 'coinflip', 'shop', 'inventory',
|
|
'eco', 'userinfo', 'serverinfo', 'roleinfo', 'channelinfo', 'avatar', 'banner', 'poll', 'remindme',
|
|
'reminders', 'afk', 'emoji', 'sticker', 'timestamp', 'snipe', 'editsnipe', 'embed', '8ball', 'dice',
|
|
'flip', 'rps', 'choose', 'trivia', 'tictactoe', 'connect4', 'hangman', 'meme', 'cat', 'dog',
|
|
'giveaway', 'ticket', 'selfroles', 'tag', 'starboard', 'suggest', 'suggestion', 'birthday', 'voice',
|
|
'stats', 'invites', 'feeds', 'schedule', 'announce', 'backup', 'help', 'info', 'invite', 'support',
|
|
'privacy', 'gdpr'
|
|
] as const;
|
|
export type KnownCommandName = (typeof KNOWN_COMMAND_NAMES)[number];
|