diff --git a/.github/workflows/prod-deploy-api.yml b/.github/workflows/prod-deploy-api.yml index b1d8b1fa3c6..354300a65f5 100644 --- a/.github/workflows/prod-deploy-api.yml +++ b/.github/workflows/prod-deploy-api.yml @@ -79,11 +79,6 @@ jobs: id-token: write steps: - uses: actions/checkout@v3 - - uses: ./.github/actions/checkout-submodules - with: - enabled: ${{ contains (matrix.name,'ee') }} - submodule_token: ${{ secrets.SUBMODULES_TOKEN }} - submodule_branch: "main" - uses: ./.github/actions/setup-project - name: build api diff --git a/.github/workflows/prod-deploy-worker.yml b/.github/workflows/prod-deploy-worker.yml index cd3b480e09c..8ce444cf0c9 100644 --- a/.github/workflows/prod-deploy-worker.yml +++ b/.github/workflows/prod-deploy-worker.yml @@ -38,11 +38,6 @@ jobs: id-token: write steps: - uses: actions/checkout@v3 - - uses: ./.github/actions/checkout-submodules - with: - enabled: ${{ contains (matrix.name,'ee') }} - submodule_token: ${{ secrets.SUBMODULES_TOKEN }} - submodule_branch: "main" - uses: ./.github/actions/setup-project - name: build worker diff --git a/.github/workflows/prod-deploy-ws.yml b/.github/workflows/prod-deploy-ws.yml index aef0b169635..87b98c2b825 100644 --- a/.github/workflows/prod-deploy-ws.yml +++ b/.github/workflows/prod-deploy-ws.yml @@ -23,6 +23,8 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 80 environment: Production + needs: + - test_ws strategy: matrix: name: [ 'novu/ws-ee', 'novu/ws' ] diff --git a/.github/workflows/reusable-api-e2e.yml b/.github/workflows/reusable-api-e2e.yml index 703863658f3..15ec2ecf64e 100644 --- a/.github/workflows/reusable-api-e2e.yml +++ b/.github/workflows/reusable-api-e2e.yml @@ -46,11 +46,6 @@ jobs: fi - uses: actions/checkout@v3 # checkout with submodules if token is provided - - uses: ./.github/actions/checkout-submodules - with: - enabled: ${{ steps.setup.outputs.has_token == 'true' }} - submodule_token: ${{ secrets.SUBMODULES_TOKEN }} - submodule_branch: ${{ inputs.submodule_branch }} - uses: ./.github/actions/setup-project - uses: ./.github/actions/setup-redis-cluster - uses: mansagroup/nrwl-nx-action@v3 diff --git a/.github/workflows/reusable-inbound-mail-e2e.yml b/.github/workflows/reusable-inbound-mail-e2e.yml index efb72234c81..35d50ef1fa8 100644 --- a/.github/workflows/reusable-inbound-mail-e2e.yml +++ b/.github/workflows/reusable-inbound-mail-e2e.yml @@ -38,11 +38,6 @@ jobs: steps: # checkout with submodules if token is provided - uses: actions/checkout@v3 - - uses: ./.github/actions/checkout-submodules - with: - enabled: ${{ steps.setup.outputs.has_token == 'true' }} - submodule_token: ${{ secrets.SUBMODULES_TOKEN }} - submodule_branch: ${{ inputs.submodule_branch }} - uses: ./.github/actions/setup-project - uses: ./.github/actions/setup-redis-cluster - uses: mansagroup/nrwl-nx-action@v3 diff --git a/.github/workflows/reusable-web-e2e.yml b/.github/workflows/reusable-web-e2e.yml index 4cbc5f16302..3970dc3d776 100644 --- a/.github/workflows/reusable-web-e2e.yml +++ b/.github/workflows/reusable-web-e2e.yml @@ -52,11 +52,6 @@ jobs: - uses: actions/checkout@v3 # checkout with submodules if token is provided - - uses: ./.github/actions/checkout-submodules - with: - enabled: ${{ steps.setup.outputs.has_token == 'true' }} - submodule_token: ${{ secrets.SUBMODULES_TOKEN }} - submodule_branch: ${{ inputs.submodule_branch }} - uses: ./.github/actions/setup-project id: setup-project with: diff --git a/.github/workflows/reusable-widget-e2e.yml b/.github/workflows/reusable-widget-e2e.yml index 2e786ce7ed2..f619bc64b39 100644 --- a/.github/workflows/reusable-widget-e2e.yml +++ b/.github/workflows/reusable-widget-e2e.yml @@ -51,12 +51,6 @@ jobs: fi - uses: actions/checkout@v3 # checkout with submodules if token is provided - - uses: ./.github/actions/checkout-submodules - with: - enabled: ${{ steps.setup.outputs.has_token == 'true' }} - submodule_token: ${{ secrets.SUBMODULES_TOKEN }} - submodule_branch: ${{ inputs.submodule_branch }} - - uses: ./.github/actions/setup-project id: setup-project with: diff --git a/.github/workflows/reusable-worker-e2e.yml b/.github/workflows/reusable-worker-e2e.yml index 976b6db593b..ce4a2bd04c9 100644 --- a/.github/workflows/reusable-worker-e2e.yml +++ b/.github/workflows/reusable-worker-e2e.yml @@ -46,11 +46,7 @@ jobs: fi - uses: actions/checkout@v3 # checkout with submodules if token is provided - - uses: ./.github/actions/checkout-submodules - with: - enabled: ${{ steps.setup.outputs.has_token == 'true' }} - submodule_token: ${{ secrets.SUBMODULES_TOKEN }} - submodule_branch: ${{ inputs.submodule_branch }} + - uses: ./.github/actions/setup-project - uses: ./.github/actions/setup-redis-cluster diff --git a/.github/workflows/reusable-ws-e2e.yml b/.github/workflows/reusable-ws-e2e.yml index 580ee7fee25..df4dd129fce 100644 --- a/.github/workflows/reusable-ws-e2e.yml +++ b/.github/workflows/reusable-ws-e2e.yml @@ -44,12 +44,6 @@ jobs: echo "has_token=false" >> $GITHUB_OUTPUT fi - uses: actions/checkout@v3 - # checkout with submodules if token is provided - - uses: ./.github/actions/checkout-submodules - with: - enabled: ${{ steps.setup.outputs.has_token == 'true' }} - submodule_token: ${{ secrets.SUBMODULES_TOKEN }} - submodule_branch: ${{ inputs.submodule_branch }} - uses: ./.github/actions/setup-project - uses: mansagroup/nrwl-nx-action@v3 with: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 099f7c724d3..ea1619b2416 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -33,8 +33,8 @@ You can open a new issue with this [issue form](https://github.com/novuhq/novu/i The project is a monorepo, meaning that it is a collection of multiple packages managed in the same repository. -To learn more about the project structure visit [https://docs.novu.co/community/monorepo-structure](https://docs.novu.co/community/monorepo-structure). +To learn more about the project structure and running the project locally, please have a look [here](https://docs.novu.co/community-support/introduction#run-novu-locally). After cloning your fork, you will need to run the `npm run setup:project` command to install and build all dependencies. To learn a detailed guide on running the project locally, checkout our guide on [how to run novu in local machine](https://docs.novu.co/community/run-in-local-machine). diff --git a/apps/api/package.json b/apps/api/package.json index 2059dbabbac..04b50c466e5 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -1,6 +1,6 @@ { "name": "@novu/api", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "description", "author": "", "private": "true", @@ -38,12 +38,12 @@ "@nestjs/platform-express": "^10.2.2", "@nestjs/swagger": "^7.1.8", "@nestjs/terminus": "^10.0.1", - "@novu/application-generic": "^0.19.0", - "@novu/dal": "^0.19.0", - "@novu/node": "^0.19.0", - "@novu/shared": "^0.19.0", - "@novu/stateless": "^0.19.0", - "@novu/testing": "^0.19.0", + "@novu/application-generic": "^0.20.0-alpha.0", + "@novu/dal": "^0.20.0-alpha.0", + "@novu/node": "^0.20.0-alpha.0", + "@novu/shared": "^0.20.0-alpha.0", + "@novu/stateless": "^0.20.0-alpha.0", + "@novu/testing": "^0.20.0-alpha.0", "@sendgrid/mail": "^7.6.0", "@sentry/hub": "^7.40.0", "@sentry/node": "^7.40.0", @@ -113,7 +113,9 @@ "@novu/ee-auth": "^0.19.0" }, "nx": { - "implicitDependencies": ["@novu/ee-auth"] + "implicitDependencies": [ + "@novu/ee-auth" + ] }, "lint-staged": { "*.{js,jsx,ts,tsx}": [ diff --git a/apps/api/src/app/events/usecases/parse-event-request/parse-event-request.e2e.ts b/apps/api/src/app/events/usecases/parse-event-request/parse-event-request.e2e.ts new file mode 100644 index 00000000000..cc38c8cc882 --- /dev/null +++ b/apps/api/src/app/events/usecases/parse-event-request/parse-event-request.e2e.ts @@ -0,0 +1,71 @@ +import { Test } from '@nestjs/testing'; +import { expect } from 'chai'; +import { v4 as uuid } from 'uuid'; + +import { SubscribersService, UserSession } from '@novu/testing'; +import { SubscriberRepository, NotificationTemplateEntity } from '@novu/dal'; +import { TriggerRecipients } from '@novu/shared'; + +import { SharedModule } from '../../../shared/shared.module'; +import { EventsModule } from '../../events.module'; +import { ParseEventRequestCommand } from './parse-event-request.command'; +import { ParseEventRequest } from './parse-event-request.usecase'; + +describe('ParseEventRequest Usecase', () => { + let session: UserSession; + let subscribersService: SubscribersService; + let parseEventRequestUsecase: ParseEventRequest; + let template: NotificationTemplateEntity; + + beforeEach(async () => { + const moduleRef = await Test.createTestingModule({ + imports: [SharedModule, EventsModule], + providers: [], + }).compile(); + + session = new UserSession(); + await session.initialize(); + + template = await session.createTemplate(); + parseEventRequestUsecase = moduleRef.get(ParseEventRequest); + subscribersService = new SubscribersService(session.organization._id, session.environment._id); + }); + + it('should throw exception when subscriber id sent as array', async () => { + const transactionId = uuid(); + const subscriberId = [SubscriberRepository.createObjectId()]; + + const command = buildCommand( + session, + transactionId, + [{ subscriberId: subscriberId } as unknown as string], + template.triggers[0].identifier + ); + + try { + await parseEventRequestUsecase.execute(command); + } catch (error) { + expect(error.message).to.be.eql( + 'subscriberId under property to is type array, which is not allowed please make sure all subscribers ids are strings' + ); + } + }); +}); + +const buildCommand = ( + session: UserSession, + transactionId: string, + to: TriggerRecipients, + identifier: string +): ParseEventRequestCommand => { + return ParseEventRequestCommand.create({ + organizationId: session.organization._id, + environmentId: session.environment._id, + to, + transactionId, + userId: session.user._id, + identifier, + payload: {}, + overrides: {}, + }); +}; diff --git a/apps/api/src/app/events/usecases/parse-event-request/parse-event-request.usecase.ts b/apps/api/src/app/events/usecases/parse-event-request/parse-event-request.usecase.ts index c0546cd5240..32853c50ebc 100644 --- a/apps/api/src/app/events/usecases/parse-event-request/parse-event-request.usecase.ts +++ b/apps/api/src/app/events/usecases/parse-event-request/parse-event-request.usecase.ts @@ -173,6 +173,12 @@ export class ParseEventRequest { for (const subscriber of to) { const subscriberIdExists = typeof subscriber === 'string' ? subscriber : subscriber.subscriberId; + if (Array.isArray(subscriberIdExists)) { + throw new ApiException( + 'subscriberId under property to is type array, which is not allowed please make sure all subscribers ids are strings' + ); + } + if (!subscriberIdExists) { throw new ApiException( 'subscriberId under property to is not configured, please make sure all subscribers contains subscriberId property' diff --git a/apps/api/src/app/inbound-parse/e2e/inbound-email-parse.e2e.ts b/apps/api/src/app/inbound-parse/e2e/inbound-email-parse.e2e.ts index 5bc3218bc44..ef8f8a974d2 100644 --- a/apps/api/src/app/inbound-parse/e2e/inbound-email-parse.e2e.ts +++ b/apps/api/src/app/inbound-parse/e2e/inbound-email-parse.e2e.ts @@ -75,39 +75,38 @@ describe('Should handle the new arrived mail', () => { }); it('should not send webhook request with missing transactionId', async () => { - const message = await triggerEmail(); - - const mail = getMailData(message, false); - - const getStub = sandbox.stub(axios, 'post').resolves(); - - await inboundEmailParseUsecase.execute(InboundEmailParseCommand.create(mail)); - - sinon.assert.notCalled(getStub); + try { + const message = await triggerEmail(); + const mail = getMailData(message, false); + + await inboundEmailParseUsecase.execute(InboundEmailParseCommand.create(mail)); + } catch (e) { + expect(e.message).to.contains('Missing transactionId on address'); + } }); it('should not send webhook request with when domain white list', async () => { - const message = await triggerEmail(true, false); + try { + const message = await triggerEmail(true, false); - const mail = getMailData(message); + const mail = getMailData(message); - const getStub = sandbox.stub(axios, 'post').resolves(); - - await inboundEmailParseUsecase.execute(InboundEmailParseCommand.create(mail)); - - sinon.assert.notCalled(getStub); + await inboundEmailParseUsecase.execute(InboundEmailParseCommand.create(mail)); + } catch (e) { + expect(e.message).to.equal('Domain is not in environment white list'); + } }); it('should not send webhook request when missing replay callback url', async () => { - const message = await triggerEmail(true, true, true, false); - - const mail = getMailData(message); - - const getStub = sandbox.stub(axios, 'post').resolves(); + try { + const message = await triggerEmail(true, true, true, false); - await inboundEmailParseUsecase.execute(InboundEmailParseCommand.create(mail)); + const mail = getMailData(message); - sinon.assert.notCalled(getStub); + await inboundEmailParseUsecase.execute(InboundEmailParseCommand.create(mail)); + } catch (e) { + expect(e.message).to.contains('Missing parse webhook on template'); + } }); async function triggerEmail( diff --git a/apps/api/src/app/inbound-parse/services/inbound-parse.queue.service.ts b/apps/api/src/app/inbound-parse/services/inbound-parse.queue.service.ts index 2848eafbe72..dc4b3cf24ca 100644 --- a/apps/api/src/app/inbound-parse/services/inbound-parse.queue.service.ts +++ b/apps/api/src/app/inbound-parse/services/inbound-parse.queue.service.ts @@ -7,11 +7,13 @@ import { WorkerOptions, } from '@novu/application-generic'; import { JobTopicNameEnum } from '@novu/shared'; -import { Injectable } from '@nestjs/common'; +import { Injectable, Logger } from '@nestjs/common'; import { InboundEmailParse } from '../usecases/inbound-email-parse/inbound-email-parse.usecase'; import { InboundEmailParseCommand } from '../usecases/inbound-email-parse/inbound-email-parse.command'; +const LOG_CONTEXT = 'InboundParseQueueService'; + @Injectable() export class InboundParseQueueService { public readonly queue: Queue; @@ -35,6 +37,7 @@ export class InboundParseQueueService { public getWorkerProcessor() { return async ({ data }: { data: InboundEmailParseCommand }) => { + Logger.verbose({ data }, 'Processing the inbound parsed email', LOG_CONTEXT); await this.emailParseUsecase.execute(InboundEmailParseCommand.create({ ...data })); }; } diff --git a/apps/api/src/app/inbound-parse/usecases/inbound-email-parse/inbound-email-parse.usecase.ts b/apps/api/src/app/inbound-parse/usecases/inbound-email-parse/inbound-email-parse.usecase.ts index c0545391f66..682dc6abbd0 100644 --- a/apps/api/src/app/inbound-parse/usecases/inbound-email-parse/inbound-email-parse.usecase.ts +++ b/apps/api/src/app/inbound-parse/usecases/inbound-email-parse/inbound-email-parse.usecase.ts @@ -1,4 +1,4 @@ -import { Injectable, Logger } from '@nestjs/common'; +import { BadRequestException, Injectable, Logger } from '@nestjs/common'; import { InboundEmailParseCommand } from './inbound-email-parse.command'; import { JobEntity, @@ -12,6 +12,8 @@ import axios from 'axios'; import { createHash } from '../../../shared/helpers/hmac.service'; import { CompileTemplate, CompileTemplateCommand } from '@novu/application-generic'; +const LOG_CONTEXT = 'InboundEmailParse'; + @Injectable() export class InboundEmailParse { constructor( @@ -21,55 +23,38 @@ export class InboundEmailParse { ) {} async execute(command: InboundEmailParseCommand) { - const { toDomain, toTransactionId, toEnvironmentId } = this.splitTo(command.to[0].address); - - Logger.debug('toDomain in InboundEmailParse is: ' + toDomain); - Logger.debug('toTransactionId in InboundEmailParse is: ' + toTransactionId); - - if (!toTransactionId) { - Logger.warn(`missing transactionId on address ${command.to[0].address}`); - - return; - } + const { domain, transactionId, environmentId } = this.splitTo(command.to[0].address); - Logger.debug('toEnvironmentId in InboundEmailParse is: ' + toEnvironmentId); - - if (!toEnvironmentId) { - Logger.warn(`missing environmentId on address ${command.to[0].address}`); - - return; - } + Logger.debug({ domain, transactionId, environmentId }, `Received new email to parse`, LOG_CONTEXT); const { template, notification, subscriber, environment, job, message } = await this.getEntities( - toTransactionId, - toEnvironmentId + transactionId, + environmentId ); - if (toDomain !== environment?.dns?.inboundParseDomain) { - Logger.warn('to domain is not in environment white list'); - - return; + if (domain !== environment?.dns?.inboundParseDomain) { + this.throwMiddleware('Domain is not in environment white list'); } const currentParseWebhook = template.steps.find((step) => step?._id?.toString() === job?.step?._id)?.replyCallback ?.url; if (!currentParseWebhook) { - Logger.warn(`missing parse webhook on template ${template._id} job ${job._id} transactionId ${toTransactionId}.`); - - return; + this.throwMiddleware( + `Missing parse webhook on template ${template._id} job ${job._id} transactionId ${transactionId}.` + ); } const compiledDomain = await this.compileTemplate.execute( CompileTemplateCommand.create({ - template: currentParseWebhook, + template: currentParseWebhook as string, data: job.payload, }) ); const userPayload: IUserWebhookPayload = { hmac: createHash(environment?.apiKeys[0]?.key, subscriber.subscriberId), - transactionId: toTransactionId, + transactionId: transactionId, payload: job.payload, templateIdentifier: job.identifier, template, @@ -84,11 +69,29 @@ export class InboundEmailParse { private splitTo(address: string) { const userNameDelimiter = '-nv-e='; - const [toUser, toDomain] = address.split('@'); - const toMetaIds = toUser.split('+')[1]; - const [toTransactionId, toEnvironmentId] = toMetaIds.split(userNameDelimiter); + const [user, domain] = address.split('@'); + const toMetaIds = user.split('+')[1]; + const [transactionId, environmentId] = toMetaIds.split(userNameDelimiter); + + if (!transactionId) { + this.throwMiddleware(`Missing transactionId on address ${address}`); + } + + if (!domain) { + this.throwMiddleware(`Missing domain on address ${address}`); + } + + if (!environmentId) { + this.throwMiddleware(`Missing environmentId on address ${address}`); + } + + return { domain, transactionId, environmentId }; + } + + private throwMiddleware(error: string) { + Logger.error(error, LOG_CONTEXT); - return { toDomain, toTransactionId, toEnvironmentId }; + throw new BadRequestException(error); } private async getEntities(transactionId: string, environmentId: string) { diff --git a/apps/inbound-mail/package.json b/apps/inbound-mail/package.json index c6b33eddec1..d3631b027b5 100644 --- a/apps/inbound-mail/package.json +++ b/apps/inbound-mail/package.json @@ -1,6 +1,6 @@ { "name": "@novu/inbound-mail", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "", "author": "", "private": true, @@ -19,8 +19,8 @@ "test": "cross-env TS_NODE_COMPILER_OPTIONS='{\"strictNullChecks\": false}' TZ=UTC NODE_ENV=test E2E_RUNNER=true mocha --trace-warnings --timeout 10000 --require ts-node/register --exit --file e2e/setup.ts src/**/**/*.spec.ts" }, "dependencies": { - "@novu/application-generic": "^0.19.0", - "@novu/shared": "^0.19.0", + "@novu/application-generic": "^0.20.0-alpha.0", + "@novu/shared": "^0.20.0-alpha.0", "@sentry/node": "^7.12.1", "bluebird": "^2.9.30", "dotenv": "^8.6.0", @@ -39,7 +39,7 @@ "winston": "^3.9.0" }, "devDependencies": { - "@novu/testing": "^0.19.0", + "@novu/testing": "^0.20.0-alpha.0", "@types/chai": "^4.2.11", "@types/express": "^4.17.8", "@types/html-to-text": "^9.0.1", diff --git a/apps/web/package.json b/apps/web/package.json index 1fa2b8c0434..1a8ebcc7f19 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,6 +1,6 @@ { "name": "@novu/web", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "private": true, "scripts": { "start": "cross-env PORT=4200 react-app-rewired start", @@ -49,8 +49,8 @@ "@mantine/notifications": "^5.7.1", "@mantine/prism": "^5.7.1", "@mantine/spotlight": "^5.7.1", - "@novu/notification-center": "^0.19.0", - "@novu/shared": "^0.19.0", + "@novu/notification-center": "^0.20.0-alpha.0", + "@novu/shared": "^0.20.0-alpha.0", "@segment/analytics-next": "^1.48.0", "@sentry/react": "^7.40.0", "@sentry/tracing": "^7.40.0", @@ -126,8 +126,8 @@ "@babel/preset-react": "^7.13.13", "@babel/preset-typescript": "^7.13.0", "@babel/runtime": "^7.20.13", - "@novu/dal": "^0.19.0", - "@novu/testing": "^0.19.0", + "@novu/dal": "^0.20.0-alpha.0", + "@novu/testing": "^0.20.0-alpha.0", "@storybook/addon-actions": "^7.4.2", "@storybook/addon-essentials": "^7.4.2", "@storybook/addon-links": "^7.4.2", diff --git a/apps/web/src/pages/auth/components/LoginForm.tsx b/apps/web/src/pages/auth/components/LoginForm.tsx index 77499e5fa53..0b4d9efb91e 100644 --- a/apps/web/src/pages/auth/components/LoginForm.tsx +++ b/apps/web/src/pages/auth/components/LoginForm.tsx @@ -113,7 +113,7 @@ export function LoginForm({ email, invitationToken }: LoginFormProps) { > Sign In with GitHub - Sign In with Google - + */} Or} color={colors.B30} labelPosition="center" my="md" /> diff --git a/apps/webhook/package.json b/apps/webhook/package.json index 4448c955d19..26de79fcf22 100644 --- a/apps/webhook/package.json +++ b/apps/webhook/package.json @@ -1,6 +1,6 @@ { "name": "@novu/webhook", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "", "author": "", "private": true, @@ -25,11 +25,11 @@ "@nestjs/core": "^10.2.2", "@nestjs/platform-express": "^10.2.2", "@nestjs/terminus": "^10.0.1", - "@novu/application-generic": "^0.19.0", - "@novu/dal": "^0.19.0", - "@novu/shared": "^0.19.0", - "@novu/stateless": "^0.19.0", - "@novu/testing": "^0.19.0", + "@novu/application-generic": "^0.20.0-alpha.0", + "@novu/dal": "^0.20.0-alpha.0", + "@novu/shared": "^0.20.0-alpha.0", + "@novu/stateless": "^0.20.0-alpha.0", + "@novu/testing": "^0.20.0-alpha.0", "@sentry/node": "^7.66.0", "axios": "^1.3.3", "class-transformer": "^0.5.1", diff --git a/apps/widget/package.json b/apps/widget/package.json index 64f36674b15..8265f5f1768 100644 --- a/apps/widget/package.json +++ b/apps/widget/package.json @@ -1,6 +1,6 @@ { "name": "@novu/widget", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "private": true, "scripts": { "start": "craco start", @@ -29,8 +29,8 @@ "@emotion/styled": "^11.6.0", "@mantine/core": "4.2.12", "@mantine/hooks": "4.2.12", - "@novu/notification-center": "^0.19.0", - "@novu/shared": "^0.19.0", + "@novu/notification-center": "^0.20.0-alpha.0", + "@novu/shared": "^0.20.0-alpha.0", "antd": "^4.10.0", "babel-plugin-import": "^1.13.3", "chroma-js": "^2.4.2", @@ -55,8 +55,8 @@ "@craco/craco": "^7.0.0", "@emotion/babel-plugin": "^11.7.2", "@faker-js/faker": "^6.0.0", - "@novu/dal": "^0.19.0", - "@novu/testing": "^0.19.0", + "@novu/dal": "^0.20.0-alpha.0", + "@novu/testing": "^0.20.0-alpha.0", "@types/jest": "^29.5.0", "@types/node": "^12.0.0", "@types/react": "17.0.62", diff --git a/apps/worker/package.json b/apps/worker/package.json index 1ed87723264..5ea2385c5b8 100644 --- a/apps/worker/package.json +++ b/apps/worker/package.json @@ -1,6 +1,6 @@ { "name": "@novu/worker", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "description", "author": "", "private": "true", @@ -29,11 +29,11 @@ "@nestjs/platform-express": "^10.2.2", "@nestjs/swagger": "^7.1.9", "@nestjs/terminus": "^10.0.1", - "@novu/application-generic": "^0.19.0", - "@novu/dal": "^0.19.0", - "@novu/shared": "^0.19.0", - "@novu/stateless": "^0.19.0", - "@novu/testing": "^0.19.0", + "@novu/application-generic": "^0.20.0-alpha.0", + "@novu/dal": "^0.20.0-alpha.0", + "@novu/shared": "^0.20.0-alpha.0", + "@novu/stateless": "^0.20.0-alpha.0", + "@novu/testing": "^0.20.0-alpha.0", "@sentry/node": "^7.40.0", "@sentry/tracing": "^7.40.0", "@types/newrelic": "^9.13.0", diff --git a/apps/worker/src/app/workflow/services/cold-start.service.ts b/apps/worker/src/app/workflow/services/cold-start.service.ts index 191223d7024..f132c7decf3 100644 --- a/apps/worker/src/app/workflow/services/cold-start.service.ts +++ b/apps/worker/src/app/workflow/services/cold-start.service.ts @@ -3,6 +3,7 @@ import { INovuWorker, ReadinessService } from '@novu/application-generic'; import { StandardWorker } from './standard.worker'; import { WorkflowWorker } from './workflow.worker'; +import { OldInstanceStandardWorker } from './old-instance-standard.worker'; import { OldInstanceWorkflowWorker } from './old-instance-workflow.worker'; /** @@ -11,9 +12,10 @@ import { OldInstanceWorkflowWorker } from './old-instance-workflow.worker'; const getWorkers = (app: INestApplication): INovuWorker[] => { const standardWorker = app.get(StandardWorker, { strict: false }); const workflowWorker = app.get(WorkflowWorker, { strict: false }); + const oldInstanceStandardWorker = app.get(OldInstanceStandardWorker, { strict: false }); const oldInstanceWorkflowWorker = app.get(OldInstanceWorkflowWorker, { strict: false }); - const workers: INovuWorker[] = [standardWorker, workflowWorker, oldInstanceWorkflowWorker]; + const workers: INovuWorker[] = [standardWorker, workflowWorker, oldInstanceStandardWorker, oldInstanceWorkflowWorker]; return workers; }; diff --git a/apps/worker/src/app/workflow/services/index.ts b/apps/worker/src/app/workflow/services/index.ts index 228b77b38c1..ee0d3b62794 100644 --- a/apps/worker/src/app/workflow/services/index.ts +++ b/apps/worker/src/app/workflow/services/index.ts @@ -2,4 +2,5 @@ export * from './active-jobs-metric.service'; export * from './completed-jobs-metric.service'; export * from './standard.worker'; export * from './workflow.worker'; +export * from './old-instance-standard.worker'; export * from './old-instance-workflow.worker'; diff --git a/apps/worker/src/app/workflow/services/old-instance-standard.worker.ts b/apps/worker/src/app/workflow/services/old-instance-standard.worker.ts new file mode 100644 index 00000000000..e8fdde4afd8 --- /dev/null +++ b/apps/worker/src/app/workflow/services/old-instance-standard.worker.ts @@ -0,0 +1,199 @@ +const nr = require('newrelic'); +import { forwardRef, Inject, Injectable, Logger } from '@nestjs/common'; +import { IJobData, ObservabilityBackgroundTransactionEnum } from '@novu/shared'; +import { + INovuWorker, + Job, + OldInstanceBullMqService, + PinoLogger, + storage, + Store, + OldInstanceStandardWorkerService, + WorkerOptions, +} from '@novu/application-generic'; + +import { + RunJob, + RunJobCommand, + SetJobAsCommand, + SetJobAsCompleted, + SetJobAsFailed, + SetJobAsFailedCommand, + WebhookFilterBackoffStrategy, + HandleLastFailedJobCommand, + HandleLastFailedJob, +} from '../usecases'; + +const LOG_CONTEXT = 'OldInstanceStandardWorker'; + +/** + * TODO: Temporary for migration to MemoryDB + */ +@Injectable() +export class OldInstanceStandardWorker extends OldInstanceStandardWorkerService implements INovuWorker { + constructor( + private handleLastFailedJob: HandleLastFailedJob, + private runJob: RunJob, + @Inject(forwardRef(() => SetJobAsCompleted)) private setJobAsCompleted: SetJobAsCompleted, + @Inject(forwardRef(() => SetJobAsFailed)) private setJobAsFailed: SetJobAsFailed, + @Inject(forwardRef(() => WebhookFilterBackoffStrategy)) + private webhookFilterBackoffStrategy: WebhookFilterBackoffStrategy + ) { + super(); + + this.initWorker(this.getWorkerProcessor(), this.getWorkerOptions()); + + if (this.bullMqService.enabled) { + this.worker.on('completed', async (job: Job): Promise => { + await this.jobHasCompleted(job); + }); + + this.worker.on('failed', async (job: Job, error: Error): Promise => { + await this.jobHasFailed(job, error); + }); + } + } + + private getWorkerOptions(): WorkerOptions { + return { + lockDuration: 90000, + concurrency: 200, + settings: { + backoffStrategy: this.getBackoffStrategies(), + }, + }; + } + + private extractMinimalJobData(job: any): { + environmentId: string; + organizationId: string; + jobId: string; + userId: string; + } { + const { _environmentId: environmentId, _id: jobId, _organizationId: organizationId, _userId: userId } = job; + + if (!environmentId || !jobId || !organizationId || !userId) { + const message = job.payload.message; + + return { + environmentId: message._environmentId, + jobId: message._jobId, + organizationId: message._organizationId, + userId: job.userId, + }; + } + + return { + environmentId, + jobId, + organizationId, + userId, + }; + } + + private getWorkerProcessor() { + return async ({ data }: { data: IJobData | any }) => { + const minimalJobData = this.extractMinimalJobData(data); + + Logger.verbose(`Job ${minimalJobData.jobId} is being processed in the old instance standard worker`, LOG_CONTEXT); + + return await new Promise(async (resolve, reject) => { + // eslint-disable-next-line @typescript-eslint/no-this-alias + const _this = this; + + nr.startBackgroundTransaction( + ObservabilityBackgroundTransactionEnum.JOB_PROCESSING_QUEUE, + 'Trigger Engine', + function () { + const transaction = nr.getTransaction(); + + storage.run(new Store(PinoLogger.root), () => { + _this.runJob + .execute(RunJobCommand.create(minimalJobData)) + .then(resolve) + .catch((error) => { + Logger.error( + error, + `Failed to run the job ${minimalJobData.jobId} during worker processing`, + LOG_CONTEXT + ); + + return reject(error); + }) + .finally(() => { + transaction.end(); + }); + }); + } + ); + }); + }; + } + + private async jobHasCompleted(job: Job): Promise { + let jobId; + + try { + const minimalData = this.extractMinimalJobData(job.data); + jobId = minimalData.jobId; + const environmentId = minimalData.environmentId; + const userId = minimalData.userId; + + await this.setJobAsCompleted.execute( + SetJobAsCommand.create({ + environmentId, + jobId, + userId, + }) + ); + Logger.verbose({ job }, `Job ${jobId} set as completed`, LOG_CONTEXT); + } catch (error) { + Logger.error(error, `Failed to set job ${jobId} as completed`, LOG_CONTEXT); + } + } + + private async jobHasFailed(job: Job, error: Error): Promise { + let jobId; + + try { + const minimalData = this.extractMinimalJobData(job.data); + jobId = minimalData.jobId; + + const hasToBackoff = this.runJob.shouldBackoff(error); + const hasReachedMaxAttempts = job.attemptsMade >= this.DEFAULT_ATTEMPTS; + const shouldHandleLastFailedJob = hasToBackoff && hasReachedMaxAttempts; + + const shouldBeSetAsFailed = !hasToBackoff || shouldHandleLastFailedJob; + if (shouldBeSetAsFailed) { + await this.setJobAsFailed.execute(SetJobAsFailedCommand.create(minimalData), error); + } + + if (shouldHandleLastFailedJob) { + const handleLastFailedJobCommand = HandleLastFailedJobCommand.create({ + ...minimalData, + error, + }); + + await this.handleLastFailedJob.execute(handleLastFailedJobCommand); + } + Logger.verbose({ job }, `Job ${jobId} set as failed`, LOG_CONTEXT); + } catch (anotherError) { + Logger.error(anotherError, `Failed to set job ${jobId} as failed`, LOG_CONTEXT); + } + } + + private getBackoffStrategies = () => { + return async (attemptsMade: number, type: string, eventError: Error, eventJob: Job): Promise => { + const command = { + attemptsMade, + environmentId: eventJob?.data?._environmentId, + eventError, + eventJob, + organizationId: eventJob?.data?._organizationId, + userId: eventJob?.data?._userId, + }; + + return await this.webhookFilterBackoffStrategy.execute(command); + }; + }; +} diff --git a/apps/worker/src/app/workflow/services/old-instance-workflow.worker.ts b/apps/worker/src/app/workflow/services/old-instance-workflow.worker.ts index 56e7fa41ac0..60d6535c07f 100644 --- a/apps/worker/src/app/workflow/services/old-instance-workflow.worker.ts +++ b/apps/worker/src/app/workflow/services/old-instance-workflow.worker.ts @@ -9,21 +9,10 @@ import { storage, Store, OldInstanceWorkflowWorkerService, + TriggerEvent, WorkerOptions, } from '@novu/application-generic'; -import { - RunJob, - RunJobCommand, - SetJobAsCommand, - SetJobAsCompleted, - SetJobAsFailed, - SetJobAsFailedCommand, - WebhookFilterBackoffStrategy, - HandleLastFailedJobCommand, - HandleLastFailedJob, -} from '../usecases'; - const LOG_CONTEXT = 'OldInstanceWorkflowWorker'; /** @@ -31,93 +20,38 @@ const LOG_CONTEXT = 'OldInstanceWorkflowWorker'; */ @Injectable() export class OldInstanceWorkflowWorker extends OldInstanceWorkflowWorkerService implements INovuWorker { - constructor( - private handleLastFailedJob: HandleLastFailedJob, - private runJob: RunJob, - @Inject(forwardRef(() => SetJobAsCompleted)) private setJobAsCompleted: SetJobAsCompleted, - @Inject(forwardRef(() => SetJobAsFailed)) private setJobAsFailed: SetJobAsFailed, - @Inject(forwardRef(() => WebhookFilterBackoffStrategy)) - private webhookFilterBackoffStrategy: WebhookFilterBackoffStrategy - ) { + constructor(private triggerEventUsecase: TriggerEvent) { super(); this.initWorker(this.getWorkerProcessor(), this.getWorkerOptions()); - - if (this.bullMqService.enabled) { - this.worker.on('completed', async (job: Job): Promise => { - await this.jobHasCompleted(job); - }); - - this.worker.on('failed', async (job: Job, error: Error): Promise => { - await this.jobHasFailed(job, error); - }); - } } private getWorkerOptions(): WorkerOptions { return { lockDuration: 90000, concurrency: 200, - settings: { - backoffStrategy: this.getBackoffStrategies(), - }, - }; - } - - private extractMinimalJobData(job: any): { - environmentId: string; - organizationId: string; - jobId: string; - userId: string; - } { - const { _environmentId: environmentId, _id: jobId, _organizationId: organizationId, _userId: userId } = job; - - if (!environmentId || !jobId || !organizationId || !userId) { - const message = job.payload.message; - - return { - environmentId: message._environmentId, - jobId: message._jobId, - organizationId: message._organizationId, - userId: job.userId, - }; - } - - return { - environmentId, - jobId, - organizationId, - userId, }; } private getWorkerProcessor() { return async ({ data }: { data: IJobData | any }) => { - const minimalJobData = this.extractMinimalJobData(data); - return await new Promise(async (resolve, reject) => { // eslint-disable-next-line @typescript-eslint/no-this-alias const _this = this; + Logger.verbose(`Job ${data._id} is being processed in the old instance workflow worker`, LOG_CONTEXT); + nr.startBackgroundTransaction( - ObservabilityBackgroundTransactionEnum.JOB_PROCESSING_QUEUE, + ObservabilityBackgroundTransactionEnum.TRIGGER_HANDLER_QUEUE, 'Trigger Engine', function () { const transaction = nr.getTransaction(); storage.run(new Store(PinoLogger.root), () => { - _this.runJob - .execute(RunJobCommand.create(minimalJobData)) + _this.triggerEventUsecase + .execute(data) .then(resolve) - .catch((error) => { - Logger.error( - error, - `Failed to run the job ${minimalJobData.jobId} during worker processing`, - LOG_CONTEXT - ); - - return reject(error); - }) + .catch(reject) .finally(() => { transaction.end(); }); @@ -127,71 +61,4 @@ export class OldInstanceWorkflowWorker extends OldInstanceWorkflowWorkerService }); }; } - - private async jobHasCompleted(job: Job): Promise { - let jobId; - - try { - const minimalData = this.extractMinimalJobData(job.data); - jobId = minimalData.jobId; - const environmentId = minimalData.environmentId; - const userId = minimalData.userId; - - await this.setJobAsCompleted.execute( - SetJobAsCommand.create({ - environmentId, - jobId, - userId, - }) - ); - Logger.verbose({ job }, `Job ${jobId} set as completed`, LOG_CONTEXT); - } catch (error) { - Logger.error(error, `Failed to set job ${jobId} as completed`, LOG_CONTEXT); - } - } - - private async jobHasFailed(job: Job, error: Error): Promise { - let jobId; - - try { - const minimalData = this.extractMinimalJobData(job.data); - jobId = minimalData.jobId; - - const hasToBackoff = this.runJob.shouldBackoff(error); - const hasReachedMaxAttempts = job.attemptsMade >= this.DEFAULT_ATTEMPTS; - const shouldHandleLastFailedJob = hasToBackoff && hasReachedMaxAttempts; - - const shouldBeSetAsFailed = !hasToBackoff || shouldHandleLastFailedJob; - if (shouldBeSetAsFailed) { - await this.setJobAsFailed.execute(SetJobAsFailedCommand.create(minimalData), error); - } - - if (shouldHandleLastFailedJob) { - const handleLastFailedJobCommand = HandleLastFailedJobCommand.create({ - ...minimalData, - error, - }); - - await this.handleLastFailedJob.execute(handleLastFailedJobCommand); - } - Logger.verbose({ job }, `Job ${jobId} set as failed`, LOG_CONTEXT); - } catch (anotherError) { - Logger.error(anotherError, `Failed to set job ${jobId} as failed`, LOG_CONTEXT); - } - } - - private getBackoffStrategies = () => { - return async (attemptsMade: number, type: string, eventError: Error, eventJob: Job): Promise => { - const command = { - attemptsMade, - environmentId: eventJob?.data?._environmentId, - eventError, - eventJob, - organizationId: eventJob?.data?._organizationId, - userId: eventJob?.data?._userId, - }; - - return await this.webhookFilterBackoffStrategy.execute(command); - }; - }; } diff --git a/apps/worker/src/app/workflow/services/standard.worker.ts b/apps/worker/src/app/workflow/services/standard.worker.ts index a8dc38c9b15..3b4cca0254d 100644 --- a/apps/worker/src/app/workflow/services/standard.worker.ts +++ b/apps/worker/src/app/workflow/services/standard.worker.ts @@ -94,6 +94,8 @@ export class StandardWorker extends StandardWorkerService implements INovuWorker return async ({ data }: { data: IJobData | any }) => { const minimalJobData = this.extractMinimalJobData(data); + Logger.verbose(`Job ${minimalJobData.jobId} is being processed in the new instance standard worker`, LOG_CONTEXT); + return await new Promise(async (resolve, reject) => { // eslint-disable-next-line @typescript-eslint/no-this-alias const _this = this; diff --git a/apps/worker/src/app/workflow/services/workflow.worker.ts b/apps/worker/src/app/workflow/services/workflow.worker.ts index 4a7d9b309e7..34c67d1dd45 100644 --- a/apps/worker/src/app/workflow/services/workflow.worker.ts +++ b/apps/worker/src/app/workflow/services/workflow.worker.ts @@ -36,6 +36,8 @@ export class WorkflowWorker extends WorkflowWorkerService implements INovuWorker // eslint-disable-next-line @typescript-eslint/no-this-alias const _this = this; + Logger.verbose(`Job ${data.identifier} is being processed in the new instance workflow worker`, LOG_CONTEXT); + nr.startBackgroundTransaction( ObservabilityBackgroundTransactionEnum.TRIGGER_HANDLER_QUEUE, 'Trigger Engine', diff --git a/apps/worker/src/app/workflow/usecases/run-job/run-job.usecase.ts b/apps/worker/src/app/workflow/usecases/run-job/run-job.usecase.ts index f7b1f2b4e5b..aac6297aff8 100644 --- a/apps/worker/src/app/workflow/usecases/run-job/run-job.usecase.ts +++ b/apps/worker/src/app/workflow/usecases/run-job/run-job.usecase.ts @@ -40,7 +40,7 @@ export class RunJob { jobId: job._id, }); } catch (e) { - Logger.error(e, 'RunJob'); + Logger.error(e, 'RunJob', LOG_CONTEXT); } const canceled = await this.delayedEventIsCanceled(job); diff --git a/apps/worker/src/app/workflow/usecases/send-message/send-message.usecase.ts b/apps/worker/src/app/workflow/usecases/send-message/send-message.usecase.ts index d68528ac9f0..f6550189940 100644 --- a/apps/worker/src/app/workflow/usecases/send-message/send-message.usecase.ts +++ b/apps/worker/src/app/workflow/usecases/send-message/send-message.usecase.ts @@ -85,7 +85,7 @@ export class SendMessage { }; } - this.analyticsService.track('Process Workflow Step - [Triggers]', command.userId, { + this.analyticsService.mixpanelTrack('Process Workflow Step - [Triggers]', '', { _template: command.job._templateId, _organization: command.organizationId, _environment: command.environmentId, diff --git a/apps/worker/src/app/workflow/workflow.module.ts b/apps/worker/src/app/workflow/workflow.module.ts index 5c60966f028..17cc75ed935 100644 --- a/apps/worker/src/app/workflow/workflow.module.ts +++ b/apps/worker/src/app/workflow/workflow.module.ts @@ -34,6 +34,7 @@ import { StandardWorker, WorkflowWorker, OldInstanceWorkflowWorker, + OldInstanceStandardWorker, } from './services'; import { @@ -111,6 +112,7 @@ const PROVIDERS: Provider[] = [ StandardWorker, WorkflowWorker, OldInstanceBullMqService, + OldInstanceStandardWorker, OldInstanceWorkflowWorker, ]; diff --git a/apps/ws/package.json b/apps/ws/package.json index 50946b41473..69628c19e86 100644 --- a/apps/ws/package.json +++ b/apps/ws/package.json @@ -1,6 +1,6 @@ { "name": "@novu/ws", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "", "author": "", "private": true, @@ -28,10 +28,10 @@ "@nestjs/swagger": "^7.1.9", "@nestjs/terminus": "^10.0.1", "@nestjs/websockets": "^10.2.2", - "@novu/application-generic": "^0.19.0", - "@novu/dal": "^0.19.0", - "@novu/shared": "^0.19.0", - "@novu/testing": "^0.19.0", + "@novu/application-generic": "^0.20.0-alpha.0", + "@novu/dal": "^0.20.0-alpha.0", + "@novu/shared": "^0.20.0-alpha.0", + "@novu/testing": "^0.20.0-alpha.0", "@sentry/node": "^7.30.0", "@socket.io/redis-adapter": "^7.2.0", "class-transformer": "^0.5.1", diff --git a/apps/ws/src/socket/services/index.ts b/apps/ws/src/socket/services/index.ts index b03b9f0b02d..735d2d9ed04 100644 --- a/apps/ws/src/socket/services/index.ts +++ b/apps/ws/src/socket/services/index.ts @@ -1 +1,3 @@ +export { OldInstanceWebSocketsWorker } from './old-instance-web-sockets.worker'; +export { OldInstanceWebSocketsWorkerService } from './old-instance-web-sockets-worker.service'; export { WebSocketWorker } from './web-socket.worker'; diff --git a/apps/ws/src/socket/services/old-instance-web-sockets-worker.service.ts b/apps/ws/src/socket/services/old-instance-web-sockets-worker.service.ts new file mode 100644 index 00000000000..91ba7c714c6 --- /dev/null +++ b/apps/ws/src/socket/services/old-instance-web-sockets-worker.service.ts @@ -0,0 +1,91 @@ +import { IJobData, JobTopicNameEnum } from '@novu/shared'; +import { Inject, Injectable, Logger } from '@nestjs/common'; + +import { JobsOptions, OldInstanceBullMqService, Processor, Worker, WorkerOptions } from '@novu/application-generic'; + +const LOG_CONTEXT = 'OldInstanceWebSocketsWorkerService'; + +type WorkerProcessor = string | Processor | undefined; + +/** + * TODO: Temporary for migration to MemoryDB + */ +export class OldInstanceWebSocketsWorkerService { + private instance: OldInstanceBullMqService; + + public readonly DEFAULT_ATTEMPTS = 3; + public readonly topic: JobTopicNameEnum; + + constructor() { + this.topic = JobTopicNameEnum.WEB_SOCKETS; + this.instance = new OldInstanceBullMqService(); + if (this.instance.enabled) { + Logger.log(`Old instance Worker ${this.topic} instantiated`, LOG_CONTEXT); + } else { + Logger.warn( + `Old instance web sockets worker not instantiated as it is only needed for MemoryDB migration`, + LOG_CONTEXT + ); + } + } + + public get bullMqService(): OldInstanceBullMqService { + return this.instance; + } + + public get worker(): Worker { + return this.instance.worker; + } + + public initWorker(processor: WorkerProcessor, options?: WorkerOptions): void { + if (this.instance.enabled) { + this.createWorker(processor, options); + } + } + + public createWorker(processor: WorkerProcessor, options?: WorkerOptions): void { + if (this.instance.enabled) { + this.instance.createWorker(this.topic, processor, options); + } else { + Logger.log( + { enabled: this.instance.enabled }, + 'We are not running OldInstanceWorkflowWorkerService as it is not needed in this environment', + LOG_CONTEXT + ); + } + } + + public async isRunning(): Promise { + return await this.instance.isWorkerRunning(); + } + + public async isPaused(): Promise { + return await this.instance.isWorkerPaused(); + } + + public async pause(): Promise { + if (this.instance.enabled && this.worker) { + await this.instance.pauseWorker(); + } + } + + public async resume(): Promise { + if (this.instance.enabled && this.worker) { + await this.instance.resumeWorker(); + } + } + + public async gracefulShutdown(): Promise { + if (this.instance.enabled) { + Logger.log('Shutting the old web sockets Worker service down', LOG_CONTEXT); + + await this.instance.gracefulShutdown(); + + Logger.log('Shutting down the old web sockets Worker service has finished', LOG_CONTEXT); + } + } + + async onModuleDestroy(): Promise { + await this.gracefulShutdown(); + } +} diff --git a/apps/ws/src/socket/services/old-instance-web-sockets.worker.ts b/apps/ws/src/socket/services/old-instance-web-sockets.worker.ts new file mode 100644 index 00000000000..fea4f6138c6 --- /dev/null +++ b/apps/ws/src/socket/services/old-instance-web-sockets.worker.ts @@ -0,0 +1,71 @@ +const nr = require('newrelic'); +import { Injectable, Logger } from '@nestjs/common'; + +import { INovuWorker, WebSocketsWorkerService } from '@novu/application-generic'; + +import { ExternalServicesRoute, ExternalServicesRouteCommand } from '../usecases/external-services-route'; +import { ObservabilityBackgroundTransactionEnum } from '@novu/shared'; +import { OldInstanceWebSocketsWorkerService } from './old-instance-web-sockets-worker.service'; + +const LOG_CONTEXT = 'OldInstanceWebSocketsWorker'; + +@Injectable() +export class OldInstanceWebSocketsWorker extends OldInstanceWebSocketsWorkerService implements INovuWorker { + constructor(private externalServicesRoute: ExternalServicesRoute) { + super(); + + this.initWorker(this.getWorkerProcessor(), this.getWorkerOpts()); + } + + private getWorkerProcessor() { + return async (job) => { + return new Promise((resolve, reject) => { + // eslint-disable-next-line @typescript-eslint/no-this-alias + const _this = this; + + Logger.verbose( + `Job ${job.id} / ${job.data.event} is being processed in the old instance web sockets worker`, + LOG_CONTEXT + ); + + nr.startBackgroundTransaction( + ObservabilityBackgroundTransactionEnum.WS_SOCKET_QUEUE, + 'WS Service', + function () { + const transaction = nr.getTransaction(); + + _this.externalServicesRoute + .execute( + ExternalServicesRouteCommand.create({ + userId: job.data.userId, + event: job.data.event, + payload: job.data.payload, + _environmentId: job.data._environmentId, + }) + ) + .then(resolve) + .catch((error) => { + Logger.error( + 'Unexpected exception occurred while handling external services route ', + error, + LOG_CONTEXT + ); + + reject(error); + }) + .finally(() => { + transaction.end(); + }); + } + ); + }); + }; + } + + private getWorkerOpts() { + return { + lockDuration: 90000, + concurrency: 100, + }; + } +} diff --git a/apps/ws/src/socket/services/web-socket.worker.ts b/apps/ws/src/socket/services/web-socket.worker.ts index 06bc7597074..dc07a2b3331 100644 --- a/apps/ws/src/socket/services/web-socket.worker.ts +++ b/apps/ws/src/socket/services/web-socket.worker.ts @@ -22,6 +22,11 @@ export class WebSocketWorker extends WebSocketsWorkerService implements INovuWor // eslint-disable-next-line @typescript-eslint/no-this-alias const _this = this; + Logger.verbose( + `Job ${job.id} / ${job.data.event} is being processed in the MemoryDB instance WebSocketWorker`, + LOG_CONTEXT + ); + nr.startBackgroundTransaction( ObservabilityBackgroundTransactionEnum.WS_SOCKET_QUEUE, 'WS Service', diff --git a/apps/ws/src/socket/socket.module.ts b/apps/ws/src/socket/socket.module.ts index 15173f355a1..2b29edf2f24 100644 --- a/apps/ws/src/socket/socket.module.ts +++ b/apps/ws/src/socket/socket.module.ts @@ -6,11 +6,17 @@ import { WSGateway } from './ws.gateway'; import { SharedModule } from '../shared/shared.module'; import { ExternalServicesRoute } from './usecases/external-services-route'; -import { WebSocketWorker } from './services'; +import { OldInstanceWebSocketsWorker, OldInstanceWebSocketsWorkerService, WebSocketWorker } from './services'; const USE_CASES: Provider[] = [ExternalServicesRoute]; -const PROVIDERS: Provider[] = [WSGateway, WebSocketsWorkerService, WebSocketWorker]; +const PROVIDERS: Provider[] = [ + WSGateway, + OldInstanceWebSocketsWorker, + OldInstanceWebSocketsWorkerService, + WebSocketsWorkerService, + WebSocketWorker, +]; @Module({ imports: [SharedModule], diff --git a/enterprise/packages b/enterprise/packages deleted file mode 160000 index 8f0b31fcf98..00000000000 --- a/enterprise/packages +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8f0b31fcf987bd0626b80224d73349fcbf71ceea diff --git a/lerna.json b/lerna.json index d34c472a3d0..da11865f407 100644 --- a/lerna.json +++ b/lerna.json @@ -8,5 +8,5 @@ "message": "chore(release): publish - ci skip" } }, - "version": "0.19.0" + "version": "0.20.0-alpha.0" } diff --git a/libs/dal/package.json b/libs/dal/package.json index 876fa4ebaae..8a34231beeb 100644 --- a/libs/dal/package.json +++ b/libs/dal/package.json @@ -1,6 +1,6 @@ { "name": "@novu/dal", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "", "private": true, "scripts": { @@ -24,7 +24,7 @@ "@aws-sdk/client-s3": "^3.382.0", "@aws-sdk/s3-request-presigner": "^3.382.0", "@faker-js/faker": "^6.0.0", - "@novu/shared": "^0.19.0", + "@novu/shared": "^0.20.0-alpha.0", "@sendgrid/mail": "^7.4.2", "JSONStream": "^1.3.5", "archiver": "^5.0.0", diff --git a/libs/embed/package.json b/libs/embed/package.json index af638ac532e..1eaa5658b1a 100644 --- a/libs/embed/package.json +++ b/libs/embed/package.json @@ -1,6 +1,6 @@ { "name": "@novu/embed", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "private": true, "description": "", "keywords": [], @@ -118,7 +118,7 @@ "typescript": "4.9.5" }, "dependencies": { - "@novu/notification-center": "^0.19.0", + "@novu/notification-center": "^0.20.0-alpha.0", "@types/iframe-resizer": "^3.5.8", "iframe-resizer": "^4.3.1" } diff --git a/libs/shared/package.json b/libs/shared/package.json index e4e85cfbe3f..a56af53b5ec 100644 --- a/libs/shared/package.json +++ b/libs/shared/package.json @@ -1,6 +1,6 @@ { "name": "@novu/shared", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "", "scripts": { "start": "npm run start:dev", diff --git a/libs/testing/package.json b/libs/testing/package.json index 8f075822785..fa24b022bb3 100644 --- a/libs/testing/package.json +++ b/libs/testing/package.json @@ -1,6 +1,6 @@ { "name": "@novu/testing", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "", "private": true, "scripts": { @@ -22,8 +22,8 @@ "types": "dist/index.d.ts", "dependencies": { "@faker-js/faker": "^6.0.0", - "@novu/dal": "^0.19.0", - "@novu/shared": "^0.19.0", + "@novu/dal": "^0.20.0-alpha.0", + "@novu/shared": "^0.20.0-alpha.0", "JSONStream": "^1.3.5", "async": "^3.2.0", "axios": "^1.3.3", diff --git a/packages/application-generic/package.json b/packages/application-generic/package.json index 7629b5c35d8..8dbb47e4ffd 100644 --- a/packages/application-generic/package.json +++ b/packages/application-generic/package.json @@ -1,6 +1,6 @@ { "name": "@novu/application-generic", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "Generic backend code used inside of Novu's different services", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -35,10 +35,10 @@ "peerDependencies": { "@nestjs/common": ">=10", "@nestjs/core": ">=10", + "@nestjs/jwt": "^10.1.0", "@nestjs/swagger": ">=6", "@nestjs/terminus": ">=10", "@nestjs/testing": ">=10", - "@nestjs/jwt": "^10.1.0", "newrelic": "^9", "reflect-metadata": "^0.1.13" }, @@ -47,52 +47,52 @@ "@aws-sdk/s3-request-presigner": "^3.382.0", "@azure/storage-blob": "^12.11.0", "@google-cloud/storage": "^6.2.3", - "@novu/africas-talking": "^0.19.0", - "@novu/apns": "^0.19.0", - "@novu/burst-sms": "^0.19.0", - "@novu/clickatell": "^0.19.0", - "@novu/dal": "^0.19.0", - "@novu/discord": "^0.19.0", - "@novu/email-webhook": "^0.19.0", - "@novu/emailjs": "^0.19.0", - "@novu/expo": "^0.19.0", - "@novu/fcm": "^0.19.0", - "@novu/firetext": "^0.19.0", - "@novu/forty-six-elks": "^0.19.0", - "@novu/gupshup": "^0.19.0", - "@novu/infobip": "^0.19.0", - "@novu/kannel": "^0.19.0", - "@novu/mailersend": "^0.19.0", - "@novu/mailgun": "^0.19.0", - "@novu/mailjet": "^0.19.0", - "@novu/mandrill": "^0.19.0", - "@novu/maqsam": "^0.19.0", - "@novu/mattermost": "^0.19.0", - "@novu/ms-teams": "^0.19.0", - "@novu/netcore": "^0.19.0", - "@novu/nodemailer": "^0.19.0", - "@novu/one-signal": "^0.19.0", - "@novu/outlook365": "^0.19.0", - "@novu/plivo": "^0.19.0", - "@novu/plunk": "^0.19.0", - "@novu/postmark": "^0.19.0", - "@novu/push-webhook": "^0.19.0", - "@novu/resend": "^0.19.0", - "@novu/sendchamp": "^0.19.0", - "@novu/sendgrid": "^0.19.0", - "@novu/sendinblue": "^0.19.0", - "@novu/ses": "^0.19.0", - "@novu/shared": "^0.19.0", - "@novu/slack": "^0.19.0", - "@novu/sms-central": "^0.19.0", - "@novu/sms77": "^0.19.0", - "@novu/sns": "^0.19.0", - "@novu/sparkpost": "^0.19.0", - "@novu/stateless": "^0.19.0", - "@novu/telnyx": "^0.19.0", - "@novu/termii": "^0.19.0", - "@novu/testing": "^0.19.0", - "@novu/twilio": "^0.19.0", + "@novu/africas-talking": "^0.20.0-alpha.0", + "@novu/apns": "^0.20.0-alpha.0", + "@novu/burst-sms": "^0.20.0-alpha.0", + "@novu/clickatell": "^0.20.0-alpha.0", + "@novu/dal": "^0.20.0-alpha.0", + "@novu/discord": "^0.20.0-alpha.0", + "@novu/email-webhook": "^0.20.0-alpha.0", + "@novu/emailjs": "^0.20.0-alpha.0", + "@novu/expo": "^0.20.0-alpha.0", + "@novu/fcm": "^0.20.0-alpha.0", + "@novu/firetext": "^0.20.0-alpha.0", + "@novu/forty-six-elks": "^0.20.0-alpha.0", + "@novu/gupshup": "^0.20.0-alpha.0", + "@novu/infobip": "^0.20.0-alpha.0", + "@novu/kannel": "^0.20.0-alpha.0", + "@novu/mailersend": "^0.20.0-alpha.0", + "@novu/mailgun": "^0.20.0-alpha.0", + "@novu/mailjet": "^0.20.0-alpha.0", + "@novu/mandrill": "^0.20.0-alpha.0", + "@novu/maqsam": "^0.20.0-alpha.0", + "@novu/mattermost": "^0.20.0-alpha.0", + "@novu/ms-teams": "^0.20.0-alpha.0", + "@novu/netcore": "^0.20.0-alpha.0", + "@novu/nodemailer": "^0.20.0-alpha.0", + "@novu/one-signal": "^0.20.0-alpha.0", + "@novu/outlook365": "^0.20.0-alpha.0", + "@novu/plivo": "^0.20.0-alpha.0", + "@novu/plunk": "^0.20.0-alpha.0", + "@novu/postmark": "^0.20.0-alpha.0", + "@novu/push-webhook": "^0.20.0-alpha.0", + "@novu/resend": "^0.20.0-alpha.0", + "@novu/sendchamp": "^0.20.0-alpha.0", + "@novu/sendgrid": "^0.20.0-alpha.0", + "@novu/sendinblue": "^0.20.0-alpha.0", + "@novu/ses": "^0.20.0-alpha.0", + "@novu/shared": "^0.20.0-alpha.0", + "@novu/slack": "^0.20.0-alpha.0", + "@novu/sms-central": "^0.20.0-alpha.0", + "@novu/sms77": "^0.20.0-alpha.0", + "@novu/sns": "^0.20.0-alpha.0", + "@novu/sparkpost": "^0.20.0-alpha.0", + "@novu/stateless": "^0.20.0-alpha.0", + "@novu/telnyx": "^0.20.0-alpha.0", + "@novu/termii": "^0.20.0-alpha.0", + "@novu/testing": "^0.20.0-alpha.0", + "@novu/twilio": "^0.20.0-alpha.0", "@sentry/node": "^7.12.1", "analytics-node": "^6.2.0", "bullmq": "^3.10.2", @@ -103,6 +103,7 @@ "ioredis": "^5.2.4", "launchdarkly-node-server-sdk": "^7.0.1", "lodash": "^4.17.15", + "mixpanel": "^0.17.0", "nestjs-pino": "^3.4.0", "node-fetch": "^3.2.10", "pino-http": "^8.3.3", diff --git a/packages/application-generic/src/modules/queues.module.ts b/packages/application-generic/src/modules/queues.module.ts index 63ff7946cde..5d2d1cfe771 100644 --- a/packages/application-generic/src/modules/queues.module.ts +++ b/packages/application-generic/src/modules/queues.module.ts @@ -29,6 +29,7 @@ import { StandardWorkerService, WebSocketsWorkerService, WorkflowWorkerService, + OldInstanceStandardWorkerService, OldInstanceWorkflowWorkerService, } from '../services/workers'; @@ -54,6 +55,7 @@ const PROVIDERS: Provider[] = [ WorkflowQueueService, WorkflowQueueServiceHealthIndicator, WorkflowWorkerService, + OldInstanceStandardWorkerService, OldInstanceWorkflowWorkerService, OldInstanceBullMqService, ]; diff --git a/packages/application-generic/src/services/analytics.service.ts b/packages/application-generic/src/services/analytics.service.ts index f91112773a7..47ecf50d732 100644 --- a/packages/application-generic/src/services/analytics.service.ts +++ b/packages/application-generic/src/services/analytics.service.ts @@ -1,5 +1,6 @@ import Analytics from 'analytics-node'; import { Logger } from '@nestjs/common'; +import * as Mixpanel from 'mixpanel'; // Due to problematic analytics-node types, we need to use require // eslint-disable-next-line @typescript-eslint/naming-convention @@ -23,7 +24,7 @@ const LOG_CONTEXT = 'AnalyticsService'; export class AnalyticsService { private segment: Analytics; - + private mixpanel: Mixpanel.Mixpanel; constructor(private segmentToken?: string | null, private batchSize = 100) {} async initialize() { @@ -32,6 +33,10 @@ export class AnalyticsService { flushAt: this.batchSize, }); } + + if (process.env.MIXPANEL_TOKEN) { + this.mixpanel = Mixpanel.init(process.env.MIXPANEL_TOKEN); + } } upsertGroup( @@ -104,6 +109,7 @@ export class AnalyticsService { { name, data, + source: 'segment', }, LOG_CONTEXT ); @@ -128,7 +134,46 @@ export class AnalyticsService { } } + mixpanelTrack( + name: string, + userId: string, + data: Record = {} + ) { + if (this.mixpanelEnabled) { + Logger.log( + 'Tracking event: ' + name, + { + name, + data, + source: 'mixpanel', + }, + LOG_CONTEXT + ); + + try { + this.mixpanel.track(name, { + distinct_id: userId, + ...data, + }); + } catch (error: any) { + Logger.error( + { + eventName: name, + usedId: userId, + message: error?.message, + }, + 'There has been an error when tracking mixpanel', + LOG_CONTEXT + ); + } + } + } + private get segmentEnabled() { return process.env.NODE_ENV !== 'test' && this.segment; } + + private get mixpanelEnabled() { + return process.env.NODE_ENV !== 'test' && this.mixpanel; + } } diff --git a/packages/application-generic/src/services/index.ts b/packages/application-generic/src/services/index.ts index f3f71f1989b..a6d6f0dcf89 100644 --- a/packages/application-generic/src/services/index.ts +++ b/packages/application-generic/src/services/index.ts @@ -16,6 +16,7 @@ export { BullMqService, Job, JobsOptions, + Processor, Queue, QueueBaseOptions, QueueOptions, diff --git a/packages/application-generic/src/services/workers/index.ts b/packages/application-generic/src/services/workers/index.ts index ee6f6d9b4dd..2a2eb18fb55 100644 --- a/packages/application-generic/src/services/workers/index.ts +++ b/packages/application-generic/src/services/workers/index.ts @@ -10,6 +10,7 @@ import { InboundParseWorkerService } from './inbound-parse-worker.service'; import { StandardWorkerService } from './standard-worker.service'; import { WebSocketsWorkerService } from './web-sockets-worker.service'; import { WorkflowWorkerService } from './workflow-worker.service'; +import { OldInstanceStandardWorkerService } from './old-instance-standard-worker.service'; import { OldInstanceWorkflowWorkerService } from './old-instance-workflow-worker.service'; export { @@ -22,5 +23,6 @@ export { WorkerOptions, WorkerProcessor, WorkflowWorkerService, + OldInstanceStandardWorkerService, OldInstanceWorkflowWorkerService, }; diff --git a/packages/application-generic/src/services/workers/old-instance-standard-worker.service.ts b/packages/application-generic/src/services/workers/old-instance-standard-worker.service.ts new file mode 100644 index 00000000000..03852a75223 --- /dev/null +++ b/packages/application-generic/src/services/workers/old-instance-standard-worker.service.ts @@ -0,0 +1,106 @@ +import { IJobData, JobTopicNameEnum } from '@novu/shared'; +import { Inject, Injectable, Logger } from '@nestjs/common'; + +import { + JobsOptions, + OldInstanceBullMqService, + Processor, + Worker, + WorkerOptions, +} from '../bull-mq'; + +const LOG_CONTEXT = 'OldInstanceStandardWorkerService'; + +type WorkerProcessor = string | Processor | undefined; + +/** + * TODO: Temporary for migration to MemoryDB + */ +export class OldInstanceStandardWorkerService { + private instance: OldInstanceBullMqService; + + public readonly DEFAULT_ATTEMPTS = 3; + public readonly topic: JobTopicNameEnum; + + constructor() { + this.topic = JobTopicNameEnum.STANDARD; + this.instance = new OldInstanceBullMqService(); + if (this.instance.enabled) { + Logger.log(`Worker ${this.topic} instantiated`, LOG_CONTEXT); + } else { + Logger.warn( + `Old instance standard worker not instantiated as it is only needed for MemoryDB migration`, + LOG_CONTEXT + ); + } + } + + public get bullMqService(): OldInstanceBullMqService { + return this.instance; + } + + public get worker(): Worker { + return this.instance.worker; + } + + public initWorker(processor: WorkerProcessor, options?: WorkerOptions): void { + if (this.instance.enabled) { + this.createWorker(processor, options); + } + } + + public createWorker( + processor: WorkerProcessor, + options: WorkerOptions + ): void { + if (this.instance.enabled) { + this.instance.createWorker(this.topic, processor, options); + } else { + Logger.log( + { enabled: this.instance.enabled }, + 'We are not running OldInstanceStandardWorkerService as it is not needed in this environment', + LOG_CONTEXT + ); + } + } + + public async isRunning(): Promise { + return await this.instance.isWorkerRunning(); + } + + public async isPaused(): Promise { + return await this.instance.isWorkerPaused(); + } + + public async pause(): Promise { + if (this.instance.enabled && this.worker) { + await this.instance.pauseWorker(); + } + } + + public async resume(): Promise { + if (this.instance.enabled && this.worker) { + await this.instance.resumeWorker(); + } + } + + public async gracefulShutdown(): Promise { + if (this.instance.enabled) { + Logger.log( + 'Shutting the old instance standard worker service down', + LOG_CONTEXT + ); + + await this.instance.gracefulShutdown(); + + Logger.log( + 'Shutting down the old instance standard worker service has finished', + LOG_CONTEXT + ); + } + } + + async onModuleDestroy(): Promise { + await this.gracefulShutdown(); + } +} diff --git a/packages/application-generic/src/services/workers/old-instance-workflow-worker.service.ts b/packages/application-generic/src/services/workers/old-instance-workflow-worker.service.ts index bca898a0118..74a04372f35 100644 --- a/packages/application-generic/src/services/workers/old-instance-workflow-worker.service.ts +++ b/packages/application-generic/src/services/workers/old-instance-workflow-worker.service.ts @@ -9,7 +9,7 @@ import { WorkerOptions, } from '../bull-mq'; -const LOG_CONTEXT = 'OldInstanceWorkerService'; +const LOG_CONTEXT = 'OldInstanceWorkflowWorkerService'; type WorkerProcessor = string | Processor | undefined; @@ -23,7 +23,7 @@ export class OldInstanceWorkflowWorkerService { public readonly topic: JobTopicNameEnum; constructor() { - this.topic = JobTopicNameEnum.STANDARD; + this.topic = JobTopicNameEnum.WORKFLOW; this.instance = new OldInstanceBullMqService(); if (this.instance.enabled) { Logger.log(`Worker ${this.topic} instantiated`, LOG_CONTEXT); @@ -86,11 +86,17 @@ export class OldInstanceWorkflowWorkerService { public async gracefulShutdown(): Promise { if (this.instance.enabled) { - Logger.log('Shutting the Worker service down', LOG_CONTEXT); + Logger.log( + 'Shutting the old instance workflow worker service down', + LOG_CONTEXT + ); await this.instance.gracefulShutdown(); - Logger.log('Shutting down the Worker service has finished', LOG_CONTEXT); + Logger.log( + 'Shutting down the old instance workflow worker service has finished', + LOG_CONTEXT + ); } } diff --git a/packages/application-generic/src/usecases/trigger-event/trigger-event.usecase.ts b/packages/application-generic/src/usecases/trigger-event/trigger-event.usecase.ts index 3a46d709f48..85fdc5aa7aa 100644 --- a/packages/application-generic/src/usecases/trigger-event/trigger-event.usecase.ts +++ b/packages/application-generic/src/usecases/trigger-event/trigger-event.usecase.ts @@ -58,155 +58,172 @@ export class TriggerEvent { @InstrumentUsecase() async execute(command: TriggerEventCommand) { - const { - actor, - environmentId, - identifier, - organizationId, - to, - userId, - tenant, - } = command; + try { + const { + actor, + environmentId, + identifier, + organizationId, + to, + userId, + tenant, + } = command; - await this.validateTransactionIdProperty( - command.transactionId, - environmentId - ); - - Sentry.addBreadcrumb({ - message: 'Sending trigger', - data: { - triggerIdentifier: identifier, - }, - }); + await this.validateTransactionIdProperty( + command.transactionId, + environmentId + ); - this.logger.assign({ - transactionId: command.transactionId, - environmentId: command.environmentId, - organizationId: command.organizationId, - }); + Sentry.addBreadcrumb({ + message: 'Sending trigger', + data: { + triggerIdentifier: identifier, + }, + }); - const template = await this.getNotificationTemplateByTriggerIdentifier({ - environmentId: command.environmentId, - triggerIdentifier: command.identifier, - }); + this.logger.assign({ + transactionId: command.transactionId, + environmentId: command.environmentId, + organizationId: command.organizationId, + }); - /* - * Makes no sense to execute anything if template doesn't exist - * TODO: Send a 404? - */ - if (!template) { - const message = 'Notification template could not be found'; - const error = new ApiException(message); - throw error; - } + const template = await this.getNotificationTemplateByTriggerIdentifier({ + environmentId: command.environmentId, + triggerIdentifier: command.identifier, + }); - const templateProviderIds = await this.getProviderIdsForTemplate( - command.environmentId, - template - ); + /* + * Makes no sense to execute anything if template doesn't exist + * TODO: Send a 404? + */ + if (!template) { + const message = 'Notification template could not be found'; + const error = new ApiException(message); + Logger.error(error, message, LOG_CONTEXT); + throw error; + } - if (tenant) { - const tenantProcessed = await this.processTenant.execute( - ProcessTenantCommand.create({ - environmentId, - organizationId, - userId, - tenant, - }) + const templateProviderIds = await this.getProviderIdsForTemplate( + command.environmentId, + template ); - if (!tenantProcessed) { - Logger.warn( - `Tenant with identifier ${JSON.stringify( - tenant.identifier - )} of organization ${command.organizationId} in transaction ${ - command.transactionId - } could not be processed.`, - LOG_CONTEXT + if (tenant) { + const tenantProcessed = await this.processTenant.execute( + ProcessTenantCommand.create({ + environmentId, + organizationId, + userId, + tenant, + }) ); - } - } - - // We might have a single actor for every trigger, so we only need to check for it once - let actorProcessed; - if (actor) { - actorProcessed = await this.processSubscriber.execute( - ProcessSubscriberCommand.create({ - environmentId, - organizationId, - userId, - subscriber: actor, - }) - ); - } - for (const subscriber of to) { - this.analyticsService.track( - 'Notification event trigger - [Triggers]', - command.userId, - { - transactionId: command.transactionId, - _template: template._id, - _organization: command.organizationId, - channels: template?.steps.map((step) => step.template?.type), - source: command.payload.__source || 'api', + if (!tenantProcessed) { + Logger.warn( + `Tenant with identifier ${JSON.stringify( + tenant.identifier + )} of organization ${command.organizationId} in transaction ${ + command.transactionId + } could not be processed.`, + LOG_CONTEXT + ); } - ); - - const subscriberProcessed = await this.processSubscriber.execute( - ProcessSubscriberCommand.create({ - environmentId, - organizationId, - userId, - subscriber, - }) - ); + } - // If no subscriber makes no sense to try to create notification - if (subscriberProcessed) { - const createNotificationJobsCommand = - CreateNotificationJobsCommand.create({ + // We might have a single actor for every trigger, so we only need to check for it once + let actorProcessed; + if (actor) { + actorProcessed = await this.processSubscriber.execute( + ProcessSubscriberCommand.create({ environmentId, - identifier, organizationId, - overrides: command.overrides, - payload: command.payload, - subscriber: subscriberProcessed, - template, - templateProviderIds, - to: subscriber, - transactionId: command.transactionId, userId, - ...(actor && actorProcessed && { actor: actorProcessed }), - tenant, - }); + subscriber: actor, + }) + ); + } - const notificationJobs = await this.createNotificationJobs.execute( - createNotificationJobsCommand + for (const subscriber of to) { + this.analyticsService.mixpanelTrack( + 'Notification event trigger - [Triggers]', + '', + { + transactionId: command.transactionId, + _template: template._id, + _organization: command.organizationId, + channels: template?.steps.map((step) => step.template?.type), + source: command.payload.__source || 'api', + } ); - const storeSubscriberJobsCommand = StoreSubscriberJobsCommand.create({ - environmentId: command.environmentId, - jobs: notificationJobs, - organizationId: command.organizationId, - }); - await this.storeSubscriberJobs.execute(storeSubscriberJobsCommand); - } else { - /** - * TODO: Potentially add a CreateExecutionDetails entry. Right now we - * have the limitation we need a job to be created for that. Here there - * is no job at this point. - */ - Logger.warn( - `Subscriber ${JSON.stringify( - subscriber.subscriberId - )} of organization ${command.organizationId} in transaction ${ - command.transactionId - } was not processed. No jobs are created.`, - LOG_CONTEXT + const subscriberProcessed = await this.processSubscriber.execute( + ProcessSubscriberCommand.create({ + environmentId, + organizationId, + userId, + subscriber, + }) ); + + // If no subscriber makes no sense to try to create notification + if (subscriberProcessed) { + const createNotificationJobsCommand = + CreateNotificationJobsCommand.create({ + environmentId, + identifier, + organizationId, + overrides: command.overrides, + payload: command.payload, + subscriber: subscriberProcessed, + template, + templateProviderIds, + to: subscriber, + transactionId: command.transactionId, + userId, + ...(actor && actorProcessed && { actor: actorProcessed }), + tenant, + }); + + const notificationJobs = await this.createNotificationJobs.execute( + createNotificationJobsCommand + ); + + const storeSubscriberJobsCommand = StoreSubscriberJobsCommand.create({ + environmentId: command.environmentId, + jobs: notificationJobs, + organizationId: command.organizationId, + }); + await this.storeSubscriberJobs.execute(storeSubscriberJobsCommand); + } else { + /** + * TODO: Potentially add a CreateExecutionDetails entry. Right now we + * have the limitation we need a job to be created for that. Here there + * is no job at this point. + */ + Logger.warn( + `Subscriber ${JSON.stringify( + subscriber.subscriberId + )} of organization ${command.organizationId} in transaction ${ + command.transactionId + } was not processed. No jobs are created.`, + LOG_CONTEXT + ); + } } + } catch (e) { + Logger.error( + { + transactionId: command.transactionId, + organization: command.organizationId, + triggerIdentifier: command.identifier, + userId: command.userId, + error: e, + }, + 'Unexpected error has occurred when triggering event', + LOG_CONTEXT + ); + + throw e; } } diff --git a/packages/cli/package.json b/packages/cli/package.json index 6c6202214ac..4ac9c0f60a0 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "novu", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "On-Boarding Cli", "main": "index.js", "scripts": { @@ -31,7 +31,7 @@ "ncp": "^2.0.0" }, "dependencies": { - "@novu/shared": "^0.19.0", + "@novu/shared": "^0.20.0-alpha.0", "analytics-node": "^6.2.0", "axios": "^1.3.3", "chalk": "4.1.2", diff --git a/packages/client/package.json b/packages/client/package.json index 10dc8afdb89..b381d47eab4 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@novu/client", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "repository": "https://github.com/novuhq/novu", "description": "API client to be used in end user environments", "main": "dist/cjs/index.js", @@ -44,7 +44,7 @@ "node": ">=10" }, "dependencies": { - "@novu/shared": "^0.19.0" + "@novu/shared": "^0.20.0-alpha.0" }, "devDependencies": { "@types/jest": "29.5.2", diff --git a/packages/headless/package.json b/packages/headless/package.json index 07850801eea..37d01208275 100644 --- a/packages/headless/package.json +++ b/packages/headless/package.json @@ -1,6 +1,6 @@ { "name": "@novu/headless", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "repository": "https://github.com/novuhq/novu", "description": "Headless client package that is a thin abstraction layer over the API client + state and socket management", "keywords": [], @@ -28,8 +28,8 @@ "node": ">=10" }, "dependencies": { - "@novu/client": "^0.19.0", - "@novu/shared": "^0.19.0", + "@novu/client": "^0.20.0-alpha.0", + "@novu/shared": "^0.20.0-alpha.0", "@tanstack/query-core": "^4.15.1", "socket.io-client": "4.7.2" }, diff --git a/packages/nest/package.json b/packages/nest/package.json index 3a22c168038..d5381807bd9 100644 --- a/packages/nest/package.json +++ b/packages/nest/package.json @@ -1,6 +1,6 @@ { "name": "@novu/nest", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A nestjs wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -36,7 +36,7 @@ }, "dependencies": { "@nestjs/common": "^8.2.0", - "@novu/stateless": "^0.19.0" + "@novu/stateless": "^0.20.0-alpha.0" }, "devDependencies": { "@istanbuljs/nyc-config-typescript": "^1.0.1", diff --git a/packages/node/package.json b/packages/node/package.json index db8274f4aba..95881a06969 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -1,6 +1,6 @@ { "name": "@novu/node", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "Notification Management Framework", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -42,7 +42,7 @@ "node": ">=10" }, "dependencies": { - "@novu/shared": "^0.19.0", + "@novu/shared": "^0.20.0-alpha.0", "handlebars": "^4.7.7", "lodash.get": "^4.4.2", "lodash.merge": "^4.6.2" diff --git a/packages/notification-center-angular/package.json b/packages/notification-center-angular/package.json index 255c50b94da..2f67455be9a 100644 --- a/packages/notification-center-angular/package.json +++ b/packages/notification-center-angular/package.json @@ -1,6 +1,6 @@ { "name": "@novu/notification-center-angular", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "scripts": { "ng": "ng", "start": "ng serve", @@ -37,7 +37,7 @@ "@angular/core": "~15.2.0", "@angular/platform-browser": "~15.2.0", "@angular/platform-browser-dynamic": "~15.2.0", - "@novu/notification-center": "^0.19.0", + "@novu/notification-center": "^0.20.0-alpha.0", "react": "^17.0.1", "react-dom": "^17.0.1", "tslib": "^2.3.0", diff --git a/packages/notification-center-vue/package.json b/packages/notification-center-vue/package.json index f7adebc96d6..c87cc31b17d 100644 --- a/packages/notification-center-vue/package.json +++ b/packages/notification-center-vue/package.json @@ -1,7 +1,7 @@ { "name": "@novu/notification-center-vue", "sideEffects": false, - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "Vue specific wrapper for notification-center", "repository": { "type": "git", @@ -22,7 +22,7 @@ "dependencies": { "@emotion/css": "^11.10.5", "@novu/floating-vue": "^2.0.3", - "@novu/notification-center": "^0.19.0", + "@novu/notification-center": "^0.20.0-alpha.0", "react": "^17.0.1", "react-dom": "^17.0.1" }, diff --git a/packages/notification-center/package.json b/packages/notification-center/package.json index 18a421b0847..765ad45c1eb 100644 --- a/packages/notification-center/package.json +++ b/packages/notification-center/package.json @@ -1,6 +1,6 @@ { "name": "@novu/notification-center", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "repository": "https://github.com/novuhq/novu", "description": "", "scripts": { @@ -80,8 +80,8 @@ "@emotion/styled": "^11.6.0", "@mantine/core": "^5.7.1", "@mantine/hooks": "^5.7.1", - "@novu/client": "^0.19.0", - "@novu/shared": "^0.19.0", + "@novu/client": "^0.20.0-alpha.0", + "@novu/shared": "^0.20.0-alpha.0", "@tanstack/react-query": "^4.20.4", "acorn-jsx": "^5.3.2", "axios": "^1.4.0", diff --git a/packages/stateless/package.json b/packages/stateless/package.json index 1134dae4507..e0ba5bbfcff 100644 --- a/packages/stateless/package.json +++ b/packages/stateless/package.json @@ -1,6 +1,6 @@ { "name": "@novu/stateless", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "Notification Management Framework", "main": "build/main/index.js", "typings": "build/main/index.d.ts", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 303597c2c0f..da8609e1daf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -171,13 +171,13 @@ importers: '@nestjs/swagger': ^7.1.8 '@nestjs/terminus': ^10.0.1 '@nestjs/testing': ^10.2.2 - '@novu/application-generic': ^0.19.0 - '@novu/dal': ^0.19.0 + '@novu/application-generic': ^0.20.0-alpha.0 + '@novu/dal': ^0.20.0-alpha.0 '@novu/ee-auth': ^0.19.0 - '@novu/node': ^0.19.0 - '@novu/shared': ^0.19.0 - '@novu/stateless': ^0.19.0 - '@novu/testing': ^0.19.0 + '@novu/node': ^0.20.0-alpha.0 + '@novu/shared': ^0.20.0-alpha.0 + '@novu/stateless': ^0.20.0-alpha.0 + '@novu/testing': ^0.20.0-alpha.0 '@sendgrid/mail': ^7.6.0 '@sentry/hub': ^7.40.0 '@sentry/node': ^7.40.0 @@ -321,9 +321,9 @@ importers: apps/inbound-mail: specifiers: - '@novu/application-generic': ^0.19.0 - '@novu/shared': ^0.19.0 - '@novu/testing': ^0.19.0 + '@novu/application-generic': ^0.20.0-alpha.0 + '@novu/shared': ^0.20.0-alpha.0 + '@novu/testing': ^0.20.0-alpha.0 '@sentry/node': ^7.12.1 '@types/chai': ^4.2.11 '@types/express': ^4.17.8 @@ -428,10 +428,10 @@ importers: '@mantine/notifications': ^5.7.1 '@mantine/prism': ^5.7.1 '@mantine/spotlight': ^5.7.1 - '@novu/dal': ^0.19.0 - '@novu/notification-center': ^0.19.0 - '@novu/shared': ^0.19.0 - '@novu/testing': ^0.19.0 + '@novu/dal': ^0.20.0-alpha.0 + '@novu/notification-center': ^0.20.0-alpha.0 + '@novu/shared': ^0.20.0-alpha.0 + '@novu/testing': ^0.20.0-alpha.0 '@segment/analytics-next': ^1.48.0 '@sentry/react': ^7.40.0 '@sentry/tracing': ^7.40.0 @@ -663,11 +663,11 @@ importers: '@nestjs/schematics': ^10.0.2 '@nestjs/terminus': ^10.0.1 '@nestjs/testing': ^10.2.2 - '@novu/application-generic': ^0.19.0 - '@novu/dal': ^0.19.0 - '@novu/shared': ^0.19.0 - '@novu/stateless': ^0.19.0 - '@novu/testing': ^0.19.0 + '@novu/application-generic': ^0.20.0-alpha.0 + '@novu/dal': ^0.20.0-alpha.0 + '@novu/shared': ^0.20.0-alpha.0 + '@novu/stateless': ^0.20.0-alpha.0 + '@novu/testing': ^0.20.0-alpha.0 '@sentry/node': ^7.66.0 '@types/chai': ^4.3.4 '@types/express': ^4.17.8 @@ -760,10 +760,10 @@ importers: '@faker-js/faker': ^6.0.0 '@mantine/core': 4.2.12 '@mantine/hooks': 4.2.12 - '@novu/dal': ^0.19.0 - '@novu/notification-center': ^0.19.0 - '@novu/shared': ^0.19.0 - '@novu/testing': ^0.19.0 + '@novu/dal': ^0.20.0-alpha.0 + '@novu/notification-center': ^0.20.0-alpha.0 + '@novu/shared': ^0.20.0-alpha.0 + '@novu/testing': ^0.20.0-alpha.0 '@types/jest': ^29.5.0 '@types/node': ^12.0.0 '@types/react': 17.0.62 @@ -865,11 +865,11 @@ importers: '@nestjs/swagger': ^7.1.9 '@nestjs/terminus': ^10.0.1 '@nestjs/testing': ^10.2.2 - '@novu/application-generic': ^0.19.0 - '@novu/dal': ^0.19.0 - '@novu/shared': ^0.19.0 - '@novu/stateless': ^0.19.0 - '@novu/testing': ^0.19.0 + '@novu/application-generic': ^0.20.0-alpha.0 + '@novu/dal': ^0.20.0-alpha.0 + '@novu/shared': ^0.20.0-alpha.0 + '@novu/stateless': ^0.20.0-alpha.0 + '@novu/testing': ^0.20.0-alpha.0 '@sentry/node': ^7.40.0 '@sentry/tracing': ^7.40.0 '@types/bcrypt': ^3.0.0 @@ -982,10 +982,10 @@ importers: '@nestjs/terminus': ^10.0.1 '@nestjs/testing': ^10.2.2 '@nestjs/websockets': ^10.2.2 - '@novu/application-generic': ^0.19.0 - '@novu/dal': ^0.19.0 - '@novu/shared': ^0.19.0 - '@novu/testing': ^0.19.0 + '@novu/application-generic': ^0.20.0-alpha.0 + '@novu/dal': ^0.20.0-alpha.0 + '@novu/shared': ^0.20.0-alpha.0 + '@novu/testing': ^0.20.0-alpha.0 '@sentry/node': ^7.30.0 '@socket.io/redis-adapter': ^7.2.0 '@types/chai': ^4.2.11 @@ -1078,9 +1078,9 @@ importers: '@nestjs/common': '>=9.3.x' '@nestjs/jwt': '>=9' '@nestjs/passport': 9.0.3 - '@novu/application-generic': ^0.19.0 - '@novu/dal': ^0.19.0 - '@novu/shared': ^0.19.0 + '@novu/application-generic': ^0.20.0-alpha.0 + '@novu/dal': ^0.20.0-alpha.0 + '@novu/shared': ^0.20.0-alpha.0 '@types/chai': ^4.2.11 '@types/mocha': ^8.0.1 '@types/node': ^14.6.0 @@ -1135,7 +1135,7 @@ importers: ts-node: ~10.9.1 typescript: 4.9.5 dependencies: - '@novu/shared': link:../../../libs/shared + '@novu/shared': 0.19.0 date-fns: 2.29.3 rrule: 2.7.2 devDependencies: @@ -1156,7 +1156,7 @@ importers: '@aws-sdk/client-s3': ^3.382.0 '@aws-sdk/s3-request-presigner': ^3.382.0 '@faker-js/faker': ^6.0.0 - '@novu/shared': ^0.19.0 + '@novu/shared': ^0.20.0-alpha.0 '@sendgrid/mail': ^7.4.2 '@types/async': ^3.2.1 '@types/bluebird': ^3.5.30 @@ -1232,7 +1232,7 @@ importers: specifiers: '@commitlint/cli': ^17.0.0 '@commitlint/config-conventional': ^17.0.0 - '@novu/notification-center': ^0.19.0 + '@novu/notification-center': ^0.20.0-alpha.0 '@rollup/plugin-node-resolve': ^6.0.0 '@rollup/plugin-replace': ^5.0.2 '@types/iframe-resizer': ^3.5.8 @@ -1321,8 +1321,8 @@ importers: libs/testing: specifiers: '@faker-js/faker': ^6.0.0 - '@novu/dal': ^0.19.0 - '@novu/shared': ^0.19.0 + '@novu/dal': ^0.20.0-alpha.0 + '@novu/shared': ^0.20.0-alpha.0 '@types/async': ^3.2.1 '@types/bluebird': ^3.5.30 '@types/node': ^14.6.0 @@ -1400,52 +1400,52 @@ importers: '@nestjs/swagger': '>=6' '@nestjs/terminus': '>=10' '@nestjs/testing': '>=10' - '@novu/africas-talking': ^0.19.0 - '@novu/apns': ^0.19.0 - '@novu/burst-sms': ^0.19.0 - '@novu/clickatell': ^0.19.0 - '@novu/dal': ^0.19.0 - '@novu/discord': ^0.19.0 - '@novu/email-webhook': ^0.19.0 - '@novu/emailjs': ^0.19.0 - '@novu/expo': ^0.19.0 - '@novu/fcm': ^0.19.0 - '@novu/firetext': ^0.19.0 - '@novu/forty-six-elks': ^0.19.0 - '@novu/gupshup': ^0.19.0 - '@novu/infobip': ^0.19.0 - '@novu/kannel': ^0.19.0 - '@novu/mailersend': ^0.19.0 - '@novu/mailgun': ^0.19.0 - '@novu/mailjet': ^0.19.0 - '@novu/mandrill': ^0.19.0 - '@novu/maqsam': ^0.19.0 - '@novu/mattermost': ^0.19.0 - '@novu/ms-teams': ^0.19.0 - '@novu/netcore': ^0.19.0 - '@novu/nodemailer': ^0.19.0 - '@novu/one-signal': ^0.19.0 - '@novu/outlook365': ^0.19.0 - '@novu/plivo': ^0.19.0 - '@novu/plunk': ^0.19.0 - '@novu/postmark': ^0.19.0 - '@novu/push-webhook': ^0.19.0 - '@novu/resend': ^0.19.0 - '@novu/sendchamp': ^0.19.0 - '@novu/sendgrid': ^0.19.0 - '@novu/sendinblue': ^0.19.0 - '@novu/ses': ^0.19.0 - '@novu/shared': ^0.19.0 - '@novu/slack': ^0.19.0 - '@novu/sms-central': ^0.19.0 - '@novu/sms77': ^0.19.0 - '@novu/sns': ^0.19.0 - '@novu/sparkpost': ^0.19.0 - '@novu/stateless': ^0.19.0 - '@novu/telnyx': ^0.19.0 - '@novu/termii': ^0.19.0 - '@novu/testing': ^0.19.0 - '@novu/twilio': ^0.19.0 + '@novu/africas-talking': ^0.20.0-alpha.0 + '@novu/apns': ^0.20.0-alpha.0 + '@novu/burst-sms': ^0.20.0-alpha.0 + '@novu/clickatell': ^0.20.0-alpha.0 + '@novu/dal': ^0.20.0-alpha.0 + '@novu/discord': ^0.20.0-alpha.0 + '@novu/email-webhook': ^0.20.0-alpha.0 + '@novu/emailjs': ^0.20.0-alpha.0 + '@novu/expo': ^0.20.0-alpha.0 + '@novu/fcm': ^0.20.0-alpha.0 + '@novu/firetext': ^0.20.0-alpha.0 + '@novu/forty-six-elks': ^0.20.0-alpha.0 + '@novu/gupshup': ^0.20.0-alpha.0 + '@novu/infobip': ^0.20.0-alpha.0 + '@novu/kannel': ^0.20.0-alpha.0 + '@novu/mailersend': ^0.20.0-alpha.0 + '@novu/mailgun': ^0.20.0-alpha.0 + '@novu/mailjet': ^0.20.0-alpha.0 + '@novu/mandrill': ^0.20.0-alpha.0 + '@novu/maqsam': ^0.20.0-alpha.0 + '@novu/mattermost': ^0.20.0-alpha.0 + '@novu/ms-teams': ^0.20.0-alpha.0 + '@novu/netcore': ^0.20.0-alpha.0 + '@novu/nodemailer': ^0.20.0-alpha.0 + '@novu/one-signal': ^0.20.0-alpha.0 + '@novu/outlook365': ^0.20.0-alpha.0 + '@novu/plivo': ^0.20.0-alpha.0 + '@novu/plunk': ^0.20.0-alpha.0 + '@novu/postmark': ^0.20.0-alpha.0 + '@novu/push-webhook': ^0.20.0-alpha.0 + '@novu/resend': ^0.20.0-alpha.0 + '@novu/sendchamp': ^0.20.0-alpha.0 + '@novu/sendgrid': ^0.20.0-alpha.0 + '@novu/sendinblue': ^0.20.0-alpha.0 + '@novu/ses': ^0.20.0-alpha.0 + '@novu/shared': ^0.20.0-alpha.0 + '@novu/slack': ^0.20.0-alpha.0 + '@novu/sms-central': ^0.20.0-alpha.0 + '@novu/sms77': ^0.20.0-alpha.0 + '@novu/sns': ^0.20.0-alpha.0 + '@novu/sparkpost': ^0.20.0-alpha.0 + '@novu/stateless': ^0.20.0-alpha.0 + '@novu/telnyx': ^0.20.0-alpha.0 + '@novu/termii': ^0.20.0-alpha.0 + '@novu/testing': ^0.20.0-alpha.0 + '@novu/twilio': ^0.20.0-alpha.0 '@sentry/node': ^7.12.1 '@taskforcesh/bullmq-pro': 5.1.14 '@types/analytics-node': ^3.1.9 @@ -1464,6 +1464,7 @@ importers: jest: ^27.1.0 launchdarkly-node-server-sdk: ^7.0.1 lodash: ^4.17.15 + mixpanel: ^0.17.0 nestjs-pino: ^3.4.0 newrelic: ^9 node-fetch: ^3.2.10 @@ -1547,6 +1548,7 @@ importers: ioredis: 5.3.1 launchdarkly-node-server-sdk: 7.0.1 lodash: 4.17.21 + mixpanel: 0.17.0 nestjs-pino: 3.4.0_63skzxoikz7i6kgl2v2i7k2p4y newrelic: 9.15.0 node-fetch: 3.3.1 @@ -1577,7 +1579,7 @@ importers: packages/cli: specifiers: - '@novu/shared': ^0.19.0 + '@novu/shared': ^0.20.0-alpha.0 '@types/analytics-node': ^3.1.9 '@types/configstore': ^5.0.1 '@types/inquirer': ^8.2.0 @@ -1626,7 +1628,7 @@ importers: packages/client: specifiers: - '@novu/shared': ^0.19.0 + '@novu/shared': ^0.20.0-alpha.0 '@types/jest': 29.5.2 '@types/node': ^14.6.0 codecov: ^3.5.0 @@ -1653,8 +1655,8 @@ importers: specifiers: '@babel/preset-env': ^7.13.15 '@babel/preset-typescript': ^7.13.0 - '@novu/client': ^0.19.0 - '@novu/shared': ^0.19.0 + '@novu/client': ^0.20.0-alpha.0 + '@novu/shared': ^0.20.0-alpha.0 '@tanstack/query-core': ^4.15.1 '@types/jest': ^29.2.3 '@types/node': ^14.6.0 @@ -1684,7 +1686,7 @@ importers: specifiers: '@istanbuljs/nyc-config-typescript': ^1.0.1 '@nestjs/common': ^8.2.0 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': 29.5.2 codecov: ^3.5.0 cspell: ^4.1.0 @@ -1721,7 +1723,7 @@ importers: packages/node: specifiers: - '@novu/shared': ^0.19.0 + '@novu/shared': ^0.20.0-alpha.0 '@sendgrid/mail': ^7.4.6 '@types/jest': 29.5.2 '@types/lodash.get': ^4.4.6 @@ -1772,8 +1774,8 @@ importers: '@emotion/styled': ^11.6.0 '@mantine/core': ^5.7.1 '@mantine/hooks': ^5.7.1 - '@novu/client': ^0.19.0 - '@novu/shared': ^0.19.0 + '@novu/client': ^0.20.0-alpha.0 + '@novu/shared': ^0.20.0-alpha.0 '@storybook/addon-actions': ^7.4.2 '@storybook/addon-essentials': ^7.4.2 '@storybook/addon-interactions': ^7.4.2 @@ -1887,7 +1889,7 @@ importers: '@angular/core': ~15.2.0 '@angular/platform-browser': ~15.2.0 '@angular/platform-browser-dynamic': ~15.2.0 - '@novu/notification-center': ^0.19.0 + '@novu/notification-center': ^0.20.0-alpha.0 '@types/jasmine': ~4.3.0 jasmine-core: ~4.6.0 karma: ~6.4.0 @@ -1930,7 +1932,7 @@ importers: specifiers: '@emotion/css': ^11.10.5 '@novu/floating-vue': ^2.0.3 - '@novu/notification-center': ^0.19.0 + '@novu/notification-center': ^0.20.0-alpha.0 '@rushstack/eslint-patch': ^1.1.4 '@types/node': ^18.11.12 '@vitejs/plugin-vue': ^4.0.0 @@ -2013,7 +2015,7 @@ importers: providers/africas-talking: specifiers: '@istanbuljs/nyc-config-typescript': ~1.0.1 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': ~29.5.0 africastalking: ^0.6.2 cspell: ~6.19.2 @@ -2044,7 +2046,7 @@ importers: providers/apns: specifiers: '@istanbuljs/nyc-config-typescript': ^1.0.1 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@parse/node-apn': ^5.2.3 '@types/jest': ^29.5.0 codecov: ^3.5.0 @@ -2081,7 +2083,7 @@ importers: providers/burst-sms: specifiers: '@istanbuljs/nyc-config-typescript': ^1.0.1 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': ^29.5.0 axios: ^1.3.3 codecov: ^3.5.0 @@ -2124,7 +2126,7 @@ importers: providers/clickatell: specifiers: '@istanbuljs/nyc-config-typescript': ^1.0.1 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': ^29.5.0 axios: ^1.3.3 codecov: ^3.5.0 @@ -2161,7 +2163,7 @@ importers: providers/discord: specifiers: '@istanbuljs/nyc-config-typescript': ^1.0.1 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': ^29.5.0 axios: ^1.3.3 codecov: ^3.5.0 @@ -2231,7 +2233,7 @@ importers: providers/emailjs: specifiers: '@istanbuljs/nyc-config-typescript': 1.0.2 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': 29.5.2 codecov: ^3.5.0 cspell: ^4.1.0 @@ -2270,7 +2272,7 @@ importers: providers/expo: specifiers: '@istanbuljs/nyc-config-typescript': ^1.0.1 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': ^29.5.0 codecov: ^3.5.0 cspell: ^4.1.0 @@ -2309,7 +2311,7 @@ importers: providers/fcm: specifiers: '@istanbuljs/nyc-config-typescript': ^1.0.1 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': ^29.5.0 '@types/mocha': ^8.0.1 codecov: ^3.5.0 @@ -2355,7 +2357,7 @@ importers: specifiers: '@babel/preset-env': ^7.13.15 '@istanbuljs/nyc-config-typescript': ^1.0.1 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': ^29.5.0 '@types/uuid': ^8.3.4 codecov: ^3.5.0 @@ -2399,7 +2401,7 @@ importers: providers/forty-six-elks: specifiers: '@istanbuljs/nyc-config-typescript': ~1.0.1 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': ~29.5.0 axios: ^1.3.4 cspell: ~6.19.2 @@ -2431,7 +2433,7 @@ importers: specifiers: '@babel/preset-env': ^7.13.15 '@istanbuljs/nyc-config-typescript': ^1.0.1 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': ^29.5.0 codecov: ^3.5.0 cspell: ^4.1.0 @@ -2472,7 +2474,7 @@ importers: specifiers: '@infobip-api/sdk': ^0.2.0 '@istanbuljs/nyc-config-typescript': ^1.0.1 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': ^29.5.0 codecov: ^3.5.0 cspell: ^4.1.0 @@ -2510,7 +2512,7 @@ importers: providers/kannel: specifiers: '@istanbuljs/nyc-config-typescript': ^1.0.1 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': ^29.5.0 axios: ^0.27.2 codecov: ^3.5.0 @@ -2549,7 +2551,7 @@ importers: providers/mailersend: specifiers: '@istanbuljs/nyc-config-typescript': ^1.0.1 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': ^29.5.0 codecov: ^3.5.0 cspell: ^4.1.0 @@ -2588,7 +2590,7 @@ importers: providers/mailgun: specifiers: '@istanbuljs/nyc-config-typescript': 1.0.2 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': 29.5.2 codecov: ^3.5.0 cspell: ^4.1.0 @@ -2631,7 +2633,7 @@ importers: providers/mailjet: specifiers: '@istanbuljs/nyc-config-typescript': ^1.0.1 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': 29.5.2 '@types/node-mailjet': ^3.3.7 codecov: ^3.5.0 @@ -2673,7 +2675,7 @@ importers: specifiers: '@istanbuljs/nyc-config-typescript': 1.0.2 '@mailchimp/mailchimp_transactional': ^1.0.46 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': 29.5.2 codecov: ^3.5.0 cspell: ^4.1.0 @@ -2715,7 +2717,7 @@ importers: providers/maqsam: specifiers: '@istanbuljs/nyc-config-typescript': ~1.0.1 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': ~29.5.0 axios: ^1.3.4 cspell: ~6.19.2 @@ -2750,7 +2752,7 @@ importers: providers/mattermost: specifiers: '@istanbuljs/nyc-config-typescript': ~1.0.1 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': ~29.5.0 axios: ^1.3.3 cspell: ~6.19.2 @@ -2822,7 +2824,7 @@ importers: providers/netcore: specifiers: '@istanbuljs/nyc-config-typescript': 1.0.2 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': 29.5.2 codecov: ^3.5.0 cspell: ^4.1.0 @@ -2861,7 +2863,7 @@ importers: providers/nexmo: specifiers: '@istanbuljs/nyc-config-typescript': ^1.0.1 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': 29.5.2 '@vonage/server-sdk': ^2.10.10 codecov: ^3.5.0 @@ -2900,7 +2902,7 @@ importers: providers/nodemailer: specifiers: '@istanbuljs/nyc-config-typescript': 1.0.2 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': 29.5.2 '@types/nodemailer': ^6.4.4 codecov: ^3.5.0 @@ -2941,7 +2943,7 @@ importers: providers/one-signal: specifiers: '@istanbuljs/nyc-config-typescript': ~1.0.1 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': ~29.5.0 cspell: ~6.19.2 jest: ~27.5.1 @@ -2972,7 +2974,7 @@ importers: providers/outlook365: specifiers: '@istanbuljs/nyc-config-typescript': ^1.0.1 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': ^29.5.0 codecov: ^3.5.0 cspell: ^4.1.0 @@ -3011,7 +3013,7 @@ importers: providers/plivo: specifiers: '@istanbuljs/nyc-config-typescript': 1.0.2 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': 29.5.2 codecov: ^3.5.0 cspell: ^4.1.0 @@ -3050,7 +3052,7 @@ importers: providers/plunk: specifiers: '@istanbuljs/nyc-config-typescript': ~1.0.1 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@plunk/node': 2.0.0 '@types/jest': ~27.5.2 cspell: ~6.19.2 @@ -3081,7 +3083,7 @@ importers: providers/postmark: specifiers: '@istanbuljs/nyc-config-typescript': 1.0.2 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': 29.5.2 axios: ^1.3.6 codecov: ^3.5.0 @@ -3122,7 +3124,7 @@ importers: providers/push-webhook: specifiers: '@istanbuljs/nyc-config-typescript': ~1.0.1 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': ~29.5.0 axios: ^1.3.5 cspell: ~6.19.2 @@ -3153,7 +3155,7 @@ importers: providers/resend: specifiers: '@istanbuljs/nyc-config-typescript': ^1.0.1 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': ^29.5.0 codecov: ^3.5.0 cspell: ^4.1.0 @@ -3192,7 +3194,7 @@ importers: providers/sendchamp: specifiers: '@istanbuljs/nyc-config-typescript': ~1.0.1 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': ~27.5.2 axios: ^1.4.0 cspell: ~6.19.2 @@ -3223,7 +3225,7 @@ importers: providers/sendgrid: specifiers: '@istanbuljs/nyc-config-typescript': 1.0.2 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@sendgrid/mail': ^7.4.6 '@types/jest': 29.5.2 codecov: ^3.5.0 @@ -3262,7 +3264,7 @@ importers: providers/sendinblue: specifiers: '@istanbuljs/nyc-config-typescript': ^1.0.1 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@sendinblue/client': ^3.0.1 '@types/jest': 29.5.2 codecov: ^3.5.0 @@ -3302,7 +3304,7 @@ importers: specifiers: '@aws-sdk/client-ses': 3.382.0 '@istanbuljs/nyc-config-typescript': ^1.0.1 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': 29.5.2 codecov: ^3.5.0 cspell: ^4.1.0 @@ -3342,7 +3344,7 @@ importers: providers/slack: specifiers: '@istanbuljs/nyc-config-typescript': ^1.0.1 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': ^29.5.0 axios: ^1.3.3 codecov: ^3.5.0 @@ -3413,7 +3415,7 @@ importers: specifiers: '@babel/preset-env': ^7.13.15 '@istanbuljs/nyc-config-typescript': ^1.0.1 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': 29.5.2 codecov: ^3.5.0 cspell: ^4.1.0 @@ -3456,7 +3458,7 @@ importers: specifiers: '@aws-sdk/client-sns': ^3.382.0 '@istanbuljs/nyc-config-typescript': ^1.0.1 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': 29.5.2 codecov: ^3.5.0 cspell: ^4.1.0 @@ -3494,7 +3496,7 @@ importers: providers/sparkpost: specifiers: '@istanbuljs/nyc-config-typescript': ^1.0.1 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': ^29.5.0 '@types/sparkpost': ^2.1.5 codecov: ^3.5.0 @@ -3535,7 +3537,7 @@ importers: providers/telnyx: specifiers: '@istanbuljs/nyc-config-typescript': ^1.0.1 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': ^29.5.0 codecov: ^3.5.0 cspell: ^4.1.0 @@ -3575,7 +3577,7 @@ importers: specifiers: '@babel/preset-env': ^7.13.15 '@istanbuljs/nyc-config-typescript': ^1.0.1 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': ^29.5.0 codecov: ^3.5.0 cspell: ^4.1.0 @@ -3615,7 +3617,7 @@ importers: providers/twilio: specifiers: '@istanbuljs/nyc-config-typescript': 1.0.2 - '@novu/stateless': ^0.19.0 + '@novu/stateless': ^0.20.0-alpha.0 '@types/jest': 29.5.2 codecov: ^3.5.0 cspell: ^4.1.0 @@ -5811,13 +5813,6 @@ packages: '@babel/template': 7.22.15 '@babel/types': 7.22.19 - /@babel/helper-hoist-variables/7.18.6: - resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.22.19 - dev: true - /@babel/helper-hoist-variables/7.22.5: resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} engines: {node: '>=6.9.0'} @@ -5870,6 +5865,20 @@ packages: transitivePeerDependencies: - supports-color + /@babel/helper-module-transforms/7.22.20_@babel+core@7.20.12: + resolution: {integrity: sha512-dLT7JVWIUUxKOs1UnJUBR3S70YK+pKX6AbJgB2vMIvEkZkrfJDbYDJesnPshtKV4LhDOR3Oc5YULeDizRek+5A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-simple-access': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/helper-validator-identifier': 7.22.20 + dev: true + /@babel/helper-module-transforms/7.22.20_@babel+core@7.22.11: resolution: {integrity: sha512-dLT7JVWIUUxKOs1UnJUBR3S70YK+pKX6AbJgB2vMIvEkZkrfJDbYDJesnPshtKV4LhDOR3Oc5YULeDizRek+5A==} engines: {node: '>=6.9.0'} @@ -13103,6 +13112,26 @@ packages: - webpack-cli dev: true + /@nestjs/common/10.2.2_atc7tu2sld2m3nk4hmwkqn6qde: + resolution: {integrity: sha512-TCOJK2K4FDT3GxFfURjngnjBewS/hizKNFSLBXtX4TTQm0dVQOtESnnVdP14sEiPM6suuWlrGnXW9UDqItGWiQ==} + peerDependencies: + class-transformer: '*' + class-validator: '*' + reflect-metadata: ^0.1.12 + rxjs: ^7.1.0 + peerDependenciesMeta: + class-transformer: + optional: true + class-validator: + optional: true + dependencies: + iterare: 1.2.1 + reflect-metadata: 0.1.13 + rxjs: 7.8.1 + tslib: 2.6.2 + uid: 2.0.2 + dev: false + /@nestjs/common/10.2.2_j3td4gnlgk75ora6o6suo62byy: resolution: {integrity: sha512-TCOJK2K4FDT3GxFfURjngnjBewS/hizKNFSLBXtX4TTQm0dVQOtESnnVdP14sEiPM6suuWlrGnXW9UDqItGWiQ==} peerDependencies: @@ -13332,6 +13361,16 @@ packages: passport: 0.6.0 dev: false + /@nestjs/passport/9.0.3_kn4ljbedllcoqpuu4ifhphsdsu: + resolution: {integrity: sha512-HplSJaimEAz1IOZEu+pdJHHJhQyBOPAYWXYHfAPQvRqWtw4FJF1VXl1Qtk9dcXQX1eKytDtH+qBzNQc19GWNEg==} + peerDependencies: + '@nestjs/common': ^8.0.0 || ^9.0.0 + passport: ^0.4.0 || ^0.5.0 || ^0.6.0 + dependencies: + '@nestjs/common': 10.2.2_atc7tu2sld2m3nk4hmwkqn6qde + passport: 0.6.0 + dev: false + /@nestjs/platform-express/10.2.2_h33h3l6i5mruhsbo3bha6vy2fi: resolution: {integrity: sha512-g5AeXgPQrVm62JOl9FXk0w3Tq1tD4f6ouGikLYs/Aahy0q/Z2HNP9NjXZYpqcjHrpafPYnc3bfBuUwedKW1oHg==} peerDependencies: @@ -13683,6 +13722,16 @@ packages: vue-resize: 2.0.0-alpha.1_vue@3.2.47 dev: false + /@novu/shared/0.19.0: + resolution: {integrity: sha512-qvauixX5OOMcIduxnsF+Kh8CIB7r14kjB9Dt4SLgkWIGGrxVFmiSpJjaOEjUZ4RAHsO7CZEdmAPQDJj2wwNDOQ==} + dependencies: + axios: 1.4.0 + class-transformer: 0.5.1 + class-validator: 0.14.0 + transitivePeerDependencies: + - debug + dev: false + /@novu/stateless/0.12.0: resolution: {integrity: sha512-2GVX07XtR3owk8Dg/66l+kyUvgYR5+uKMheiFCVRuTCqiDfVFww1G3ixIEs2FGIajtLfDdNyuH+PV25EoqmKVg==} engines: {node: '>=10'} @@ -21554,24 +21603,28 @@ packages: dependencies: '@webassemblyjs/helper-numbers': 1.11.5 '@webassemblyjs/helper-wasm-bytecode': 1.11.5 + dev: true /@webassemblyjs/floating-point-hex-parser/1.11.1: resolution: {integrity: sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==} /@webassemblyjs/floating-point-hex-parser/1.11.5: resolution: {integrity: sha512-1j1zTIC5EZOtCplMBG/IEwLtUojtwFVwdyVMbL/hwWqbzlQoJsWCOavrdnLkemwNoC/EOwtUFch3fuo+cbcXYQ==} + dev: true /@webassemblyjs/helper-api-error/1.11.1: resolution: {integrity: sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==} /@webassemblyjs/helper-api-error/1.11.5: resolution: {integrity: sha512-L65bDPmfpY0+yFrsgz8b6LhXmbbs38OnwDCf6NpnMUYqa+ENfE5Dq9E42ny0qz/PdR0LJyq/T5YijPnU8AXEpA==} + dev: true /@webassemblyjs/helper-buffer/1.11.1: resolution: {integrity: sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==} /@webassemblyjs/helper-buffer/1.11.5: resolution: {integrity: sha512-fDKo1gstwFFSfacIeH5KfwzjykIE6ldh1iH9Y/8YkAZrhmu4TctqYjSh7t0K2VyDSXOZJ1MLhht/k9IvYGcIxg==} + dev: true /@webassemblyjs/helper-numbers/1.11.1: resolution: {integrity: sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==} @@ -21586,12 +21639,14 @@ packages: '@webassemblyjs/floating-point-hex-parser': 1.11.5 '@webassemblyjs/helper-api-error': 1.11.5 '@xtuc/long': 4.2.2 + dev: true /@webassemblyjs/helper-wasm-bytecode/1.11.1: resolution: {integrity: sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==} /@webassemblyjs/helper-wasm-bytecode/1.11.5: resolution: {integrity: sha512-oC4Qa0bNcqnjAowFn7MPCETQgDYytpsfvz4ujZz63Zu/a/v71HeCAAmZsgZ3YVKec3zSPYytG3/PrRCqbtcAvA==} + dev: true /@webassemblyjs/helper-wasm-section/1.11.1: resolution: {integrity: sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==} @@ -21608,6 +21663,7 @@ packages: '@webassemblyjs/helper-buffer': 1.11.5 '@webassemblyjs/helper-wasm-bytecode': 1.11.5 '@webassemblyjs/wasm-gen': 1.11.5 + dev: true /@webassemblyjs/ieee754/1.11.1: resolution: {integrity: sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==} @@ -21618,6 +21674,7 @@ packages: resolution: {integrity: sha512-37aGq6qVL8A8oPbPrSGMBcp38YZFXcHfiROflJn9jxSdSMMM5dS5P/9e2/TpaJuhE+wFrbukN2WI6Hw9MH5acg==} dependencies: '@xtuc/ieee754': 1.2.0 + dev: true /@webassemblyjs/leb128/1.11.1: resolution: {integrity: sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==} @@ -21628,12 +21685,14 @@ packages: resolution: {integrity: sha512-ajqrRSXaTJoPW+xmkfYN6l8VIeNnR4vBOTQO9HzR7IygoCcKWkICbKFbVTNMjMgMREqXEr0+2M6zukzM47ZUfQ==} dependencies: '@xtuc/long': 4.2.2 + dev: true /@webassemblyjs/utf8/1.11.1: resolution: {integrity: sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==} /@webassemblyjs/utf8/1.11.5: resolution: {integrity: sha512-WiOhulHKTZU5UPlRl53gHR8OxdGsSOxqfpqWeA2FmcwBMaoEdz6b2x2si3IwC9/fSPLfe8pBMRTHVMk5nlwnFQ==} + dev: true /@webassemblyjs/wasm-edit/1.11.1: resolution: {integrity: sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==} @@ -21658,6 +21717,7 @@ packages: '@webassemblyjs/wasm-opt': 1.11.5 '@webassemblyjs/wasm-parser': 1.11.5 '@webassemblyjs/wast-printer': 1.11.5 + dev: true /@webassemblyjs/wasm-gen/1.11.1: resolution: {integrity: sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==} @@ -21676,6 +21736,7 @@ packages: '@webassemblyjs/ieee754': 1.11.5 '@webassemblyjs/leb128': 1.11.5 '@webassemblyjs/utf8': 1.11.5 + dev: true /@webassemblyjs/wasm-opt/1.11.1: resolution: {integrity: sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==} @@ -21692,6 +21753,7 @@ packages: '@webassemblyjs/helper-buffer': 1.11.5 '@webassemblyjs/wasm-gen': 1.11.5 '@webassemblyjs/wasm-parser': 1.11.5 + dev: true /@webassemblyjs/wasm-parser/1.11.1: resolution: {integrity: sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==} @@ -21712,6 +21774,7 @@ packages: '@webassemblyjs/ieee754': 1.11.5 '@webassemblyjs/leb128': 1.11.5 '@webassemblyjs/utf8': 1.11.5 + dev: true /@webassemblyjs/wast-printer/1.11.1: resolution: {integrity: sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==} @@ -21724,6 +21787,7 @@ packages: dependencies: '@webassemblyjs/ast': 1.11.5 '@xtuc/long': 4.2.2 + dev: true /@webpack-cli/configtest/2.1.1_g5qtztmog4wkrsqodniltwrmwa: resolution: {integrity: sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==} @@ -23050,21 +23114,6 @@ packages: webpack: 5.82.1_w67ycjwq2niq3jlxgktvf5aow4 dev: true - /babel-loader/8.3.0_vymqytky47ah5a633vjyq2m3sy: - resolution: {integrity: sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==} - engines: {node: '>= 8.9'} - peerDependencies: - '@babel/core': ^7.0.0 - webpack: '>=2' - dependencies: - '@babel/core': 7.21.4 - find-cache-dir: 3.3.2 - loader-utils: 2.0.4 - make-dir: 3.1.0 - schema-utils: 2.7.1 - webpack: 5.88.2 - dev: false - /babel-loader/9.1.2_7nqnrdwtl44yxbgqpombxtkqjy: resolution: {integrity: sha512-mN14niXW43tddohGl8HPu5yfQq70iUThvFL/4QzESA7GcZoC0eVOhvWdQ8+3UlSjaDE9MVtsW9mxDY07W7VpVA==} engines: {node: '>= 14.15.0'} @@ -25764,7 +25813,8 @@ packages: postcss-modules-values: 4.0.0_postcss@8.4.29 postcss-value-parser: 4.2.0 semver: 7.5.4 - webpack: 5.88.2 + webpack: 5.88.2_u5c4qderjagc6tepfyiby6xhau + dev: true /css-minimizer-webpack-plugin/3.4.1_rw5du4nyxcvxj5knuew24gpv6a: resolution: {integrity: sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q==} @@ -27193,6 +27243,7 @@ packages: /es-module-lexer/1.2.1: resolution: {integrity: sha512-9978wrXM50Y4rTMmW5kXIC09ZdXQZqkE4mxhwkd8VbzsGkXGPgV4zWuqQJgCEzYngdo2dYDa0l8xhX4fkSwJSg==} + dev: true /es-set-tostringtag/2.0.1: resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==} @@ -28729,17 +28780,6 @@ packages: schema-utils: 3.1.2 webpack: 5.78.0_u5c4qderjagc6tepfyiby6xhau - /file-loader/6.2.0_webpack@5.88.2: - resolution: {integrity: sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==} - engines: {node: '>= 10.13.0'} - peerDependencies: - webpack: ^4.0.0 || ^5.0.0 - dependencies: - loader-utils: 2.0.4 - schema-utils: 3.1.2 - webpack: 5.88.2 - dev: false - /file-selector/0.6.0: resolution: {integrity: sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==} engines: {node: '>= 12'} @@ -29047,38 +29087,6 @@ packages: /forever-agent/0.6.1: resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} - /fork-ts-checker-webpack-plugin/6.5.3_rjadthzu3mzu3rpkl7r437txge: - resolution: {integrity: sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==} - engines: {node: '>=10', yarn: '>=1.0.0'} - peerDependencies: - eslint: '>= 6' - typescript: '>= 2.7' - vue-template-compiler: '*' - webpack: '>= 4' - peerDependenciesMeta: - eslint: - optional: true - vue-template-compiler: - optional: true - dependencies: - '@babel/code-frame': 7.22.13 - '@types/json-schema': 7.0.12 - chalk: 4.1.2 - chokidar: 3.5.3 - cosmiconfig: 6.0.0 - deepmerge: 4.3.1 - eslint: 8.48.0 - fs-extra: 9.1.0 - glob: 7.2.3 - memfs: 3.5.0 - minimatch: 3.1.2 - schema-utils: 2.7.0 - semver: 7.5.4 - tapable: 1.1.3 - typescript: 4.9.5 - webpack: 5.88.2 - dev: false - /fork-ts-checker-webpack-plugin/6.5.3_vq6t4wvflba3b6dvvfvomzl76u: resolution: {integrity: sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==} engines: {node: '>=10', yarn: '>=1.0.0'} @@ -30749,6 +30757,16 @@ packages: - supports-color dev: true + /https-proxy-agent/5.0.0: + resolution: {integrity: sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==} + engines: {node: '>= 6'} + dependencies: + agent-base: 6.0.2 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: false + /https-proxy-agent/5.0.1: resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} @@ -35508,16 +35526,6 @@ packages: schema-utils: 4.0.0 webpack: 5.78.0_u5c4qderjagc6tepfyiby6xhau - /mini-css-extract-plugin/2.7.5_webpack@5.88.2: - resolution: {integrity: sha512-9HaR++0mlgom81s95vvNjxkg52n2b5s//3ZTI1EtzFb98awsLSivs2LMsVqnQ3ay0PVhqWcGNyDaTE961FOcjQ==} - engines: {node: '>= 12.13.0'} - peerDependencies: - webpack: ^5.0.0 - dependencies: - schema-utils: 4.0.0 - webpack: 5.88.2 - dev: false - /minimalistic-assert/1.0.1: resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} @@ -35716,6 +35724,15 @@ packages: is-extendable: 1.0.1 dev: true + /mixpanel/0.17.0: + resolution: {integrity: sha512-DY5WeOy/hmkPrNiiZugJpWR0iMuOwuj1a3u0bgwB2eUFRV6oIew/pIahhpawdbNjb+Bye4a8ID3gefeNPvL81g==} + engines: {node: '>=10.0'} + dependencies: + https-proxy-agent: 5.0.0 + transitivePeerDependencies: + - supports-color + dev: false + /mkdirp-classic/0.5.3: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} dev: true @@ -37864,6 +37881,27 @@ packages: passport-oauth2: 1.7.0 dev: false + /passport-google-oauth/2.0.0: + resolution: {integrity: sha512-JKxZpBx6wBQXX1/a1s7VmdBgwOugohH+IxCy84aPTZNq/iIPX6u7Mqov1zY7MKRz3niFPol0KJz8zPLBoHKtYA==} + engines: {node: '>= 0.4.0'} + dependencies: + passport-google-oauth1: 1.0.0 + passport-google-oauth20: 2.0.0 + dev: false + + /passport-google-oauth1/1.0.0: + resolution: {integrity: sha512-qpCEhuflJgYrdg5zZIpAq/K3gTqa1CtHjbubsEsidIdpBPLkEVq6tB1I8kBNcH89RdSiYbnKpCBXAZXX/dtx1Q==} + dependencies: + passport-oauth1: 1.3.0 + dev: false + + /passport-google-oauth20/2.0.0: + resolution: {integrity: sha512-KSk6IJ15RoxuGq7D1UKK/8qKhNfzbLeLrG3gkLZ7p4A6DBCcv7xpyQwuXtWdpyR0+E0mwkpjY1VfPOhxQrKzdQ==} + engines: {node: '>= 0.4.0'} + dependencies: + passport-oauth2: 1.7.0 + dev: false + /passport-jwt/4.0.1: resolution: {integrity: sha512-UCKMDYhNuGOBE9/9Ycuoyh7vP6jpeTp/+sfMJl7nLff/t6dps+iaeE0hhNkKN8/HZHcJ7lCdOyDxHdDoxoSvdQ==} dependencies: @@ -37871,6 +37909,15 @@ packages: passport-strategy: 1.0.0 dev: false + /passport-oauth1/1.3.0: + resolution: {integrity: sha512-8T/nX4gwKTw0PjxP1xfD0QhrydQNakzeOpZ6M5Uqdgz9/a/Ag62RmJxnZQ4LkbdXGrRehQHIAHNAu11rCP46Sw==} + engines: {node: '>= 0.4.0'} + dependencies: + oauth: 0.9.15 + passport-strategy: 1.0.0 + utils-merge: 1.0.1 + dev: false + /passport-oauth2/1.7.0: resolution: {integrity: sha512-j2gf34szdTF2Onw3+76alNnaAExlUmHvkc7cL+cmaS5NzHzDP/BvFHJruueQ9XAeNOdpI+CH+PWid8RA7KCwAQ==} engines: {node: '>= 0.4.0'} @@ -40178,48 +40225,6 @@ packages: react-dom: 17.0.2_react@17.0.2 dev: false - /react-dev-utils/12.0.1_rjadthzu3mzu3rpkl7r437txge: - resolution: {integrity: sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==} - engines: {node: '>=14'} - peerDependencies: - typescript: '>=2.7' - webpack: '>=4' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@babel/code-frame': 7.21.4 - address: 1.2.2 - browserslist: 4.21.10 - chalk: 4.1.2 - cross-spawn: 7.0.3 - detect-port-alt: 1.1.6 - escape-string-regexp: 4.0.0 - filesize: 8.0.7 - find-up: 5.0.0 - fork-ts-checker-webpack-plugin: 6.5.3_rjadthzu3mzu3rpkl7r437txge - global-modules: 2.0.0 - globby: 11.1.0 - gzip-size: 6.0.0 - immer: 9.0.21 - is-root: 2.1.0 - loader-utils: 3.2.1 - open: 8.4.2 - pkg-up: 3.1.0 - prompts: 2.4.2 - react-error-overlay: 6.0.11 - recursive-readdir: 2.2.3 - shell-quote: 1.8.1 - strip-ansi: 6.0.1 - text-table: 0.2.0 - typescript: 4.9.5 - webpack: 5.88.2 - transitivePeerDependencies: - - eslint - - supports-color - - vue-template-compiler - dev: false - /react-dev-utils/12.0.1_vq6t4wvflba3b6dvvfvomzl76u: resolution: {integrity: sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==} engines: {node: '>=14'} @@ -43969,30 +43974,6 @@ packages: terser: 5.19.3 webpack: 5.78.0 - /terser-webpack-plugin/5.3.7_webpack@5.88.2: - resolution: {integrity: sha512-AfKwIktyP7Cu50xNjXF/6Qb5lBNzYaWpU6YfoX3uZicTx0zTy0stDDCsvjDapKsSDvOeWo5MEq4TmdBy2cNoHw==} - engines: {node: '>= 10.13.0'} - peerDependencies: - '@swc/core': '*' - esbuild: '*' - uglify-js: '*' - webpack: ^5.1.0 - peerDependenciesMeta: - '@swc/core': - optional: true - esbuild: - optional: true - uglify-js: - optional: true - dependencies: - '@jridgewell/trace-mapping': 0.3.19 - jest-worker: 27.5.1 - schema-utils: 3.3.0 - serialize-javascript: 6.0.1 - terser: 5.19.3 - webpack: 5.88.2 - dev: false - /terser-webpack-plugin/5.3.9_2pue2hesc4kyarjonhtsco4zxm: resolution: {integrity: sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==} engines: {node: '>= 10.13.0'} @@ -44139,6 +44120,7 @@ packages: serialize-javascript: 6.0.1 terser: 5.19.3 webpack: 5.88.2 + dev: true /terser-webpack-plugin/5.3.9_zpsjxul5gtyjq5vu5uxru46xsq: resolution: {integrity: sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==} @@ -46164,6 +46146,7 @@ packages: range-parser: 1.2.1 schema-utils: 4.0.0 webpack: 5.88.2 + dev: true /webpack-dev-middleware/6.0.1_webpack@5.76.1: resolution: {integrity: sha512-PZPZ6jFinmqVPJZbisfggDiC+2EeGZ1ZByyMP5sOFJcPPWSexalISz+cvm+j+oYPT7FIJyxT76esjnw9DhE5sw==} @@ -46337,6 +46320,7 @@ packages: - debug - supports-color - utf-8-validate + dev: true /webpack-hot-middleware/2.25.3: resolution: {integrity: sha512-IK/0WAHs7MTu1tzLTjio73LjS3Ov+VvBKQmE8WPlJutgG5zT6Urgq/BbAdRrHTRpyzK0dvAvFh1Qg98akxgZpA==} @@ -46599,6 +46583,7 @@ packages: - '@swc/core' - esbuild - uglify-js + dev: true /webpack/5.88.2_@swc+core@1.3.49: resolution: {integrity: sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==} diff --git a/providers/africas-talking/package.json b/providers/africas-talking/package.json index 1d309105880..5bf268e0251 100644 --- a/providers/africas-talking/package.json +++ b/providers/africas-talking/package.json @@ -1,6 +1,6 @@ { "name": "@novu/africas-talking", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "An Africa's Talking wrapper for Novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -34,7 +34,7 @@ "pnpm": "^7.26.0" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "africastalking": "^0.6.2" }, "devDependencies": { diff --git a/providers/apns/package.json b/providers/apns/package.json index 322e2f381f2..0d539293d49 100644 --- a/providers/apns/package.json +++ b/providers/apns/package.json @@ -1,6 +1,6 @@ { "name": "@novu/apns", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A apns wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -36,7 +36,7 @@ "node": ">=10" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "@parse/node-apn": "^5.2.3" }, "devDependencies": { diff --git a/providers/burst-sms/package.json b/providers/burst-sms/package.json index 370f87c8a95..d52eafa0e13 100644 --- a/providers/burst-sms/package.json +++ b/providers/burst-sms/package.json @@ -1,6 +1,6 @@ { "name": "@novu/burst-sms", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A burstSms wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -37,7 +37,7 @@ "node": ">=10" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "axios": "^1.3.3", "qs": "^6.11.0" }, diff --git a/providers/clickatell/package.json b/providers/clickatell/package.json index 9b8b1861d4e..d11e3e17845 100644 --- a/providers/clickatell/package.json +++ b/providers/clickatell/package.json @@ -1,6 +1,6 @@ { "name": "@novu/clickatell", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A clickatell SMS provider wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -31,7 +31,7 @@ "node": ">=10" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "axios": "^1.3.3" }, "devDependencies": { diff --git a/providers/discord/package.json b/providers/discord/package.json index 15a6bdc4b39..e3eda6bb0fd 100644 --- a/providers/discord/package.json +++ b/providers/discord/package.json @@ -1,6 +1,6 @@ { "name": "@novu/discord", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A discord wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -32,7 +32,7 @@ "node": ">=10" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "axios": "^1.3.3" }, "devDependencies": { diff --git a/providers/email-webhook/package.json b/providers/email-webhook/package.json index acad833538d..c7e428f9e81 100644 --- a/providers/email-webhook/package.json +++ b/providers/email-webhook/package.json @@ -1,6 +1,6 @@ { "name": "@novu/email-webhook", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "An email channel webhook provider wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", diff --git a/providers/emailjs/package.json b/providers/emailjs/package.json index e86b805827d..7e0027b2979 100644 --- a/providers/emailjs/package.json +++ b/providers/emailjs/package.json @@ -1,6 +1,6 @@ { "name": "@novu/emailjs", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "An emailjs provider for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -45,7 +45,7 @@ "node": ">=10" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "emailjs": "^3.6.0" }, "devDependencies": { diff --git a/providers/expo/package.json b/providers/expo/package.json index 70bb32c8ded..08a2eb1c395 100644 --- a/providers/expo/package.json +++ b/providers/expo/package.json @@ -1,6 +1,6 @@ { "name": "@novu/expo", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A expo wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -32,7 +32,7 @@ "node": ">=10" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "expo-server-sdk": "^3.6.0" }, "devDependencies": { diff --git a/providers/fcm/package.json b/providers/fcm/package.json index 41d8fecacd5..4e124097fb9 100644 --- a/providers/fcm/package.json +++ b/providers/fcm/package.json @@ -1,6 +1,6 @@ { "name": "@novu/fcm", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A fcm wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -32,7 +32,7 @@ "node": ">=10" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "firebase-admin": "^11.10.1" }, "devDependencies": { diff --git a/providers/firetext/package.json b/providers/firetext/package.json index 56c85340d56..4e987a77b7e 100644 --- a/providers/firetext/package.json +++ b/providers/firetext/package.json @@ -1,6 +1,6 @@ { "name": "@novu/firetext", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A firetext wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -32,7 +32,7 @@ "node": ">=10" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "node-fetch": "^3.2.10" }, "devDependencies": { diff --git a/providers/forty-six-elks/package.json b/providers/forty-six-elks/package.json index a9a4db2c215..cb024285c0c 100644 --- a/providers/forty-six-elks/package.json +++ b/providers/forty-six-elks/package.json @@ -1,6 +1,6 @@ { "name": "@novu/forty-six-elks", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A 46elks wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -33,7 +33,7 @@ "pnpm": "^7.26.0" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "axios": "^1.3.4" }, "devDependencies": { diff --git a/providers/gupshup/package.json b/providers/gupshup/package.json index fb1cf1eab7f..16de2e73239 100644 --- a/providers/gupshup/package.json +++ b/providers/gupshup/package.json @@ -1,6 +1,6 @@ { "name": "@novu/gupshup", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A gupshup wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -32,7 +32,7 @@ "node": ">=10" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "node-fetch": "^3.2.10" }, "devDependencies": { diff --git a/providers/infobip/package.json b/providers/infobip/package.json index 3c4705daf6c..d50878c4d9c 100644 --- a/providers/infobip/package.json +++ b/providers/infobip/package.json @@ -1,6 +1,6 @@ { "name": "@novu/infobip", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A infobip wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -33,7 +33,7 @@ }, "dependencies": { "@infobip-api/sdk": "^0.2.0", - "@novu/stateless": "^0.19.0" + "@novu/stateless": "^0.20.0-alpha.0" }, "devDependencies": { "@istanbuljs/nyc-config-typescript": "^1.0.1", diff --git a/providers/kannel/package.json b/providers/kannel/package.json index 091f11e2d70..32e5bd09e32 100644 --- a/providers/kannel/package.json +++ b/providers/kannel/package.json @@ -1,6 +1,6 @@ { "name": "@novu/kannel", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A kannel wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -32,7 +32,7 @@ "node": ">=10" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "axios": "^0.27.2" }, "devDependencies": { diff --git a/providers/mailersend/package.json b/providers/mailersend/package.json index a8043ac137a..87967d95e79 100644 --- a/providers/mailersend/package.json +++ b/providers/mailersend/package.json @@ -1,6 +1,6 @@ { "name": "@novu/mailersend", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A mailersend wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -32,7 +32,7 @@ "node": ">=10" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "mailersend": "^1.3.1" }, "devDependencies": { diff --git a/providers/mailgun/package.json b/providers/mailgun/package.json index 04121153fb7..00972d34bc6 100644 --- a/providers/mailgun/package.json +++ b/providers/mailgun/package.json @@ -1,6 +1,6 @@ { "name": "@novu/mailgun", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A mailgun wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -44,7 +44,7 @@ "access": "public" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "form-data": "^4.0.0", "mailgun.js": "^8.0.1", "nock": "^13.1.3" diff --git a/providers/mailjet/package.json b/providers/mailjet/package.json index 59270cf5aa1..3488d17060c 100644 --- a/providers/mailjet/package.json +++ b/providers/mailjet/package.json @@ -1,6 +1,6 @@ { "name": "@novu/mailjet", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A mailjet wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -32,7 +32,7 @@ "node": ">=10" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "node-mailjet": "^6.0.4" }, "devDependencies": { diff --git a/providers/mandrill/package.json b/providers/mandrill/package.json index 31d252461f9..46fbcc2fd6b 100644 --- a/providers/mandrill/package.json +++ b/providers/mandrill/package.json @@ -1,6 +1,6 @@ { "name": "@novu/mandrill", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A mandrill wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -42,7 +42,7 @@ }, "dependencies": { "@mailchimp/mailchimp_transactional": "^1.0.46", - "@novu/stateless": "^0.19.0" + "@novu/stateless": "^0.20.0-alpha.0" }, "devDependencies": { "@istanbuljs/nyc-config-typescript": "1.0.2", diff --git a/providers/maqsam/package.json b/providers/maqsam/package.json index 87fce89928b..939fc363a42 100644 --- a/providers/maqsam/package.json +++ b/providers/maqsam/package.json @@ -1,6 +1,6 @@ { "name": "@novu/maqsam", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A maqsam wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -33,7 +33,7 @@ "pnpm": "^7.26.0" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "axios": "^1.3.4", "date-fns": "2.29.3", "moment": "^2.29.4" diff --git a/providers/mattermost/package.json b/providers/mattermost/package.json index 72184969a98..bb072b30ca3 100644 --- a/providers/mattermost/package.json +++ b/providers/mattermost/package.json @@ -1,6 +1,6 @@ { "name": "@novu/mattermost", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A mattermost wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -33,7 +33,7 @@ "pnpm": "^7.26.0" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "axios": "^1.3.3" }, "devDependencies": { diff --git a/providers/ms-teams/package.json b/providers/ms-teams/package.json index a743ce7c003..d0f5b932248 100644 --- a/providers/ms-teams/package.json +++ b/providers/ms-teams/package.json @@ -1,6 +1,6 @@ { "name": "@novu/ms-teams", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A MS-Teams wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", diff --git a/providers/netcore/package.json b/providers/netcore/package.json index 128ca8c8eae..8d6a6d08d71 100644 --- a/providers/netcore/package.json +++ b/providers/netcore/package.json @@ -1,6 +1,6 @@ { "name": "@novu/netcore", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A netcore wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -45,7 +45,7 @@ "node": ">=10" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "pepipost": "^5.0.0" }, "devDependencies": { diff --git a/providers/nexmo/package.json b/providers/nexmo/package.json index 7e81bb67369..b06c49cbfa0 100644 --- a/providers/nexmo/package.json +++ b/providers/nexmo/package.json @@ -1,6 +1,6 @@ { "name": "@novu/nexmo", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A nexmo wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -32,7 +32,7 @@ "node": ">=10" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "@vonage/server-sdk": "^2.10.10" }, "devDependencies": { diff --git a/providers/nodemailer/package.json b/providers/nodemailer/package.json index 2021ca2c435..216785c8e0b 100644 --- a/providers/nodemailer/package.json +++ b/providers/nodemailer/package.json @@ -1,6 +1,6 @@ { "name": "@novu/nodemailer", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A nodemailer wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -45,7 +45,7 @@ "node": ">=10" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "nodemailer": "^6.6.5" }, "devDependencies": { diff --git a/providers/one-signal/package.json b/providers/one-signal/package.json index 81a38f9a2cf..5399541be66 100644 --- a/providers/one-signal/package.json +++ b/providers/one-signal/package.json @@ -1,6 +1,6 @@ { "name": "@novu/one-signal", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A OneSignal wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -34,7 +34,7 @@ "pnpm": "^7.26.0" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "onesignal-node": "^3.4.0" }, "devDependencies": { diff --git a/providers/outlook365/package.json b/providers/outlook365/package.json index a3cfd739b8e..f85640809c9 100644 --- a/providers/outlook365/package.json +++ b/providers/outlook365/package.json @@ -1,6 +1,6 @@ { "name": "@novu/outlook365", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A outlook365 wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -32,7 +32,7 @@ "node": ">=10" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "nodemailer": "^6.6.5" }, "devDependencies": { diff --git a/providers/plivo/package.json b/providers/plivo/package.json index ecdcc4ed78d..ff7d82ce7cd 100644 --- a/providers/plivo/package.json +++ b/providers/plivo/package.json @@ -1,6 +1,6 @@ { "name": "@novu/plivo", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A plivo wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -44,7 +44,7 @@ "node": ">=10" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "plivo": "^4.22.4" }, "devDependencies": { diff --git a/providers/plunk/package.json b/providers/plunk/package.json index 0cbf2a42b90..1a3493fa17c 100644 --- a/providers/plunk/package.json +++ b/providers/plunk/package.json @@ -1,6 +1,6 @@ { "name": "@novu/plunk", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A plunk wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -33,7 +33,7 @@ "pnpm": "^7.26.0" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "@plunk/node": "2.0.0" }, "devDependencies": { diff --git a/providers/postmark/package.json b/providers/postmark/package.json index e5d6a2f31f2..03a3aec4268 100644 --- a/providers/postmark/package.json +++ b/providers/postmark/package.json @@ -1,6 +1,6 @@ { "name": "@novu/postmark", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A postmark wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -45,7 +45,7 @@ "node": ">=10" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "axios": "^1.3.6", "postmark": "^2.7.8" }, diff --git a/providers/push-webhook/package.json b/providers/push-webhook/package.json index 626d75b315b..5278eb91677 100644 --- a/providers/push-webhook/package.json +++ b/providers/push-webhook/package.json @@ -1,6 +1,6 @@ { "name": "@novu/push-webhook", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A push-webhook wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -34,7 +34,7 @@ "pnpm": "^7.26.0" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "axios": "^1.3.5" }, "devDependencies": { diff --git a/providers/resend/package.json b/providers/resend/package.json index 7686b1838e4..8f2a56c7730 100644 --- a/providers/resend/package.json +++ b/providers/resend/package.json @@ -1,6 +1,6 @@ { "name": "@novu/resend", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A resend wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -32,7 +32,7 @@ "node": ">=10" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "resend": "^0.11.0" }, "devDependencies": { diff --git a/providers/sendchamp/package.json b/providers/sendchamp/package.json index ca84ca8fdfc..e506a48789b 100644 --- a/providers/sendchamp/package.json +++ b/providers/sendchamp/package.json @@ -1,6 +1,6 @@ { "name": "@novu/sendchamp", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A sendchamp wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -33,7 +33,7 @@ "pnpm": "^7.26.0" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "axios": "^1.4.0" }, "devDependencies": { diff --git a/providers/sendgrid/package.json b/providers/sendgrid/package.json index 1f5da967e6b..3c7b8a6c6c8 100644 --- a/providers/sendgrid/package.json +++ b/providers/sendgrid/package.json @@ -1,6 +1,6 @@ { "name": "@novu/sendgrid", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A sendgrid wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -45,7 +45,7 @@ "node": ">=10" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "@sendgrid/mail": "^7.4.6" }, "devDependencies": { diff --git a/providers/sendinblue/package.json b/providers/sendinblue/package.json index 74c64a7073f..07c7b8bf375 100644 --- a/providers/sendinblue/package.json +++ b/providers/sendinblue/package.json @@ -1,6 +1,6 @@ { "name": "@novu/sendinblue", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A sendinblue wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -32,7 +32,7 @@ "node": ">=10" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "@sendinblue/client": "^3.0.1" }, "devDependencies": { diff --git a/providers/ses/package.json b/providers/ses/package.json index d976f97fe80..a5bbc189caf 100644 --- a/providers/ses/package.json +++ b/providers/ses/package.json @@ -1,6 +1,6 @@ { "name": "@novu/ses", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A ses wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -33,7 +33,7 @@ }, "dependencies": { "@aws-sdk/client-ses": "3.382.0", - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "nodemailer": "^6.6.5" }, "devDependencies": { diff --git a/providers/slack/package.json b/providers/slack/package.json index f6f4965b7ed..d734d58a109 100644 --- a/providers/slack/package.json +++ b/providers/slack/package.json @@ -1,6 +1,6 @@ { "name": "@novu/slack", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A slack wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -32,7 +32,7 @@ "node": ">=10" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "axios": "^1.3.3" }, "devDependencies": { diff --git a/providers/sms-central/package.json b/providers/sms-central/package.json index fb9e80dd2d1..c89b91e28e0 100644 --- a/providers/sms-central/package.json +++ b/providers/sms-central/package.json @@ -1,6 +1,6 @@ { "name": "@novu/sms-central", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A sms-central wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", diff --git a/providers/sms77/package.json b/providers/sms77/package.json index 1c189002aa4..a1b81954906 100644 --- a/providers/sms77/package.json +++ b/providers/sms77/package.json @@ -1,6 +1,6 @@ { "name": "@novu/sms77", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A sms77 wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -32,7 +32,7 @@ "node": ">=10" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "node-fetch": "^2.6.7", "sms77-client": "^2.14.0" }, diff --git a/providers/sns/package.json b/providers/sns/package.json index f6be0962da7..bec123b17de 100644 --- a/providers/sns/package.json +++ b/providers/sns/package.json @@ -1,6 +1,6 @@ { "name": "@novu/sns", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A sns wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -33,7 +33,7 @@ }, "dependencies": { "@aws-sdk/client-sns": "^3.382.0", - "@novu/stateless": "^0.19.0" + "@novu/stateless": "^0.20.0-alpha.0" }, "devDependencies": { "@istanbuljs/nyc-config-typescript": "^1.0.1", diff --git a/providers/sparkpost/package.json b/providers/sparkpost/package.json index 01729ec4dee..35d82a46fbf 100644 --- a/providers/sparkpost/package.json +++ b/providers/sparkpost/package.json @@ -1,6 +1,6 @@ { "name": "@novu/sparkpost", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A sparkpost wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -32,7 +32,7 @@ "node": ">=10" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "sparkpost": "^2.1.4" }, "devDependencies": { diff --git a/providers/telnyx/package.json b/providers/telnyx/package.json index c14e580093b..b95b2429956 100644 --- a/providers/telnyx/package.json +++ b/providers/telnyx/package.json @@ -1,6 +1,6 @@ { "name": "@novu/telnyx", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A telnyx wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -32,7 +32,7 @@ "node": ">=10" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "telnyx": "^1.23.0" }, "devDependencies": { diff --git a/providers/termii/package.json b/providers/termii/package.json index 6b73d023051..938d45fd752 100644 --- a/providers/termii/package.json +++ b/providers/termii/package.json @@ -1,6 +1,6 @@ { "name": "@novu/termii", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A termii wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -32,7 +32,7 @@ "node": ">=10" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "node-fetch": "^3.2.10" }, "devDependencies": { diff --git a/providers/twilio/package.json b/providers/twilio/package.json index 789dc690783..4bbc18c5f28 100644 --- a/providers/twilio/package.json +++ b/providers/twilio/package.json @@ -1,6 +1,6 @@ { "name": "@novu/twilio", - "version": "0.19.0", + "version": "0.20.0-alpha.0", "description": "A twilio wrapper for novu", "main": "build/main/index.js", "typings": "build/main/index.d.ts", @@ -44,7 +44,7 @@ "access": "public" }, "dependencies": { - "@novu/stateless": "^0.19.0", + "@novu/stateless": "^0.20.0-alpha.0", "twilio": "^4.14.1" }, "devDependencies": {