import { format } from "date-fns" import add from "date-fns/add" import { DateResolvable, Guild, GuildScheduledEvent, GuildScheduledEventCreateOptions } from "discord.js" import { findInScheduleTypes } from "../../helper/typeFind" import { Maybe } from "../../interfaces" import { RepetitonInfo, supportedSchedule } from "../../types/scheduledEventTypes" export const repetitionMarkerIsFound = (desc: string): boolean => desc.includes('$rep') export function createEventInGuild(guild: Guild, eventInfo: GuildScheduledEventCreateOptions): Promise { return guild.scheduledEvents.create(eventInfo) } export function getRepetitonInfo(description: string): RepetitonInfo { const lines = description.split(`\n`) const repetitionString = lines.find(x => x.startsWith('$rep:')) if (!repetitionString) throw new Error('Cant find repetition string') const schedule: supportedSchedule = determineSchedule(repetitionString) const { totalAmount, alreadyOccured } = determineRepetitionCount(repetitionString) const endDate = determineEndDate(repetitionString) return { totalAmount, alreadyOccured, schedule, endDate } } export function determineSchedule(repetitionLine: string): supportedSchedule { const segments = repetitionLine.split(':') const scheduleSegment = segments[1] const easilyKnownScheduleName = findInScheduleTypes(scheduleSegment) if (easilyKnownScheduleName) return easilyKnownScheduleName else throw new Error('Inferring schedule names is not yet supported') } export function determineRepetitionCount(description: string): { totalAmount: number; alreadyOccured: number } { const segments = description.split(':') const amountSegment = segments[2] const amounts = amountSegment.split('/') return { totalAmount: Number(amounts[1]) ?? 0, alreadyOccured: Number(amounts[0]) ?? 0 } } export function buildNewRepetitionString(repetitionInfo: RepetitonInfo) { if (repetitionInfo.endDate) return `$rep:${repetitionInfo.schedule}:${format(repetitionInfo.endDate, 'yyyy-MM-dd')}` return `$rep:${repetitionInfo.schedule}:${repetitionInfo.alreadyOccured + 1}/${repetitionInfo.totalAmount}` } export function addRepetitonStringToEventDescription(oldguildScheduledEvent: string, newRepetitonString: string): string | undefined { const lines = oldguildScheduledEvent.split(`\n`) const repLineIndex = lines.findIndex(x => x.startsWith('$rep:')) const newLines = lines.filter((_, index) => repLineIndex !== index) newLines.push(newRepetitonString) return newLines.join('\n') } export function getNewScheduledStart(oldguildScheduledEvent: GuildScheduledEvent<"SCHEDULED" | "ACTIVE" | "COMPLETED" | "CANCELED">, rInfo: RepetitonInfo): DateResolvable { const oldDate = oldguildScheduledEvent.scheduledStartAt let daysToAdd = 0 let monthsToAdd = 0 switch (rInfo.schedule) { case 'daily': daysToAdd = 1 break case 'weekly': daysToAdd = 7 break case 'monthly': monthsToAdd = 1 break default: throw new Error('No schedule found, cant add days') } const duration: Duration = { days: daysToAdd, months: monthsToAdd } const newDate = add(oldDate, duration) return newDate } function determineEndDate(description: string): Maybe { const segments = description.split(':') if (segments.length === 3) { // rep:sched:countOrDate const segmentValue = segments[2] if (segmentValue.includes('/')) { if (segmentValue.match(/\//g) || [].length !== 2) { return } } const dateValue = new Date(segmentValue) return dateValue } else if (segments.length === 4) { // rep:sched:count:date const segmentValue = segments[3] const dateValue = new Date(segmentValue) return dateValue } return }