From a184f20c19e1e9b50a51e440b9fe0712f5271db0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82?= Date: Mon, 15 May 2023 11:11:02 +0200 Subject: [PATCH] chore(application-generic): moved the timed digest delay calculations to the main repo --- .gitmodules | 3 - enterprise/packages | 1 - packages/application-generic/package.json | 6 +- .../calculate-delay.service.ts | 4 +- .../timed-digest-delay.service.spec.ts | 534 ++++++++++++++++++ .../timed-digest-delay.service.ts | 186 ++++++ pnpm-lock.yaml | 53 +- 7 files changed, 734 insertions(+), 53 deletions(-) delete mode 100644 .gitmodules delete mode 160000 enterprise/packages create mode 100644 packages/application-generic/src/services/calculate-delay/timed-digest-delay.service.spec.ts create mode 100644 packages/application-generic/src/services/calculate-delay/timed-digest-delay.service.ts diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index feb3b55e7bd..00000000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "enterprise/packages"] - path = enterprise/packages - url = https://github.com/novuhq/packages-enterprise.git diff --git a/enterprise/packages b/enterprise/packages deleted file mode 160000 index 30b47217aba..00000000000 --- a/enterprise/packages +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 30b47217aba08cd0eaad59b76183fc2d3aab9018 diff --git a/packages/application-generic/package.json b/packages/application-generic/package.json index 2609d1d9674..fe6edb495e4 100644 --- a/packages/application-generic/package.json +++ b/packages/application-generic/package.json @@ -102,11 +102,11 @@ "pino-http": "^8.3.3", "pino-pretty": "^9.4.0", "redlock": "4.2.0", - "reflect-metadata": "^0.1.13" + "reflect-metadata": "^0.1.13", + "rrule": "^2.7.2" }, "optionalDependencies": { - "@taskforcesh/bullmq-pro": "5.1.14", - "@novu/digest-schedule": "^0.14.0" + "@taskforcesh/bullmq-pro": "5.1.14" }, "devDependencies": { "@istanbuljs/nyc-config-typescript": "^1.0.1", diff --git a/packages/application-generic/src/services/calculate-delay/calculate-delay.service.ts b/packages/application-generic/src/services/calculate-delay/calculate-delay.service.ts index 698bb8da196..1c703627acf 100644 --- a/packages/application-generic/src/services/calculate-delay/calculate-delay.service.ts +++ b/packages/application-generic/src/services/calculate-delay/calculate-delay.service.ts @@ -11,6 +11,7 @@ import { import { ApiException } from '../../utils/exceptions'; import { isRegularDigest } from '../../utils/digest'; +import { TimedDigestDelayService } from './timed-digest-delay.service'; const IS_ENTERPRISE = process.env.NOVU_MANAGED_SERVICE === 'true'; @@ -62,9 +63,6 @@ export class CalculateDelayService { if (IS_ENTERPRISE && stepMetadata.type === DigestTypeEnum.TIMED) { const timedDigestMeta = stepMetadata as IDigestTimedMetadata; - // eslint-disable-next-line @typescript-eslint/naming-convention - const { TimedDigestDelayService } = require('@novu/digest-schedule'); - return TimedDigestDelayService.calculate({ unit: timedDigestMeta.unit, amount: timedDigestMeta.amount, diff --git a/packages/application-generic/src/services/calculate-delay/timed-digest-delay.service.spec.ts b/packages/application-generic/src/services/calculate-delay/timed-digest-delay.service.spec.ts new file mode 100644 index 00000000000..2389ef03b49 --- /dev/null +++ b/packages/application-generic/src/services/calculate-delay/timed-digest-delay.service.spec.ts @@ -0,0 +1,534 @@ +import { differenceInMilliseconds } from 'date-fns'; +import { + DaysEnum, + DigestUnitEnum, + MonthlyTypeEnum, + OrdinalEnum, + OrdinalValueEnum, +} from '@novu/shared'; + +import { TimedDigestDelayService } from './timed-digest-delay.service'; + +describe('TimedDigestDelayService', () => { + describe('calculate', () => { + let clock: typeof jest; + + beforeEach(() => { + const date = new Date('2023-05-04T12:00:00Z'); + clock = jest.useFakeTimers('modern'); + clock.setSystemTime(date.getTime()); + }); + + afterEach(() => { + clock.clearAllTimers(); + }); + + describe('minutely schedule', () => { + it('delay timeout for next minute', () => { + const result = TimedDigestDelayService.calculate({ + unit: DigestUnitEnum.MINUTES, + amount: 1, + }); + + expect(result).toEqual( + differenceInMilliseconds(new Date('2023-05-04T12:01:00Z'), new Date()) + ); + }); + + it('delay timeout for next 7 minutes', () => { + const result = TimedDigestDelayService.calculate({ + unit: DigestUnitEnum.MINUTES, + amount: 7, + }); + + expect(result).toEqual( + differenceInMilliseconds(new Date('2023-05-04T12:07:00Z'), new Date()) + ); + }); + }); + + describe('hourly schedule', () => { + it('delay timeout for next hour', () => { + const result = TimedDigestDelayService.calculate({ + unit: DigestUnitEnum.HOURS, + amount: 1, + }); + + expect(result).toEqual( + differenceInMilliseconds(new Date('2023-05-04T13:00:00Z'), new Date()) + ); + }); + + it('delay timeout for next 10 hours', () => { + const result = TimedDigestDelayService.calculate({ + unit: DigestUnitEnum.HOURS, + amount: 10, + }); + + expect(result).toEqual( + differenceInMilliseconds(new Date('2023-05-04T22:00:00Z'), new Date()) + ); + }); + }); + + describe('daily schedule', () => { + it('delay timeout for next day', () => { + const dateStart = new Date(); + const result = TimedDigestDelayService.calculate({ + dateStart, + unit: DigestUnitEnum.DAYS, + amount: 1, + timeConfig: { + atTime: '01:00:00', + }, + }); + + expect(result).toEqual( + differenceInMilliseconds( + new Date('2023-05-05T01:00:00.000Z'), + new Date() + ) + ); + }); + + it('delay timeout for next 4 days', () => { + const dateStart = new Date(); + const result = TimedDigestDelayService.calculate({ + dateStart, + unit: DigestUnitEnum.DAYS, + amount: 4, + timeConfig: { + atTime: '01:00:00', + }, + }); + + expect(result).toEqual( + differenceInMilliseconds( + new Date('2023-05-08T01:00:00.000Z'), + new Date() + ) + ); + }); + }); + + describe('weekly schedule', () => { + it('delay timeout for next weekly when days are not specified', () => { + const dateStart = new Date('2023-05-04T00:00:00.000Z'); + const result = TimedDigestDelayService.calculate({ + dateStart, + unit: DigestUnitEnum.WEEKS, + amount: 2, + timeConfig: { + atTime: '09:00:00', + }, + }); + + expect(result).toEqual( + differenceInMilliseconds( + new Date('2023-05-04T09:00:00.000Z'), + new Date() + ) + ); + }); + + it('delay timeout for next weekly when the time is after the "at time"', () => { + const dateStart = new Date('2023-05-04T10:00:00.000Z'); + const result = TimedDigestDelayService.calculate({ + dateStart, + unit: DigestUnitEnum.WEEKS, + amount: 2, + timeConfig: { + atTime: '09:00:00', + }, + }); + + expect(result).toEqual( + differenceInMilliseconds( + new Date('2023-05-18T09:00:00.000Z'), + new Date() + ) + ); + }); + + it('delay timeout for next scheduled weekly on monday', () => { + const dateStart = new Date('2023-05-01T00:00:00.000Z'); + const result = TimedDigestDelayService.calculate({ + dateStart, + unit: DigestUnitEnum.WEEKS, + amount: 2, + timeConfig: { + atTime: '09:00:00', + weekDays: [DaysEnum.MONDAY, DaysEnum.WEDNESDAY], + }, + }); + + expect(result).toEqual( + differenceInMilliseconds( + new Date('2023-05-01T09:00:00.000Z'), + new Date() + ) + ); + }); + + it('delay timeout for next scheduled weekly on wednesday', () => { + const dateStart = new Date('2023-05-02T00:00:00.000Z'); + const result = TimedDigestDelayService.calculate({ + dateStart, + unit: DigestUnitEnum.WEEKS, + amount: 2, + timeConfig: { + atTime: '09:00:00', + weekDays: [DaysEnum.MONDAY, DaysEnum.WEDNESDAY], + }, + }); + + expect(result).toEqual( + differenceInMilliseconds( + new Date('2023-05-03T09:00:00.000Z'), + new Date() + ) + ); + }); + }); + + describe('monthly schedule', () => { + it('delay timeout for next month when month days are not provided', () => { + const dateStart = new Date('2023-05-03T00:00:00.000Z'); + const result = TimedDigestDelayService.calculate({ + dateStart, + unit: DigestUnitEnum.MONTHS, + amount: 3, + timeConfig: { + atTime: '12:00:00', + }, + }); + + expect(result).toEqual( + differenceInMilliseconds( + new Date('2023-05-03T12:00:00.000Z'), + new Date() + ) + ); + }); + + it('delay timeout for next month when the time is after the "at time"', () => { + const dateStart = new Date('2023-05-03T13:00:00.000Z'); + const result = TimedDigestDelayService.calculate({ + dateStart, + unit: DigestUnitEnum.MONTHS, + amount: 3, + timeConfig: { + atTime: '12:00:00', + }, + }); + + expect(result).toEqual( + differenceInMilliseconds( + new Date('2023-08-03T12:00:00.000Z'), + new Date() + ) + ); + }); + + it('delay timeout for next month first day', () => { + const dateStart = new Date('2023-05-01T00:00:00.000Z'); + const result = TimedDigestDelayService.calculate({ + dateStart, + unit: DigestUnitEnum.MONTHS, + amount: 3, + timeConfig: { + atTime: '12:00:00', + monthDays: [1, 15], + }, + }); + + expect(result).toEqual( + differenceInMilliseconds( + new Date('2023-05-01T12:00:00.000Z'), + new Date() + ) + ); + }); + + it('delay timeout for next month fifteenth day', () => { + const dateStart = new Date('2023-05-03T00:00:00.000Z'); + const result = TimedDigestDelayService.calculate({ + dateStart, + unit: DigestUnitEnum.MONTHS, + amount: 3, + timeConfig: { + atTime: '12:00:00', + monthDays: [1, 15], + }, + }); + + expect(result).toEqual( + differenceInMilliseconds( + new Date('2023-05-15T12:00:00.000Z'), + new Date() + ) + ); + }); + + describe('with "on the" fields', () => { + describe('ordinal value "day"', () => { + it('delay timeout for the first day of the month', () => { + const result = TimedDigestDelayService.calculate({ + unit: DigestUnitEnum.MONTHS, + amount: 1, + timeConfig: { + atTime: '12:00:00', + ordinal: OrdinalEnum.FIRST, + ordinalValue: OrdinalValueEnum.DAY, + monthlyType: MonthlyTypeEnum.ON, + }, + }); + + expect(result).toEqual( + differenceInMilliseconds( + new Date('2023-06-01T12:00:00.000Z'), + new Date() + ) + ); + }); + + it('delay timeout for the second day of the month', () => { + const result = TimedDigestDelayService.calculate({ + unit: DigestUnitEnum.MONTHS, + amount: 1, + timeConfig: { + atTime: '12:00:00', + ordinal: OrdinalEnum.SECOND, + ordinalValue: OrdinalValueEnum.DAY, + monthlyType: MonthlyTypeEnum.ON, + }, + }); + + expect(result).toEqual( + differenceInMilliseconds( + new Date('2023-06-02T12:00:00.000Z'), + new Date() + ) + ); + }); + + it('delay timeout for the last day of the month', () => { + const result = TimedDigestDelayService.calculate({ + dateStart: new Date('2023-06-01T12:00:00.000Z'), + unit: DigestUnitEnum.MONTHS, + amount: 1, + timeConfig: { + atTime: '12:00:00', + ordinal: OrdinalEnum.LAST, + ordinalValue: OrdinalValueEnum.DAY, + monthlyType: MonthlyTypeEnum.ON, + }, + }); + + expect(result).toEqual( + differenceInMilliseconds( + new Date('2023-06-30T12:00:00.000Z'), + new Date() + ) + ); + }); + }); + + describe('ordinal value "weekday"', () => { + it('delay timeout for the first weekday of the month', () => { + const result = TimedDigestDelayService.calculate({ + dateStart: new Date('2023-07-01T12:00:00.000Z'), + unit: DigestUnitEnum.MONTHS, + amount: 1, + timeConfig: { + atTime: '12:00:00', + ordinal: OrdinalEnum.FIRST, + ordinalValue: OrdinalValueEnum.WEEKDAY, + monthlyType: MonthlyTypeEnum.ON, + }, + }); + + expect(result).toEqual( + differenceInMilliseconds( + new Date('2023-07-03T12:00:00.000Z'), + new Date() + ) + ); + }); + + it('delay timeout for the second weekday of the month', () => { + const result = TimedDigestDelayService.calculate({ + dateStart: new Date('2023-07-01T12:00:00.000Z'), + unit: DigestUnitEnum.MONTHS, + amount: 1, + timeConfig: { + atTime: '12:00:00', + ordinal: OrdinalEnum.SECOND, + ordinalValue: OrdinalValueEnum.WEEKDAY, + monthlyType: MonthlyTypeEnum.ON, + }, + }); + + expect(result).toEqual( + differenceInMilliseconds( + new Date('2023-07-04T12:00:00.000Z'), + new Date() + ) + ); + }); + + it('delay timeout for the last weekday of the month', () => { + const result = TimedDigestDelayService.calculate({ + dateStart: new Date('2023-07-01T12:00:00.000Z'), + unit: DigestUnitEnum.MONTHS, + amount: 1, + timeConfig: { + atTime: '12:00:00', + ordinal: OrdinalEnum.LAST, + ordinalValue: OrdinalValueEnum.WEEKDAY, + monthlyType: MonthlyTypeEnum.ON, + }, + }); + + expect(result).toEqual( + differenceInMilliseconds( + new Date('2023-07-31T12:00:00.000Z'), + new Date() + ) + ); + }); + }); + + describe('ordinal value "weekend day"', () => { + it('delay timeout for the first weekend day of the month', () => { + const result = TimedDigestDelayService.calculate({ + dateStart: new Date('2023-06-01T12:00:00.000Z'), + unit: DigestUnitEnum.MONTHS, + amount: 1, + timeConfig: { + atTime: '12:00:00', + ordinal: OrdinalEnum.FIRST, + ordinalValue: OrdinalValueEnum.WEEKEND, + monthlyType: MonthlyTypeEnum.ON, + }, + }); + + expect(result).toEqual( + differenceInMilliseconds( + new Date('2023-06-03T12:00:00.000Z'), + new Date() + ) + ); + }); + + it('delay timeout for the second weekend day of the month', () => { + const result = TimedDigestDelayService.calculate({ + dateStart: new Date('2023-06-01T12:00:00.000Z'), + unit: DigestUnitEnum.MONTHS, + amount: 1, + timeConfig: { + atTime: '12:00:00', + ordinal: OrdinalEnum.SECOND, + ordinalValue: OrdinalValueEnum.WEEKEND, + monthlyType: MonthlyTypeEnum.ON, + }, + }); + + expect(result).toEqual( + differenceInMilliseconds( + new Date('2023-06-04T12:00:00.000Z'), + new Date() + ) + ); + }); + + it('delay timeout for the last weekend day of the month', () => { + const result = TimedDigestDelayService.calculate({ + dateStart: new Date('2023-06-01T12:00:00.000Z'), + unit: DigestUnitEnum.MONTHS, + amount: 1, + timeConfig: { + atTime: '12:00:00', + ordinal: OrdinalEnum.LAST, + ordinalValue: OrdinalValueEnum.WEEKEND, + monthlyType: MonthlyTypeEnum.ON, + }, + }); + + expect(result).toEqual( + differenceInMilliseconds( + new Date('2023-06-25T12:00:00.000Z'), + new Date() + ) + ); + }); + }); + + describe('ordinal value "specific week day"', () => { + it('delay timeout for the first wednesday of the month', () => { + const result = TimedDigestDelayService.calculate({ + dateStart: new Date('2023-06-01T12:00:00.000Z'), + unit: DigestUnitEnum.MONTHS, + amount: 1, + timeConfig: { + atTime: '12:00:00', + ordinal: OrdinalEnum.FIRST, + ordinalValue: OrdinalValueEnum.WEDNESDAY, + monthlyType: MonthlyTypeEnum.ON, + }, + }); + + expect(result).toEqual( + differenceInMilliseconds( + new Date('2023-06-07T12:00:00.000Z'), + new Date() + ) + ); + }); + + it('delay timeout for the second sunday of the month', () => { + const result = TimedDigestDelayService.calculate({ + dateStart: new Date('2023-06-01T12:00:00.000Z'), + unit: DigestUnitEnum.MONTHS, + amount: 1, + timeConfig: { + atTime: '12:00:00', + ordinal: OrdinalEnum.SECOND, + ordinalValue: OrdinalValueEnum.SUNDAY, + monthlyType: MonthlyTypeEnum.ON, + }, + }); + + expect(result).toEqual( + differenceInMilliseconds( + new Date('2023-06-11T12:00:00.000Z'), + new Date() + ) + ); + }); + + it('delay timeout for the last weekend day of the month', () => { + const result = TimedDigestDelayService.calculate({ + dateStart: new Date('2023-06-01T12:00:00.000Z'), + unit: DigestUnitEnum.MONTHS, + amount: 1, + timeConfig: { + atTime: '12:00:00', + ordinal: OrdinalEnum.LAST, + ordinalValue: OrdinalValueEnum.SATURDAY, + monthlyType: MonthlyTypeEnum.ON, + }, + }); + + expect(result).toEqual( + differenceInMilliseconds( + new Date('2023-06-24T12:00:00.000Z'), + new Date() + ) + ); + }); + }); + }); + }); + }); +}); diff --git a/packages/application-generic/src/services/calculate-delay/timed-digest-delay.service.ts b/packages/application-generic/src/services/calculate-delay/timed-digest-delay.service.ts new file mode 100644 index 00000000000..c58cfd4217e --- /dev/null +++ b/packages/application-generic/src/services/calculate-delay/timed-digest-delay.service.ts @@ -0,0 +1,186 @@ +import { + differenceInMilliseconds, + addMinutes, + addHours, + addDays, + addWeeks, + addMonths, +} from 'date-fns'; +import { RRule, Frequency, Weekday } from 'rrule'; +import { + DaysEnum, + DigestUnitEnum, + ITimedConfig, + MonthlyTypeEnum, + OrdinalEnum, + OrdinalValueEnum, +} from '@novu/shared'; + +const UNIT_TO_RRULE_FREQUENCY = { + [DigestUnitEnum.MINUTES]: Frequency.MINUTELY, + [DigestUnitEnum.HOURS]: Frequency.HOURLY, + [DigestUnitEnum.DAYS]: Frequency.DAILY, + [DigestUnitEnum.WEEKS]: Frequency.WEEKLY, + [DigestUnitEnum.MONTHS]: Frequency.MONTHLY, +}; + +const DAY_OF_WEEK_TO_RRULE_DAY = { + [DaysEnum.MONDAY]: RRule.MO, + [DaysEnum.TUESDAY]: RRule.TU, + [DaysEnum.WEDNESDAY]: RRule.WE, + [DaysEnum.THURSDAY]: RRule.TH, + [DaysEnum.FRIDAY]: RRule.FR, + [DaysEnum.SATURDAY]: RRule.SA, + [DaysEnum.SUNDAY]: RRule.SU, +}; + +const ORDINAL_TO_RRULE_BYSETPOS = { + [OrdinalEnum.FIRST]: 1, + [OrdinalEnum.SECOND]: 2, + [OrdinalEnum.THIRD]: 3, + [OrdinalEnum.FOURTH]: 4, + [OrdinalEnum.FIFTH]: 5, + [OrdinalEnum.LAST]: -1, +}; + +const ORDINAL_VALUE_TO_RRULE_RRULE_DAY = { + [OrdinalValueEnum.MONDAY]: RRule.MO, + [OrdinalValueEnum.TUESDAY]: RRule.TU, + [OrdinalValueEnum.WEDNESDAY]: RRule.WE, + [OrdinalValueEnum.THURSDAY]: RRule.TH, + [OrdinalValueEnum.FRIDAY]: RRule.FR, + [OrdinalValueEnum.SATURDAY]: RRule.SA, + [OrdinalValueEnum.SUNDAY]: RRule.SU, +}; + +const ORDINAL_TO_RRULE_BYMONTHDAY = { + [OrdinalEnum.FIRST]: 1, + [OrdinalEnum.SECOND]: 2, + [OrdinalEnum.THIRD]: 3, + [OrdinalEnum.FOURTH]: 4, + [OrdinalEnum.FIFTH]: 5, + [OrdinalEnum.LAST]: -1, +}; + +interface ICalculateArgs { + dateStart?: Date; + unit: DigestUnitEnum; + amount: number; + timeConfig?: ITimedConfig; +} + +export class TimedDigestDelayService { + /** + * Calculates the delay time in miliseconds between the time for the next schedule and current time + * @returns the delay time in miliseconds + */ + public static calculate({ + dateStart = new Date(), + unit = DigestUnitEnum.MINUTES, + amount, + timeConfig: { + atTime, + weekDays, + monthDays, + monthlyType = MonthlyTypeEnum.EACH, + ordinal, + ordinalValue, + } = {}, + }: ICalculateArgs): number { + const [hours, minutes, seconds] = atTime + ? atTime.split(':').map((part) => parseInt(part, 10)) + : []; + + const { bysetpos, byweekday, bymonthday } = this.calculateByFields({ + weekDays, + monthDays, + monthlyType, + ordinal, + ordinalValue, + }); + + const rule = new RRule({ + dtstart: dateStart, + until: this.getUntilDate(dateStart, unit, amount), + freq: UNIT_TO_RRULE_FREQUENCY[unit], + interval: amount, + bysetpos, + byweekday, + bymonthday, + byhour: hours, + byminute: minutes, + bysecond: seconds, + }); + + const next = rule.after(dateStart); + + if (next === null) { + throw new Error('Delay for next digest could not be calculated'); + } + + return differenceInMilliseconds(next, new Date()); + } + + private static calculateByFields({ + weekDays, + monthDays, + monthlyType, + ordinal, + ordinalValue, + }: ITimedConfig) { + let byweekday: Weekday[] | undefined = undefined; + let bymonthday: number | number[] | undefined = undefined; + + if (monthlyType === MonthlyTypeEnum.EACH) { + byweekday = weekDays?.map((el) => DAY_OF_WEEK_TO_RRULE_DAY[el]); + bymonthday = monthDays; + + return { byweekday, bymonthday }; + } + + switch (ordinalValue) { + case OrdinalValueEnum.DAY: { + return { bymonthday: ORDINAL_TO_RRULE_BYMONTHDAY[ordinal] }; + } + case OrdinalValueEnum.WEEKDAY: { + return { + bysetpos: ORDINAL_TO_RRULE_BYSETPOS[ordinal], + byweekday: [RRule.MO, RRule.TU, RRule.WE, RRule.TH, RRule.FR], + }; + } + case OrdinalValueEnum.WEEKEND: { + return { + bysetpos: ORDINAL_TO_RRULE_BYSETPOS[ordinal], + byweekday: [RRule.SA, RRule.SU], + }; + } + default: { + return { + bysetpos: ORDINAL_TO_RRULE_BYSETPOS[ordinal], + byweekday: ORDINAL_VALUE_TO_RRULE_RRULE_DAY[ordinalValue], + }; + } + } + } + + private static getUntilDate( + dateStart: Date, + unit: DigestUnitEnum, + amount: number + ): Date { + switch (unit) { + case DigestUnitEnum.MINUTES: + return addMinutes(dateStart, amount); + case DigestUnitEnum.HOURS: + return addHours(dateStart, amount); + case DigestUnitEnum.DAYS: + return addDays(dateStart, amount); + case DigestUnitEnum.WEEKS: + return addWeeks(dateStart, amount); + case DigestUnitEnum.MONTHS: + return addMonths(dateStart, amount); + default: + return addMonths(dateStart, amount); + } + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 180e04d3339..e47e5b36e56 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -381,7 +381,7 @@ importers: cross-env: 7.0.3 nodemon: 2.0.22 prettier: 2.8.7 - ts-jest: 27.1.5_ik2qjjkgpajyhqxqenowswsmya + ts-jest: 27.1.5_cnngzrja2umb46xxazlucyx2qu ts-loader: 9.4.2_lj5zgxrzaejsnoobor62tojvse ts-node: 10.9.1_wh2cnrlliuuxb2etxm2m3ttgna tsconfig-paths: 3.14.2 @@ -1139,39 +1139,6 @@ importers: stylelint-scss: 4.6.0_stylelint@14.16.1 typescript: 4.9.5 - enterprise/packages/digest-schedule: - specifiers: - '@novu/shared': ^0.14.0 - '@types/chai': ^4.2.11 - '@types/mocha': ^8.0.1 - '@types/node': ^14.6.0 - '@types/sinon': ^9.0.0 - chai: ^4.2.0 - cross-env: ^7.0.3 - date-fns: ^2.29.2 - mocha: ^8.1.1 - nodemon: ^2.0.3 - rrule: ^2.7.2 - sinon: ^9.2.4 - ts-node: ~10.9.1 - typescript: 4.9.5 - dependencies: - '@novu/shared': link:../../../libs/shared - date-fns: 2.29.3 - rrule: 2.7.2 - devDependencies: - '@types/chai': 4.3.4 - '@types/mocha': 8.2.3 - '@types/node': 14.18.42 - '@types/sinon': 9.0.11 - chai: 4.3.7 - cross-env: 7.0.3 - mocha: 8.4.0 - nodemon: 2.0.22 - sinon: 9.2.4 - ts-node: 10.9.1_wh2cnrlliuuxb2etxm2m3ttgna - typescript: 4.9.5 - libs/dal: specifiers: '@aws-sdk/client-s3': ^3.14.0 @@ -1441,7 +1408,6 @@ importers: '@novu/burst-sms': ^0.14.0 '@novu/clickatell': ^0.14.0 '@novu/dal': ^0.14.0 - '@novu/digest-schedule': ^0.14.0 '@novu/discord': ^0.14.0 '@novu/emailjs': ^0.14.0 '@novu/expo': ^0.14.0 @@ -1510,6 +1476,7 @@ importers: redlock: 4.2.0 reflect-metadata: ^0.1.13 rimraf: ^3.0.2 + rrule: ^2.7.2 sinon: ^9.2.4 ts-jest: ^27.0.5 ts-node: ~10.9.1 @@ -1582,8 +1549,8 @@ importers: pino-pretty: 9.4.0 redlock: 4.2.0 reflect-metadata: 0.1.13 + rrule: 2.7.2 optionalDependencies: - '@novu/digest-schedule': link:../../enterprise/packages/digest-schedule '@taskforcesh/bullmq-pro': 5.1.14 devDependencies: '@istanbuljs/nyc-config-typescript': 1.0.2_nyc@15.1.0 @@ -12061,7 +12028,7 @@ packages: '@jest/test-result': 27.5.1 '@jest/transform': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 16.11.7 + '@types/node': 14.18.42 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.8.1 @@ -12105,7 +12072,7 @@ packages: '@jest/test-result': 27.5.1 '@jest/transform': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 16.11.7 + '@types/node': 14.18.42 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.8.1 @@ -21563,7 +21530,7 @@ packages: /@types/engine.io/3.1.7: resolution: {integrity: sha512-qNjVXcrp+1sS8YpRUa714r0pgzOwESdW5UjHL7D/2ZFdBX0BXUXtg1LUrp+ylvqbvMcMWUy73YpRoxPN2VoKAQ==} dependencies: - '@types/node': 18.15.11 + '@types/node': 14.18.42 dev: true /@types/eslint-scope/3.7.4: @@ -21838,6 +21805,7 @@ packages: /@types/node/16.11.7: resolution: {integrity: sha512-QB5D2sqfSjCmTuWcBWyJ+/44bcjO7VbjSbOE0ucoVbAsSNQc4Lt6QkgkVXkTDwkL4z/beecZNDvVX15D4P8Jbw==} + dev: true /@types/node/17.0.45: resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==} @@ -47568,7 +47536,7 @@ packages: tslib: 1.14.1 dev: true - /ts-jest/27.1.5_d5we6thvweerisoz5puaw7xkku: + /ts-jest/27.1.5_cnngzrja2umb46xxazlucyx2qu: resolution: {integrity: sha512-Xv6jBQPoBEvBq/5i2TeSG9tt/nqkbpcurrEG1b+2yfBrcJelOZF9Ml6dmyMh7bcW9JyFbRYpR5rxROSlBLTZHA==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} hasBin: true @@ -47589,8 +47557,6 @@ packages: esbuild: optional: true dependencies: - '@babel/core': 7.21.4 - '@types/jest': 27.5.2 bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 jest: 27.5.1_ts-node@10.9.1 @@ -47603,7 +47569,7 @@ packages: yargs-parser: 20.2.9 dev: true - /ts-jest/27.1.5_ik2qjjkgpajyhqxqenowswsmya: + /ts-jest/27.1.5_d5we6thvweerisoz5puaw7xkku: resolution: {integrity: sha512-Xv6jBQPoBEvBq/5i2TeSG9tt/nqkbpcurrEG1b+2yfBrcJelOZF9Ml6dmyMh7bcW9JyFbRYpR5rxROSlBLTZHA==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} hasBin: true @@ -47625,6 +47591,7 @@ packages: optional: true dependencies: '@babel/core': 7.21.4 + '@types/jest': 27.5.2 bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 jest: 27.5.1_ts-node@10.9.1