refactoring and adding capability to recognize more schedules
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				ci/woodpecker/push/woodpecker Pipeline failed
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	ci/woodpecker/push/woodpecker Pipeline failed
				
			This commit is contained in:
		@@ -2,7 +2,7 @@ FROM node:alpine as Build
 | 
				
			|||||||
ENV NODE_ENV=production
 | 
					ENV NODE_ENV=production
 | 
				
			||||||
WORKDIR /app
 | 
					WORKDIR /app
 | 
				
			||||||
 | 
					
 | 
				
			||||||
COPY [ "yarn.lock", "package.json", "index.ts", "tsconfig.json", "./" ]
 | 
					COPY [ "yarn.lock", "package.json", "index.ts",  "./" ]
 | 
				
			||||||
COPY server ./server
 | 
					COPY server ./server
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RUN yarn install --production
 | 
					RUN yarn install --production
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,107 +1,18 @@
 | 
				
			|||||||
import { add } from "date-fns"
 | 
					import { GuildScheduledEvent } from "discord.js"
 | 
				
			||||||
import { DateResolvable, GuildScheduledEvent, GuildScheduledEventCreateOptions, InternalDiscordGatewayAdapterCreator } from "discord.js"
 | 
					import { handleRepeatingEvent } from "../handler/repeatingEvents/repeatingEvents.controller"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const repetitionMarkerIsFound = (desc: string): boolean => desc.includes('$rep')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const name = 'guildScheduledEventUpdate'
 | 
					export const name = 'guildScheduledEventUpdate'
 | 
				
			||||||
export function execute(oldguildScheduledEvent: GuildScheduledEvent, newguildScheduledEvent: GuildScheduledEvent) {
 | 
					export function execute(oldguildScheduledEvent: GuildScheduledEvent, newguildScheduledEvent: GuildScheduledEvent) {
 | 
				
			||||||
	console.dir(oldguildScheduledEvent)
 | 
						console.dir(oldguildScheduledEvent)
 | 
				
			||||||
	console.dir(newguildScheduledEvent)
 | 
						console.dir(newguildScheduledEvent)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (oldguildScheduledEvent.description && repetitionMarkerFound(oldguildScheduledEvent.description)) {
 | 
						if (oldguildScheduledEvent.description && repetitionMarkerIsFound(oldguildScheduledEvent.description)) {
 | 
				
			||||||
		// valid repeating event
 | 
							// valid repeating event
 | 
				
			||||||
		if (newguildScheduledEvent.status === 'COMPLETED') {
 | 
							if (newguildScheduledEvent.status === 'COMPLETED')
 | 
				
			||||||
			const repetitionInfo = getRepetitonInfo(oldguildScheduledEvent.description)
 | 
								handleRepeatingEvent(oldguildScheduledEvent, newguildScheduledEvent)
 | 
				
			||||||
			if (needsToBeRepeated(repetitionInfo)) {
 | 
					 | 
				
			||||||
				try {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
					const newRepetitonString = buildNewRepetitionString(repetitionInfo)
 | 
					 | 
				
			||||||
					const newEventOptions: GuildScheduledEventCreateOptions = {
 | 
					 | 
				
			||||||
						name: oldguildScheduledEvent.name,
 | 
					 | 
				
			||||||
						description: addRepetitonStringToEventDescription(oldguildScheduledEvent.description, newRepetitonString),
 | 
					 | 
				
			||||||
						scheduledStartTime: getNewScheduledStart(oldguildScheduledEvent, repetitionInfo),
 | 
					 | 
				
			||||||
						privacyLevel: oldguildScheduledEvent.privacyLevel,
 | 
					 | 
				
			||||||
						entityType: oldguildScheduledEvent.entityType,
 | 
					 | 
				
			||||||
						channel: oldguildScheduledEvent.channel?.id,
 | 
					 | 
				
			||||||
						reason: 'Repetition'
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
					newguildScheduledEvent.guild?.scheduledEvents.create(newEventOptions)
 | 
					 | 
				
			||||||
				} catch (err) {
 | 
					 | 
				
			||||||
					console.error(err)
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
interface RepetitonInfo {
 | 
					 | 
				
			||||||
	startDate?: Date, // If defined will take precedence over repetitonAmount
 | 
					 | 
				
			||||||
	endDate?: Date,// If defined will take precedence over repetitonAmount
 | 
					 | 
				
			||||||
	totalAmount: number,
 | 
					 | 
				
			||||||
	alreadyOccured: number,
 | 
					 | 
				
			||||||
	schedule: supportedSchedules
 | 
					 | 
				
			||||||
	numberOfDays?: number
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
type supportedSchedules = 'daily' | 'weekly' | 'monthly' | 'everyTwoWeeks' | 'everyNDays'
 | 
					 | 
				
			||||||
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: supportedSchedules = determineSchedule(repetitionString)
 | 
					 | 
				
			||||||
	const { totalAmount, alreadyOccured } = determineRepetitionCount(repetitionString)
 | 
					 | 
				
			||||||
	return {
 | 
					 | 
				
			||||||
		totalAmount,
 | 
					 | 
				
			||||||
		alreadyOccured,
 | 
					 | 
				
			||||||
		schedule
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
function repetitionMarkerFound(description: string): boolean {
 | 
					 | 
				
			||||||
	return description.includes('$rep:')
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function needsToBeRepeated(rInfo: RepetitonInfo): boolean {
 | 
					 | 
				
			||||||
	return rInfo.alreadyOccured < rInfo.totalAmount
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function determineSchedule(description: string): supportedSchedules {
 | 
					 | 
				
			||||||
	return 'daily'
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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 }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function buildNewRepetitionString(repetitionInfo: RepetitonInfo) {
 | 
					 | 
				
			||||||
	return `$rep:${repetitionInfo.schedule}:${repetitionInfo.alreadyOccured + 1}/${repetitionInfo.totalAmount}`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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')
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function getNewScheduledStart(oldguildScheduledEvent: GuildScheduledEvent<"SCHEDULED" | "ACTIVE" | "COMPLETED" | "CANCELED">, rInfo: RepetitonInfo): DateResolvable {
 | 
					 | 
				
			||||||
	const oldDate = oldguildScheduledEvent.scheduledStartAt
 | 
					 | 
				
			||||||
	let daysToAdd = 0
 | 
					 | 
				
			||||||
	switch (rInfo.schedule) {
 | 
					 | 
				
			||||||
		case 'daily':
 | 
					 | 
				
			||||||
			daysToAdd = 1
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		case 'weekly':
 | 
					 | 
				
			||||||
			daysToAdd = 7
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			throw new Error('No schedule found, cant add days')
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	const duration: Duration = {
 | 
					 | 
				
			||||||
		days: daysToAdd
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	const newDate = add(oldDate, duration)
 | 
					 | 
				
			||||||
	return newDate
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										68
									
								
								server/handler/repeatingEvents/helper.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								server/handler/repeatingEvents/helper.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
				
			|||||||
 | 
					import add from "date-fns/add"
 | 
				
			||||||
 | 
					import { DateResolvable, GuildScheduledEvent } from "discord.js"
 | 
				
			||||||
 | 
					import { findInScheduleTypes } from "../../helper/typeFind"
 | 
				
			||||||
 | 
					import { RepetitonInfo, supportedSchedule } from "../../types/scheduledEventTypes"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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)
 | 
				
			||||||
 | 
						return {
 | 
				
			||||||
 | 
							totalAmount,
 | 
				
			||||||
 | 
							alreadyOccured,
 | 
				
			||||||
 | 
							schedule
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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) {
 | 
				
			||||||
 | 
						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
 | 
				
			||||||
 | 
						switch (rInfo.schedule) {
 | 
				
			||||||
 | 
							case 'daily':
 | 
				
			||||||
 | 
								daysToAdd = 1
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							case 'weekly':
 | 
				
			||||||
 | 
								daysToAdd = 7
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								throw new Error('No schedule found, cant add days')
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						const duration: Duration = {
 | 
				
			||||||
 | 
							days: daysToAdd
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						const newDate = add(oldDate, duration)
 | 
				
			||||||
 | 
						return newDate
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										28
									
								
								server/handler/repeatingEvents/repeatingEvents.controller.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								server/handler/repeatingEvents/repeatingEvents.controller.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
				
			|||||||
 | 
					import { GuildScheduledEvent, GuildScheduledEventCreateOptions } from "discord.js"
 | 
				
			||||||
 | 
					import { RepetitonInfo } from "../../types/scheduledEventTypes"
 | 
				
			||||||
 | 
					import { addRepetitonStringToEventDescription, buildNewRepetitionString, getNewScheduledStart, getRepetitonInfo } from "./helper"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const needsToBeRepeated = (rInfo: RepetitonInfo): boolean => rInfo.alreadyOccured < rInfo.totalAmount
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function handleRepeatingEvent(oldguildScheduledEvent: GuildScheduledEvent, newguildScheduledEvent: GuildScheduledEvent) {
 | 
				
			||||||
 | 
						if (!oldguildScheduledEvent.description) throw new Error('Event has no description -> cant handle this')
 | 
				
			||||||
 | 
						const repetitionInfo = getRepetitonInfo(oldguildScheduledEvent.description)
 | 
				
			||||||
 | 
						if (needsToBeRepeated(repetitionInfo)) {
 | 
				
			||||||
 | 
							try {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								const newRepetitonString = buildNewRepetitionString(repetitionInfo)
 | 
				
			||||||
 | 
								const newEventOptions: GuildScheduledEventCreateOptions = {
 | 
				
			||||||
 | 
									name: oldguildScheduledEvent.name,
 | 
				
			||||||
 | 
									description: addRepetitonStringToEventDescription(oldguildScheduledEvent.description, newRepetitonString),
 | 
				
			||||||
 | 
									scheduledStartTime: getNewScheduledStart(oldguildScheduledEvent, repetitionInfo),
 | 
				
			||||||
 | 
									privacyLevel: oldguildScheduledEvent.privacyLevel,
 | 
				
			||||||
 | 
									entityType: oldguildScheduledEvent.entityType,
 | 
				
			||||||
 | 
									channel: oldguildScheduledEvent.channel?.id,
 | 
				
			||||||
 | 
									reason: 'Repetition'
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								newguildScheduledEvent.guild?.scheduledEvents.create(newEventOptions)
 | 
				
			||||||
 | 
							} catch (err) {
 | 
				
			||||||
 | 
								console.error(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										13
									
								
								server/helper/typeFind.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								server/helper/typeFind.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					import { scheduleNames, supportedSchedule } from "../types/scheduledEventTypes";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function findInScheduleTypes(inputString: string): supportedSchedule {
 | 
				
			||||||
 | 
						const maybeScheduleName: unknown = JSON.parse(`"${inputString.toLowerCase()}"`);
 | 
				
			||||||
 | 
						const scheduleName = scheduleNames.find((validName: supportedSchedule) => validName === maybeScheduleName);
 | 
				
			||||||
 | 
						if (scheduleName) {
 | 
				
			||||||
 | 
							// `sheepName` comes from the list of `sheepNames` so the compiler is happy.
 | 
				
			||||||
 | 
							return scheduleName;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						throw new Error('That is not a schedule name.');
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										11
									
								
								server/types/scheduledEventTypes.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								server/types/scheduledEventTypes.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					export interface RepetitonInfo {
 | 
				
			||||||
 | 
						startDate?: Date, // If defined will take precedence over repetitonAmount
 | 
				
			||||||
 | 
						endDate?: Date,// If defined will take precedence over repetitonAmount
 | 
				
			||||||
 | 
						totalAmount: number,
 | 
				
			||||||
 | 
						alreadyOccured: number,
 | 
				
			||||||
 | 
						schedule: supportedSchedule
 | 
				
			||||||
 | 
						numberOfDays?: number
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					export const scheduleNames = ['daily', 'weekly', 'monthly', 'everyTwoWeeks', 'everyNDays']
 | 
				
			||||||
 | 
					export type supportedSchedule = typeof scheduleNames[number]
 | 
				
			||||||
							
								
								
									
										35
									
								
								tests/repetition.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								tests/repetition.test.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
				
			|||||||
 | 
					import { findInScheduleTypes } from '../server/helper/typeFind'
 | 
				
			||||||
 | 
					import { supportedSchedule } from '../server/types/scheduledEventTypes'
 | 
				
			||||||
 | 
					import { getRepetitonInfo } from '../server/handler/repeatingEvents/helper'
 | 
				
			||||||
 | 
					import { RepetitonInfo } from '../server/types/scheduledEventTypes'
 | 
				
			||||||
 | 
					describe('Schedule names are parsed correctly', () => {
 | 
				
			||||||
 | 
						const dailyValue: supportedSchedule = 'daily'
 | 
				
			||||||
 | 
						const weeklyValue: supportedSchedule = 'weekly'
 | 
				
			||||||
 | 
						const monthlyValue: supportedSchedule = 'monthly'
 | 
				
			||||||
 | 
						test('Easy schedule names', () => {
 | 
				
			||||||
 | 
							expect(findInScheduleTypes('daily')).toEqual(dailyValue)
 | 
				
			||||||
 | 
							expect(findInScheduleTypes('weekly')).toEqual(weeklyValue)
 | 
				
			||||||
 | 
							expect(findInScheduleTypes('monthly')).toEqual(monthlyValue)
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						test('Medium schedule names', () => {
 | 
				
			||||||
 | 
							expect(findInScheduleTypes('Daily')).toEqual(dailyValue)
 | 
				
			||||||
 | 
							expect(findInScheduleTypes('Weekly')).toEqual(weeklyValue)
 | 
				
			||||||
 | 
							expect(findInScheduleTypes('Monthly')).toEqual(monthlyValue)
 | 
				
			||||||
 | 
							expect(findInScheduleTypes('DAILY')).toEqual(dailyValue)
 | 
				
			||||||
 | 
							expect(findInScheduleTypes('WEEKLy')).toEqual(weeklyValue)
 | 
				
			||||||
 | 
							expect(findInScheduleTypes('MONTHly')).toEqual(monthlyValue)
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					describe('Parsing of Repetition Info from Description String',()=>{
 | 
				
			||||||
 | 
						test('Happy Path',()=>{
 | 
				
			||||||
 | 
							const inputString = '$rep:daily:1/3'
 | 
				
			||||||
 | 
							const expectedInfo: RepetitonInfo = {
 | 
				
			||||||
 | 
								totalAmount: 3,
 | 
				
			||||||
 | 
								alreadyOccured: 1,
 | 
				
			||||||
 | 
								schedule: 'daily'
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							expect(getRepetitonInfo(inputString)).toEqual(expectedInfo)
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	"extends":"@tsconfig/recommended/tsconfig.json",
 | 
						"extends":"@tsconfig/recommended/tsconfig.json",
 | 
				
			||||||
 | 
						"exclude":["node_modules","**/*.test.ts"],
 | 
				
			||||||
  "compilerOptions": {
 | 
					  "compilerOptions": {
 | 
				
			||||||
    /* Basic Options */
 | 
					    /* Basic Options */
 | 
				
			||||||
    "target": "es6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */,
 | 
					    "target": "es6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */,
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user