diff --git a/.commitlintrc.json b/.commitlintrc.json
index 7185c74f33d..1e59a32dc9b 100644
--- a/.commitlintrc.json
+++ b/.commitlintrc.json
@@ -1,10 +1,23 @@
{
- "extends": ["@commitlint/config-conventional"],
+ "extends": [
+ "@commitlint/config-conventional"
+ ],
"rules": {
+ "body-max-line-length": [
+ 0,
+ "always"
+ ],
"subject-case": [
2,
"always",
- ["sentence-case", "start-case", "pascal-case", "upper-case", "lower-case", "camel-case"]
+ [
+ "sentence-case",
+ "start-case",
+ "pascal-case",
+ "upper-case",
+ "lower-case",
+ "camel-case"
+ ]
],
"type-enum": [
2,
diff --git a/.cspell.json b/.cspell.json
index 6ad454ad71d..5b4cbf3728f 100644
--- a/.cspell.json
+++ b/.cspell.json
@@ -567,6 +567,9 @@
"upserted",
"upstash",
"Upstash",
+ "usecase",
+ "USECASE",
+ "Vonage",
"Krakend",
"ratelimit",
"Ratelimit",
@@ -600,19 +603,26 @@
"cpack",
"pulumi",
"hostedtoolcache",
+ "OTLP",
+ "otlp",
+ "hostedtoolcache",
"pyroscope",
"HEAY",
"Pyroscope",
"PYROSCOPE",
"usecases",
- "hbspt",
+ "hbspt",
"prepopulating",
"Vonage",
"fieldtype",
"usecase",
"zulip",
"uuidv",
- "Vonage"
+ "Vonage",
+ "runtimes",
+ "cafebabe",
+ "Icann",
+ "limitbar",
],
"flagWords": [],
"patterns": [
@@ -675,6 +685,7 @@
"apps/api/src/.env.test",
"apps/ws/src/.env.test",
"apps/ws/src/.example.env",
+ "apps/web/playwright.config.ts",
".cspell.json",
"package.json",
"package-lock.json",
@@ -696,6 +707,6 @@
"angular.json",
"ng-package.json",
"libs/shared/src/types/timezones/timezones.types.ts",
- "*.riv"
+ "*.riv",
]
}
diff --git a/.eslintrc.js b/.eslintrc.js
index eb5537025dd..324b870bf86 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -66,6 +66,7 @@ module.exports = {
{
patterns: [
'@novu/shared/*',
+ '!@novu/shared/utils',
'@novu/dal/*',
'!import2/good',
'*../libs/dal/*',
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 85904f46bdf..2cf10e5d3e3 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,12 +1,16 @@
-### What change does this PR introduce?
+### What changed? Why was the change needed?
+
-
+### Screenshots
+
-### Why was this change needed?
+Expand for optional sections
-
+### Related enterprise PR
+
-### Other information (Screenshots)
+### Special notes for your reviewer
+
-
-
+
- React Component - · Vue Component - · Angular Component + React Component + · Vue Component + · Angular Component
Red Text
'); }); + + it('should NOT sanitize img tags', function () { + const result = sanitizeMessageContent([ + { + type: EmailBlockTypeEnum.TEXT, + content: '', + url: '', + }, + ]); + + expect(result[0].content).to.equal(''); + }); }); diff --git a/apps/api/src/app/message-template/shared/sanitizer.service.ts b/apps/api/src/app/message-template/shared/sanitizer.service.ts index ea2651d5798..a3bafe14aa8 100644 --- a/apps/api/src/app/message-template/shared/sanitizer.service.ts +++ b/apps/api/src/app/message-template/shared/sanitizer.service.ts @@ -10,13 +10,14 @@ const sanitizeOptions: sanitize.IOptions = { /** * Additional tags to allow. */ - allowedTags: sanitize.defaults.allowedTags.concat(['style']), + allowedTags: sanitize.defaults.allowedTags.concat(['style', 'img']), allowedAttributes: { ...sanitize.defaults.allowedAttributes, /** * Additional attributes to allow on all tags. */ '*': ['style'], + img: ['src', 'srcset', 'alt', 'title', 'width', 'height', 'loading'], }, /** * Required to disable console warnings when allowing style tags. diff --git a/apps/api/src/app/message-template/usecases/update-message-template/update-message-template.usecase.ts b/apps/api/src/app/message-template/usecases/update-message-template/update-message-template.usecase.ts index a3c4d91516e..f1398f9a3c6 100644 --- a/apps/api/src/app/message-template/usecases/update-message-template/update-message-template.usecase.ts +++ b/apps/api/src/app/message-template/usecases/update-message-template/update-message-template.usecase.ts @@ -33,7 +33,7 @@ export class UpdateMessageTemplate { updatePayload.name = command.name; } - if (command.content !== null) { + if (command.content !== null || command.content !== undefined) { updatePayload.content = command.contentType === 'editor' ? sanitizeMessageContent(command.content) : command.content; } diff --git a/apps/api/src/app/organization/organization.module.ts b/apps/api/src/app/organization/organization.module.ts index 9e058638c81..b9764c53d60 100644 --- a/apps/api/src/app/organization/organization.module.ts +++ b/apps/api/src/app/organization/organization.module.ts @@ -1,4 +1,13 @@ -import { MiddlewareConsumer, Module, NestModule, RequestMethod, forwardRef } from '@nestjs/common'; +import { + MiddlewareConsumer, + Module, + DynamicModule, + NestModule, + RequestMethod, + forwardRef, + Logger, + ForwardReference, +} from '@nestjs/common'; import { AuthGuard } from '@nestjs/passport'; import { EnvironmentsModule } from '../environments/environments.module'; import { IntegrationModule } from '../integrations/integrations.module'; @@ -7,9 +16,32 @@ import { UserModule } from '../user/user.module'; import { OrganizationController } from './organization.controller'; import { USE_CASES } from './usecases'; import { AuthModule } from '../auth/auth.module'; +import { Type } from '@nestjs/common/interfaces/type.interface'; + +const enterpriseImports = (): Array
@@ -55,13 +56,14 @@ export function AppLayout() {
)}
>
-
+
+
-
+
diff --git a/apps/web/src/components/layout/components/EchoStatus.tsx b/apps/web/src/components/layout/components/EchoStatus.tsx
index 3982bf6ea30..2905a3cbf11 100644
--- a/apps/web/src/components/layout/components/EchoStatus.tsx
+++ b/apps/web/src/components/layout/components/EchoStatus.tsx
@@ -31,9 +31,13 @@ export function EchoStatus() {
return null;
}
- if (!echoEnabled || isInitialLoading) return null;
+ if (!echoEnabled) return null;
const status = data?.status === 'ok' && !error ? 'ok' : 'down';
+ let color = status === 'ok' ? 'green' : 'red';
+ if (isInitialLoading) {
+ color = 'yellow';
+ }
return (
+
Echo
}
diff --git a/apps/web/src/components/layout/components/FreeTrialBanner.tsx b/apps/web/src/components/layout/components/FreeTrialBanner.tsx
new file mode 100644
index 00000000000..1135ff84ba5
--- /dev/null
+++ b/apps/web/src/components/layout/components/FreeTrialBanner.tsx
@@ -0,0 +1,23 @@
+import { FeatureFlagsKeysEnum } from '@novu/shared';
+import { IS_DOCKER_HOSTED, useFeatureFlag } from '@novu/shared-web';
+
+export function FreeTrialBanner() {
+ const isEnabled = useFeatureFlag(FeatureFlagsKeysEnum.IS_BILLING_REVERSE_TRIAL_ENABLED);
+
+ if (IS_DOCKER_HOSTED) {
+ return null;
+ }
+
+ if (!isEnabled) {
+ return null;
+ }
+
+ try {
+ const module = require('@novu/ee-billing-web');
+ const Component = module.FreeTrialBanner;
+
+ return ;
+ } catch (e) {}
+
+ return null;
+}
diff --git a/apps/web/src/components/layout/components/FreeTrialSidebarWidget.tsx b/apps/web/src/components/layout/components/FreeTrialSidebarWidget.tsx
new file mode 100644
index 00000000000..9c455e9ae63
--- /dev/null
+++ b/apps/web/src/components/layout/components/FreeTrialSidebarWidget.tsx
@@ -0,0 +1,23 @@
+import { FeatureFlagsKeysEnum } from '@novu/shared';
+import { IS_DOCKER_HOSTED, useFeatureFlag } from '@novu/shared-web';
+
+export const FreeTrialSidebarWidget = () => {
+ const isEnabled = useFeatureFlag(FeatureFlagsKeysEnum.IS_BILLING_REVERSE_TRIAL_ENABLED);
+
+ if (IS_DOCKER_HOSTED) {
+ return null;
+ }
+
+ if (!isEnabled) {
+ return null;
+ }
+
+ try {
+ const module = require('@novu/ee-billing-web');
+ const Component = module.FreeTrialSidebarWidget;
+
+ return ;
+ } catch (e) {}
+
+ return null;
+};
diff --git a/apps/web/src/components/layout/components/OrganizationSelect.tsx b/apps/web/src/components/layout/components/OrganizationSelect.tsx
index 22f824d3161..8fd6a6d5a29 100644
--- a/apps/web/src/components/layout/components/OrganizationSelect.tsx
+++ b/apps/web/src/components/layout/components/OrganizationSelect.tsx
@@ -4,7 +4,7 @@ import * as capitalize from 'lodash.capitalize';
import styled from '@emotion/styled';
import { useNavigate } from 'react-router-dom';
import type { IResponseError, IOrganizationEntity } from '@novu/shared';
-import { Select } from '@novu/design-system';
+import { Select, successMessage } from '@novu/design-system';
import { addOrganization, switchOrganization } from '../../../api/organization';
import { useAuthContext } from '../../providers/AuthProvider';
@@ -25,7 +25,11 @@ export default function OrganizationSelect() {
IOrganizationEntity,
IResponseError,
string
- >((name) => addOrganization(name));
+ >((name) => addOrganization(name), {
+ onSuccess: () => {
+ successMessage('Your Business trial has started');
+ },
+ });
const { mutateAsync: changeOrganization } = useMutation((id) =>
switchOrganization(id)
diff --git a/apps/web/src/components/layout/components/SideNav.tsx b/apps/web/src/components/layout/components/SideNav.tsx
index 083757e78e2..f46a9062046 100644
--- a/apps/web/src/components/layout/components/SideNav.tsx
+++ b/apps/web/src/components/layout/components/SideNav.tsx
@@ -34,6 +34,7 @@ import { useSpotlightContext } from '../../providers/SpotlightProvider';
import { ChangesCountBadge } from './ChangesCountBadge';
import OrganizationSelect from './OrganizationSelect';
import { FeatureFlagsKeysEnum, UTM_CAMPAIGN_QUERY_PARAM } from '@novu/shared';
+import { FreeTrialSidebarWidget } from './FreeTrialSidebarWidget';
import { useUserOnboardingStatus } from '../../../api/hooks/useUserOnboardingStatus';
import { VisibilityOff } from './VisibilityOff';
import { useSegment } from '../../providers/SegmentProvider';
@@ -171,19 +172,19 @@ export function SideNav({}: Props) {
borderRight: 'none',
width: '300px',
minHeight: '100vh',
- padding: '16px 24px',
+ padding: '16px 0',
paddingBottom: '0px',
'@media (max-width: 768px)': {
width: '100%',
},
}}
>
-
+
-
+
+
{
}),
],
environment: ENV,
-
+ ignoreErrors: [
+ 'Network Error',
+ 'network error (Error)',
+ 'ResizeObserver loop limit exceeded',
+ 'ResizeObserver loop completed with undelivered notifications',
+ 'Non-Error exception captured',
+ 'Non-Error promise rejection captured',
+ ],
/*
* This sets the sample rate to be 10%. You may want this to be 100% while
* in development and sample at a lower rate in production
diff --git a/apps/web/src/pages/auth/components/HubspotSignupForm.tsx b/apps/web/src/pages/auth/components/HubspotSignupForm.tsx
index c25cad97f3c..9d1f7c8d29c 100644
--- a/apps/web/src/pages/auth/components/HubspotSignupForm.tsx
+++ b/apps/web/src/pages/auth/components/HubspotSignupForm.tsx
@@ -14,6 +14,7 @@ import { useVercelIntegration, useVercelParams } from '../../../hooks';
import { ROUTES } from '../../../constants/routes.enum';
import { HUBSPOT_FORM_IDS } from '../../../constants/hubspotForms';
import SetupLoader from './SetupLoader';
+import { successMessage } from '@novu/design-system';
export function HubspotSignupForm() {
const [loading, setLoading] = useState();
@@ -51,6 +52,9 @@ export function HubspotSignupForm() {
const { organizationName, jobTitle, ...rest } = data;
const createDto: ICreateOrganizationDto = { ...rest, name: organizationName, jobTitle };
const organization = await createOrganizationMutation(createDto);
+
+ successMessage('Your Business trial has started');
+
const organizationResponseToken = await api.post(`/v1/auth/organizations/${organization._id}/switch`, {});
setToken(organizationResponseToken);
diff --git a/apps/web/src/pages/auth/components/LoginForm.tsx b/apps/web/src/pages/auth/components/LoginForm.tsx
index ffcc4448dde..b545fdf9ad8 100644
--- a/apps/web/src/pages/auth/components/LoginForm.tsx
+++ b/apps/web/src/pages/auth/components/LoginForm.tsx
@@ -13,6 +13,7 @@ import { useVercelParams } from '../../../hooks';
import { useAcceptInvite } from './useAcceptInvite';
import { ROUTES } from '../../../constants/routes.enum';
import { OAuth } from './OAuth';
+import { parseServerErrorMessage } from '../../../utils/errors';
type LoginFormProps = {
invitationToken?: string;
@@ -78,29 +79,28 @@ export function LoginForm({ email, invitationToken }: LoginFormProps) {
}
};
- const serverErrorString = useMemo(() => {
- return Array.isArray(error?.message) ? error?.message[0] : error?.message;
- }, [error]);
+ const emailClientError = errors.email?.message;
+ let emailServerError = parseServerErrorMessage(error);
- const emailServerError = useMemo(() => {
- if (serverErrorString === 'email must be an email') return 'Please provide a valid email';
-
- return '';
- }, [serverErrorString]);
+ // TODO: Use a more human-friendly message in the IsEmail validator and remove this patch
+ if (emailServerError === 'email must be an email') {
+ emailServerError = 'Please provide a valid email address';
+ }
return (
<>
- {isError && !emailServerError && (
-
- {' '}
- {error?.message}
-
- )}
>
);
}
diff --git a/apps/web/src/pages/auth/components/QuestionnaireForm.tsx b/apps/web/src/pages/auth/components/QuestionnaireForm.tsx
index d698ba91821..c8c59eb87c1 100644
--- a/apps/web/src/pages/auth/components/QuestionnaireForm.tsx
+++ b/apps/web/src/pages/auth/components/QuestionnaireForm.tsx
@@ -9,7 +9,6 @@ import { JobTitleEnum, jobTitleToLabelMapper, ProductUseCasesEnum } from '@novu/
import type { ProductUseCases, IResponseError, ICreateOrganizationDto, IJwtPayload } from '@novu/shared';
import {
Button,
- colors,
Digest,
HalfClock,
Input,
@@ -26,6 +25,7 @@ import { useVercelIntegration, useVercelParams } from '../../../hooks';
import { ROUTES } from '../../../constants/routes.enum';
import { DynamicCheckBox } from './dynamic-checkbox/DynamicCheckBox';
import styled from '@emotion/styled/macro';
+import { useDomainParser } from './useDomainHook';
import { OnboardingExperimentV2ModalKey } from '../../../constants/experimentsConstants';
export function QuestionnaireForm() {
@@ -34,11 +34,13 @@ export function QuestionnaireForm() {
handleSubmit,
formState: { errors },
control,
+ setError,
} = useForm({});
const navigate = useNavigate();
const { setToken, token } = useAuthContext();
const { startVercelSetup } = useVercelIntegration();
const { isFromVercel } = useVercelParams();
+ const { parse } = useDomainParser();
const { mutateAsync: createOrganizationMutation } = useMutation<
{ _id: string },
@@ -162,9 +164,14 @@ export function QuestionnaireForm() {
name="domain"
control={control}
rules={{
- pattern: {
- value: /^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]\.[a-zA-Z]{2,}$/,
- message: 'Please make sure you specified a valid domain',
+ validate: {
+ isValiDomain: (value) => {
+ const val = parse(value as string);
+
+ if (value && !val.isIcann) {
+ return 'Please provide a valid domain';
+ }
+ },
},
}}
render={({ field }) => {
diff --git a/apps/web/src/pages/auth/components/SignUpForm.tsx b/apps/web/src/pages/auth/components/SignUpForm.tsx
index 5ae9274d156..ca81b0e2b56 100644
--- a/apps/web/src/pages/auth/components/SignUpForm.tsx
+++ b/apps/web/src/pages/auth/components/SignUpForm.tsx
@@ -3,7 +3,6 @@ import { Link, useNavigate } from 'react-router-dom';
import { useMutation } from '@tanstack/react-query';
import { useForm } from 'react-hook-form';
import { Center } from '@mantine/core';
-import { showNotification } from '@mantine/notifications';
import { passwordConstraints, UTM_CAMPAIGN_QUERY_PARAM } from '@novu/shared';
import type { IResponseError } from '@novu/shared';
import { PasswordInput, Button, colors, Input, Text, Checkbox } from '@novu/design-system';
@@ -13,7 +12,6 @@ import { api } from '../../../api/api.client';
import { applyToken, useVercelParams } from '../../../hooks';
import { useAcceptInvite } from './useAcceptInvite';
import { PasswordRequirementPopover } from './PasswordRequirementPopover';
-import { buildGithubLink, buildVercelGithubLink } from './gitHubUtils';
import { ROUTES } from '../../../constants/routes.enum';
import { OAuth } from './OAuth';
@@ -36,9 +34,6 @@ export function SignUpForm({ invitationToken, email }: SignUpFormProps) {
const { isFromVercel, code, next, configurationId } = useVercelParams();
const vercelQueryParams = `code=${code}&next=${next}&configurationId=${configurationId}`;
const loginLink = isFromVercel ? `/auth/login?${vercelQueryParams}` : ROUTES.AUTH_LOGIN;
- const githubLink = isFromVercel
- ? buildVercelGithubLink({ code, next, configurationId })
- : buildGithubLink({ invitationToken });
const { isLoading, mutateAsync, isError, error } = useMutation<
{ token: string },
@@ -52,21 +47,14 @@ export function SignUpForm({ invitationToken, email }: SignUpFormProps) {
>((data) => api.post('/v1/auth/register', data));
const onSubmit = async (data) => {
+ const [firstName, lastName] = data?.fullName.trim().split(' ');
const itemData = {
- firstName: data.fullName.split(' ')[0],
- lastName: data.fullName.split(' ')[1],
+ firstName,
+ lastName,
email: data.email,
password: data.password,
};
- if (!itemData.lastName) {
- showNotification({
- message: 'Please write your full name including last name',
- color: 'red',
- });
-
- return;
- }
const response = await mutateAsync(itemData);
/**
@@ -80,10 +68,9 @@ export function SignUpForm({ invitationToken, email }: SignUpFormProps) {
submitToken(token, invitationToken);
return true;
- } else {
- setToken(token);
}
+ setToken(token);
navigate(isFromVercel ? `/auth/application?${vercelQueryParams}` : ROUTES.AUTH_APPLICATION);
return true;
diff --git a/apps/web/src/pages/auth/components/useDomainHook.ts b/apps/web/src/pages/auth/components/useDomainHook.ts
new file mode 100644
index 00000000000..68deb7fb0d5
--- /dev/null
+++ b/apps/web/src/pages/auth/components/useDomainHook.ts
@@ -0,0 +1,62 @@
+import { useCallback, useEffect, useRef } from 'react';
+
+interface DomainInfo {
+ domain: string;
+ domainWithoutSuffix: string;
+ hostname: string;
+ isIcann: boolean;
+ isIp: boolean;
+ isPrivate: boolean;
+ publicSuffix: string;
+ subdomain: string;
+}
+
+function stripProtocol(url: string): string {
+ return (url || '').replace(/(https?)?(:\/+)?/, '');
+}
+
+function fallbackParser(url: string) {
+ const parts = stripProtocol(url).split('.');
+
+ if (parts.length > 2) {
+ const [subdomain, ...domainParts] = parts;
+
+ return {
+ subdomain: subdomain || '',
+ domain: domainParts.join('.'),
+ };
+ }
+
+ return {
+ subdomain: '',
+ domain: url,
+ };
+}
+
+export function useDomainParser(): { parse: (url: string) => Partial } {
+ const tldParser = useRef(null);
+
+ useEffect(() => {
+ import(
+ /* webpackIgnore: true */
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-ignore
+ // eslint-disable-next-line import/extensions
+ 'https://unpkg.com/tldts/dist/es6/index.js?module'
+ )
+ .then((mod) => (tldParser.current = mod))
+ .catch(() => (tldParser.current = null));
+ }, []);
+
+ const parse = useCallback((url: string) => {
+ url = stripProtocol(url);
+
+ if (tldParser.current) {
+ return (tldParser.current as any).parse(url, { allowPrivateDomains: true }) as DomainInfo;
+ }
+
+ return fallbackParser(url);
+ }, []);
+
+ return { parse };
+}
diff --git a/apps/web/src/pages/get-started/consts/DelayUseCase.const.tsx b/apps/web/src/pages/get-started/consts/DelayUseCase.const.tsx
index 4bff312c356..c50a3232694 100644
--- a/apps/web/src/pages/get-started/consts/DelayUseCase.const.tsx
+++ b/apps/web/src/pages/get-started/consts/DelayUseCase.const.tsx
@@ -9,7 +9,7 @@ import { OnboardingUseCasesTabsEnum } from './OnboardingUseCasesTabsEnum';
const USECASE_BLUEPRINT_IDENTIFIER = 'get-started-delay';
export const DelayUseCaseConst: OnboardingUseCase = {
- useCaseLink: 'https://docs.novu.co/workflows/delay-action',
+ useCaseLink: 'https://docs.novu.co/workflows/delay-action?utm_campaign=inapp-usecase-delay',
type: OnboardingUseCasesTabsEnum.DELAY,
title: 'Delay step execution',
description: 'Introduces a specified time delay between workflow steps, ensuring a well-paced progression of events.',
diff --git a/apps/web/src/pages/get-started/consts/DigestUseCase.const.tsx b/apps/web/src/pages/get-started/consts/DigestUseCase.const.tsx
index c2aed0be20d..92ffd13cbfc 100644
--- a/apps/web/src/pages/get-started/consts/DigestUseCase.const.tsx
+++ b/apps/web/src/pages/get-started/consts/DigestUseCase.const.tsx
@@ -15,7 +15,7 @@ export const DigestUseCaseConst: OnboardingUseCase = {
type: OnboardingUseCasesTabsEnum.DIGEST,
description:
'Aggregates multiple events into a single, concise message, preventing user overload with excessive notifications.',
- useCaseLink: 'https://docs.novu.co/workflows/digest',
+ useCaseLink: 'https://docs.novu.co/workflows/digest?utm_campaign=inapp-usecase-digest',
steps: [
{
title: 'Configure providers',
diff --git a/apps/web/src/pages/get-started/consts/InAppUseCase.const.tsx b/apps/web/src/pages/get-started/consts/InAppUseCase.const.tsx
index dcb0fcba3d7..0f3afbf2010 100644
--- a/apps/web/src/pages/get-started/consts/InAppUseCase.const.tsx
+++ b/apps/web/src/pages/get-started/consts/InAppUseCase.const.tsx
@@ -16,7 +16,7 @@ export const InAppUseCaseConst: OnboardingUseCase = {
description:
"Utilize Novu's pre-built customizable in-app component. " +
'Or opt for the headless library to create your own in-app notification center.',
- useCaseLink: 'https://docs.novu.co/channels-and-providers/in-app/introduction',
+ useCaseLink: 'https://docs.novu.co/channels-and-providers/in-app/introduction?utm_campaign=inapp-usecase-inapp',
steps: [
{
title: 'Configure In-App provider',
diff --git a/apps/web/src/pages/get-started/consts/MultiChannelUseCase.const.tsx b/apps/web/src/pages/get-started/consts/MultiChannelUseCase.const.tsx
index 1db41a28ed7..97803d5c069 100644
--- a/apps/web/src/pages/get-started/consts/MultiChannelUseCase.const.tsx
+++ b/apps/web/src/pages/get-started/consts/MultiChannelUseCase.const.tsx
@@ -15,7 +15,7 @@ export const MultiChannelUseCaseConst: OnboardingUseCase = {
'Notifies subscribers using a wide range of channels: In-App, Email, Chat, Push, and SMS.\n' +
'\n' +
'Configure as many providers as you like to Customize notification experience.',
- useCaseLink: 'https://docs.novu.co/channels-and-providers/introduction',
+ useCaseLink: 'https://docs.novu.co/channels-and-providers/introduction?utm_campaign=inapp-usecase-multichannel',
steps: [
{
title: 'Configure providers',
diff --git a/apps/web/src/pages/get-started/consts/TranslationUseCase.const.tsx b/apps/web/src/pages/get-started/consts/TranslationUseCase.const.tsx
index ac9a5f6dffd..1b6f84f7387 100644
--- a/apps/web/src/pages/get-started/consts/TranslationUseCase.const.tsx
+++ b/apps/web/src/pages/get-started/consts/TranslationUseCase.const.tsx
@@ -11,7 +11,7 @@ export const TranslationUseCaseConst: OnboardingUseCase = {
description:
'Upload translations to use them as variables or for auto-upload in the editor in a workflow. ' +
'This feature is available for business and enterprise plan.',
- useCaseLink: 'https://docs.novu.co/content-creation-design/translations',
+ useCaseLink: 'https://docs.novu.co/content-creation-design/translations?utm_campaign=inapp-usecase-translation',
steps: [
{
title: 'Configure providers',
diff --git a/apps/web/src/pages/integrations/components/NovuInAppForm.tsx b/apps/web/src/pages/integrations/components/NovuInAppForm.tsx
index 1c8a44139ef..50a5101cac9 100644
--- a/apps/web/src/pages/integrations/components/NovuInAppForm.tsx
+++ b/apps/web/src/pages/integrations/components/NovuInAppForm.tsx
@@ -131,7 +131,7 @@ export const NovuInAppForm = ({
{
window.open(
- `https://docs.novu.co/notification-center/client/iframe${UTM_CAMPAIGN_QUERY_PARAM}#enabling-hmac-encryption`
+ `https://docs.novu.co/notification-center/client/iframe#enabling-hmac-encryption${UTM_CAMPAIGN_QUERY_PARAM}`
);
}}
/>
diff --git a/apps/web/src/pages/quick-start/components/OnboardingExperimentModal.tsx b/apps/web/src/pages/quick-start/components/OnboardingExperimentModal.tsx
index e02139bcea6..b1791aeef8d 100644
--- a/apps/web/src/pages/quick-start/components/OnboardingExperimentModal.tsx
+++ b/apps/web/src/pages/quick-start/components/OnboardingExperimentModal.tsx
@@ -1,4 +1,4 @@
-import { useState } from 'react';
+import { useEffect, useState } from 'react';
import { Modal, useMantineTheme, Grid } from '@mantine/core';
import styled from '@emotion/styled';
@@ -22,6 +22,13 @@ export function OnboardingExperimentModal() {
setOpened(true);
};
+ useEffect(() => {
+ segment.track('Welcome modal open - [Onboarding]', {
+ experiment_id: '2024-w15-onb',
+ _organization: currentOrganization?._id,
+ });
+ }, [currentOrganization?._id, segment]);
+
return (
({ open: false });
- const isOnboardingModalEnabled = localStorage.getItem(OnboardingExperimentV2ModalKey) === 'true';
+ const isOnboardingModalEnabled =
+ localStorage.getItem(OnboardingExperimentV2ModalKey) === 'true' && window.innerWidth > 768;
const onIntegrationModalClose = () => setClickedChannel({ open: false });
useEffect(() => {
segment.track(OnBoardingAnalyticsEnum.CONFIGURE_PROVIDER_VISIT);
- if (isOnboardingModalEnabled) {
- segment.track('Welcome modal open - [Onboarding]', {
- experiment_id: '2024-w15-onb',
- _organization: currentOrganization?._id,
- });
- }
}, [currentOrganization?._id, isOnboardingModalEnabled, segment]);
function handleOnClick() {
diff --git a/apps/web/src/pages/templates/WorkflowListPage.tsx b/apps/web/src/pages/templates/WorkflowListPage.tsx
index 97e6abc4375..927deb23c10 100644
--- a/apps/web/src/pages/templates/WorkflowListPage.tsx
+++ b/apps/web/src/pages/templates/WorkflowListPage.tsx
@@ -52,7 +52,7 @@ const columns: IExtendedColumn[] = [
-
+
diff --git a/apps/web/src/pages/templates/components/InputVariables.tsx b/apps/web/src/pages/templates/components/InputVariables.tsx
index 45365e41f18..00bfc1bcc32 100644
--- a/apps/web/src/pages/templates/components/InputVariables.tsx
+++ b/apps/web/src/pages/templates/components/InputVariables.tsx
@@ -18,11 +18,11 @@ export const InputVariables = ({
}
try {
- const module = require('@novu/ee-billing-web');
+ const module = require('@novu/ee-echo-web');
const InputVariablesComponent = module.InputVariables;
return ;
- } catch (e) {}
-
- return null;
+ } catch (e) {
+ throw e;
+ }
};
diff --git a/apps/web/src/pages/templates/components/InputVariablesForm.tsx b/apps/web/src/pages/templates/components/InputVariablesForm.tsx
index dff89da03d4..38a19e495a2 100644
--- a/apps/web/src/pages/templates/components/InputVariablesForm.tsx
+++ b/apps/web/src/pages/templates/components/InputVariablesForm.tsx
@@ -27,7 +27,7 @@ export const InputVariablesForm = ({ onChange }: { onChange?: (data: any) => voi
}
try {
- const module = require('@novu/ee-billing-web');
+ const module = require('@novu/ee-echo-web');
const InputVariablesComponent = module.InputVariablesForm;
return (
@@ -40,7 +40,7 @@ export const InputVariablesForm = ({ onChange }: { onChange?: (data: any) => voi
/>
>
);
- } catch (e) {}
-
- return null;
+ } catch (e) {
+ throw e;
+ }
};
diff --git a/apps/web/src/pages/templates/components/WorkflowSidebar.tsx b/apps/web/src/pages/templates/components/WorkflowSidebar.tsx
index e803fd89f74..d32059667ef 100644
--- a/apps/web/src/pages/templates/components/WorkflowSidebar.tsx
+++ b/apps/web/src/pages/templates/components/WorkflowSidebar.tsx
@@ -2,16 +2,17 @@ import { ReactNode } from 'react';
import { Title } from '@mantine/core';
import { useNavigate } from 'react-router-dom';
import { colors, Sidebar } from '@novu/design-system';
+import { useMantineColorScheme } from '@mantine/core';
import { useBasePath } from '../hooks/useBasePath';
-import { useLocalThemePreference } from '@novu/shared-web';
export const WorkflowSidebar = ({ children, title }: { children: ReactNode; title: string }) => {
const navigate = useNavigate();
const path = useBasePath();
- const { themeStatus } = useLocalThemePreference();
- const isDark = themeStatus === 'dark';
+ const { colorScheme } = useMantineColorScheme();
+
+ const isDark = colorScheme === 'dark';
return (
{
- return ;
+ return ;
}}
/>
);
diff --git a/apps/web/src/pages/templates/hooks/usePreviewEmailTemplate.ts b/apps/web/src/pages/templates/hooks/usePreviewEmailTemplate.ts
index 0965203d7e1..327a8bcb0e6 100644
--- a/apps/web/src/pages/templates/hooks/usePreviewEmailTemplate.ts
+++ b/apps/web/src/pages/templates/hooks/usePreviewEmailTemplate.ts
@@ -5,6 +5,7 @@ import { usePreviewEmail } from '../../../api/hooks';
import { IForm } from '../components/formTypes';
import { useStepFormCombinedErrors } from './useStepFormCombinedErrors';
import { useStepFormPath } from './useStepFormPath';
+import { parsePayload } from '../../../utils';
export const usePreviewEmailTemplate = ({ locale, payload }: { locale?: string; payload: string }) => {
const { watch } = useFormContext();
@@ -39,7 +40,7 @@ export const usePreviewEmailTemplate = ({ locale, payload }: { locale?: string;
contentType: contentType,
content,
layoutId: layoutId,
- payload: JSON.parse(payloadArg),
+ payload: parsePayload(payloadArg),
subject: subject ?? '',
locale,
});
diff --git a/apps/web/src/pages/templates/hooks/usePreviewInAppTemplate.ts b/apps/web/src/pages/templates/hooks/usePreviewInAppTemplate.ts
index a8beaf4cbfd..e5fff8af8a4 100644
--- a/apps/web/src/pages/templates/hooks/usePreviewInAppTemplate.ts
+++ b/apps/web/src/pages/templates/hooks/usePreviewInAppTemplate.ts
@@ -6,6 +6,7 @@ import { useProcessVariables } from '../../../hooks';
import { IForm } from '../components/formTypes';
import { useStepFormCombinedErrors } from './useStepFormCombinedErrors';
import { useStepFormPath } from './useStepFormPath';
+import { parsePayload } from '../../../utils';
export type ParsedPreviewStateType = {
ctaButtons: IMessageButton[];
@@ -42,7 +43,7 @@ export const usePreviewInAppTemplate = ({ locale }: { locale?: string }) => {
getInAppPreview({
locale,
content: templateContent as string,
- payload: JSON.parse(payloadArg),
+ payload: parsePayload(payloadArg),
cta: templateCta,
});
},
diff --git a/apps/web/src/pages/templates/workflow/digest/TimedDigestWillBeSentHeader.tsx b/apps/web/src/pages/templates/workflow/digest/TimedDigestWillBeSentHeader.tsx
index b8ff9380772..6b07ae932ea 100644
--- a/apps/web/src/pages/templates/workflow/digest/TimedDigestWillBeSentHeader.tsx
+++ b/apps/web/src/pages/templates/workflow/digest/TimedDigestWillBeSentHeader.tsx
@@ -5,7 +5,6 @@ import { DigestUnitEnum, MonthlyTypeEnum } from '@novu/shared';
import { colors } from '@novu/design-system';
import { pluralizeTime } from '../../../../utils';
-import { useStepFormPath } from '../../hooks/useStepFormPath';
const Highlight = ({ children, isHighlight }) => {
const { colorScheme } = useMantineColorScheme();
@@ -61,13 +60,12 @@ const sortWeekdays = (weekdays: string[]): string[] => {
return weekdays.sort((a, b) => WEEKDAYS_ORDER.indexOf(a) - WEEKDAYS_ORDER.indexOf(b));
};
-export const TimedDigestWillBeSentHeader = ({ isHighlight = true }: { isHighlight?: boolean }) => {
+export const TimedDigestWillBeSentHeader = ({ path, isHighlight = true }: { path: string; isHighlight?: boolean }) => {
const { watch } = useFormContext();
- const stepFormPath = useStepFormPath();
- const unit = watch(`${stepFormPath}.digestMetadata.timed.unit`);
+ const unit = watch(`${path}.digestMetadata.timed.unit`);
if (unit == DigestUnitEnum.MINUTES) {
- const amount = watch(`${stepFormPath}.digestMetadata.timed.minutes.amount`);
+ const amount = watch(`${path}.digestMetadata.timed.minutes.amount`);
return (
<>
@@ -77,7 +75,7 @@ export const TimedDigestWillBeSentHeader = ({ isHighlight = true }: { isHighligh
}
if (unit == DigestUnitEnum.HOURS) {
- const amount = watch(`${stepFormPath}.digestMetadata.timed.hours.amount`);
+ const amount = watch(`${path}.digestMetadata.timed.hours.amount`);
return (
<>
@@ -87,8 +85,8 @@ export const TimedDigestWillBeSentHeader = ({ isHighlight = true }: { isHighligh
}
if (unit === DigestUnitEnum.DAYS) {
- const amount = watch(`${stepFormPath}.digestMetadata.timed.days.amount`);
- const atTime = watch(`${stepFormPath}.digestMetadata.timed.days.atTime`);
+ const amount = watch(`${path}.digestMetadata.timed.days.amount`);
+ const atTime = watch(`${path}.digestMetadata.timed.days.atTime`);
if (amount !== '' && amount !== '1') {
return (
@@ -118,9 +116,9 @@ export const TimedDigestWillBeSentHeader = ({ isHighlight = true }: { isHighligh
}
if (unit === DigestUnitEnum.WEEKS) {
- const amount = watch(`${stepFormPath}.digestMetadata.timed.weeks.amount`);
- const atTime = watch(`${stepFormPath}.digestMetadata.timed.weeks.atTime`);
- const weekDays = watch(`${stepFormPath}.digestMetadata.timed.weeks.weekDays`) || [];
+ const amount = watch(`${path}.digestMetadata.timed.weeks.amount`);
+ const atTime = watch(`${path}.digestMetadata.timed.weeks.atTime`);
+ const weekDays = watch(`${path}.digestMetadata.timed.weeks.weekDays`) || [];
const weekDaysString =
weekDays?.length > 2
@@ -162,14 +160,14 @@ export const TimedDigestWillBeSentHeader = ({ isHighlight = true }: { isHighligh
);
}
- const amount = watch(`${stepFormPath}.digestMetadata.timed.months.amount`);
- const monthlyType = watch(`${stepFormPath}.digestMetadata.timed.months.monthlyType`);
- const atTime = watch(`${stepFormPath}.digestMetadata.timed.months.atTime`);
- const monthDays = watch(`${stepFormPath}.digestMetadata.timed.months.monthDays`) || [];
+ const amount = watch(`${path}.digestMetadata.timed.months.amount`);
+ const monthlyType = watch(`${path}.digestMetadata.timed.months.monthlyType`);
+ const atTime = watch(`${path}.digestMetadata.timed.months.atTime`);
+ const monthDays = watch(`${path}.digestMetadata.timed.months.monthDays`) || [];
if (monthlyType === MonthlyTypeEnum.ON) {
- const ordinal = watch(`${stepFormPath}.digestMetadata.timed.months.ordinal`);
- const ordinalValue = watch(`${stepFormPath}.digestMetadata.timed.months.ordinalValue`);
+ const ordinal = watch(`${path}.digestMetadata.timed.months.ordinal`);
+ const ordinalValue = watch(`${path}.digestMetadata.timed.months.ordinalValue`);
if (!ordinal || !ordinalValue) {
return null;
diff --git a/apps/web/src/pages/templates/workflow/digest/WillBeSentHeader.tsx b/apps/web/src/pages/templates/workflow/digest/WillBeSentHeader.tsx
index 78cc99cc17c..984c4a730a7 100644
--- a/apps/web/src/pages/templates/workflow/digest/WillBeSentHeader.tsx
+++ b/apps/web/src/pages/templates/workflow/digest/WillBeSentHeader.tsx
@@ -37,7 +37,7 @@ export const WillBeSentHeader = ({ path, isHighlight = true }: { path: string; i
const type = watch(`${path}.digestMetadata.type`);
if (type === DigestTypeEnum.TIMED) {
- return ;
+ return ;
}
const unit = watch(`${path}.digestMetadata.regular.unit`);
diff --git a/apps/web/src/utils/errors.ts b/apps/web/src/utils/errors.ts
new file mode 100644
index 00000000000..214017bcded
--- /dev/null
+++ b/apps/web/src/utils/errors.ts
@@ -0,0 +1,9 @@
+import type { IResponseError } from '@novu/shared';
+
+export function parseServerErrorMessage(error: IResponseError | null): String {
+ if (!error) {
+ return '';
+ }
+
+ return Array.isArray(error?.message) ? error?.message[0] : error?.message;
+}
diff --git a/apps/web/src/utils/utils.ts b/apps/web/src/utils/utils.ts
index 7416e14e6b5..66f66c7433d 100644
--- a/apps/web/src/utils/utils.ts
+++ b/apps/web/src/utils/utils.ts
@@ -18,3 +18,11 @@ export function formatNumber(num: number, digits: number) {
return item ? (num / item.value).toFixed(digits).replace(rx, '$1') + item.symbol : '0';
}
+
+export function parsePayload(payload: string) {
+ try {
+ return JSON.parse(payload);
+ } catch (e) {
+ return {};
+ }
+}
diff --git a/apps/web/tests/activity-graph.spec.ts b/apps/web/tests/activity-graph.spec.ts
new file mode 100644
index 00000000000..f8b784ce627
--- /dev/null
+++ b/apps/web/tests/activity-graph.spec.ts
@@ -0,0 +1,25 @@
+import { test, expect } from '@playwright/test';
+
+import { getByTestId, initializeSession } from './utils.ts/browser';
+import { createNotifications } from './utils.ts/plugins';
+
+let session;
+
+test.beforeEach(async ({ context }) => {
+ session = await initializeSession(context);
+ await createNotifications({
+ identifier: session.templates[0].triggers[0].identifier,
+ token: session.token,
+ count: 25,
+ organizationId: session.organization._id,
+ environmentId: session.environment._id,
+ });
+});
+
+test('should be able to add a new channel', async ({ page }) => {
+ await page.goto('/activities');
+ await expect(page).toHaveURL(/\/activities/);
+
+ const addChannelButton = getByTestId(page, 'activity-stats-weekly-sent');
+ await expect(addChannelButton).toContainText('25');
+});
diff --git a/apps/web/tests/digest-playground.spec.ts b/apps/web/tests/digest-playground.spec.ts
new file mode 100644
index 00000000000..3dce3206873
--- /dev/null
+++ b/apps/web/tests/digest-playground.spec.ts
@@ -0,0 +1,185 @@
+import { test, expect } from '@playwright/test';
+
+import { getByTestId, initializeSession } from './utils.ts/browser';
+
+let session;
+
+test.beforeEach(async ({ context }) => {
+ session = await initializeSession(context, { noTemplates: true });
+});
+
+test('should have a link to the docs', async ({ page }) => {
+ await page.goto('/get-started');
+
+ const getStartedFooterLeftSide = getByTestId(page, 'get-started-footer-left-side');
+ await getStartedFooterLeftSide.click();
+
+ const tryDigestPlaygroundBtn = getByTestId(page, 'try-digest-playground-btn');
+ await tryDigestPlaygroundBtn.click();
+
+ await expect(page).toHaveURL(/\/digest-playground/);
+ await expect(page).toHaveTitle(/Digest Workflow Playground/);
+
+ const learnMoreLink = page.locator('a[href^="https://docs.novu.co/workflows/digest"]');
+ await expect(learnMoreLink).toHaveText('Learn more in docs');
+});
+
+test('the set up digest workflow should redirect to template edit page', async ({ page }) => {
+ await page.goto('/get-started');
+
+ const getStartedFooterLeftSide = getByTestId(page, 'get-started-footer-left-side');
+ await getStartedFooterLeftSide.click();
+
+ const tryDigestPlaygroundBtn = getByTestId(page, 'try-digest-playground-btn');
+ await tryDigestPlaygroundBtn.click();
+
+ await expect(page).toHaveURL(/\/digest-playground/);
+ await expect(page).toHaveTitle(/Digest Workflow Playground/);
+
+ const setupDigestWorkflowButton = page.getByRole('button', { name: 'Set Up Digest Workflow' });
+ await setupDigestWorkflowButton.click();
+
+ await expect(page).toHaveURL(/\/workflows\/edit/);
+});
+
+test('should show the digest workflow hints', async ({ page }) => {
+ await page.goto('/get-started');
+
+ const getStartedFooterLeftSide = getByTestId(page, 'get-started-footer-left-side');
+ await getStartedFooterLeftSide.click();
+
+ // click try digest playground
+ const tryDigestPlaygroundBtn = getByTestId(page, 'try-digest-playground-btn');
+ await tryDigestPlaygroundBtn.click();
+
+ await expect(page).toHaveURL(/\/digest-playground/);
+ await expect(page).toHaveTitle(/Digest Workflow Playground/);
+
+ // click set up digest workflow
+ const setupDigestWorkflowButton = page.getByRole('button', { name: 'Set Up Digest Workflow' });
+ await setupDigestWorkflowButton.click();
+
+ // in the template workflow editor
+ await expect(page).toHaveURL(/\/workflows\/edit/);
+
+ // check the digest hint
+ let digestWorkflowTooltip = getByTestId(page, 'digest-workflow-tooltip');
+ await expect(digestWorkflowTooltip).toContainText('Set-up time interval');
+ await expect(digestWorkflowTooltip).toContainText(
+ 'Specify for how long the digest should collect events before sending a digested event to the next step step in the workflow.'
+ );
+ let primaryButton = page.getByRole('button', { name: 'Next' });
+ await expect(primaryButton).toBeVisible();
+ let skipTourButton = page.getByRole('button', { name: 'Skip tour' });
+ await expect(skipTourButton).toBeVisible();
+ let dotsNavigation = getByTestId(page, 'digest-workflow-tooltip-dots-navigation');
+ await expect(dotsNavigation).toBeVisible();
+
+ // check if has digest step
+ const digestNode = getByTestId(page, 'node-digestSelector');
+ await expect(digestNode).toBeVisible();
+ // check if digest step settings opened
+ let digestSettings = getByTestId(page, 'step-editor-sidebar');
+ await expect(digestSettings).toBeVisible();
+ await expect(digestSettings).toContainText('All events');
+
+ // click next on hint
+ await primaryButton.click();
+
+ // check the email hint
+ digestWorkflowTooltip = getByTestId(page, 'digest-workflow-tooltip');
+ await expect(digestWorkflowTooltip).toContainText('Set-up email content');
+ await expect(digestWorkflowTooltip).toContainText(
+ 'Use custom HTML or our visual editor to define how the email will look like when sent to the subscriber.'
+ );
+ primaryButton = page.getByRole('button', { name: 'Next' });
+ await expect(primaryButton).toBeVisible();
+ skipTourButton = page.getByRole('button', { name: 'Skip tour' });
+ await expect(skipTourButton).toBeVisible();
+ dotsNavigation = getByTestId(page, 'digest-workflow-tooltip-dots-navigation');
+ await expect(dotsNavigation).toBeVisible();
+
+ // check if email step settings opened
+ digestSettings = getByTestId(page, 'step-editor-sidebar');
+ await expect(digestSettings).toBeVisible();
+ await expect(digestSettings).toContainText('Email');
+
+ // click next on hint
+ await primaryButton.click();
+
+ // check the email hint
+ digestWorkflowTooltip = getByTestId(page, 'digest-workflow-tooltip');
+ await expect(digestWorkflowTooltip).toContainText('Test your workflow');
+ await expect(digestWorkflowTooltip).toContainText(
+ 'We will trigger the workflow multiple times to represent how it aggregates notifications.'
+ );
+ primaryButton = page.getByRole('button', { name: 'Got it' });
+ await expect(primaryButton).toBeVisible();
+ skipTourButton = page.getByRole('button', { name: 'Skip tour' });
+ await expect(skipTourButton).not.toBeVisible();
+ dotsNavigation = getByTestId(page, 'digest-workflow-tooltip-dots-navigation');
+ await expect(dotsNavigation).toBeVisible();
+
+ // the step settings should be hidden
+ const workflowSidebar = getByTestId(page, 'workflow-sidebar');
+ await expect(workflowSidebar).toBeVisible();
+ await expect(workflowSidebar).toContainText('Trigger');
+
+ // click got it should hide the hint
+ await primaryButton.click();
+ digestWorkflowTooltip = getByTestId(page, 'digest-workflow-tooltip');
+ await expect(digestWorkflowTooltip).not.toBeVisible();
+});
+
+test('should hide the digest workflow hints when clicking on skip tour button', async ({ page }) => {
+ await page.goto('/get-started');
+
+ const getStartedFooterLeftSide = getByTestId(page, 'get-started-footer-left-side');
+ await getStartedFooterLeftSide.click();
+
+ // click try digest playground
+ const tryDigestPlaygroundBtn = getByTestId(page, 'try-digest-playground-btn');
+ await tryDigestPlaygroundBtn.click();
+
+ await expect(page).toHaveURL(/\/digest-playground/);
+ await expect(page).toHaveTitle(/Digest Workflow Playground/);
+
+ // click set up digest workflow
+ const setupDigestWorkflowButton = page.getByRole('button', { name: 'Set Up Digest Workflow' });
+ await setupDigestWorkflowButton.click();
+
+ // in the template workflow editor
+ await expect(page).toHaveURL(/\/workflows\/edit/);
+
+ // check the digest hint
+ let digestWorkflowTooltip = getByTestId(page, 'digest-workflow-tooltip');
+ await expect(digestWorkflowTooltip).toContainText('Set-up time interval');
+ const skipTourButton = page.getByRole('button', { name: 'Skip tour' });
+ await skipTourButton.click();
+
+ digestWorkflowTooltip = getByTestId(page, 'digest-workflow-tooltip');
+ await expect(digestWorkflowTooltip).not.toBeVisible();
+});
+
+test('when clicking on the back button from the playground it should redirect to /get-started/preview', async ({
+ page,
+}) => {
+ await page.goto('/get-started');
+
+ const getStartedFooterLeftSide = getByTestId(page, 'get-started-footer-left-side');
+ await getStartedFooterLeftSide.click();
+
+ // click try digest playground
+ const tryDigestPlaygroundBtn = getByTestId(page, 'try-digest-playground-btn');
+ await tryDigestPlaygroundBtn.click();
+
+ await expect(page).toHaveURL(/\/digest-playground/);
+ await expect(page).toHaveTitle(/Digest Workflow Playground/);
+
+ // click set up digest workflow
+ const goBack = page.getByRole('button', { name: 'Go Back' });
+ await goBack.click();
+
+ // in the template workflow editor
+ await expect(page).toHaveURL(/\/get-started\/preview/);
+});
diff --git a/apps/web/tests/integrations-list-modal.spec.ts b/apps/web/tests/integrations-list-modal.spec.ts
new file mode 100644
index 00000000000..9db0e4e0d58
--- /dev/null
+++ b/apps/web/tests/integrations-list-modal.spec.ts
@@ -0,0 +1,831 @@
+import {
+ ChannelTypeEnum,
+ chatProviders,
+ EmailProviderIdEnum,
+ emailProviders,
+ InAppProviderIdEnum,
+ inAppProviders,
+ pushProviders,
+ SmsProviderIdEnum,
+ smsProviders,
+} from '@novu/shared';
+import { test, expect } from '@playwright/test';
+
+import { getByTestId, initializeSession, isDarkTheme } from './utils.ts/browser';
+import {
+ checkTableLoading,
+ checkTableRow,
+ clickOnListRow,
+ interceptIntegrationsRequest,
+ navigateToGetStarted,
+} from './utils.ts/integrations';
+import { deleteProvider } from './utils.ts/plugins';
+
+let session;
+
+test.beforeEach(async ({ context }) => {
+ session = await initializeSession(context);
+});
+
+test('should show the table loading skeleton and empty state', async ({ page }) => {
+ const integrationsPromise = interceptIntegrationsRequest({
+ page,
+ modifyBody: () => ({ data: [] }),
+ });
+
+ await navigateToGetStarted(page, 'channel-card-sms');
+
+ const providerSidebar = getByTestId(page, 'select-provider-sidebar');
+ await expect(providerSidebar).toBeVisible();
+
+ const sidebarClose = getByTestId(page, 'sidebar-close');
+ await sidebarClose.click();
+
+ await checkTableLoading(page);
+ await integrationsPromise;
+
+ const noIntegrationsPlaceholder = getByTestId(page, 'no-integrations-placeholder');
+ await expect(noIntegrationsPlaceholder).toBeVisible();
+ await expect(noIntegrationsPlaceholder).toContainText('Choose a channel you want to start sending notifications');
+
+ const inAppCard = getByTestId(page, 'integration-channel-card-in_app');
+ await expect(inAppCard).toBeEnabled();
+ await expect(inAppCard).toContainText('In-App');
+ const emailCard = getByTestId(page, 'integration-channel-card-email');
+ await expect(emailCard).toBeEnabled();
+ await expect(emailCard).toContainText('Email');
+ const chatCard = getByTestId(page, 'integration-channel-card-chat');
+ await expect(chatCard).toBeEnabled();
+ await expect(chatCard).toContainText('Chat');
+ const pushCard = getByTestId(page, 'integration-channel-card-push');
+ await expect(pushCard).toBeEnabled();
+ await expect(pushCard).toContainText('Push');
+ const smsCard = getByTestId(page, 'integration-channel-card-sms');
+ await expect(smsCard).toBeEnabled();
+ await expect(smsCard).toContainText('SMS');
+});
+
+test('should show the table loading skeleton and then table', async ({ page }) => {
+ const integrationsPromise = interceptIntegrationsRequest({
+ page,
+ });
+
+ await navigateToGetStarted(page, 'channel-card-sms');
+
+ const providerSidebar = getByTestId(page, 'select-provider-sidebar');
+ await expect(providerSidebar).toBeVisible();
+
+ const sidebarClose = getByTestId(page, 'sidebar-close');
+ await sidebarClose.click();
+
+ await checkTableLoading(page);
+ await integrationsPromise;
+
+ const addProvider = getByTestId(page, 'add-provider');
+ await expect(addProvider).toBeEnabled();
+ await expect(addProvider).toContainText('Add a provider');
+
+ await checkTableRow(page, {
+ name: 'SendGrid',
+ provider: 'SendGrid',
+ channel: 'Email',
+ environment: 'Development',
+ status: 'Active',
+ });
+
+ await checkTableRow(page, {
+ name: 'Twilio',
+ provider: 'Twilio',
+ channel: 'SMS',
+ environment: 'Development',
+ status: 'Active',
+ });
+
+ await checkTableRow(page, {
+ name: 'Slack',
+ provider: 'Slack',
+ channel: 'Chat',
+ environment: 'Development',
+ status: 'Active',
+ });
+
+ await checkTableRow(page, {
+ name: 'Discord',
+ provider: 'Discord',
+ channel: 'Chat',
+ environment: 'Development',
+ status: 'Active',
+ });
+
+ await checkTableRow(page, {
+ name: 'Firebase Cloud Messaging',
+ provider: 'Firebase Cloud Messaging',
+ channel: 'Push',
+ environment: 'Development',
+ status: 'Active',
+ });
+
+ await checkTableRow(page, {
+ name: 'Novu In-App',
+ isFree: false,
+ provider: 'Novu In-App',
+ channel: 'In-App',
+ environment: 'Development',
+ status: 'Active',
+ });
+});
+
+test('should show the select provider sidebar', async ({ page }) => {
+ await deleteProvider({
+ providerId: InAppProviderIdEnum.Novu,
+ channel: ChannelTypeEnum.IN_APP,
+ environmentId: session.environment.id,
+ organizationId: session.organization.id,
+ });
+
+ await navigateToGetStarted(page);
+
+ const addProvider = getByTestId(page, 'add-provider');
+ await expect(addProvider).toBeEnabled();
+ await addProvider.click();
+
+ const selectProviderSidebar = getByTestId(page, 'select-provider-sidebar');
+ await expect(selectProviderSidebar).toBeVisible();
+ await expect(selectProviderSidebar).toContainText('Select a provider');
+ await expect(selectProviderSidebar).toContainText('Select a provider to create instance for a channel');
+ const search = selectProviderSidebar.locator('input[type="search"]');
+ await expect(search).toHaveAttribute('placeholder', 'Search a provider...');
+ const sidebarClose = getByTestId(selectProviderSidebar, 'sidebar-close');
+ await expect(sidebarClose).toBeVisible();
+
+ const channelTabs = selectProviderSidebar.locator('[role="tablist"]');
+ const activeTab = channelTabs.locator('[data-active="true"]');
+ await expect(activeTab).toContainText('Email');
+ await expect(channelTabs).toContainText('In-App');
+ await expect(channelTabs).toContainText('Email');
+ await expect(channelTabs).toContainText('Chat');
+ await expect(channelTabs).toContainText('Push');
+ await expect(channelTabs).toContainText('SMS');
+
+ const inAppGroup = getByTestId(page, 'providers-group-in_app');
+ await expect(inAppGroup).toContainText('In-App');
+ const emailGroup = getByTestId(page, 'providers-group-email');
+ await expect(emailGroup).toContainText('Email');
+ const chatGroup = getByTestId(page, 'providers-group-chat');
+ await expect(chatGroup).toContainText('Chat');
+ const pushGroup = getByTestId(page, 'providers-group-push');
+ await expect(pushGroup).toContainText('Push');
+ const smsGroup = getByTestId(page, 'providers-group-sms');
+ await expect(smsGroup).toContainText('SMS');
+
+ const allProviders = inAppProviders.concat(emailProviders, chatProviders, pushProviders, smsProviders);
+ for (const provider of allProviders) {
+ if (provider.id === EmailProviderIdEnum.Novu || provider.id === SmsProviderIdEnum.Novu) {
+ continue;
+ }
+
+ const providerInGroup = getByTestId(selectProviderSidebar, `provider-${provider.id}`);
+ await expect(providerInGroup).toContainText(provider.displayName);
+ }
+
+ const cancel = getByTestId(selectProviderSidebar, 'select-provider-sidebar-cancel');
+ await expect(cancel).toContainText('Cancel');
+ const next = getByTestId(selectProviderSidebar, 'select-provider-sidebar-next');
+ await expect(next).toContainText('Next');
+ await expect(next).toBeDisabled();
+});
+
+test('should allow for searching', async ({ page }) => {
+ await navigateToGetStarted(page);
+
+ const selectProviderSidebar = getByTestId(page, 'select-provider-sidebar');
+ await expect(selectProviderSidebar).toBeVisible();
+
+ const search = selectProviderSidebar.locator('input[type="search"]');
+ await search.fill('Mail');
+
+ const channelTabs = selectProviderSidebar.locator('[role="tablist"]');
+ const inAppTab = channelTabs.locator('button', { hasText: 'In-App' });
+ await expect(inAppTab).toBeHidden();
+ const emailTab = channelTabs.locator('button', { hasText: 'Email' });
+ await expect(emailTab).toBeVisible();
+ const chatTab = channelTabs.locator('button', { hasText: 'Chat' });
+ await expect(chatTab).toBeHidden();
+ const pushTab = channelTabs.locator('button', { hasText: 'Push' });
+ await expect(pushTab).toBeHidden();
+ const smsTab = channelTabs.locator('button', { hasText: 'SMS' });
+ await expect(smsTab).toBeHidden();
+
+ const emailGroup = getByTestId(page, 'providers-group-email');
+ await expect(emailGroup).toContainText('Email');
+ const mailjet = getByTestId(selectProviderSidebar, `provider-${EmailProviderIdEnum.Mailjet}`);
+ await expect(mailjet).toContainText('Mailjet');
+ const mailgun = getByTestId(selectProviderSidebar, `provider-${EmailProviderIdEnum.Mailgun}`);
+ await expect(mailgun).toContainText('Mailgun');
+ const mailerSend = getByTestId(selectProviderSidebar, `provider-${EmailProviderIdEnum.MailerSend}`);
+ await expect(mailerSend).toContainText('MailerSend');
+ const emailWebhook = getByTestId(selectProviderSidebar, `provider-${EmailProviderIdEnum.EmailWebhook}`);
+ await expect(emailWebhook).toContainText('Email Webhook');
+
+ const next = getByTestId(selectProviderSidebar, 'select-provider-sidebar-next');
+ await expect(next).toContainText('Next');
+ await expect(next).toBeDisabled();
+});
+
+test('should show empty search results', async ({ page }) => {
+ await navigateToGetStarted(page);
+
+ const selectProviderSidebar = getByTestId(page, 'select-provider-sidebar');
+ await expect(selectProviderSidebar).toBeVisible();
+
+ const search = selectProviderSidebar.locator('input[type="search"]');
+ await search.fill('safasdfasdfasdfasdfas');
+
+ const channelTabs = selectProviderSidebar.locator('[role="tablist"]');
+ const inAppTab = channelTabs.locator('button', { hasText: 'In-App' });
+ await expect(inAppTab).toBeHidden();
+ const emailTab = channelTabs.locator('button', { hasText: 'Email' });
+ await expect(emailTab).toBeHidden();
+ const chatTab = channelTabs.locator('button', { hasText: 'Chat' });
+ await expect(chatTab).toBeHidden();
+ const pushTab = channelTabs.locator('button', { hasText: 'Push' });
+ await expect(pushTab).toBeHidden();
+ const smsTab = channelTabs.locator('button', { hasText: 'SMS' });
+ await expect(smsTab).toBeHidden();
+
+ const noSearchResults = getByTestId(page, 'select-provider-no-search-results-img');
+ await expect(noSearchResults).toBeVisible();
+
+ const next = getByTestId(selectProviderSidebar, 'select-provider-sidebar-next');
+ await expect(next).toContainText('Next');
+ await expect(next).toBeDisabled();
+});
+
+test('should allow selecting a provider', async ({ page }) => {
+ await navigateToGetStarted(page);
+
+ const selectProviderSidebar = getByTestId(page, 'select-provider-sidebar');
+ await expect(selectProviderSidebar).toBeVisible();
+
+ const mailjet = getByTestId(selectProviderSidebar, `provider-${EmailProviderIdEnum.Mailjet}`);
+ await expect(mailjet).toContainText('Mailjet');
+ await mailjet.click();
+
+ const selectedProviderImage = getByTestId(
+ selectProviderSidebar,
+ `selected-provider-image-${EmailProviderIdEnum.Mailjet}`
+ ).first();
+ const isDarkThemeEnabled = await isDarkTheme(page);
+ await expect(selectedProviderImage).toHaveAttribute(
+ 'src',
+ `/static/images/providers/${isDarkThemeEnabled ? 'dark' : 'light'}/square/${EmailProviderIdEnum.Mailjet}.svg`
+ );
+
+ const selectedProviderName = getByTestId(selectProviderSidebar, 'selected-provider-name');
+ await expect(selectedProviderName).toContainText('Mailjet');
+
+ const next = getByTestId(selectProviderSidebar, 'select-provider-sidebar-next');
+ await expect(next).toContainText('Next');
+ await expect(next).toBeEnabled();
+});
+
+test('should allow moving to create sidebar', async ({ page }) => {
+ await navigateToGetStarted(page);
+
+ const selectProviderSidebar = getByTestId(page, 'select-provider-sidebar');
+ await expect(selectProviderSidebar).toBeVisible();
+
+ const mailjet = getByTestId(selectProviderSidebar, `provider-${EmailProviderIdEnum.Mailjet}`);
+ await expect(mailjet).toContainText('Mailjet');
+ await mailjet.click();
+
+ const next = getByTestId(selectProviderSidebar, 'select-provider-sidebar-next');
+ await expect(next).toContainText('Next');
+ await next.click();
+
+ const createProviderInstanceSidebar = getByTestId(page, 'create-provider-instance-sidebar');
+ await expect(createProviderInstanceSidebar).toBeVisible();
+ await expect(createProviderInstanceSidebar).toContainText(
+ 'Specify assignment preferences to automatically allocate the provider instance to the Email channel.'
+ );
+ await expect(createProviderInstanceSidebar).toContainText('Environment');
+ await expect(createProviderInstanceSidebar).toContainText('Provider instance executes only for');
+
+ const sidebarClose = getByTestId(createProviderInstanceSidebar, 'sidebar-close');
+ await expect(sidebarClose).toBeVisible();
+
+ const selectedProviderImage = getByTestId(
+ createProviderInstanceSidebar,
+ `selected-provider-image-${EmailProviderIdEnum.Mailjet}`
+ ).first();
+ const isDarkThemeEnabled = await isDarkTheme(page);
+ await expect(selectedProviderImage).toHaveAttribute(
+ 'src',
+ `/static/images/providers/${isDarkThemeEnabled ? 'dark' : 'light'}/square/${EmailProviderIdEnum.Mailjet}.svg`
+ );
+
+ const selectedProviderName = getByTestId(createProviderInstanceSidebar, 'provider-instance-name');
+ await expect(selectedProviderName).toBeVisible();
+ await expect(selectedProviderName).toHaveValue('Mailjet');
+
+ const environmentRadios = createProviderInstanceSidebar.locator('[role="radiogroup"]');
+ const selectedEnv = environmentRadios.locator('[data-checked="true"]');
+ await expect(selectedEnv).toContainText('Development');
+ await expect(environmentRadios).toContainText('Production');
+
+ const cancel = getByTestId(createProviderInstanceSidebar, 'create-provider-instance-sidebar-cancel');
+ await expect(cancel).toContainText('Cancel');
+ await expect(cancel).toBeEnabled();
+
+ const create = getByTestId(createProviderInstanceSidebar, 'create-provider-instance-sidebar-create');
+ await expect(create).toContainText('Create');
+ await expect(create).toBeEnabled();
+});
+
+test('should allow moving back from create provider sidebar to select provider sidebar', async ({ page }) => {
+ await navigateToGetStarted(page);
+
+ let selectProviderSidebar = getByTestId(page, 'select-provider-sidebar');
+ await expect(selectProviderSidebar).toBeVisible();
+
+ const mailjet = getByTestId(selectProviderSidebar, `provider-${EmailProviderIdEnum.Mailjet}`);
+ await expect(mailjet).toContainText('Mailjet');
+ await mailjet.click();
+
+ const next = getByTestId(selectProviderSidebar, 'select-provider-sidebar-next');
+ await expect(next).toContainText('Next');
+ await next.click();
+
+ const back = getByTestId(page, 'create-provider-instance-sidebar-back');
+ await expect(back).toBeVisible();
+ await back.click();
+
+ selectProviderSidebar = getByTestId(page, 'select-provider-sidebar');
+ await expect(selectProviderSidebar).toBeVisible();
+});
+
+test('should create a new mailjet integration', async ({ page }) => {
+ await navigateToGetStarted(page);
+
+ let selectProviderSidebar = getByTestId(page, 'select-provider-sidebar');
+ await expect(selectProviderSidebar).toBeVisible();
+
+ const mailjet = getByTestId(selectProviderSidebar, `provider-${EmailProviderIdEnum.Mailjet}`);
+ await expect(mailjet).toContainText('Mailjet');
+ await mailjet.click();
+
+ const next = getByTestId(selectProviderSidebar, 'select-provider-sidebar-next');
+ await expect(next).toContainText('Next');
+ await next.click();
+
+ const providerName = getByTestId(page, 'provider-instance-name');
+ await providerName.clear();
+ await providerName.fill('Mailjet Integration');
+
+ const create = getByTestId(page, 'create-provider-instance-sidebar-create');
+ await expect(create).toContainText('Create');
+ await expect(create).toBeEnabled();
+ await create.click();
+
+ const updateProviderSidebar = getByTestId(page, 'update-provider-sidebar');
+ await expect(updateProviderSidebar).toBeVisible();
+
+ const close = getByTestId(updateProviderSidebar, 'sidebar-close');
+ await expect(close).toBeVisible();
+ await close.click();
+
+ await checkTableRow(page, {
+ name: 'Mailjet Integration',
+ provider: 'Mailjet',
+ channel: 'Email',
+ environment: 'Development',
+ status: 'Disabled',
+ });
+});
+
+test('should update the mailjet integration', async ({ page }) => {
+ await navigateToGetStarted(page);
+
+ let selectProviderSidebar = getByTestId(page, 'select-provider-sidebar');
+ await expect(selectProviderSidebar).toBeVisible();
+
+ const mailjet = getByTestId(selectProviderSidebar, `provider-${EmailProviderIdEnum.Mailjet}`);
+ await expect(mailjet).toContainText('Mailjet');
+ await mailjet.click();
+
+ const next = getByTestId(selectProviderSidebar, 'select-provider-sidebar-next');
+ await expect(next).toContainText('Next');
+ await next.click();
+
+ let providerName = getByTestId(page, 'provider-instance-name');
+ await providerName.clear();
+ await providerName.fill('Mailjet Integration');
+
+ const create = getByTestId(page, 'create-provider-instance-sidebar-create');
+ await expect(create).toContainText('Create');
+ await expect(create).toBeEnabled();
+ await create.click();
+
+ const updateProviderSidebar = getByTestId(page, 'update-provider-sidebar');
+ await expect(updateProviderSidebar).toBeVisible();
+ await expect(updateProviderSidebar).toContainText('Set up credentials to start sending notifications.');
+
+ const integrationChannel = getByTestId(updateProviderSidebar, 'provider-instance-channel');
+ await expect(integrationChannel).toContainText('Email');
+
+ const integrationEnvironment = getByTestId(updateProviderSidebar, 'provider-instance-environment');
+ await expect(integrationEnvironment).toContainText('Development');
+
+ const isActive = getByTestId(updateProviderSidebar, 'is_active_id');
+ await expect(isActive).toHaveValue('false');
+
+ providerName = updateProviderSidebar.getByPlaceholder('Enter instance name');
+ await expect(providerName).toHaveValue('Mailjet Integration');
+
+ const identifier = getByTestId(updateProviderSidebar, 'provider-instance-identifier');
+ await expect(identifier).toHaveValue(/mailjet/);
+
+ const updateButton = getByTestId(updateProviderSidebar, 'update-provider-sidebar-update');
+ await expect(updateButton).toBeDisabled();
+
+ await providerName.clear();
+ await providerName.fill('Mailjet Integration Updated');
+
+ await isActive.locator('~ label').click();
+
+ const apiKey = getByTestId(updateProviderSidebar, 'apiKey');
+ await apiKey.fill('fake-api-key');
+
+ const secretKey = getByTestId(updateProviderSidebar, 'secretKey');
+ await secretKey.fill('fake-secret-key');
+
+ const fromField = getByTestId(updateProviderSidebar, 'from');
+ await fromField.fill('info@novu.co');
+
+ const senderName = getByTestId(updateProviderSidebar, 'senderName');
+ await senderName.fill('Novu');
+
+ await expect(updateButton).toBeEnabled();
+ await updateButton.click();
+
+ const modalClose = page.locator('.mantine-Modal-close');
+ await modalClose.click();
+ const sidebarClose = getByTestId(page, 'sidebar-close');
+ await sidebarClose.click();
+
+ await checkTableRow(page, {
+ name: 'Mailjet Integration Updated',
+ provider: 'Mailjet',
+ channel: 'Email',
+ environment: 'Development',
+ status: 'Active',
+ });
+});
+
+test('should update the mailjet integration from the list', async ({ page }) => {
+ await navigateToGetStarted(page);
+
+ let selectProviderSidebar = getByTestId(page, 'select-provider-sidebar');
+ await expect(selectProviderSidebar).toBeVisible();
+
+ const mailjet = getByTestId(selectProviderSidebar, `provider-${EmailProviderIdEnum.Mailjet}`);
+ await expect(mailjet).toContainText('Mailjet');
+ await mailjet.click();
+
+ const next = getByTestId(selectProviderSidebar, 'select-provider-sidebar-next');
+ await expect(next).toContainText('Next');
+ await next.click();
+
+ let providerName = getByTestId(page, 'provider-instance-name');
+ await providerName.clear();
+ await providerName.fill('Mailjet Integration');
+
+ const create = getByTestId(page, 'create-provider-instance-sidebar-create');
+ await expect(create).toContainText('Create');
+ await expect(create).toBeEnabled();
+ await create.click();
+
+ let updateProviderSidebar = getByTestId(page, 'update-provider-sidebar');
+ await expect(updateProviderSidebar).toBeVisible();
+
+ let sidebarClose = getByTestId(page, 'sidebar-close');
+ await sidebarClose.click();
+
+ await clickOnListRow(page, 'Mailjet Integration');
+
+ updateProviderSidebar = getByTestId(page, 'update-provider-sidebar');
+ await expect(updateProviderSidebar).toBeVisible();
+
+ const isActive = getByTestId(updateProviderSidebar, 'is_active_id');
+ await expect(isActive).toHaveValue('false');
+
+ providerName = updateProviderSidebar.getByPlaceholder('Enter instance name');
+ await expect(providerName).toHaveValue('Mailjet Integration');
+
+ const identifier = getByTestId(updateProviderSidebar, 'provider-instance-identifier');
+ await expect(identifier).toHaveValue(/mailjet/);
+
+ const updateButton = getByTestId(updateProviderSidebar, 'update-provider-sidebar-update');
+ await expect(updateButton).toBeDisabled();
+
+ providerName = updateProviderSidebar.getByPlaceholder('Enter instance name');
+ await providerName.clear();
+ await providerName.fill('Mailjet Integration Updated');
+
+ await isActive.locator('~ label').click();
+
+ const apiKey = getByTestId(updateProviderSidebar, 'apiKey');
+ await apiKey.fill('fake-api-key');
+
+ const secretKey = getByTestId(updateProviderSidebar, 'secretKey');
+ await secretKey.fill('fake-secret-key');
+
+ const fromField = getByTestId(updateProviderSidebar, 'from');
+ await fromField.fill('info@novu.co');
+
+ const senderName = getByTestId(updateProviderSidebar, 'senderName');
+ await senderName.fill('Novu');
+
+ await expect(updateButton).toBeEnabled();
+ await updateButton.click();
+
+ const modalClose = page.locator('.mantine-Modal-close');
+ await modalClose.click();
+ sidebarClose = getByTestId(page, 'sidebar-close');
+ await sidebarClose.click();
+
+ await checkTableRow(page, {
+ name: 'Mailjet Integration Updated',
+ provider: 'Mailjet',
+ channel: 'Email',
+ environment: 'Development',
+ status: 'Active',
+ });
+});
+
+test('should allow to delete the mailjet integration', async ({ page }) => {
+ await navigateToGetStarted(page);
+
+ let selectProviderSidebar = getByTestId(page, 'select-provider-sidebar');
+ await expect(selectProviderSidebar).toBeVisible();
+
+ const mailjet = getByTestId(selectProviderSidebar, `provider-${EmailProviderIdEnum.Mailjet}`);
+ await expect(mailjet).toContainText('Mailjet');
+ await mailjet.click();
+
+ const next = getByTestId(selectProviderSidebar, 'select-provider-sidebar-next');
+ await expect(next).toContainText('Next');
+ await next.click();
+
+ let providerName = getByTestId(page, 'provider-instance-name');
+ await providerName.clear();
+ await providerName.fill('Mailjet Integration');
+
+ const create = getByTestId(page, 'create-provider-instance-sidebar-create');
+ await expect(create).toContainText('Create');
+ await expect(create).toBeEnabled();
+ await create.click();
+
+ let updateProviderSidebar = getByTestId(page, 'update-provider-sidebar');
+ await expect(updateProviderSidebar).toBeVisible();
+
+ let sidebarClose = getByTestId(page, 'sidebar-close');
+ await sidebarClose.click();
+
+ await clickOnListRow(page, 'Mailjet Integration');
+
+ updateProviderSidebar = getByTestId(page, 'update-provider-sidebar');
+ await expect(updateProviderSidebar).toBeVisible();
+
+ const menu = updateProviderSidebar.locator('[aria-haspopup="menu"]');
+ await menu.click();
+ const deleteButton = updateProviderSidebar.locator('button[data-menu-item="true"]', { hasText: 'Delete' });
+ await deleteButton.click();
+
+ const deleteModal = getByTestId(page, 'delete-provider-instance-modal');
+ await expect(deleteModal).toBeVisible();
+ await expect(deleteModal).toContainText('Delete Mailjet Integration instance?');
+ await expect(deleteModal).toContainText(
+ 'Deleting a provider instance will fail workflows relying on its configuration, leading to undelivered notifications.'
+ );
+
+ const cancel = deleteModal.getByRole('button', { name: 'Cancel' });
+ await expect(cancel).toBeEnabled();
+ const deleteInstanceButton = deleteModal.getByRole('button', { name: 'Delete instance' });
+ await expect(deleteInstanceButton).toBeEnabled();
+ await deleteInstanceButton.click();
+
+ const integrationsTable = getByTestId(page, 'integration-name-cell', { hasText: 'Mailjet Integration' });
+ await expect(integrationsTable).toBeHidden();
+});
+
+test('should show the Novu in-app integration', async ({ page }) => {
+ await navigateToGetStarted(page);
+
+ await clickOnListRow(page, new RegExp(`Novu In-App.*Development`));
+
+ const updateProviderSidebar = getByTestId(page, 'update-provider-sidebar');
+ await expect(updateProviderSidebar).toBeVisible();
+ await expect(updateProviderSidebar).toContainText(
+ 'Select a framework to set up credentials to start sending notifications.'
+ );
+
+ const sidebarClose = getByTestId(updateProviderSidebar, 'sidebar-close');
+ await expect(sidebarClose).toBeVisible();
+
+ const integrationChannel = getByTestId(updateProviderSidebar, 'provider-instance-channel');
+ await expect(integrationChannel).toContainText('In-App');
+
+ const integrationEnvironment = getByTestId(updateProviderSidebar, 'provider-instance-environment');
+ await expect(integrationEnvironment).toContainText('Development');
+
+ const linkToDocs = updateProviderSidebar.getByRole('link', { name: 'Explore set-up guide' });
+ await expect(linkToDocs).toBeVisible();
+
+ const isActive = getByTestId(updateProviderSidebar, 'is_active_id');
+ await expect(isActive).toHaveValue('true');
+
+ const isDarkThemeEnabled = await isDarkTheme(page);
+ const selectedProviderImage = getByTestId(
+ updateProviderSidebar,
+ `selected-provider-image-${InAppProviderIdEnum.Novu}`
+ );
+ await expect(selectedProviderImage).toHaveAttribute(
+ 'src',
+ `/static/images/providers/${isDarkThemeEnabled ? 'dark' : 'light'}/square/${InAppProviderIdEnum.Novu}.svg`
+ );
+
+ const selectedProviderName = getByTestId(updateProviderSidebar, 'provider-instance-name').first();
+ await expect(selectedProviderName).toBeVisible();
+ await expect(selectedProviderName).toHaveValue('Novu In-App');
+
+ const identifier = getByTestId(updateProviderSidebar, 'provider-instance-identifier');
+ await expect(identifier).toHaveValue(/novu-in-app/);
+
+ const hmacCheckbox = getByTestId(updateProviderSidebar, 'hmac');
+ await expect(hmacCheckbox).not.toBeChecked();
+
+ const novuInAppFrameworks = getByTestId(updateProviderSidebar, 'novu-in-app-frameworks');
+ await expect(novuInAppFrameworks).toContainText('Integrate In-App using a framework below');
+ await expect(novuInAppFrameworks).toContainText('React');
+ await expect(novuInAppFrameworks).toContainText('Angular');
+ await expect(novuInAppFrameworks).toContainText('Web Component');
+ await expect(novuInAppFrameworks).toContainText('Headless');
+ await expect(novuInAppFrameworks).toContainText('Vue');
+ await expect(novuInAppFrameworks).toContainText('iFrame');
+
+ const updateButton = getByTestId(updateProviderSidebar, 'update-provider-sidebar-update');
+ await expect(updateButton).toContainText('Update');
+ await expect(updateButton).toBeDisabled();
+});
+
+test('should show the Novu in-app integration - React guide', async ({ page }) => {
+ await navigateToGetStarted(page);
+
+ await clickOnListRow(page, new RegExp(`Novu In-App.*Development`));
+
+ let updateProviderSidebar = getByTestId(page, 'update-provider-sidebar');
+ await expect(updateProviderSidebar).toBeVisible();
+
+ const novuInAppFrameworks = getByTestId(updateProviderSidebar, 'novu-in-app-frameworks');
+ await expect(novuInAppFrameworks).toContainText('React');
+
+ const reactGuide = novuInAppFrameworks.locator('div').filter({ hasText: 'React' }).nth(1);
+ await reactGuide.click();
+
+ updateProviderSidebar = getByTestId(page, 'update-provider-sidebar');
+ await expect(updateProviderSidebar).toContainText('React integration guide');
+
+ const sidebarBack = getByTestId(updateProviderSidebar, 'sidebar-back');
+ await expect(sidebarBack).toBeVisible();
+ const setupTimeline = getByTestId(updateProviderSidebar, 'setup-timeline');
+ await expect(setupTimeline).toBeVisible();
+
+ const updateButton = getByTestId(updateProviderSidebar, 'update-provider-sidebar-update');
+ await expect(updateButton).toContainText('Update');
+ await expect(updateButton).toBeDisabled();
+});
+
+test('should show the Novu Email integration sidebar', async ({ page }) => {
+ const integrationsPromise = interceptIntegrationsRequest({
+ page,
+ modifyBody: (body) => {
+ const [firstIntegration] = body.data;
+ body.data = [
+ {
+ _id: EmailProviderIdEnum.Novu,
+ _environmentId: firstIntegration._environmentId,
+ providerId: EmailProviderIdEnum.Novu,
+ active: true,
+ channel: ChannelTypeEnum.EMAIL,
+ name: 'Novu Email',
+ identifier: EmailProviderIdEnum.Novu,
+ },
+ ...body.data,
+ ];
+
+ return body;
+ },
+ });
+
+ await navigateToGetStarted(page);
+ await integrationsPromise;
+
+ const sidebarClose = getByTestId(page, 'sidebar-close');
+ await sidebarClose.click();
+
+ await clickOnListRow(page, new RegExp(`Novu Email.*Development`));
+
+ let updateProviderSidebar = getByTestId(page, 'update-provider-sidebar-novu');
+ await expect(updateProviderSidebar).toContainText('Test Provider');
+ await expect(updateProviderSidebar).toBeVisible();
+
+ const isDarkThemeEnabled = await isDarkTheme(page);
+ const novuEmailLogo = updateProviderSidebar.locator(
+ `img[src="/static/images/providers/${isDarkThemeEnabled ? 'dark' : 'light'}/square/${
+ EmailProviderIdEnum.Novu
+ }.svg"]`
+ );
+ await expect(novuEmailLogo).toBeVisible();
+
+ const integrationChannel = getByTestId(updateProviderSidebar, 'provider-instance-channel');
+ await expect(integrationChannel).toContainText('Email');
+
+ const integrationEnvironment = getByTestId(updateProviderSidebar, 'provider-instance-environment');
+ await expect(integrationEnvironment).toContainText('Development');
+
+ const selectedProviderName = getByTestId(updateProviderSidebar, 'provider-instance-name').first();
+ await expect(selectedProviderName).toBeVisible();
+ await expect(selectedProviderName).toHaveValue('Novu Email');
+
+ const providerLimits = getByTestId(updateProviderSidebar, 'novu-provider-limits');
+ const providerLimitsText = await providerLimits.innerText();
+ await expect(providerLimitsText).toEqual(
+ 'Novu provider allows sending max 300 emails per month,\nto send more messages, configure a different provider'
+ );
+
+ const limitbarLimit = getByTestId(updateProviderSidebar, 'limitbar-limit');
+ const limitbarText = await limitbarLimit.innerText();
+ await expect(limitbarText).toEqual('300 emails per month');
+});
+
+test('should show the Novu SMS integration sidebar', async ({ page }) => {
+ const integrationsPromise = interceptIntegrationsRequest({
+ page,
+ modifyBody: (body) => {
+ const [firstIntegration] = body.data;
+ body.data = [
+ {
+ _id: SmsProviderIdEnum.Novu,
+ _environmentId: firstIntegration._environmentId,
+ providerId: SmsProviderIdEnum.Novu,
+ active: true,
+ channel: ChannelTypeEnum.SMS,
+ name: 'Novu SMS',
+ identifier: SmsProviderIdEnum.Novu,
+ },
+ ...body.data,
+ ];
+
+ return body;
+ },
+ });
+
+ await navigateToGetStarted(page);
+ await integrationsPromise;
+
+ const sidebarClose = getByTestId(page, 'sidebar-close');
+ await sidebarClose.click();
+
+ await clickOnListRow(page, new RegExp(`Novu SMS.*Development`));
+
+ let updateProviderSidebar = getByTestId(page, 'update-provider-sidebar-novu');
+ await expect(updateProviderSidebar).toContainText('Test Provider');
+ await expect(updateProviderSidebar).toBeVisible();
+
+ const isDarkThemeEnabled = await isDarkTheme(page);
+ const novuEmailLogo = updateProviderSidebar.locator(
+ `img[src="/static/images/providers/${isDarkThemeEnabled ? 'dark' : 'light'}/square/${SmsProviderIdEnum.Novu}.svg"]`
+ );
+ await expect(novuEmailLogo).toBeVisible();
+
+ const integrationChannel = getByTestId(updateProviderSidebar, 'provider-instance-channel');
+ await expect(integrationChannel).toContainText('SMS');
+
+ const integrationEnvironment = getByTestId(updateProviderSidebar, 'provider-instance-environment');
+ await expect(integrationEnvironment).toContainText('Development');
+
+ const selectedProviderName = getByTestId(updateProviderSidebar, 'provider-instance-name').first();
+ await expect(selectedProviderName).toBeVisible();
+ await expect(selectedProviderName).toHaveValue('Novu SMS');
+
+ const providerLimits = getByTestId(updateProviderSidebar, 'novu-provider-limits');
+ const providerLimitsText = await providerLimits.innerText();
+ await expect(providerLimitsText).toEqual(
+ 'Novu provider allows sending max 20 messages per month,\nto send more messages, configure a different provider'
+ );
+
+ const limitbarLimit = getByTestId(updateProviderSidebar, 'limitbar-limit');
+ const limitbarText = await limitbarLimit.innerText();
+ await expect(limitbarText).toEqual('20 messages per month');
+});
diff --git a/apps/web/tests/integrations-list-page.spec.ts b/apps/web/tests/integrations-list-page.spec.ts
new file mode 100644
index 00000000000..88c1056c81f
--- /dev/null
+++ b/apps/web/tests/integrations-list-page.spec.ts
@@ -0,0 +1,1105 @@
+import {
+ ChannelTypeEnum,
+ chatProviders,
+ EmailProviderIdEnum,
+ emailProviders,
+ InAppProviderIdEnum,
+ inAppProviders,
+ pushProviders,
+ SmsProviderIdEnum,
+ smsProviders,
+} from '@novu/shared';
+import { test, expect } from '@playwright/test';
+
+import { getByTestId, initializeSession, isDarkTheme } from './utils.ts/browser';
+import {
+ checkTableLoading,
+ checkTableRow,
+ clickOnListRow,
+ interceptIntegrationsRequest,
+} from './utils.ts/integrations';
+import { deleteProvider } from './utils.ts/plugins';
+
+let session;
+
+test.beforeEach(async ({ context }) => {
+ session = await initializeSession(context);
+});
+
+test('should show the table loading skeleton and empty state', async ({ page }) => {
+ const integrationsPromise = interceptIntegrationsRequest({
+ page,
+ modifyBody: () => ({ data: [] }),
+ });
+
+ await page.goto('/integrations');
+ await expect(page).toHaveURL(/\/integrations/);
+
+ await checkTableLoading(page);
+ await integrationsPromise;
+
+ const noIntegrationsPlaceholder = getByTestId(page, 'no-integrations-placeholder');
+ await expect(noIntegrationsPlaceholder).toBeVisible();
+ await expect(noIntegrationsPlaceholder).toContainText('Choose a channel you want to start sending notifications');
+
+ const inAppCard = getByTestId(page, 'integration-channel-card-in_app');
+ await expect(inAppCard).toBeEnabled();
+ await expect(inAppCard).toContainText('In-App');
+ const emailCard = getByTestId(page, 'integration-channel-card-email');
+ await expect(emailCard).toBeEnabled();
+ await expect(emailCard).toContainText('Email');
+ const chatCard = getByTestId(page, 'integration-channel-card-chat');
+ await expect(chatCard).toBeEnabled();
+ await expect(chatCard).toContainText('Chat');
+ const pushCard = getByTestId(page, 'integration-channel-card-push');
+ await expect(pushCard).toBeEnabled();
+ await expect(pushCard).toContainText('Push');
+ const smsCard = getByTestId(page, 'integration-channel-card-sms');
+ await expect(smsCard).toBeEnabled();
+ await expect(smsCard).toContainText('SMS');
+});
+
+test('should show the table loading skeleton and then table', async ({ page }) => {
+ const integrationsPromise = interceptIntegrationsRequest({
+ page,
+ });
+
+ await page.goto('/integrations');
+ await expect(page).toHaveURL(/\/integrations/);
+
+ await checkTableLoading(page);
+ await integrationsPromise;
+
+ const addProvider = getByTestId(page, 'add-provider');
+ await expect(addProvider).toBeEnabled();
+ await expect(addProvider).toContainText('Add a provider');
+
+ await checkTableRow(page, {
+ name: 'SendGrid',
+ provider: 'SendGrid',
+ channel: 'Email',
+ environment: 'Development',
+ status: 'Active',
+ });
+
+ await checkTableRow(page, {
+ name: 'Twilio',
+ provider: 'Twilio',
+ channel: 'SMS',
+ environment: 'Development',
+ status: 'Active',
+ });
+
+ await checkTableRow(page, {
+ name: 'Slack',
+ provider: 'Slack',
+ channel: 'Chat',
+ environment: 'Development',
+ status: 'Active',
+ });
+
+ await checkTableRow(page, {
+ name: 'Discord',
+ provider: 'Discord',
+ channel: 'Chat',
+ environment: 'Development',
+ status: 'Active',
+ });
+
+ await checkTableRow(page, {
+ name: 'Firebase Cloud Messaging',
+ provider: 'Firebase Cloud Messaging',
+ channel: 'Push',
+ environment: 'Development',
+ status: 'Active',
+ });
+
+ await checkTableRow(page, {
+ name: 'Novu In-App',
+ isFree: false,
+ provider: 'Novu In-App',
+ channel: 'In-App',
+ environment: 'Development',
+ status: 'Active',
+ });
+});
+
+test('should show the select provider sidebar', async ({ page }) => {
+ await deleteProvider({
+ providerId: InAppProviderIdEnum.Novu,
+ channel: ChannelTypeEnum.IN_APP,
+ environmentId: session.environment.id,
+ organizationId: session.organization.id,
+ });
+
+ await page.goto('/integrations');
+ await expect(page).toHaveURL(/\/integrations/);
+
+ const addProvider = getByTestId(page, 'add-provider');
+ await expect(addProvider).toBeEnabled();
+ await addProvider.click();
+
+ const selectProviderSidebar = getByTestId(page, 'select-provider-sidebar');
+ await expect(selectProviderSidebar).toBeVisible();
+ await expect(selectProviderSidebar).toContainText('Select a provider');
+ await expect(selectProviderSidebar).toContainText('Select a provider to create instance for a channel');
+ const search = selectProviderSidebar.locator('input[type="search"]');
+ await expect(search).toHaveAttribute('placeholder', 'Search a provider...');
+ const sidebarClose = getByTestId(selectProviderSidebar, 'sidebar-close');
+ await expect(sidebarClose).toBeVisible();
+
+ const channelTabs = selectProviderSidebar.locator('[role="tablist"]');
+ const activeTab = channelTabs.locator('[data-active="true"]');
+ await expect(activeTab).toContainText('In-App');
+ await expect(channelTabs).toContainText('In-App');
+ await expect(channelTabs).toContainText('Email');
+ await expect(channelTabs).toContainText('Chat');
+ await expect(channelTabs).toContainText('Push');
+ await expect(channelTabs).toContainText('SMS');
+
+ const inAppGroup = getByTestId(page, 'providers-group-in_app');
+ await expect(inAppGroup).toContainText('In-App');
+ const emailGroup = getByTestId(page, 'providers-group-email');
+ await expect(emailGroup).toContainText('Email');
+ const chatGroup = getByTestId(page, 'providers-group-chat');
+ await expect(chatGroup).toContainText('Chat');
+ const pushGroup = getByTestId(page, 'providers-group-push');
+ await expect(pushGroup).toContainText('Push');
+ const smsGroup = getByTestId(page, 'providers-group-sms');
+ await expect(smsGroup).toContainText('SMS');
+
+ const allProviders = inAppProviders.concat(emailProviders, chatProviders, pushProviders, smsProviders);
+ for (const provider of allProviders) {
+ if (provider.id === EmailProviderIdEnum.Novu || provider.id === SmsProviderIdEnum.Novu) {
+ continue;
+ }
+
+ const providerInGroup = getByTestId(selectProviderSidebar, `provider-${provider.id}`);
+ await expect(providerInGroup).toContainText(provider.displayName);
+ }
+
+ const cancel = getByTestId(selectProviderSidebar, 'select-provider-sidebar-cancel');
+ await expect(cancel).toContainText('Cancel');
+ const next = getByTestId(selectProviderSidebar, 'select-provider-sidebar-next');
+ await expect(next).toContainText('Next');
+ await expect(next).toBeDisabled();
+});
+
+test('should allow for searching', async ({ page }) => {
+ await page.goto('/integrations');
+ await expect(page).toHaveURL(/\/integrations/);
+
+ const addProvider = getByTestId(page, 'add-provider');
+ await expect(addProvider).toBeEnabled();
+ await addProvider.click();
+
+ const selectProviderSidebar = getByTestId(page, 'select-provider-sidebar');
+ await expect(selectProviderSidebar).toBeVisible();
+
+ const search = selectProviderSidebar.locator('input[type="search"]');
+ await search.fill('Mail');
+
+ const channelTabs = selectProviderSidebar.locator('[role="tablist"]');
+ const inAppTab = channelTabs.locator('button', { hasText: 'In-App' });
+ await expect(inAppTab).toBeHidden();
+ const emailTab = channelTabs.locator('button', { hasText: 'Email' });
+ await expect(emailTab).toBeVisible();
+ const chatTab = channelTabs.locator('button', { hasText: 'Chat' });
+ await expect(chatTab).toBeHidden();
+ const pushTab = channelTabs.locator('button', { hasText: 'Push' });
+ await expect(pushTab).toBeHidden();
+ const smsTab = channelTabs.locator('button', { hasText: 'SMS' });
+ await expect(smsTab).toBeHidden();
+
+ const emailGroup = getByTestId(page, 'providers-group-email');
+ await expect(emailGroup).toContainText('Email');
+ const mailjet = getByTestId(selectProviderSidebar, `provider-${EmailProviderIdEnum.Mailjet}`);
+ await expect(mailjet).toContainText('Mailjet');
+ const mailgun = getByTestId(selectProviderSidebar, `provider-${EmailProviderIdEnum.Mailgun}`);
+ await expect(mailgun).toContainText('Mailgun');
+ const mailerSend = getByTestId(selectProviderSidebar, `provider-${EmailProviderIdEnum.MailerSend}`);
+ await expect(mailerSend).toContainText('MailerSend');
+ const emailWebhook = getByTestId(selectProviderSidebar, `provider-${EmailProviderIdEnum.EmailWebhook}`);
+ await expect(emailWebhook).toContainText('Email Webhook');
+
+ const next = getByTestId(selectProviderSidebar, 'select-provider-sidebar-next');
+ await expect(next).toContainText('Next');
+ await expect(next).toBeDisabled();
+});
+
+test('should show empty search results', async ({ page }) => {
+ await page.goto('/integrations');
+ await expect(page).toHaveURL(/\/integrations/);
+
+ const addProvider = getByTestId(page, 'add-provider');
+ await expect(addProvider).toBeEnabled();
+ await addProvider.click();
+
+ const selectProviderSidebar = getByTestId(page, 'select-provider-sidebar');
+ await expect(selectProviderSidebar).toBeVisible();
+
+ const search = selectProviderSidebar.locator('input[type="search"]');
+ await search.fill('safasdfasdfasdfasdfas');
+
+ const channelTabs = selectProviderSidebar.locator('[role="tablist"]');
+ const inAppTab = channelTabs.locator('button', { hasText: 'In-App' });
+ await expect(inAppTab).toBeHidden();
+ const emailTab = channelTabs.locator('button', { hasText: 'Email' });
+ await expect(emailTab).toBeHidden();
+ const chatTab = channelTabs.locator('button', { hasText: 'Chat' });
+ await expect(chatTab).toBeHidden();
+ const pushTab = channelTabs.locator('button', { hasText: 'Push' });
+ await expect(pushTab).toBeHidden();
+ const smsTab = channelTabs.locator('button', { hasText: 'SMS' });
+ await expect(smsTab).toBeHidden();
+
+ const noSearchResults = getByTestId(page, 'select-provider-no-search-results-img');
+ await expect(noSearchResults).toBeVisible();
+
+ const next = getByTestId(selectProviderSidebar, 'select-provider-sidebar-next');
+ await expect(next).toContainText('Next');
+ await expect(next).toBeDisabled();
+});
+
+test('should allow selecting a provider', async ({ page }) => {
+ await page.goto('/integrations');
+ await expect(page).toHaveURL(/\/integrations/);
+
+ const addProvider = getByTestId(page, 'add-provider');
+ await expect(addProvider).toBeEnabled();
+ await addProvider.click();
+
+ const selectProviderSidebar = getByTestId(page, 'select-provider-sidebar');
+ await expect(selectProviderSidebar).toBeVisible();
+
+ const mailjet = getByTestId(selectProviderSidebar, `provider-${EmailProviderIdEnum.Mailjet}`);
+ await expect(mailjet).toContainText('Mailjet');
+ await mailjet.click();
+
+ const selectedProviderImage = getByTestId(
+ selectProviderSidebar,
+ `selected-provider-image-${EmailProviderIdEnum.Mailjet}`
+ ).first();
+ const isDarkThemeEnabled = await isDarkTheme(page);
+ await expect(selectedProviderImage).toHaveAttribute(
+ 'src',
+ `/static/images/providers/${isDarkThemeEnabled ? 'dark' : 'light'}/square/${EmailProviderIdEnum.Mailjet}.svg`
+ );
+
+ const selectedProviderName = getByTestId(selectProviderSidebar, 'selected-provider-name');
+ await expect(selectedProviderName).toContainText('Mailjet');
+
+ const next = getByTestId(selectProviderSidebar, 'select-provider-sidebar-next');
+ await expect(next).toContainText('Next');
+ await expect(next).toBeEnabled();
+});
+
+test('should allow moving to create sidebar', async ({ page }) => {
+ await page.goto('/integrations');
+ await expect(page).toHaveURL(/\/integrations/);
+
+ const addProvider = getByTestId(page, 'add-provider');
+ await expect(addProvider).toBeEnabled();
+ await addProvider.click();
+
+ const selectProviderSidebar = getByTestId(page, 'select-provider-sidebar');
+ await expect(selectProviderSidebar).toBeVisible();
+
+ const mailjet = getByTestId(selectProviderSidebar, `provider-${EmailProviderIdEnum.Mailjet}`);
+ await expect(mailjet).toContainText('Mailjet');
+ await mailjet.click();
+
+ const next = getByTestId(selectProviderSidebar, 'select-provider-sidebar-next');
+ await expect(next).toContainText('Next');
+ await next.click();
+
+ const createProviderInstanceSidebar = getByTestId(page, 'create-provider-instance-sidebar');
+ await expect(createProviderInstanceSidebar).toBeVisible();
+ await expect(createProviderInstanceSidebar).toContainText(
+ 'Specify assignment preferences to automatically allocate the provider instance to the Email channel.'
+ );
+ await expect(createProviderInstanceSidebar).toContainText('Environment');
+ await expect(createProviderInstanceSidebar).toContainText('Provider instance executes only for');
+
+ const sidebarClose = getByTestId(createProviderInstanceSidebar, 'sidebar-close');
+ await expect(sidebarClose).toBeVisible();
+
+ const selectedProviderImage = getByTestId(
+ createProviderInstanceSidebar,
+ `selected-provider-image-${EmailProviderIdEnum.Mailjet}`
+ ).first();
+ const isDarkThemeEnabled = await isDarkTheme(page);
+ await expect(selectedProviderImage).toHaveAttribute(
+ 'src',
+ `/static/images/providers/${isDarkThemeEnabled ? 'dark' : 'light'}/square/${EmailProviderIdEnum.Mailjet}.svg`
+ );
+
+ const selectedProviderName = getByTestId(createProviderInstanceSidebar, 'provider-instance-name');
+ await expect(selectedProviderName).toBeVisible();
+ await expect(selectedProviderName).toHaveValue('Mailjet');
+
+ const environmentRadios = createProviderInstanceSidebar.locator('[role="radiogroup"]');
+ const selectedEnv = environmentRadios.locator('[data-checked="true"]');
+ await expect(selectedEnv).toContainText('Development');
+ await expect(environmentRadios).toContainText('Production');
+
+ const cancel = getByTestId(createProviderInstanceSidebar, 'create-provider-instance-sidebar-cancel');
+ await expect(cancel).toContainText('Cancel');
+ await expect(cancel).toBeEnabled();
+
+ const create = getByTestId(createProviderInstanceSidebar, 'create-provider-instance-sidebar-create');
+ await expect(create).toContainText('Create');
+ await expect(create).toBeEnabled();
+});
+
+test('should allow moving back from create provider sidebar to select provider sidebar', async ({ page }) => {
+ await page.goto('/integrations');
+ await expect(page).toHaveURL(/\/integrations/);
+
+ const addProvider = getByTestId(page, 'add-provider');
+ await expect(addProvider).toBeEnabled();
+ await addProvider.click();
+
+ let selectProviderSidebar = getByTestId(page, 'select-provider-sidebar');
+ await expect(selectProviderSidebar).toBeVisible();
+
+ const mailjet = getByTestId(selectProviderSidebar, `provider-${EmailProviderIdEnum.Mailjet}`);
+ await expect(mailjet).toContainText('Mailjet');
+ await mailjet.click();
+
+ const next = getByTestId(selectProviderSidebar, 'select-provider-sidebar-next');
+ await expect(next).toContainText('Next');
+ await next.click();
+
+ const back = getByTestId(page, 'create-provider-instance-sidebar-back');
+ await expect(back).toBeVisible();
+ await back.click();
+
+ selectProviderSidebar = getByTestId(page, 'select-provider-sidebar');
+ await expect(selectProviderSidebar).toBeVisible();
+});
+
+test('should create a new mailjet integration', async ({ page }) => {
+ await page.goto('/integrations');
+ await expect(page).toHaveURL(/\/integrations/);
+
+ const addProvider = getByTestId(page, 'add-provider');
+ await expect(addProvider).toBeEnabled();
+ await addProvider.click();
+
+ let selectProviderSidebar = getByTestId(page, 'select-provider-sidebar');
+ await expect(selectProviderSidebar).toBeVisible();
+
+ const mailjet = getByTestId(selectProviderSidebar, `provider-${EmailProviderIdEnum.Mailjet}`);
+ await expect(mailjet).toContainText('Mailjet');
+ await mailjet.click();
+
+ const next = getByTestId(selectProviderSidebar, 'select-provider-sidebar-next');
+ await expect(next).toContainText('Next');
+ await next.click();
+
+ const providerName = getByTestId(page, 'provider-instance-name');
+ await providerName.clear();
+ await providerName.fill('Mailjet Integration');
+
+ const create = getByTestId(page, 'create-provider-instance-sidebar-create');
+ await expect(create).toContainText('Create');
+ await expect(create).toBeEnabled();
+ await create.click();
+
+ const updateProviderSidebar = getByTestId(page, 'update-provider-sidebar');
+ await expect(updateProviderSidebar).toBeVisible();
+
+ const close = getByTestId(updateProviderSidebar, 'sidebar-close');
+ await expect(close).toBeVisible();
+ await close.click();
+
+ await checkTableRow(page, {
+ name: 'Mailjet Integration',
+ provider: 'Mailjet',
+ channel: 'Email',
+ environment: 'Development',
+ status: 'Disabled',
+ });
+});
+
+test('should create a new mailjet integration with conditions', async ({ page }) => {
+ await page.goto('/integrations');
+ await expect(page).toHaveURL(/\/integrations/);
+
+ const addProvider = getByTestId(page, 'add-provider');
+ await expect(addProvider).toBeEnabled();
+ await addProvider.click();
+
+ let selectProviderSidebar = getByTestId(page, 'select-provider-sidebar');
+ await expect(selectProviderSidebar).toBeVisible();
+
+ const mailjet = getByTestId(selectProviderSidebar, `provider-${EmailProviderIdEnum.Mailjet}`);
+ await expect(mailjet).toContainText('Mailjet');
+ await mailjet.click();
+
+ const next = getByTestId(selectProviderSidebar, 'select-provider-sidebar-next');
+ await expect(next).toContainText('Next');
+ await next.click();
+
+ const providerName = getByTestId(page, 'provider-instance-name');
+ await providerName.clear();
+ await providerName.fill('Mailjet Integration');
+
+ const addConditionsButton = getByTestId(page, 'add-conditions-btn');
+ await addConditionsButton.click();
+
+ const conditionsTitle = getByTestId(page, 'conditions-form-title');
+ await expect(conditionsTitle).toContainText('Conditions for Mailjet Integration provider instance');
+
+ const addConditionButton = getByTestId(page, 'add-new-condition');
+ await addConditionButton.click();
+
+ const formOn = getByTestId(page, 'conditions-form-on');
+ await expect(formOn).toHaveValue('Tenant');
+
+ const formKey = getByTestId(page, 'conditions-form-key');
+ await formKey.fill('identifier');
+
+ const formOperator = getByTestId(page, 'conditions-form-operator');
+ await expect(formOperator).toHaveValue('Equal');
+
+ const formValue = getByTestId(page, 'conditions-form-value');
+ await formValue.fill('tenant123');
+
+ let applyButton = getByTestId(page, 'apply-conditions-btn');
+ await applyButton.click();
+
+ await expect(addConditionsButton).toContainText('Edit conditions');
+
+ const create = getByTestId(page, 'create-provider-instance-sidebar-create');
+ await expect(create).toContainText('Create');
+ await expect(create).toBeEnabled();
+ await create.click();
+
+ const updateProviderSidebar = getByTestId(page, 'update-provider-sidebar');
+ await expect(updateProviderSidebar).toBeVisible();
+
+ let headerAddConditions = getByTestId(updateProviderSidebar, 'header-add-conditions-btn');
+ await expect(headerAddConditions).toContainText('1');
+ await headerAddConditions.click();
+
+ const addNewCondition = getByTestId(page, 'add-new-condition');
+ await addNewCondition.click();
+
+ const conditionsFormKey = getByTestId(page, 'conditions-form-key').last();
+ await conditionsFormKey.fill('identifier');
+
+ const conditionsFormValue = getByTestId(page, 'conditions-form-value').last();
+ await conditionsFormValue.fill('tenant456');
+
+ applyButton = getByTestId(page, 'apply-conditions-btn');
+ await applyButton.click();
+
+ headerAddConditions = getByTestId(updateProviderSidebar, 'header-add-conditions-btn');
+ await expect(headerAddConditions).toContainText('2');
+
+ await expect(page).toHaveURL(/\/integrations\//);
+
+ const close = getByTestId(updateProviderSidebar, 'sidebar-close');
+ await expect(close).toBeVisible();
+ await close.click();
+
+ await checkTableRow(page, {
+ name: 'Mailjet Integration',
+ provider: 'Mailjet',
+ channel: 'Email',
+ environment: 'Development',
+ status: 'Disabled',
+ });
+});
+
+test('should remove as primary when adding conditions', async ({ page }) => {
+ await page.goto('/integrations');
+ await expect(page).toHaveURL(/\/integrations/);
+
+ await clickOnListRow(page, new RegExp(`SendGrid.*Development`));
+
+ const headerAddConditions = getByTestId(page, 'header-add-conditions-btn');
+ await headerAddConditions.click();
+
+ const removePrimaryFlagModal = getByTestId(page, 'remove-primary-flag-modal');
+ await expect(removePrimaryFlagModal).toBeVisible();
+ await expect(removePrimaryFlagModal).toContainText('Primary flag will be removed');
+ await expect(removePrimaryFlagModal).toContainText(
+ 'Adding conditions to the primary provider instance removes its primary status when a user applies changes by'
+ );
+
+ const cancel = removePrimaryFlagModal.getByRole('button', { name: 'Cancel' });
+ await expect(cancel).toBeVisible();
+
+ const gotIt = removePrimaryFlagModal.getByRole('button', { name: 'Got it' });
+ await expect(gotIt).toBeVisible();
+ await gotIt.click();
+
+ const conditionsTitle = getByTestId(page, 'conditions-form-title');
+ await expect(conditionsTitle).toContainText('Conditions for SendGrid provider instance');
+
+ const addConditionButton = getByTestId(page, 'add-new-condition');
+ await addConditionButton.click();
+
+ const formOn = getByTestId(page, 'conditions-form-on');
+ await expect(formOn).toHaveValue('Tenant');
+
+ const formKey = getByTestId(page, 'conditions-form-key');
+ await formKey.fill('identifier');
+
+ const formOperator = getByTestId(page, 'conditions-form-operator');
+ await expect(formOperator).toHaveValue('Equal');
+
+ const formValue = getByTestId(page, 'conditions-form-value');
+ await formValue.fill('tenant123');
+
+ let applyButton = getByTestId(page, 'apply-conditions-btn');
+ await applyButton.click();
+
+ const providerName = page.getByPlaceholder('Enter instance name');
+ await providerName.clear();
+ await providerName.fill('SendGrid test');
+
+ const fromField = getByTestId(page, 'from');
+ await fromField.fill('info@novu.co');
+
+ const senderName = getByTestId(page, 'senderName');
+ await senderName.fill('Novu');
+
+ const updateButton = getByTestId(page, 'update-provider-sidebar-update');
+ await expect(updateButton).toContainText('Update');
+ await expect(updateButton).toBeEnabled();
+ await updateButton.click();
+
+ const makePrimaryButton = page.locator('button', { hasText: 'Make primary' });
+ await expect(makePrimaryButton).toBeVisible();
+
+ const closeButton = page.locator('.mantine-Modal-close');
+ await closeButton.click();
+});
+
+test('should remove conditions when set to primary', async ({ page }) => {
+ await page.goto('/integrations');
+ await expect(page).toHaveURL(/\/integrations/);
+
+ const addProvider = getByTestId(page, 'add-provider');
+ await expect(addProvider).toBeEnabled();
+ await addProvider.click();
+
+ await expect(page).toHaveURL(/\/integrations\/create/);
+
+ const selectProviderSidebar = getByTestId(page, 'select-provider-sidebar');
+ await expect(selectProviderSidebar).toBeVisible();
+
+ const mailjet = getByTestId(selectProviderSidebar, `provider-${EmailProviderIdEnum.Mailjet}`);
+ await expect(mailjet).toContainText('Mailjet');
+ await mailjet.click();
+
+ const next = getByTestId(selectProviderSidebar, 'select-provider-sidebar-next');
+ await expect(next).toContainText('Next');
+ await next.click();
+
+ await expect(page).toHaveURL(/\/integrations\/create\/email\/mailjet/);
+
+ const providerName = page.getByPlaceholder('Enter instance name');
+ await providerName.clear();
+ await providerName.fill('Mailjet Integration');
+
+ const addConditionsButton = getByTestId(page, 'add-conditions-btn');
+ await addConditionsButton.click();
+
+ const conditionsTitle = getByTestId(page, 'conditions-form-title');
+ await expect(conditionsTitle).toContainText('Conditions for Mailjet Integration provider instance');
+
+ const addNewCondition = getByTestId(page, 'add-new-condition');
+ await addNewCondition.click();
+
+ const formOn = getByTestId(page, 'conditions-form-on');
+ await expect(formOn).toHaveValue('Tenant');
+
+ const formKey = getByTestId(page, 'conditions-form-key');
+ await formKey.fill('identifier');
+
+ const formOperator = getByTestId(page, 'conditions-form-operator');
+ await expect(formOperator).toHaveValue('Equal');
+
+ const formValue = getByTestId(page, 'conditions-form-value');
+ await formValue.fill('tenant123');
+
+ let applyButton = getByTestId(page, 'apply-conditions-btn');
+ await applyButton.click();
+
+ const create = getByTestId(page, 'create-provider-instance-sidebar-create');
+ await expect(create).toContainText('Create');
+ await expect(create).toBeEnabled();
+ await create.click();
+
+ const updateProviderSidebar = getByTestId(page, 'update-provider-sidebar');
+ await expect(updateProviderSidebar).toBeVisible();
+
+ const headerAddConditions = getByTestId(updateProviderSidebar, 'header-add-conditions-btn');
+ await expect(headerAddConditions).toContainText('1');
+
+ let makePrimaryButton = getByTestId(updateProviderSidebar, 'header-make-primary-btn');
+ await makePrimaryButton.click();
+
+ const removeConditionsModal = getByTestId(page, 'remove-conditions-modal');
+ await expect(removeConditionsModal).toBeVisible();
+ await expect(removeConditionsModal).toContainText('Conditions will be removed');
+ await expect(removeConditionsModal).toContainText('Marking this instance as primary will remove all conditions');
+ const cancel = removeConditionsModal.getByRole('button', { name: 'Cancel' });
+ await expect(cancel).toBeVisible();
+ const removeConditionsButton = removeConditionsModal.getByRole('button', { name: 'Remove conditions' });
+ await expect(removeConditionsButton).toBeVisible();
+ await removeConditionsButton.click();
+
+ makePrimaryButton = getByTestId(updateProviderSidebar, 'header-make-primary-btn');
+ await expect(makePrimaryButton).toBeHidden();
+
+ const sidebarClose = getByTestId(page, 'sidebar-close');
+ await sidebarClose.click();
+
+ await clickOnListRow(page, new RegExp(`Mailjet Integration.*Development`));
+});
+
+test('should update the mailjet integration', async ({ page }) => {
+ await page.goto('/integrations');
+ await expect(page).toHaveURL(/\/integrations/);
+
+ const addProvider = getByTestId(page, 'add-provider');
+ await expect(addProvider).toBeEnabled();
+ await addProvider.click();
+
+ let selectProviderSidebar = getByTestId(page, 'select-provider-sidebar');
+ await expect(selectProviderSidebar).toBeVisible();
+
+ const mailjet = getByTestId(selectProviderSidebar, `provider-${EmailProviderIdEnum.Mailjet}`);
+ await expect(mailjet).toContainText('Mailjet');
+ await mailjet.click();
+
+ const next = getByTestId(selectProviderSidebar, 'select-provider-sidebar-next');
+ await expect(next).toContainText('Next');
+ await next.click();
+
+ let providerName = getByTestId(page, 'provider-instance-name');
+ await providerName.clear();
+ await providerName.fill('Mailjet Integration');
+
+ const create = getByTestId(page, 'create-provider-instance-sidebar-create');
+ await expect(create).toContainText('Create');
+ await expect(create).toBeEnabled();
+ await create.click();
+
+ const updateProviderSidebar = getByTestId(page, 'update-provider-sidebar');
+ await expect(updateProviderSidebar).toBeVisible();
+ await expect(updateProviderSidebar).toContainText('Set up credentials to start sending notifications.');
+
+ const integrationChannel = getByTestId(updateProviderSidebar, 'provider-instance-channel');
+ await expect(integrationChannel).toContainText('Email');
+
+ const integrationEnvironment = getByTestId(updateProviderSidebar, 'provider-instance-environment');
+ await expect(integrationEnvironment).toContainText('Development');
+
+ const isActive = getByTestId(updateProviderSidebar, 'is_active_id');
+ await expect(isActive).toHaveValue('false');
+
+ providerName = updateProviderSidebar.getByPlaceholder('Enter instance name');
+ await expect(providerName).toHaveValue('Mailjet Integration');
+
+ const identifier = getByTestId(updateProviderSidebar, 'provider-instance-identifier');
+ await expect(identifier).toHaveValue(/mailjet/);
+
+ const updateButton = getByTestId(updateProviderSidebar, 'update-provider-sidebar-update');
+ await expect(updateButton).toBeDisabled();
+
+ await providerName.clear();
+ await providerName.fill('Mailjet Integration Updated');
+
+ await isActive.locator('~ label').click();
+
+ const apiKey = getByTestId(updateProviderSidebar, 'apiKey');
+ await apiKey.fill('fake-api-key');
+
+ const secretKey = getByTestId(updateProviderSidebar, 'secretKey');
+ await secretKey.fill('fake-secret-key');
+
+ const fromField = getByTestId(updateProviderSidebar, 'from');
+ await fromField.fill('info@novu.co');
+
+ const senderName = getByTestId(updateProviderSidebar, 'senderName');
+ await senderName.fill('Novu');
+
+ await expect(updateButton).toBeEnabled();
+ await updateButton.click();
+
+ const modalClose = page.locator('.mantine-Modal-close');
+ await modalClose.click();
+ const sidebarClose = getByTestId(page, 'sidebar-close');
+ await sidebarClose.click();
+
+ await checkTableRow(page, {
+ name: 'Mailjet Integration Updated',
+ provider: 'Mailjet',
+ channel: 'Email',
+ environment: 'Development',
+ status: 'Active',
+ });
+});
+
+test('should update the mailjet integration from the list', async ({ page }) => {
+ await page.goto('/integrations');
+ await expect(page).toHaveURL(/\/integrations/);
+
+ const addProvider = getByTestId(page, 'add-provider');
+ await expect(addProvider).toBeEnabled();
+ await addProvider.click();
+
+ let selectProviderSidebar = getByTestId(page, 'select-provider-sidebar');
+ await expect(selectProviderSidebar).toBeVisible();
+
+ const mailjet = getByTestId(selectProviderSidebar, `provider-${EmailProviderIdEnum.Mailjet}`);
+ await expect(mailjet).toContainText('Mailjet');
+ await mailjet.click();
+
+ const next = getByTestId(selectProviderSidebar, 'select-provider-sidebar-next');
+ await expect(next).toContainText('Next');
+ await next.click();
+
+ let providerName = getByTestId(page, 'provider-instance-name');
+ await providerName.clear();
+ await providerName.fill('Mailjet Integration');
+
+ const create = getByTestId(page, 'create-provider-instance-sidebar-create');
+ await expect(create).toContainText('Create');
+ await expect(create).toBeEnabled();
+ await create.click();
+
+ let updateProviderSidebar = getByTestId(page, 'update-provider-sidebar');
+ await expect(updateProviderSidebar).toBeVisible();
+
+ let sidebarClose = getByTestId(page, 'sidebar-close');
+ await sidebarClose.click();
+
+ await clickOnListRow(page, 'Mailjet Integration');
+
+ updateProviderSidebar = getByTestId(page, 'update-provider-sidebar');
+ await expect(updateProviderSidebar).toBeVisible();
+
+ const isActive = getByTestId(updateProviderSidebar, 'is_active_id');
+ await expect(isActive).toHaveValue('false');
+
+ providerName = updateProviderSidebar.getByPlaceholder('Enter instance name');
+ await expect(providerName).toHaveValue('Mailjet Integration');
+
+ const identifier = getByTestId(updateProviderSidebar, 'provider-instance-identifier');
+ await expect(identifier).toHaveValue(/mailjet/);
+
+ const updateButton = getByTestId(updateProviderSidebar, 'update-provider-sidebar-update');
+ await expect(updateButton).toBeDisabled();
+
+ providerName = updateProviderSidebar.getByPlaceholder('Enter instance name');
+ await providerName.clear();
+ await providerName.fill('Mailjet Integration Updated');
+
+ await isActive.locator('~ label').click();
+
+ const apiKey = getByTestId(updateProviderSidebar, 'apiKey');
+ await apiKey.fill('fake-api-key');
+
+ const secretKey = getByTestId(updateProviderSidebar, 'secretKey');
+ await secretKey.fill('fake-secret-key');
+
+ const fromField = getByTestId(updateProviderSidebar, 'from');
+ await fromField.fill('info@novu.co');
+
+ const senderName = getByTestId(updateProviderSidebar, 'senderName');
+ await senderName.fill('Novu');
+
+ await expect(updateButton).toBeEnabled();
+ await updateButton.click();
+
+ const modalClose = page.locator('.mantine-Modal-close');
+ await modalClose.click();
+ sidebarClose = getByTestId(page, 'sidebar-close');
+ await sidebarClose.click();
+
+ await checkTableRow(page, {
+ name: 'Mailjet Integration Updated',
+ provider: 'Mailjet',
+ channel: 'Email',
+ environment: 'Development',
+ status: 'Active',
+ });
+});
+
+test('should allow to delete the mailjet integration', async ({ page }) => {
+ await page.goto('/integrations');
+ await expect(page).toHaveURL(/\/integrations/);
+
+ const addProvider = getByTestId(page, 'add-provider');
+ await expect(addProvider).toBeEnabled();
+ await addProvider.click();
+
+ let selectProviderSidebar = getByTestId(page, 'select-provider-sidebar');
+ await expect(selectProviderSidebar).toBeVisible();
+
+ const mailjet = getByTestId(selectProviderSidebar, `provider-${EmailProviderIdEnum.Mailjet}`);
+ await expect(mailjet).toContainText('Mailjet');
+ await mailjet.click();
+
+ const next = getByTestId(selectProviderSidebar, 'select-provider-sidebar-next');
+ await expect(next).toContainText('Next');
+ await next.click();
+
+ let providerName = getByTestId(page, 'provider-instance-name');
+ await providerName.clear();
+ await providerName.fill('Mailjet Integration');
+
+ const create = getByTestId(page, 'create-provider-instance-sidebar-create');
+ await expect(create).toContainText('Create');
+ await expect(create).toBeEnabled();
+ await create.click();
+
+ let updateProviderSidebar = getByTestId(page, 'update-provider-sidebar');
+ await expect(updateProviderSidebar).toBeVisible();
+
+ let sidebarClose = getByTestId(page, 'sidebar-close');
+ await sidebarClose.click();
+
+ await clickOnListRow(page, 'Mailjet Integration');
+
+ updateProviderSidebar = getByTestId(page, 'update-provider-sidebar');
+ await expect(updateProviderSidebar).toBeVisible();
+
+ const menu = updateProviderSidebar.locator('[aria-haspopup="menu"]');
+ await menu.click();
+ const deleteButton = updateProviderSidebar.locator('button[data-menu-item="true"]', { hasText: 'Delete' });
+ await deleteButton.click();
+
+ const deleteModal = getByTestId(page, 'delete-provider-instance-modal');
+ await expect(deleteModal).toBeVisible();
+ await expect(deleteModal).toContainText('Delete Mailjet Integration instance?');
+ await expect(deleteModal).toContainText(
+ 'Deleting a provider instance will fail workflows relying on its configuration, leading to undelivered notifications.'
+ );
+
+ const cancel = deleteModal.getByRole('button', { name: 'Cancel' });
+ await expect(cancel).toBeEnabled();
+ const deleteInstanceButton = deleteModal.getByRole('button', { name: 'Delete instance' });
+ await expect(deleteInstanceButton).toBeEnabled();
+ await deleteInstanceButton.click();
+
+ const integrationsTable = getByTestId(page, 'integration-name-cell', { hasText: 'Mailjet Integration' });
+ await expect(integrationsTable).toBeHidden();
+});
+
+test('should show the Novu in-app integration', async ({ page }) => {
+ await page.goto('/integrations');
+ await expect(page).toHaveURL(/\/integrations/);
+
+ await clickOnListRow(page, new RegExp(`Novu In-App.*Development`));
+
+ const updateProviderSidebar = getByTestId(page, 'update-provider-sidebar');
+ await expect(updateProviderSidebar).toBeVisible();
+ await expect(updateProviderSidebar).toContainText(
+ 'Select a framework to set up credentials to start sending notifications.'
+ );
+
+ const sidebarClose = getByTestId(updateProviderSidebar, 'sidebar-close');
+ await expect(sidebarClose).toBeVisible();
+
+ const integrationChannel = getByTestId(updateProviderSidebar, 'provider-instance-channel');
+ await expect(integrationChannel).toContainText('In-App');
+
+ const integrationEnvironment = getByTestId(updateProviderSidebar, 'provider-instance-environment');
+ await expect(integrationEnvironment).toContainText('Development');
+
+ const linkToDocs = updateProviderSidebar.getByRole('link', { name: 'Explore set-up guide' });
+ await expect(linkToDocs).toBeVisible();
+
+ const isActive = getByTestId(updateProviderSidebar, 'is_active_id');
+ await expect(isActive).toHaveValue('true');
+
+ const isDarkThemeEnabled = await isDarkTheme(page);
+ const selectedProviderImage = getByTestId(
+ updateProviderSidebar,
+ `selected-provider-image-${InAppProviderIdEnum.Novu}`
+ );
+ await expect(selectedProviderImage).toHaveAttribute(
+ 'src',
+ `/static/images/providers/${isDarkThemeEnabled ? 'dark' : 'light'}/square/${InAppProviderIdEnum.Novu}.svg`
+ );
+
+ const selectedProviderName = getByTestId(updateProviderSidebar, 'provider-instance-name').first();
+ await expect(selectedProviderName).toBeVisible();
+ await expect(selectedProviderName).toHaveValue('Novu In-App');
+
+ const identifier = getByTestId(updateProviderSidebar, 'provider-instance-identifier');
+ await expect(identifier).toHaveValue(/novu-in-app/);
+
+ const hmacCheckbox = getByTestId(updateProviderSidebar, 'hmac');
+ await expect(hmacCheckbox).not.toBeChecked();
+
+ const novuInAppFrameworks = getByTestId(updateProviderSidebar, 'novu-in-app-frameworks');
+ await expect(novuInAppFrameworks).toContainText('Integrate In-App using a framework below');
+ await expect(novuInAppFrameworks).toContainText('React');
+ await expect(novuInAppFrameworks).toContainText('Angular');
+ await expect(novuInAppFrameworks).toContainText('Web Component');
+ await expect(novuInAppFrameworks).toContainText('Headless');
+ await expect(novuInAppFrameworks).toContainText('Vue');
+ await expect(novuInAppFrameworks).toContainText('iFrame');
+
+ const updateButton = getByTestId(updateProviderSidebar, 'update-provider-sidebar-update');
+ await expect(updateButton).toContainText('Update');
+ await expect(updateButton).toBeDisabled();
+});
+
+test('should show the Novu in-app integration - React guide', async ({ page }) => {
+ await page.goto('/integrations');
+ await expect(page).toHaveURL(/\/integrations/);
+
+ await clickOnListRow(page, new RegExp(`Novu In-App.*Development`));
+
+ let updateProviderSidebar = getByTestId(page, 'update-provider-sidebar');
+ await expect(updateProviderSidebar).toBeVisible();
+
+ const novuInAppFrameworks = getByTestId(updateProviderSidebar, 'novu-in-app-frameworks');
+ await expect(novuInAppFrameworks).toContainText('React');
+
+ const reactGuide = novuInAppFrameworks.locator('div').filter({ hasText: 'React' }).nth(1);
+ await reactGuide.click();
+
+ updateProviderSidebar = getByTestId(page, 'update-provider-sidebar');
+ await expect(updateProviderSidebar).toContainText('React integration guide');
+
+ const sidebarBack = getByTestId(updateProviderSidebar, 'sidebar-back');
+ await expect(sidebarBack).toBeVisible();
+ const setupTimeline = getByTestId(updateProviderSidebar, 'setup-timeline');
+ await expect(setupTimeline).toBeVisible();
+
+ const updateButton = getByTestId(updateProviderSidebar, 'update-provider-sidebar-update');
+ await expect(updateButton).toContainText('Update');
+ await expect(updateButton).toBeDisabled();
+});
+
+test('should show the Novu Email integration sidebar', async ({ page }) => {
+ const integrationsPromise = interceptIntegrationsRequest({
+ page,
+ modifyBody: (body) => {
+ const [firstIntegration] = body.data;
+ body.data = [
+ {
+ _id: EmailProviderIdEnum.Novu,
+ _environmentId: firstIntegration._environmentId,
+ providerId: EmailProviderIdEnum.Novu,
+ active: true,
+ channel: ChannelTypeEnum.EMAIL,
+ name: 'Novu Email',
+ identifier: EmailProviderIdEnum.Novu,
+ },
+ ...body.data,
+ ];
+
+ return body;
+ },
+ });
+
+ await page.goto('/integrations');
+ await expect(page).toHaveURL(/\/integrations/);
+ await integrationsPromise;
+
+ await clickOnListRow(page, new RegExp(`Novu Email.*Development`));
+
+ let updateProviderSidebar = getByTestId(page, 'update-provider-sidebar-novu');
+ await expect(updateProviderSidebar).toContainText('Test Provider');
+ await expect(updateProviderSidebar).toBeVisible();
+
+ const isDarkThemeEnabled = await isDarkTheme(page);
+ const novuEmailLogo = updateProviderSidebar.locator(
+ `img[src="/static/images/providers/${isDarkThemeEnabled ? 'dark' : 'light'}/square/${
+ EmailProviderIdEnum.Novu
+ }.svg"]`
+ );
+ await expect(novuEmailLogo).toBeVisible();
+
+ const integrationChannel = getByTestId(updateProviderSidebar, 'provider-instance-channel');
+ await expect(integrationChannel).toContainText('Email');
+
+ const integrationEnvironment = getByTestId(updateProviderSidebar, 'provider-instance-environment');
+ await expect(integrationEnvironment).toContainText('Development');
+
+ const selectedProviderName = getByTestId(updateProviderSidebar, 'provider-instance-name').first();
+ await expect(selectedProviderName).toBeVisible();
+ await expect(selectedProviderName).toHaveValue('Novu Email');
+
+ const providerLimits = getByTestId(updateProviderSidebar, 'novu-provider-limits');
+ const providerLimitsText = await providerLimits.innerText();
+ await expect(providerLimitsText).toEqual(
+ 'Novu provider allows sending max 300 emails per month,\nto send more messages, configure a different provider'
+ );
+
+ const limitbarLimit = getByTestId(updateProviderSidebar, 'limitbar-limit');
+ const limitbarText = await limitbarLimit.innerText();
+ await expect(limitbarText).toEqual('300 emails per month');
+});
+
+test('should show the Novu SMS integration sidebar', async ({ page }) => {
+ const integrationsPromise = interceptIntegrationsRequest({
+ page,
+ modifyBody: (body) => {
+ const [firstIntegration] = body.data;
+ body.data = [
+ {
+ _id: SmsProviderIdEnum.Novu,
+ _environmentId: firstIntegration._environmentId,
+ providerId: SmsProviderIdEnum.Novu,
+ active: true,
+ channel: ChannelTypeEnum.SMS,
+ name: 'Novu SMS',
+ identifier: SmsProviderIdEnum.Novu,
+ },
+ ...body.data,
+ ];
+
+ return body;
+ },
+ });
+
+ await page.goto('/integrations');
+ await expect(page).toHaveURL(/\/integrations/);
+ await integrationsPromise;
+
+ await clickOnListRow(page, new RegExp(`Novu SMS.*Development`));
+
+ let updateProviderSidebar = getByTestId(page, 'update-provider-sidebar-novu');
+ await expect(updateProviderSidebar).toContainText('Test Provider');
+ await expect(updateProviderSidebar).toBeVisible();
+
+ const isDarkThemeEnabled = await isDarkTheme(page);
+ const novuEmailLogo = updateProviderSidebar.locator(
+ `img[src="/static/images/providers/${isDarkThemeEnabled ? 'dark' : 'light'}/square/${SmsProviderIdEnum.Novu}.svg"]`
+ );
+ await expect(novuEmailLogo).toBeVisible();
+
+ const integrationChannel = getByTestId(updateProviderSidebar, 'provider-instance-channel');
+ await expect(integrationChannel).toContainText('SMS');
+
+ const integrationEnvironment = getByTestId(updateProviderSidebar, 'provider-instance-environment');
+ await expect(integrationEnvironment).toContainText('Development');
+
+ const selectedProviderName = getByTestId(updateProviderSidebar, 'provider-instance-name').first();
+ await expect(selectedProviderName).toBeVisible();
+ await expect(selectedProviderName).toHaveValue('Novu SMS');
+
+ const providerLimits = getByTestId(updateProviderSidebar, 'novu-provider-limits');
+ const providerLimitsText = await providerLimits.innerText();
+ await expect(providerLimitsText).toEqual(
+ 'Novu provider allows sending max 20 messages per month,\nto send more messages, configure a different provider'
+ );
+
+ const limitbarLimit = getByTestId(updateProviderSidebar, 'limitbar-limit');
+ const limitbarText = await limitbarLimit.innerText();
+ await expect(limitbarText).toEqual('20 messages per month');
+});
diff --git a/apps/web/tests/main-functionality.spec.ts b/apps/web/tests/main-functionality.spec.ts
new file mode 100644
index 00000000000..0ccbf787aa6
--- /dev/null
+++ b/apps/web/tests/main-functionality.spec.ts
@@ -0,0 +1,577 @@
+import { test, expect } from '@playwright/test';
+import os from 'node:os';
+
+import { dragAndDrop, getByTestId, initializeSession } from './utils.ts/browser';
+import {
+ addAndEditChannel,
+ editChannel,
+ fillBasicNotificationDetails,
+ goBack,
+ updateWorkflowButtonClick,
+} from './utils.ts/workflow-editor';
+
+let session;
+
+const isMac = os.platform() === 'darwin';
+const modifier = isMac ? 'Meta' : 'Control';
+
+test.beforeEach(async ({ context }) => {
+ session = await initializeSession(context);
+});
+
+test('should not reset data when switching channel types', async ({ page }) => {
+ await page.goto('/workflows/create');
+
+ await fillBasicNotificationDetails(page);
+ await goBack(page);
+ await addAndEditChannel(page, 'inApp');
+
+ const editorParent = page.locator('.monaco-editor textarea').locator('xpath=..');
+ await editorParent.click();
+ await editorParent.locator('textarea').fill('{{firstName}} someone assigned you to {{taskName}}');
+
+ await goBack(page);
+ await addAndEditChannel(page, 'email');
+
+ const subjectEl = getByTestId(page, 'emailSubject');
+ await subjectEl.fill('this is email subject');
+
+ const preheaderEl = getByTestId(page, 'emailPreheader');
+ await preheaderEl.fill('this is email preheader');
+
+ const editableText = getByTestId(page, 'editable-text-content');
+ await editableText.clear();
+ await editableText.pressSequentially('This text is written from a test {{firstName}}');
+
+ await goBack(page);
+
+ await editChannel(page, 'inApp');
+ await goBack(page);
+
+ await editChannel(page, 'email');
+ await expect(getByTestId(page, 'emailSubject')).toHaveValue('this is email subject');
+ await expect(getByTestId(page, 'emailPreheader')).toHaveValue('this is email preheader');
+ await expect(getByTestId(page, 'editable-text-content')).toContainText('This text is written from a test');
+});
+
+test('should update to empty data when switching from editor to customHtml', async ({ page }) => {
+ await page.goto('/workflows/create');
+
+ await fillBasicNotificationDetails(page, { title: 'Test Notification' });
+ await goBack(page);
+ await addAndEditChannel(page, 'email');
+
+ const editableText = getByTestId(page, 'editable-text-content');
+ await editableText.clear();
+ await editableText.pressSequentially('This text is written from a test {{firstName}}');
+
+ let subjectEl = getByTestId(page, 'emailSubject');
+ await subjectEl.fill('this is email subject');
+
+ await updateWorkflowButtonClick(page);
+
+ await page
+ .locator('[data-test-id="editor-type-selector"] .mantine-Tabs-tabsList')
+ .getByText(/Custom Code/)
+ .first()
+ .click();
+
+ subjectEl = getByTestId(page, 'emailSubject');
+ await subjectEl.clear();
+ await subjectEl.fill('new email subject');
+
+ await updateWorkflowButtonClick(page, { noWaitAfter: true });
+
+ const templatesLinkPage = getByTestId(page, 'side-nav-templates-link');
+ await templatesLinkPage.click();
+
+ const notificationsTemplate = getByTestId(page, 'notifications-template');
+ await notificationsTemplate.getByText(/Test Notification/).click();
+
+ await editChannel(page, 'email');
+
+ await expect(
+ page
+ .locator('[data-test-id="editor-type-selector"] .mantine-Tabs-tabsList')
+ .locator('[data-active="true"]')
+ .getByText(/Custom Code/)
+ .first()
+ ).toBeVisible();
+});
+
+test('should save avatar enabled and content for in app', async ({ page }) => {
+ await page.goto('/workflows/create');
+
+ await fillBasicNotificationDetails(page, { title: 'Test save avatar' });
+ await goBack(page);
+ await addAndEditChannel(page, 'inApp');
+
+ const editorParent = page.locator('.monaco-editor textarea').locator('xpath=..');
+ await editorParent.click();
+ await editorParent.locator('textarea').fill('new content for notification');
+
+ const enableAddAvatar = getByTestId(page, 'enable-add-avatar');
+ await enableAddAvatar.click();
+ const chooseAvatar = getByTestId(page, 'choose-avatar-btn');
+ await chooseAvatar.click();
+ const avatarIconInfo = getByTestId(page, 'avatar-icon-info');
+ await avatarIconInfo.click();
+
+ await updateWorkflowButtonClick(page);
+
+ await expect(getByTestId(page, 'enabled-avatar')).toBeChecked();
+ await expect(getByTestId(page, 'avatar-icon-info')).toBeVisible();
+});
+
+test('should edit in-app notification', async ({ page }) => {
+ const template = session.templates[0];
+ await page.goto(`/workflows/edit/${template._id}`);
+
+ const settingsPage = getByTestId(page, 'settings-page');
+ await settingsPage.click();
+
+ let nameInput = getByTestId(page, 'name-input');
+ await expect(nameInput.first()).toHaveValue(template.name);
+
+ await goBack(page);
+ await editChannel(page, 'inApp');
+
+ let editorParent = page.locator('.monaco-editor textarea').locator('xpath=..');
+ await editorParent.click();
+ await editorParent.locator('textarea').fill('Test content for {{firstName}}');
+
+ await goBack(page);
+
+ nameInput = getByTestId(page, 'name-input');
+ await nameInput.clear();
+ await nameInput.fill('This is the new notification title');
+
+ await editChannel(page, 'inApp');
+ const feedButton = getByTestId(page, 'feed-button-1');
+ await feedButton.click();
+
+ const monacoEditor = page.locator('.monaco-editor').nth(0);
+ await monacoEditor.click();
+ await monacoEditor.press(`${modifier}+KeyX`);
+ await page.keyboard.type('new content for notification');
+
+ await goBack(page);
+
+ await updateWorkflowButtonClick(page);
+
+ await page.goto(`/workflows`);
+ const notificationsTemplate = getByTestId(page, 'notifications-template');
+ await expect(await notificationsTemplate.getByText(/This is the new notification title/)).toBeVisible();
+
+ await page.goto(`/workflows/edit/${template._id}`);
+ await editChannel(page, 'inApp');
+
+ await expect(getByTestId(page, 'feed-button-0')).toBeVisible();
+ await expect(getByTestId(page, 'feed-button-1-checked')).toBeVisible();
+ const createFeedInput = getByTestId(page, 'create-feed-input');
+ await createFeedInput.fill('test4');
+
+ const addFeedButton = getByTestId(page, 'add-feed-button');
+ await addFeedButton.click();
+ await expect(getByTestId(page, 'feed-button-2-checked')).toBeVisible();
+});
+
+test('should unset feedId for in app step', async ({ page }) => {
+ const template = session.templates[0];
+
+ await page.goto(`/workflows/edit/${template._id}`);
+ await editChannel(page, 'inApp');
+
+ let feedsCheckbox = getByTestId(page, 'use-feeds-checkbox');
+ await expect(feedsCheckbox).toBeChecked();
+ await feedsCheckbox.click();
+
+ await updateWorkflowButtonClick(page);
+
+ await page.goto(`/workflows`);
+
+ const notificationsTemplate = getByTestId(page, 'notifications-template');
+ await expect(notificationsTemplate.getByText(template.name, { exact: false })).toBeVisible();
+
+ await page.goto(`/workflows/edit/${template._id}`);
+ await editChannel(page, 'inApp');
+
+ feedsCheckbox = getByTestId(page, 'use-feeds-checkbox');
+ await expect(feedsCheckbox).not.toBeChecked();
+});
+
+test('should edit email notification', async ({ page }) => {
+ const template = session.templates[0];
+
+ await page.goto(`/workflows/edit/${template._id}`);
+ await editChannel(page, 'email');
+
+ const emailEditor = getByTestId(page, 'email-editor');
+ const firstEditorRow = getByTestId(emailEditor, 'editor-row').first();
+ await firstEditorRow.click();
+ await firstEditorRow.press(`${modifier}+KeyA`);
+ await firstEditorRow.press(`${modifier}+KeyX`);
+ await page.keyboard.type('Hello world!');
+});
+
+test('should update notification active status', async ({ page }) => {
+ const template = session.templates[0];
+
+ await page.goto(`/workflows/edit/${template._id}`);
+
+ let settingsPage = getByTestId(page, 'settings-page');
+ await settingsPage.click();
+
+ const toggleSwitch = getByTestId(page, 'active-toggle-switch');
+ await expect(toggleSwitch).toBeVisible();
+ await expect(page.getByText('Active')).toBeVisible();
+ await toggleSwitch.locator('~ label').click({ force: true });
+ await expect(page.getByText('Inactive')).toBeVisible();
+
+ await page.goto(`/workflows/edit/${template._id}`);
+
+ settingsPage = getByTestId(page, 'settings-page');
+ await settingsPage.click();
+
+ await expect(page.getByText('Inactive')).toBeVisible();
+});
+
+test('should toggle active states of channels', async ({ page }) => {
+ await page.goto(`/workflows/create`);
+
+ await fillBasicNotificationDetails(page, { title: 'Test toggle active states of channels' });
+ await goBack(page);
+
+ await addAndEditChannel(page, 'email');
+
+ let stepActiveSwitch = getByTestId(page, 'step-active-switch');
+ await expect(stepActiveSwitch).toHaveValue('on');
+
+ await stepActiveSwitch.locator('~ label').click({ force: true });
+ await stepActiveSwitch.locator('~ label').click({ force: true });
+
+ await goBack(page);
+
+ await addAndEditChannel(page, 'inApp');
+ stepActiveSwitch = getByTestId(page, 'step-active-switch');
+ await expect(stepActiveSwitch).toHaveValue('on');
+});
+
+test('should show trigger snippet block when editing', async ({ page }) => {
+ const template = session.templates[0];
+ await page.goto(`/workflows/edit/${template._id}`);
+
+ const getSnippetButton = getByTestId(page, 'get-snippet-btn');
+ await getSnippetButton.click();
+
+ const triggerCodeSnippet = getByTestId(page, 'trigger-code-snippet');
+ await expect(triggerCodeSnippet).toContainText('test-event');
+});
+
+test('should show error on node if message field is missing', async ({ page }) => {
+ await page.goto(`/workflows/create`);
+
+ await fillBasicNotificationDetails(page);
+ await goBack(page);
+
+ await dragAndDrop(page, `dnd-emailSelector`, 'addNodeButton');
+ let emailNode = getByTestId(page, 'node-emailSelector');
+ let errorCircle = getByTestId(emailNode, 'error-circle');
+ await expect(errorCircle).toBeVisible();
+
+ await editChannel(page, 'email');
+ const emailSubject = getByTestId(page, 'emailSubject');
+ await expect(emailSubject).toHaveClass(/mantine-TextInput-invalid/);
+
+ await emailSubject.fill('this is email subject');
+ await goBack(page);
+ emailNode = getByTestId(page, 'node-emailSelector');
+ errorCircle = getByTestId(emailNode, 'error-circle');
+ await expect(errorCircle).not.toBeVisible();
+});
+
+test('should allow uploading a logo from email editor', async ({ page }) => {
+ await page.route('**/organizations', async (route) => {
+ const response = await page.request.fetch(route.request());
+ const body = await response.json();
+ if (body) {
+ delete body.data[0].branding.logo;
+ }
+
+ await route.fulfill({
+ response,
+ body,
+ });
+ });
+
+ await page.goto(`/workflows/create`);
+ await fillBasicNotificationDetails(page, { title: 'Test allow uploading a logo from email editor' });
+ await goBack(page);
+
+ await addAndEditChannel(page, 'email');
+ const uploadImageButton = getByTestId(page, 'upload-image-button');
+ await uploadImageButton.click();
+
+ const modalButton = page.getByRole('button', { name: 'Yes' });
+
+ await modalButton.click();
+ await expect(page.url()).toContain('/brand');
+});
+
+test('should show the brand logo on main page', async ({ page }) => {
+ await page.goto(`/workflows/create`);
+ await fillBasicNotificationDetails(page, { title: 'Test allow uploading a logo from email editor' });
+ await goBack(page);
+
+ await addAndEditChannel(page, 'email');
+
+ const brandLogo = getByTestId(page, 'brand-logo');
+ await expect(brandLogo).toHaveAttribute('src', 'https://web.novu.co/static/images/logo-light.png');
+});
+
+test('should support RTL text content', async ({ page }) => {
+ await page.goto(`/workflows/create`);
+ await fillBasicNotificationDetails(page, { title: 'Test support RTL text content' });
+ await goBack(page);
+
+ await addAndEditChannel(page, 'email');
+
+ let editableTextContent = getByTestId(page, 'editable-text-content');
+ await editableTextContent.hover();
+ await expect(editableTextContent).toHaveCSS('text-align', 'left');
+
+ const settingsRowButton = getByTestId(page, 'settings-row-btn');
+ await settingsRowButton.click();
+
+ const alignRightButton = getByTestId(page, 'align-right-btn');
+ await alignRightButton.click();
+ editableTextContent = getByTestId(page, 'editable-text-content');
+ await expect(editableTextContent).toHaveCSS('text-align', 'right');
+});
+
+test('should create an SMS channel message', async ({ page }) => {
+ await page.goto(`/workflows/create`);
+ await fillBasicNotificationDetails(page, { title: 'Test SMS Notification Title' });
+ await goBack(page);
+
+ await addAndEditChannel(page, 'sms');
+
+ const editorParent = page.locator('.monaco-editor textarea').locator('xpath=..');
+ await editorParent.click();
+ await editorParent.locator('textarea').fill('{{firstName}} someone assigned you to {{taskName}}');
+ await goBack(page);
+
+ const submitButton = getByTestId(page, 'notification-template-submit-btn');
+ await submitButton.click();
+
+ const getSnippetButton = getByTestId(page, 'get-snippet-btn');
+ await getSnippetButton.click();
+ const workflowSidebar = getByTestId(page, 'workflow-sidebar');
+ await expect(workflowSidebar).toBeVisible();
+ const triggerCodeSnippet = getByTestId(workflowSidebar, 'trigger-code-snippet');
+ await expect(triggerCodeSnippet).toContainText('test-sms-notification-title');
+ await expect(triggerCodeSnippet).toContainText("import { Novu } from '@novu/node'");
+ await expect(triggerCodeSnippet).toContainText('taskName');
+ await expect(triggerCodeSnippet).toContainText('firstName');
+});
+
+test('should save HTML template email', async ({ page }) => {
+ await page.goto(`/workflows/create`);
+ await fillBasicNotificationDetails(page, { title: 'Custom Code HTML Notification Title' });
+ await goBack(page);
+
+ await addAndEditChannel(page, 'email');
+
+ const subjectEl = getByTestId(page, 'emailSubject');
+ await subjectEl.fill('this is email subject');
+
+ await page
+ .locator('[data-test-id="editor-type-selector"] .mantine-Tabs-tabsList')
+ .getByText(/Custom Code/)
+ .first()
+ .click();
+
+ let editorParent = page.locator('.monaco-editor textarea').locator('xpath=..');
+ await editorParent.click();
+ await editorParent.locator('textarea').fill('Hello world code {{name}} Test');
+
+ await goBack(page);
+
+ await editChannel(page, 'email');
+
+ editorParent = page.locator('.monaco-editor textarea').locator('xpath=..');
+ await editorParent.click();
+ await expect(editorParent).toContainText('Hello world code {{name}} Test');
+});
+
+test('should redirect to the workflows page when switching environments', async ({ page }) => {
+ await page.goto(`/workflows/create`);
+ await fillBasicNotificationDetails(page, { title: 'Environment Switching' });
+ await goBack(page);
+
+ await updateWorkflowButtonClick(page);
+
+ await page.goto(`/changes`);
+ const promoteChangesPromise = page.waitForResponse((response) => {
+ return !!response.url().match(/\/v1\/changes\/.*\/apply/) && response.request().method() === 'POST';
+ });
+ const promoteButton = getByTestId(page, 'promote-btn').first();
+ await promoteButton.click();
+ await promoteChangesPromise;
+
+ let environmentSwitchPromise = page.waitForResponse((response) => {
+ return !!response.url().match(/\/auth\/environments\/.*\/switch/) && response.request().method() === 'POST';
+ });
+ let environmentSwitch = getByTestId(page, 'environment-switch');
+ const productionButton = environmentSwitch.getByText('Production');
+ await productionButton.click();
+ await environmentSwitchPromise;
+ await expect(page).toHaveURL(/\/workflows/);
+
+ const notificationsTemplate = getByTestId(page, 'notifications-template');
+ await notificationsTemplate.getByText(/Environment Switching/).click();
+ await expect(page).toHaveURL(/\/workflows\/edit/);
+
+ environmentSwitchPromise = page.waitForResponse((response) => {
+ return !!response.url().match(/\/auth\/environments\/.*\/switch/) && response.request().method() === 'POST';
+ });
+ environmentSwitch = getByTestId(page, 'environment-switch');
+ const developmentButton = environmentSwitch.getByText('Development');
+ await developmentButton.click();
+ await environmentSwitchPromise;
+ await expect(page).toHaveURL(/\/workflows/);
+});
+
+test('New workflow button should be disabled in the Production', async ({ page }) => {
+ await page.goto(`/workflows`);
+
+ let environmentSwitch = getByTestId(page, 'environment-switch');
+ const productionButton = environmentSwitch.getByText('Production');
+ await productionButton.click();
+
+ const createWorkflowButton = getByTestId(page, 'create-workflow-btn');
+ await expect(createWorkflowButton).toBeDisabled();
+});
+
+test('Should not allow to go to New Template page in Production', async ({ page }) => {
+ await page.goto(`/workflows/create`);
+
+ let environmentSwitch = getByTestId(page, 'environment-switch');
+ const productionButton = environmentSwitch.getByText('Production');
+ await productionButton.click();
+
+ await expect(page.url()).toContain('/workflows');
+});
+
+test('should save Cta buttons state in inApp channel', async ({ page }) => {
+ await page.goto(`/workflows/create`);
+ await fillBasicNotificationDetails(page, { title: 'In App CTA Button' });
+ await goBack(page);
+
+ await addAndEditChannel(page, 'inApp');
+ const editorParent = page.locator('.monaco-editor textarea').locator('xpath=..');
+ await editorParent.click();
+ await editorParent.locator('textarea').fill('Text content');
+
+ const controlAdd = getByTestId(page, 'control-add').first();
+ await controlAdd.click();
+
+ const clickArea = getByTestId(page, 'template-container-click-area').first();
+ await clickArea.click();
+
+ await goBack(page);
+
+ await updateWorkflowButtonClick(page);
+
+ await page.goto(`/workflows`);
+
+ const notificationsTemplate = getByTestId(page, 'notifications-template');
+ await notificationsTemplate.getByText(/In App CTA Button/).click();
+ await expect(page.url()).toContain('/workflows/edit');
+
+ await editChannel(page, 'inApp');
+
+ const templateContainerInput = getByTestId(page, 'template-container').first().locator('input');
+ await expect(templateContainerInput).toHaveCount(1);
+
+ const removeButton = getByTestId(page, 'remove-button-icon');
+ await removeButton.click();
+
+ await goBack(page);
+
+ await editChannel(page, 'inApp');
+ getByTestId(page, 'control-add').first();
+});
+
+test('should load successfully the recently created notification template, when going back from editor -> templates list -> editor', async ({
+ page,
+}) => {
+ await page.goto(`/workflows`);
+
+ const createWorkflowButton = getByTestId(page, 'create-workflow-btn');
+ await createWorkflowButton.click();
+
+ const createBlankWorkflow = getByTestId(page, 'create-workflow-blank');
+ await createBlankWorkflow.click();
+
+ await fillBasicNotificationDetails(page, { title: 'Test notification' });
+ await goBack(page);
+
+ await addAndEditChannel(page, 'inApp');
+ const editorParent = page.locator('.monaco-editor textarea').locator('xpath=..');
+ await editorParent.click();
+ await editorParent.locator('textarea').fill('Test in-app');
+ await goBack(page);
+
+ await addAndEditChannel(page, 'email');
+ const editableText = getByTestId(page, 'editable-text-content');
+ await editableText.clear();
+ await editableText.pressSequentially('Test email');
+ const subjectEl = getByTestId(page, 'emailSubject');
+ await subjectEl.fill('this is email subject');
+ const emailPreheader = getByTestId(page, 'emailPreheader');
+ await emailPreheader.fill('this is email preheader');
+ await goBack(page);
+
+ await updateWorkflowButtonClick(page);
+
+ const workflowsLink = getByTestId(page, 'side-nav-templates-link');
+ await workflowsLink.click();
+
+ const notificationsTemplate = getByTestId(page, 'notifications-template');
+ await notificationsTemplate.getByText(/Test notification/).click();
+ await expect(page.url()).toContain('/workflows/edit');
+
+ const inAppNode = getByTestId(page, 'node-inAppSelector');
+ await expect(inAppNode).toBeVisible();
+ const emailNode = getByTestId(page, 'node-emailSelector');
+ await expect(emailNode).toBeVisible();
+});
+
+test('should load successfully the same notification template, when going back from templates list -> editor -> templates list -> editor', async ({
+ page,
+}) => {
+ await page.goto(`/workflows`);
+ const template = session.templates[0];
+
+ let notificationsTemplate = getByTestId(page, 'notifications-template');
+ await notificationsTemplate.getByText(template.name).click();
+ await expect(page.url()).toContain('/workflows/edit');
+
+ let inAppNode = getByTestId(page, 'node-inAppSelector');
+ await expect(inAppNode).toBeVisible();
+ let emailNode = getByTestId(page, 'node-emailSelector');
+ await expect(emailNode).toBeVisible();
+
+ const workflowsLink = getByTestId(page, 'side-nav-templates-link');
+ await workflowsLink.click();
+
+ notificationsTemplate = getByTestId(page, 'notifications-template');
+ await notificationsTemplate.getByText(template.name).click();
+ await expect(page.url()).toContain('/workflows/edit');
+
+ inAppNode = getByTestId(page, 'node-inAppSelector');
+ await expect(inAppNode).toBeVisible();
+ emailNode = getByTestId(page, 'node-emailSelector');
+ await expect(emailNode).toBeVisible();
+});
diff --git a/apps/web/tests/start-from-scratch-tour.spec.ts b/apps/web/tests/start-from-scratch-tour.spec.ts
new file mode 100644
index 00000000000..9463676dadb
--- /dev/null
+++ b/apps/web/tests/start-from-scratch-tour.spec.ts
@@ -0,0 +1,183 @@
+import { test, expect } from '@playwright/test';
+import os from 'node:os';
+
+import { getByTestId, initializeSession } from './utils.ts/browser';
+
+let session;
+
+test.beforeEach(async ({ context }) => {
+ session = await initializeSession(context, { showOnBoardingTour: true });
+});
+
+test('should show the start from scratch intro step', async ({ page }) => {
+ await page.goto('/workflows/create');
+
+ const scratchWorkflowTooltip = await getByTestId(page, 'scratch-workflow-tooltip');
+ await expect(scratchWorkflowTooltip).toBeVisible();
+
+ const scratchWorkflowTooltipTitle = await getByTestId(page, 'scratch-workflow-tooltip-title');
+ await expect(scratchWorkflowTooltipTitle).toHaveText('Discover a quick guide');
+
+ const scratchWorkflowTooltipDescription = await getByTestId(page, 'scratch-workflow-tooltip-description');
+ await expect(scratchWorkflowTooltipDescription).toHaveText('Four simple tips to become a workflow expert.');
+
+ const scratchWorkflowTooltipSkipButton = await getByTestId(page, 'scratch-workflow-tooltip-skip-button');
+ await expect(scratchWorkflowTooltipSkipButton).toHaveText('Watch later');
+
+ const scratchWorkflowTooltipPrimaryButton = await getByTestId(page, 'scratch-workflow-tooltip-primary-button');
+ await expect(scratchWorkflowTooltipPrimaryButton).toHaveText('Show me');
+});
+
+test('should hide the start from scratch intro step after clicking on watch later', async ({ page }) => {
+ await page.goto('/workflows/create');
+
+ const scratchWorkflowTooltip = await getByTestId(page, 'scratch-workflow-tooltip');
+ await expect(scratchWorkflowTooltip).toBeVisible();
+
+ const scratchWorkflowTooltipTitle = await getByTestId(page, 'scratch-workflow-tooltip-title');
+ await expect(scratchWorkflowTooltipTitle).toHaveText('Discover a quick guide');
+
+ const scratchWorkflowTooltipDescription = await getByTestId(page, 'scratch-workflow-tooltip-description');
+ await expect(scratchWorkflowTooltipDescription).toHaveText('Four simple tips to become a workflow expert.');
+
+ const scratchWorkflowTooltipPrimaryButton = await getByTestId(page, 'scratch-workflow-tooltip-primary-button');
+ await expect(scratchWorkflowTooltipPrimaryButton).toHaveText('Show me');
+
+ const scratchWorkflowTooltipSkipButton = await getByTestId(page, 'scratch-workflow-tooltip-skip-button');
+ await expect(scratchWorkflowTooltipSkipButton).toHaveText('Watch later');
+ await scratchWorkflowTooltipSkipButton.click();
+
+ await expect(scratchWorkflowTooltip).not.toBeVisible();
+});
+
+test('should show the start from scratch tour hints', async ({ page }) => {
+ await page.goto('/workflows/create');
+
+ const scratchWorkflowTooltip = await getByTestId(page, 'scratch-workflow-tooltip');
+ await expect(scratchWorkflowTooltip).toBeVisible();
+
+ const scratchWorkflowTooltipTitle = await getByTestId(page, 'scratch-workflow-tooltip-title');
+ await expect(scratchWorkflowTooltipTitle).toHaveText('Discover a quick guide');
+
+ const scratchWorkflowTooltipDescription = await getByTestId(page, 'scratch-workflow-tooltip-description');
+ await expect(scratchWorkflowTooltipDescription).toHaveText('Four simple tips to become a workflow expert.');
+
+ const scratchWorkflowTooltipSkipButton = await getByTestId(page, 'scratch-workflow-tooltip-skip-button');
+ await expect(scratchWorkflowTooltipSkipButton).toHaveText('Watch later');
+
+ const scratchWorkflowTooltipPrimaryButton = await getByTestId(page, 'scratch-workflow-tooltip-primary-button');
+ await expect(scratchWorkflowTooltipPrimaryButton).toHaveText('Show me');
+ await scratchWorkflowTooltipPrimaryButton.click();
+
+ const scratchWorkflowTooltipTitle2 = await getByTestId(page, 'scratch-workflow-tooltip-title');
+ await expect(scratchWorkflowTooltipTitle2).toHaveText('Click to edit workflow name');
+
+ const scratchWorkflowTooltipDescription2 = await getByTestId(page, 'scratch-workflow-tooltip-description');
+ await expect(scratchWorkflowTooltipDescription2).toHaveText(
+ 'Specify a name for your workflow here or in the workflow settings.'
+ );
+
+ const scratchWorkflowTooltipPrimaryButton2 = await getByTestId(page, 'scratch-workflow-tooltip-primary-button');
+ await expect(scratchWorkflowTooltipPrimaryButton2).toHaveText('Next');
+ await scratchWorkflowTooltipPrimaryButton2.click();
+
+ const scratchWorkflowTooltipTitle3 = await getByTestId(page, 'scratch-workflow-tooltip-title');
+ await expect(scratchWorkflowTooltipTitle3).toHaveText('Verify workflow settings');
+
+ const scratchWorkflowTooltipDescription3 = await getByTestId(page, 'scratch-workflow-tooltip-description');
+ await expect(scratchWorkflowTooltipDescription3).toHaveText(
+ 'Manage name, identifier, group and description. Set up channels, active by default.'
+ );
+
+ const scratchWorkflowTooltipPrimaryButton3 = await getByTestId(page, 'scratch-workflow-tooltip-primary-button');
+ await expect(scratchWorkflowTooltipPrimaryButton3).toHaveText('Next');
+ await scratchWorkflowTooltipPrimaryButton3.click();
+
+ const scratchWorkflowTooltipTitle4 = await getByTestId(page, 'scratch-workflow-tooltip-title');
+ await expect(scratchWorkflowTooltipTitle4).toHaveText('Build a notification workflow');
+
+ const scratchWorkflowTooltipDescription4 = await getByTestId(page, 'scratch-workflow-tooltip-description');
+ await expect(scratchWorkflowTooltipDescription4).toHaveText(
+ 'Add channels you would like to send notifications to. The channels will be inserted to the trigger snippet.'
+ );
+
+ const scratchWorkflowTooltipPrimaryButton4 = await getByTestId(page, 'scratch-workflow-tooltip-primary-button');
+ await expect(scratchWorkflowTooltipPrimaryButton4).toHaveText('Next');
+ await scratchWorkflowTooltipPrimaryButton4.click();
+
+ const scratchWorkflowTooltipTitle5 = await getByTestId(page, 'scratch-workflow-tooltip-title');
+ await expect(scratchWorkflowTooltipTitle5).toHaveText('Run a test or Get Snippet');
+
+ const scratchWorkflowTooltipDescription5 = await getByTestId(page, 'scratch-workflow-tooltip-description');
+ await expect(scratchWorkflowTooltipDescription5).toHaveText(
+ 'Test a trigger as if it was sent from your API. Deploy it to your App by copy/paste trigger snippet.'
+ );
+
+ const gotItButton = await getByTestId(page, 'scratch-workflow-tooltip-primary-button');
+ await expect(gotItButton).toHaveText('Got it');
+ await gotItButton.click();
+
+ await expect(scratchWorkflowTooltip).not.toBeVisible();
+});
+
+test('should show the dots navigation after the intro step', async ({ page }) => {
+ await page.goto('/workflows/create');
+
+ const scratchWorkflowTooltip = await getByTestId(page, 'scratch-workflow-tooltip');
+ await expect(scratchWorkflowTooltip).toBeVisible();
+
+ const scratchWorkflowTooltipTitle = await getByTestId(page, 'scratch-workflow-tooltip-title');
+ await expect(scratchWorkflowTooltipTitle).toHaveText('Discover a quick guide');
+
+ const scratchWorkflowTooltipDescription = await getByTestId(page, 'scratch-workflow-tooltip-description');
+ await expect(scratchWorkflowTooltipDescription).toHaveText('Four simple tips to become a workflow expert.');
+
+ const scratchWorkflowTooltipSkipButton = await getByTestId(page, 'scratch-workflow-tooltip-skip-button');
+ await expect(scratchWorkflowTooltipSkipButton).toHaveText('Watch later');
+
+ const scratchWorkflowTooltipPrimaryButton = await getByTestId(page, 'scratch-workflow-tooltip-primary-button');
+ await expect(scratchWorkflowTooltipPrimaryButton).toHaveText('Show me');
+ await scratchWorkflowTooltipPrimaryButton.click();
+
+ const dotsNavigation = await getByTestId(page, 'scratch-workflow-tooltip-dots-navigation');
+ await expect(dotsNavigation).toBeVisible();
+});
+
+test('should show not show the start from scratch tour hints after it is shown twice ', async ({ page }) => {
+ await page.goto('/workflows/create');
+
+ let scratchWorkflowTooltip = await getByTestId(page, 'scratch-workflow-tooltip');
+ await expect(scratchWorkflowTooltip).toBeVisible();
+
+ const scratchWorkflowTooltipTitle = await getByTestId(page, 'scratch-workflow-tooltip-title');
+ await expect(scratchWorkflowTooltipTitle).toHaveText('Discover a quick guide');
+
+ const scratchWorkflowTooltipDescription = await getByTestId(page, 'scratch-workflow-tooltip-description');
+ await expect(scratchWorkflowTooltipDescription).toHaveText('Four simple tips to become a workflow expert.');
+
+ const scratchWorkflowTooltipPrimaryButton = await getByTestId(page, 'scratch-workflow-tooltip-primary-button');
+ await expect(scratchWorkflowTooltipPrimaryButton).toHaveText('Show me');
+
+ let scratchWorkflowTooltipSkipButton = await getByTestId(page, 'scratch-workflow-tooltip-skip-button');
+ await expect(scratchWorkflowTooltipSkipButton).toHaveText('Watch later');
+ await scratchWorkflowTooltipSkipButton.click();
+
+ await expect(scratchWorkflowTooltip).not.toBeVisible();
+
+ await page.reload();
+
+ scratchWorkflowTooltip = await getByTestId(page, 'scratch-workflow-tooltip');
+ await expect(scratchWorkflowTooltip).toBeVisible();
+
+ scratchWorkflowTooltipSkipButton = await getByTestId(page, 'scratch-workflow-tooltip-skip-button');
+ await expect(scratchWorkflowTooltipSkipButton).toHaveText('Watch later');
+ await scratchWorkflowTooltipSkipButton.click();
+
+ const scratchWorkflowTooltip2 = await getByTestId(page, 'scratch-workflow-tooltip');
+ await expect(scratchWorkflowTooltip2).not.toBeVisible();
+
+ await page.reload();
+
+ scratchWorkflowTooltip = await getByTestId(page, 'scratch-workflow-tooltip');
+ await expect(scratchWorkflowTooltip).not.toBeVisible();
+});
diff --git a/apps/web/tests/utils.ts/browser.ts b/apps/web/tests/utils.ts/browser.ts
new file mode 100644
index 00000000000..1985519aa13
--- /dev/null
+++ b/apps/web/tests/utils.ts/browser.ts
@@ -0,0 +1,31 @@
+import { BrowserContext, Locator, Page } from '@playwright/test';
+
+import { getSession, ISessionOptions } from './plugins';
+
+export async function initializeSession(context: BrowserContext, settings: ISessionOptions = {}) {
+ const session = await getSession(settings);
+
+ await context.addInitScript((session) => {
+ (window as any).isPlaywright = true;
+ localStorage.setItem('auth_token', session.token);
+ }, session);
+
+ return session;
+}
+
+export function getByTestId(page: Page | Locator, selector: string, options?: Parameters[1]) {
+ return page.locator(`[data-test-id="${selector}"]`, options);
+}
+
+export async function dragAndDrop(page: Page, dragSelector: string, dropSelector: string) {
+ const dndEl = await getByTestId(page, dragSelector);
+ await dndEl.dragTo(await getByTestId(page, dropSelector), { force: true });
+}
+
+export async function isDarkTheme(page: Page) {
+ const backgroundColor = await page.evaluate(() => {
+ const body = document.body;
+ return window.getComputedStyle(body).backgroundColor;
+ });
+ return backgroundColor.toLowerCase() !== '#EDF0F2' && backgroundColor.toLowerCase() !== 'rgb(237, 240, 242)';
+}
diff --git a/apps/web/tests/utils.ts/integrations.ts b/apps/web/tests/utils.ts/integrations.ts
new file mode 100644
index 00000000000..f16ed59cfb5
--- /dev/null
+++ b/apps/web/tests/utils.ts/integrations.ts
@@ -0,0 +1,107 @@
+import { expect, Locator, Page } from '@playwright/test';
+
+import { getByTestId } from './browser';
+
+export const navigateToGetStarted = async (page: Page, card = 'channel-card-email') => {
+ await page.goto('/get-started');
+ await expect(page).toHaveURL(/\/get-started/);
+
+ const cardComponent = getByTestId(page, card);
+ const button = cardComponent.locator('button');
+ await expect(button).toContainText('Change Provider');
+ await button.click();
+
+ const integrationsModal = getByTestId(page, 'integrations-list-modal');
+ await expect(integrationsModal).toBeVisible();
+ await expect(integrationsModal).toContainText('Integrations Store');
+};
+
+export const checkTableLoading = async (page: Page | Locator) => {
+ const nameCellLoadingElements = getByTestId(page, 'integration-name-cell-loading');
+ await expect(nameCellLoadingElements).toHaveCount(10);
+ await expect(nameCellLoadingElements.first()).toBeVisible();
+
+ const providerCellLoadingElements = getByTestId(page, 'integration-provider-cell-loading');
+ await expect(providerCellLoadingElements).toHaveCount(10);
+ await expect(providerCellLoadingElements.first()).toBeVisible();
+
+ const channelCellLoadingElements = getByTestId(page, 'integration-channel-cell-loading');
+ await expect(channelCellLoadingElements).toHaveCount(10);
+ await expect(channelCellLoadingElements.first()).toBeVisible();
+
+ const envCellLoadingElements = getByTestId(page, 'integration-environment-cell-loading');
+ await expect(envCellLoadingElements).toHaveCount(10);
+ await expect(envCellLoadingElements.first()).toBeVisible();
+
+ const statusCellLoadingElements = getByTestId(page, 'integration-status-cell-loading');
+ await expect(statusCellLoadingElements).toHaveCount(10);
+ await expect(statusCellLoadingElements.first()).toBeVisible();
+};
+
+export const checkTableRow = async (
+ page: Page | Locator,
+ {
+ name,
+ isFree,
+ provider,
+ channel,
+ environment,
+ status,
+ }: {
+ name: string;
+ isFree?: boolean;
+ provider: string;
+ channel: string;
+ environment?: string;
+ status: string;
+ }
+) => {
+ const integrationsTable = getByTestId(page, 'integrations-list-table');
+ const nthRow = integrationsTable.locator('tbody tr', { hasText: new RegExp(`${name}.*${environment ?? ''}`) });
+ const nameCell = getByTestId(nthRow, 'integration-name-cell', { hasText: name });
+ await expect(nameCell).toBeVisible();
+
+ if (isFree) {
+ await expect(nameCell).toContainText('Test Provider');
+ }
+
+ const providerCell = getByTestId(nthRow, 'integration-provider-cell', { hasText: provider });
+ await expect(providerCell).toBeVisible();
+
+ const channelCell = getByTestId(nthRow, 'integration-channel-cell', { hasText: channel });
+ await expect(channelCell).toBeVisible();
+
+ if (environment) {
+ const environmentCell = getByTestId(nthRow, 'integration-environment-cell', { hasText: environment });
+ await expect(environmentCell).toBeVisible();
+ }
+
+ const statusCell = getByTestId(nthRow, 'integration-status-cell', { hasText: status });
+ await expect(statusCell).toBeVisible();
+};
+
+export const clickOnListRow = async (page: Page | Locator, name: string | RegExp) => {
+ const integrationsTable = getByTestId(page, 'integrations-list-table');
+ const row = integrationsTable.locator('tr', { hasText: name }).first();
+ await expect(row).toBeVisible();
+ await row.click();
+};
+
+export async function interceptIntegrationsRequest({
+ page,
+ modifyBody,
+}: {
+ page: Page;
+ modifyBody?: (body: any) => any;
+}) {
+ return page.route('**/v1/integrations', async (route) => {
+ const response = await page.request.fetch(route.request());
+ await new Promise((resolve) => setTimeout(resolve, 3000));
+ const body = await response.json();
+
+ await route.fulfill({
+ response,
+ body: JSON.stringify(modifyBody ? modifyBody(body) : body),
+ });
+ });
+}
diff --git a/apps/web/tests/utils.ts/plugins.ts b/apps/web/tests/utils.ts/plugins.ts
new file mode 100644
index 00000000000..013a6dfaa42
--- /dev/null
+++ b/apps/web/tests/utils.ts/plugins.ts
@@ -0,0 +1,122 @@
+import { DalService, IntegrationRepository, NotificationTemplateEntity } from '@novu/dal';
+import { ChannelTypeEnum, ProvidersIdEnum } from '@novu/shared';
+import {
+ UserSession,
+ NotificationTemplateService,
+ SubscribersService,
+ NotificationsService,
+ JobsService,
+} from '@novu/testing';
+
+export interface ISessionOptions {
+ noEnvironment?: boolean;
+ partialTemplate?: Partial;
+ noTemplates?: boolean;
+ showOnBoardingTour?: boolean;
+}
+
+export async function getSession(settings: ISessionOptions = {}) {
+ const dal = new DalService();
+ await dal.connect(process.env.MONGODB_URL ?? '');
+
+ const session = new UserSession('http://127.0.0.1:1336');
+ await session.initialize({
+ noEnvironment: settings?.noEnvironment,
+ showOnBoardingTour: settings?.showOnBoardingTour,
+ });
+
+ const notificationTemplateService = new NotificationTemplateService(
+ session.user._id,
+ session.organization._id,
+ session.environment._id as string
+ );
+
+ let templates;
+ if (!settings?.noTemplates) {
+ const templatePartial = settings?.partialTemplate || {};
+
+ templates = await Promise.all([
+ notificationTemplateService.createTemplate({ ...(templatePartial as any) }),
+ notificationTemplateService.createTemplate({
+ active: false,
+ draft: true,
+ }),
+ notificationTemplateService.createTemplate(),
+ notificationTemplateService.createTemplate(),
+ notificationTemplateService.createTemplate(),
+ notificationTemplateService.createTemplate(),
+ ]);
+ }
+
+ return {
+ token: session.token.split(' ')[1],
+ user: session.user,
+ organization: session.organization,
+ environment: session.environment,
+ templates,
+ };
+}
+
+export async function deleteProvider(query: {
+ providerId: ProvidersIdEnum;
+ channel: ChannelTypeEnum;
+ environmentId: string;
+ organizationId: string;
+}) {
+ const dal = new DalService();
+ await dal.connect(process.env.MONGODB_URL ?? '');
+
+ const repository = new IntegrationRepository();
+
+ return await repository.deleteMany({
+ channel: query.channel,
+ providerId: query.providerId,
+ _environmentId: query.environmentId,
+ _organizationId: query.organizationId,
+ });
+}
+
+export async function createNotifications({
+ identifier,
+ token,
+ count = 1,
+ subscriberId,
+ environmentId,
+ organizationId,
+ templateId,
+}: {
+ identifier: string;
+ token: string;
+ count?: number;
+ subscriberId?: string;
+ environmentId: string;
+ organizationId: string;
+ templateId?: string;
+}) {
+ const jobsService = new JobsService();
+ let subId = subscriberId;
+ if (!subId) {
+ const subscribersService = new SubscribersService(organizationId, environmentId);
+ const subscriber = await subscribersService.createSubscriber();
+ subId = subscriber.subscriberId;
+ }
+
+ const triggerIdentifier = identifier;
+ const service = new NotificationsService(token);
+ const session = new UserSession(process.env.API_URL);
+
+ // eslint-disable-next-line no-plusplus
+ for (let i = 0; i < count; i++) {
+ await service.triggerEvent(triggerIdentifier, subId, {});
+ }
+
+ if (organizationId) {
+ await session.awaitRunningJobs(templateId, undefined, 0, organizationId);
+ }
+
+ while ((await jobsService.standardQueue.getWaitingCount()) || (await jobsService.standardQueue.getActiveCount())) {
+ await new Promise((resolve) => setTimeout(resolve, 50));
+ }
+
+ return 'ok';
+}
diff --git a/apps/web/tests/utils.ts/workflow-editor.ts b/apps/web/tests/utils.ts/workflow-editor.ts
new file mode 100644
index 00000000000..90ab651843e
--- /dev/null
+++ b/apps/web/tests/utils.ts/workflow-editor.ts
@@ -0,0 +1,61 @@
+import { Page } from '@playwright/test';
+
+import { dragAndDrop, getByTestId } from './browser';
+
+export type Channel = 'inApp' | 'email' | 'sms' | 'chat' | 'push' | 'digest' | 'delay';
+
+export async function fillBasicNotificationDetails(
+ page: Page,
+ { title, description }: { title?: string; description?: string } = {}
+) {
+ const settings = await getByTestId(page, 'settings-page');
+ await settings.click();
+
+ const titleEl = await getByTestId(page, 'title');
+ await titleEl.first().clear();
+ await titleEl.first().fill(title ?? 'Test Notification Title');
+
+ const descriptionEl = await getByTestId(page, 'description');
+ await descriptionEl.fill(description ?? 'This is a test description for a test title');
+}
+
+export async function goBack(page: Page) {
+ const closeButton = await getByTestId(page, 'sidebar-close');
+ await closeButton.click();
+}
+
+export async function editChannel(page: Page, channel: Channel) {
+ const stepNode = await getByTestId(page, `node-${channel}Selector`);
+ await stepNode.last().click();
+
+ if (['inApp', 'email', 'sms', 'chat', 'push'].includes(channel)) {
+ const sidebarComponent = await getByTestId(page, 'step-editor-sidebar');
+ const editButton = await getByTestId(sidebarComponent, 'edit-action');
+ await editButton.click();
+ }
+}
+
+export async function addAndEditChannel(page: Page, channel: Channel) {
+ await dragAndDrop(page, `dnd-${channel}Selector`, 'addNodeButton');
+ await editChannel(page, channel);
+}
+
+export async function updateWorkflowButtonClick(page: Page, { noWaitAfter = false }: { noWaitAfter?: boolean } = {}) {
+ if (noWaitAfter) {
+ const updateWorkflowButton = getByTestId(page, 'notification-template-submit-btn');
+ await updateWorkflowButton.click();
+
+ return;
+ }
+
+ const updateTemplateRequest = page.waitForResponse((response) => {
+ return response.url().match(/\/v1\/notification-templates\/.*/) && response.request().method() === 'PUT';
+ });
+ const getTemplateRequest = page.waitForResponse((response) => {
+ return response.url().match(/\/v1\/notification-templates\/.*/) && response.request().method() === 'GET';
+ });
+ let updateWorkflowButton = getByTestId(page, 'notification-template-submit-btn');
+ await updateWorkflowButton.click();
+ await updateTemplateRequest;
+ await getTemplateRequest;
+}
diff --git a/apps/webhook/package.json b/apps/webhook/package.json
index 10fff80369a..00845628c8c 100644
--- a/apps/webhook/package.json
+++ b/apps/webhook/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/webhook",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "",
"author": "",
"private": true,
@@ -26,11 +26,11 @@
"@nestjs/core": "^10.2.2",
"@nestjs/platform-express": "^10.2.2",
"@nestjs/terminus": "^10.0.1",
- "@novu/application-generic": "^0.24.0",
- "@novu/dal": "^0.24.0",
- "@novu/shared": "^0.24.0",
- "@novu/stateless": "^0.24.0",
- "@novu/testing": "^0.24.0",
+ "@novu/application-generic": "^0.24.1",
+ "@novu/dal": "^0.24.1",
+ "@novu/shared": "^0.24.1",
+ "@novu/stateless": "^0.24.1",
+ "@novu/testing": "^0.24.1",
"@sentry/node": "^7.66.0",
"axios": "^1.6.2",
"class-transformer": "^0.5.1",
diff --git a/apps/webhook/src/app.module.ts b/apps/webhook/src/app.module.ts
index 079c6b0b52b..7c6fab5b756 100644
--- a/apps/webhook/src/app.module.ts
+++ b/apps/webhook/src/app.module.ts
@@ -19,7 +19,7 @@ const modules = [
SharedModule,
HealthModule,
WebhooksModule,
- TracingModule.register(packageJson.name),
+ TracingModule.register(packageJson.name, packageJson.version),
ProfilingModule.register(packageJson.name),
LoggerModule.forRoot(
createNestLoggingModuleOptions({
diff --git a/apps/webhook/src/health/health.controller.ts b/apps/webhook/src/health/health.controller.ts
index cf7335561f3..93310ed892f 100644
--- a/apps/webhook/src/health/health.controller.ts
+++ b/apps/webhook/src/health/health.controller.ts
@@ -12,14 +12,12 @@ export class HealthController {
@HealthCheck()
async healthCheck(): Promise {
const result = await this.healthCheckService.check([
- async () => {
- return {
- apiVersion: {
- version,
- status: 'up',
- },
- };
- },
+ async () => ({
+ apiVersion: {
+ version,
+ status: 'up',
+ },
+ }),
() => this.dalHealthIndicator.isHealthy(),
]);
diff --git a/apps/widget/cypress/e2e/notifications-list.spec.ts b/apps/widget/cypress/e2e/notifications-list.spec.ts
index e7a24666b19..5aadb6ef2f6 100644
--- a/apps/widget/cypress/e2e/notifications-list.spec.ts
+++ b/apps/widget/cypress/e2e/notifications-list.spec.ts
@@ -191,18 +191,9 @@ describe('Notifications List', function () {
scrollToBottom();
cy.getByTestId('notification-list-item').should('have.length', 26);
- cy.getByTestId('notification-list-item')
- .should('exist')
- .each(($item, $index) => {
- const notificationContentNumber = 20 - $index > 0 ? ' ' + (20 - $index).toString() : '';
- cy.wrap($item)
- .invoke('text')
- .then((text) => {
- if ($index !== 0) {
- expect(text).to.contains(`John${notificationContentNumber}`);
- }
- });
- });
+ for (let i = 0; i < 21; i++) {
+ cy.getByTestId('notification-list-item').contains(`John ${i}`).should('exist');
+ }
});
});
diff --git a/apps/widget/package.json b/apps/widget/package.json
index e59d929fa03..0e5575e2207 100644
--- a/apps/widget/package.json
+++ b/apps/widget/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/widget",
- "version": "0.24.0",
+ "version": "0.24.1",
"private": true,
"scripts": {
"start": "react-app-rewired start",
@@ -29,8 +29,8 @@
"@emotion/styled": "^11.6.0",
"@mantine/core": "4.2.12",
"@mantine/hooks": "4.2.12",
- "@novu/notification-center": "^0.24.0",
- "@novu/shared": "^0.24.0",
+ "@novu/notification-center": "^0.24.1",
+ "@novu/shared": "^0.24.1",
"antd": "^4.10.0",
"babel-plugin-import": "^1.13.3",
"chroma-js": "^2.4.2",
@@ -63,8 +63,8 @@
"@emotion/react": "^11.7.1",
"@emotion/styled": "^11.6.0",
"@faker-js/faker": "^6.0.0",
- "@novu/dal": "^0.24.0",
- "@novu/testing": "^0.24.0",
+ "@novu/dal": "^0.24.1",
+ "@novu/testing": "^0.24.1",
"@types/jest": "^29.5.0",
"@types/node": "^12.0.0",
"@types/react": "^17.0.0",
diff --git a/apps/worker/package.json b/apps/worker/package.json
index 0514b00c93e..63dcae3c0fb 100644
--- a/apps/worker/package.json
+++ b/apps/worker/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/worker",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "description",
"author": "",
"private": "true",
@@ -30,11 +30,11 @@
"@nestjs/platform-express": "^10.2.2",
"@nestjs/swagger": "^7.1.9",
"@nestjs/terminus": "^10.0.1",
- "@novu/application-generic": "^0.24.0",
- "@novu/dal": "^0.24.0",
- "@novu/shared": "^0.24.0",
- "@novu/stateless": "^0.24.0",
- "@novu/testing": "^0.24.0",
+ "@novu/application-generic": "^0.24.1",
+ "@novu/dal": "^0.24.1",
+ "@novu/shared": "^0.24.1",
+ "@novu/stateless": "^0.24.1",
+ "@novu/testing": "^0.24.1",
"@sentry/node": "^7.40.0",
"@sentry/tracing": "^7.40.0",
"@types/newrelic": "^9.13.0",
@@ -84,10 +84,10 @@
"typescript": "4.9.5"
},
"optionalDependencies": {
- "@novu/ee-chimera-connect": "^0.24.0",
- "@novu/ee-auth": "^0.24.0",
- "@novu/ee-billing": "^0.24.0",
- "@novu/ee-translation": "^0.24.0"
+ "@novu/ee-chimera-connect": "^0.24.1",
+ "@novu/ee-auth": "^0.24.1",
+ "@novu/ee-billing": "^0.24.1",
+ "@novu/ee-translation": "^0.24.1"
},
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
diff --git a/apps/worker/src/.env.test b/apps/worker/src/.env.test
index 75042df4b1b..f7eea5a5d35 100644
--- a/apps/worker/src/.env.test
+++ b/apps/worker/src/.env.test
@@ -79,6 +79,7 @@ LAUNCH_DARKLY_SDK_KEY=
AUTO_CREATE_INDEXES=true
IS_USE_MERGED_DIGEST_ID_ENABLED=true
+IS_TOPIC_NOTIFICATION_ENABLED=true
BROADCAST_QUEUE_CHUNK_SIZE=100
MULTICAST_QUEUE_CHUNK_SIZE=100
diff --git a/apps/worker/src/app/health/health.controller.ts b/apps/worker/src/app/health/health.controller.ts
index 1a71031996d..0363132e47e 100644
--- a/apps/worker/src/app/health/health.controller.ts
+++ b/apps/worker/src/app/health/health.controller.ts
@@ -21,14 +21,12 @@ export class HealthController {
return this.healthCheckService.check([
async () => this.dalHealthIndicator.isHealthy(),
...this.healthIndicators.map((indicator) => async () => indicator.isHealthy()),
- async () => {
- return {
- apiVersion: {
- version,
- status: 'up',
- },
- };
- },
+ async () => ({
+ apiVersion: {
+ version,
+ status: 'up',
+ },
+ }),
]);
}
}
diff --git a/apps/worker/src/app/workflow/services/active-jobs-metric.service.ts b/apps/worker/src/app/workflow/services/active-jobs-metric.service.ts
index ab27231edc2..96f73db8f0e 100644
--- a/apps/worker/src/app/workflow/services/active-jobs-metric.service.ts
+++ b/apps/worker/src/app/workflow/services/active-jobs-metric.service.ts
@@ -1,3 +1,5 @@
+const nr = require('newrelic');
+
import {
ActiveJobsMetricQueueService,
ActiveJobsMetricWorkerService,
@@ -75,7 +77,11 @@ export class ActiveJobsMetricService {
return undefined;
})
- .catch((error) => Logger.error('Metric Job Exists function errored', LOG_CONTEXT, error));
+ .catch((error) => {
+ nr.noticeError(error);
+
+ Logger.error('Metric Job Exists function errored', LOG_CONTEXT, error);
+ });
}
private getWorkerOptions(): WorkerOptions {
diff --git a/apps/worker/src/app/workflow/services/execution-log.worker.ts b/apps/worker/src/app/workflow/services/execution-log.worker.ts
index bf5ab242f08..cef1b40e3f0 100644
--- a/apps/worker/src/app/workflow/services/execution-log.worker.ts
+++ b/apps/worker/src/app/workflow/services/execution-log.worker.ts
@@ -48,7 +48,9 @@ export class ExecutionLogWorker extends ExecutionLogWorkerService {
_this.createExecutionDetails
.execute(data)
.then(resolve)
- .catch(reject)
+ .catch((e) => {
+ reject(e);
+ })
.finally(() => {
transaction.end();
});
diff --git a/apps/worker/src/app/workflow/services/standard.worker.ts b/apps/worker/src/app/workflow/services/standard.worker.ts
index e619f08584a..a797a0c44c5 100644
--- a/apps/worker/src/app/workflow/services/standard.worker.ts
+++ b/apps/worker/src/app/workflow/services/standard.worker.ts
@@ -153,6 +153,8 @@ export class StandardWorker extends StandardWorkerService {
private async jobHasFailed(job: Job, error: Error): Promise {
let jobId;
+ nr.noticeError(error);
+
try {
const minimalData = this.extractMinimalJobData(job.data);
jobId = minimalData.jobId;
diff --git a/apps/worker/src/app/workflow/services/subscriber-process.worker.ts b/apps/worker/src/app/workflow/services/subscriber-process.worker.ts
index 70621545d0c..96f39c6b60b 100644
--- a/apps/worker/src/app/workflow/services/subscriber-process.worker.ts
+++ b/apps/worker/src/app/workflow/services/subscriber-process.worker.ts
@@ -46,6 +46,7 @@ export class SubscriberProcessWorker extends SubscriberProcessWorkerService {
.then(resolve)
.catch((e) => {
Logger.error(e, 'unexpected error', 'SubscriberProcessWorkerService - getWorkerProcessor');
+ nr.noticeError(e);
reject(e);
})
diff --git a/apps/worker/src/app/workflow/services/workflow.worker.ts b/apps/worker/src/app/workflow/services/workflow.worker.ts
index d52eeec1a3a..f13cb3b5e22 100644
--- a/apps/worker/src/app/workflow/services/workflow.worker.ts
+++ b/apps/worker/src/app/workflow/services/workflow.worker.ts
@@ -51,7 +51,10 @@ export class WorkflowWorker extends WorkflowWorkerService {
_this.triggerEventUsecase
.execute(data)
.then(resolve)
- .catch(reject)
+ .catch((e) => {
+ nr.noticeError(e);
+ reject(e);
+ })
.finally(() => {
transaction.end();
});
diff --git a/apps/worker/src/app/workflow/usecases/send-message/digest/digest.usecase.ts b/apps/worker/src/app/workflow/usecases/send-message/digest/digest.usecase.ts
index 342a055c0b3..28e1827ca9d 100644
--- a/apps/worker/src/app/workflow/usecases/send-message/digest/digest.usecase.ts
+++ b/apps/worker/src/app/workflow/usecases/send-message/digest/digest.usecase.ts
@@ -71,11 +71,13 @@ export class Digest extends SendMessageType {
})
);
+ const jobsToUpdate = [...nextJobs.map((job) => job._id), command.job._id];
+
await this.jobRepository.update(
{
_environmentId: command.environmentId,
_id: {
- $in: nextJobs.map((job) => job._id),
+ $in: jobsToUpdate,
},
},
{
diff --git a/apps/worker/src/app/workflow/usecases/send-message/send-message-email.usecase.ts b/apps/worker/src/app/workflow/usecases/send-message/send-message-email.usecase.ts
index be6e0b75302..b251200d156 100644
--- a/apps/worker/src/app/workflow/usecases/send-message/send-message-email.usecase.ts
+++ b/apps/worker/src/app/workflow/usecases/send-message/send-message-email.usecase.ts
@@ -453,7 +453,7 @@ export class SendMessageEmail extends SendMessageBase {
message,
'error',
'mail_unexpected_error',
- 'Error while sending email with provider',
+ error.message || error.name || 'Error while sending email with provider',
command,
LogCodeEnum.MAIL_PROVIDER_DELIVERY_ERROR,
error
@@ -468,7 +468,7 @@ export class SendMessageEmail extends SendMessageBase {
status: ExecutionDetailsStatusEnum.FAILED,
isTest: false,
isRetry: false,
- raw: JSON.stringify(error),
+ raw: JSON.stringify(error) === '{}' ? JSON.stringify({ message: error.message }) : JSON.stringify(error),
})
);
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 5cfe288974a..febe515fcca 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
@@ -88,13 +88,16 @@ export class SendMessage {
const stepType = command.step?.template?.type;
- const chimeraResponse = await this.chimeraConnector.execute<
- SendMessageCommand & { variables: IFilterVariables },
- ExecuteOutput | null
- >({
- ...command,
- variables: shouldRun.variables,
- });
+ let chimeraResponse: ExecuteOutput | null = null;
+ if (!['digest', 'delay'].includes(stepType as any)) {
+ chimeraResponse = await this.chimeraConnector.execute<
+ SendMessageCommand & { variables: IFilterVariables },
+ ExecuteOutput | null
+ >({
+ ...command,
+ variables: shouldRun.variables,
+ });
+ }
if (!command.payload?.$on_boarding_trigger) {
const usedFilters = shouldRun?.conditions.reduce(ConditionsFilter.sumFilters, {
diff --git a/apps/ws/package.json b/apps/ws/package.json
index ae5ee302efe..b07212bc1a0 100644
--- a/apps/ws/package.json
+++ b/apps/ws/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/ws",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
- "@novu/dal": "^0.24.0",
- "@novu/shared": "^0.24.0",
- "@novu/testing": "^0.24.0",
+ "@novu/application-generic": "^0.24.1",
+ "@novu/dal": "^0.24.1",
+ "@novu/shared": "^0.24.1",
+ "@novu/testing": "^0.24.1",
"@sentry/node": "^7.30.0",
"@socket.io/redis-adapter": "^7.2.0",
"class-transformer": "^0.5.1",
diff --git a/apps/ws/src/app.module.ts b/apps/ws/src/app.module.ts
index 1762244d937..1cc7423e305 100644
--- a/apps/ws/src/app.module.ts
+++ b/apps/ws/src/app.module.ts
@@ -19,7 +19,7 @@ import * as packageJson from '../package.json';
const modules = [
SharedModule,
HealthModule,
- TracingModule.register(packageJson.name),
+ TracingModule.register(packageJson.name, packageJson.version),
ProfilingModule.register(packageJson.name),
SocketModule,
LoggerModule.forRoot(
diff --git a/apps/ws/src/health/health.controller.ts b/apps/ws/src/health/health.controller.ts
index 26ac141ed20..92eb672d6b2 100644
--- a/apps/ws/src/health/health.controller.ts
+++ b/apps/ws/src/health/health.controller.ts
@@ -23,14 +23,12 @@ export class HealthController {
...indicatorHealthCheckFunctions,
async () => this.dalHealthIndicator.isHealthy(),
async () => this.wsServerHealthIndicator.isHealthy(),
- async () => {
- return {
- apiVersion: {
- version,
- status: 'up',
- },
- };
- },
+ async () => ({
+ apiVersion: {
+ version,
+ status: 'up',
+ },
+ }),
]);
return result;
diff --git a/apps/ws/src/shared/subscriber-online/subscriber-online.service.ts b/apps/ws/src/shared/subscriber-online/subscriber-online.service.ts
index 513e6578767..8a68cd02ab5 100644
--- a/apps/ws/src/shared/subscriber-online/subscriber-online.service.ts
+++ b/apps/ws/src/shared/subscriber-online/subscriber-online.service.ts
@@ -30,7 +30,7 @@ export class SubscriberOnlineService {
private async updateOnlineStatus(subscriber: ISubscriberJwt, updatePayload: IUpdateSubscriberPayload) {
await this.subscriberRepository.update(
- { _id: subscriber._id, _organizationId: subscriber.organizationId },
+ { _id: subscriber._id, _environmentId: subscriber.environmentId },
{
$set: updatePayload,
}
diff --git a/apps/ws/src/socket/services/ws-server-health-indicator.service.ts b/apps/ws/src/socket/services/ws-server-health-indicator.service.ts
index 46d29d955ae..892e7dc07ae 100644
--- a/apps/ws/src/socket/services/ws-server-health-indicator.service.ts
+++ b/apps/ws/src/socket/services/ws-server-health-indicator.service.ts
@@ -1,4 +1,4 @@
-import { HealthIndicator, HealthIndicatorResult } from '@nestjs/terminus';
+import { HealthCheckError, HealthIndicator, HealthIndicatorResult } from '@nestjs/terminus';
import { Injectable } from '@nestjs/common';
import { IHealthIndicator } from '@novu/application-generic';
@@ -7,16 +7,21 @@ import { WSGateway } from '../ws.gateway';
@Injectable()
export class WSServerHealthIndicator extends HealthIndicator implements IHealthIndicator {
- private INDICATOR_KEY = 'ws-server';
+ private static KEY = 'ws-server';
constructor(private wsGateway: WSGateway) {
super();
}
async isHealthy(): Promise {
- const status = !!this.wsGateway.server;
+ const isHealthy = !!this.wsGateway.server;
+ const result = this.getStatus(WSServerHealthIndicator.KEY, isHealthy);
- return this.getStatus(this.INDICATOR_KEY, status);
+ if (isHealthy) {
+ return result;
+ }
+
+ throw new HealthCheckError('WS server health check failed', result);
}
isActive(): Promise {
diff --git a/enterprise/packages/auth/package.json b/enterprise/packages/auth/package.json
index 1f00e70b814..92368af56a5 100644
--- a/enterprise/packages/auth/package.json
+++ b/enterprise/packages/auth/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/ee-auth",
- "version": "0.24.0",
+ "version": "0.24.1",
"private": true,
"main": "dist/index.js",
"scripts": {
@@ -12,9 +12,9 @@
"test-ee": "cross-env TS_NODE_COMPILER_OPTIONS='{\"strictNullChecks\": false}' TZ=UTC NODE_ENV=test E2E_RUNNER=true mocha --timeout 10000 --require ts-node/register --exit --file tests/setup.ts src/**/**/*.spec.ts"
},
"dependencies": {
- "@novu/application-generic": "^0.24.0",
- "@novu/dal": "^0.24.0",
- "@novu/shared": "^0.24.0",
+ "@novu/application-generic": "^0.24.1",
+ "@novu/dal": "^0.24.1",
+ "@novu/shared": "^0.24.1",
"passport-google-oauth": "^2.0.0"
},
"devDependencies": {
diff --git a/enterprise/packages/billing-web/package.json b/enterprise/packages/billing-web/package.json
index 07b2f12454d..6500bf3ab2e 100644
--- a/enterprise/packages/billing-web/package.json
+++ b/enterprise/packages/billing-web/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/ee-billing-web",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "",
"repository": "https://github.com/novuhq/novu",
"license": "ISC",
@@ -30,10 +30,10 @@
"@emotion/styled": "^11.6.0",
"@mantine/core": "^5.7.1",
"@mantine/hooks": "^5.7.1",
- "@novu/client": "^0.24.0",
- "@novu/design-system": "^0.24.0",
- "@novu/shared": "^0.24.0",
- "@novu/shared-web": "^0.24.0",
+ "@novu/client": "^0.24.1",
+ "@novu/design-system": "^0.24.1",
+ "@novu/shared": "^0.24.1",
+ "@novu/shared-web": "^0.24.1",
"@rjsf/chakra-ui": "^5.17.1",
"@rjsf/core": "^5.17.1",
"@rjsf/utils": "^5.17.1",
diff --git a/enterprise/packages/billing/package.json b/enterprise/packages/billing/package.json
index d7019d977b1..f3a7367443d 100644
--- a/enterprise/packages/billing/package.json
+++ b/enterprise/packages/billing/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/ee-billing",
- "version": "0.24.0",
+ "version": "0.24.1",
"private": true,
"main": "dist/index.js",
"scripts": {
@@ -15,9 +15,9 @@
"dependencies": {
"@nestjs/swagger": "^7.1.8",
"@nestjs/throttler": "^5.0.1",
- "@novu/application-generic": "^0.24.0",
- "@novu/ee-dal": "^0.24.0",
- "@novu/shared": "^0.24.0",
+ "@novu/application-generic": "^0.24.1",
+ "@novu/ee-dal": "^0.24.1",
+ "@novu/shared": "^0.24.1",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
"date-fns": "^2.29.2",
@@ -43,6 +43,6 @@
"@nestjs/common": "10.2.2",
"@nestjs/jwt": "10.2.0",
"@nestjs/platform-express": "^10.2.2",
- "@novu/dal": "^0.24.0"
+ "@novu/dal": "^0.24.1"
}
}
diff --git a/enterprise/packages/chimera-connect/package.json b/enterprise/packages/chimera-connect/package.json
index 69c1afe9aa3..55d2ae757b9 100644
--- a/enterprise/packages/chimera-connect/package.json
+++ b/enterprise/packages/chimera-connect/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/ee-chimera-connect",
- "version": "0.24.0",
+ "version": "0.24.1",
"private": true,
"main": "dist/index.js",
"scripts": {
@@ -12,11 +12,11 @@
"test-ee": "cross-env TS_NODE_COMPILER_OPTIONS='{\"strictNullChecks\": false}' TZ=UTC NODE_ENV=test E2E_RUNNER=true mocha --timeout 10000 --require ts-node/register --exit --file tests/setup.ts src/**/**/*.spec.ts"
},
"dependencies": {
- "@novu/ee-dal": "^0.24.0",
- "@novu/stateless": "^0.24.0",
- "@novu/dal": "^0.24.0",
- "@novu/shared": "^0.24.0",
- "@novu/testing": "^0.24.0",
+ "@novu/ee-dal": "^0.24.1",
+ "@novu/stateless": "^0.24.1",
+ "@novu/dal": "^0.24.1",
+ "@novu/shared": "^0.24.1",
+ "@novu/testing": "^0.24.1",
"axios": "^1.6.2",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
diff --git a/enterprise/packages/chimera/package.json b/enterprise/packages/chimera/package.json
index f2889d6aa00..860d8137523 100644
--- a/enterprise/packages/chimera/package.json
+++ b/enterprise/packages/chimera/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/ee-chimera",
- "version": "0.24.0",
+ "version": "0.24.1",
"private": true,
"main": "dist/index.js",
"scripts": {
@@ -12,12 +12,12 @@
"test-ee": "cross-env TS_NODE_COMPILER_OPTIONS='{\"strictNullChecks\": false}' TZ=UTC NODE_ENV=test E2E_RUNNER=true mocha --timeout 10000 --require ts-node/register --exit --file tests/setup.ts src/**/**/*.spec.ts"
},
"dependencies": {
- "@novu/application-generic": "^0.24.0",
- "@novu/dal": "^0.24.0",
- "@novu/ee-dal": "^0.24.0",
- "@novu/shared": "^0.24.0",
- "@novu/stateless": "^0.24.0",
- "@novu/testing": "^0.24.0",
+ "@novu/application-generic": "^0.24.1",
+ "@novu/dal": "^0.24.1",
+ "@novu/ee-dal": "^0.24.1",
+ "@novu/shared": "^0.24.1",
+ "@novu/stateless": "^0.24.1",
+ "@novu/testing": "^0.24.1",
"axios": "^1.6.2",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
diff --git a/enterprise/packages/libs/dal/package.json b/enterprise/packages/libs/dal/package.json
index 18bef58e056..33a01e3629e 100644
--- a/enterprise/packages/libs/dal/package.json
+++ b/enterprise/packages/libs/dal/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/ee-dal",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "",
"private": true,
"scripts": {
@@ -18,8 +18,8 @@
"license": "ISC",
"main": "dist/index.js",
"dependencies": {
- "@novu/dal": "^0.24.0",
- "@novu/shared": "^0.24.0",
+ "@novu/dal": "^0.24.1",
+ "@novu/shared": "^0.24.1",
"mongoose": "^7.5.0",
"mongoose-delete": "^1.0.1",
"rimraf": "^3.0.2"
diff --git a/enterprise/packages/translation-web/package.json b/enterprise/packages/translation-web/package.json
index 7149da3fe92..d58fecae031 100644
--- a/enterprise/packages/translation-web/package.json
+++ b/enterprise/packages/translation-web/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/ee-translation-web",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "",
"repository": "https://github.com/novuhq/novu",
"license": "ISC",
@@ -33,10 +33,10 @@
"@mantine/hooks": "^5.7.1",
"@mantine/prism": "^5.7.1",
"@monaco-editor/react": "^4.6.0",
- "@novu/client": "^0.24.0",
- "@novu/design-system": "^0.24.0",
- "@novu/shared": "^0.24.0",
- "@novu/shared-web": "^0.24.0",
+ "@novu/client": "^0.24.1",
+ "@novu/design-system": "^0.24.1",
+ "@novu/shared": "^0.24.1",
+ "@novu/shared-web": "^0.24.1",
"@tanstack/react-query": "^4.20.4",
"axios": "^1.4.0",
"date-fns": "^2.29.2",
diff --git a/enterprise/packages/translation/package.json b/enterprise/packages/translation/package.json
index b73c052af72..9b737ff7c69 100644
--- a/enterprise/packages/translation/package.json
+++ b/enterprise/packages/translation/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/ee-translation",
- "version": "0.24.0",
+ "version": "0.24.1",
"private": true,
"main": "dist/index.js",
"scripts": {
@@ -14,9 +14,9 @@
"dependencies": {
"@handlebars/parser": "^2.1.0",
"@nestjs/swagger": "^7.1.8",
- "@novu/application-generic": "^0.24.0",
- "@novu/ee-dal": "^0.24.0",
- "@novu/shared": "^0.24.0",
+ "@novu/application-generic": "^0.24.1",
+ "@novu/ee-dal": "^0.24.1",
+ "@novu/shared": "^0.24.1",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
"multer": "^1.4.5-lts.1",
@@ -41,6 +41,6 @@
"@nestjs/common": "10.2.2",
"@nestjs/jwt": "10.2.0",
"@nestjs/platform-express": "^10.2.2",
- "@novu/dal": "^0.24.0"
+ "@novu/dal": "^0.24.1"
}
}
diff --git a/enterprise/packages/web/echo/.eslintrc.js b/enterprise/packages/web/echo/.eslintrc.js
new file mode 100644
index 00000000000..2f449acbcd9
--- /dev/null
+++ b/enterprise/packages/web/echo/.eslintrc.js
@@ -0,0 +1,43 @@
+module.exports = {
+ rules: {
+ 'func-names': 'off',
+ 'react/jsx-props-no-spreading': 'off',
+ 'react/no-array-index-key': 'off',
+ 'no-empty-pattern': 'off',
+ '@typescript-eslint/explicit-module-boundary-types': 'off',
+ 'react/no-unescaped-entities': 'off',
+ 'react/jsx-closing-bracket-location': 'off',
+ '@typescript-eslint/ban-types': 'off',
+ 'react/jsx-wrap-multilines': 'off',
+ 'jsx-a11y/anchor-is-valid': 'off',
+ 'promise/catch-or-return': 'off',
+ 'react/jsx-one-expression-per-line': 'off',
+ '@typescript-eslint/no-explicit-any': 'off',
+ 'jsx-a11y/aria-role': 'off',
+ 'jsx-a11y/no-static-element-interactions': 'off',
+ 'react/require-default-props': 'off',
+ 'react/no-danger': 'off',
+ 'jsx-a11y/click-events-have-key-events': 'off',
+ '@typescript-eslint/naming-convention': [
+ 'error',
+ {
+ filter: '_',
+ selector: 'variableLike',
+ leadingUnderscore: 'allow',
+ format: ['PascalCase', 'camelCase', 'UPPER_CASE'],
+ },
+ ],
+ '@typescript-eslint/no-empty-function': 'off',
+ },
+ env: {
+ 'cypress/globals': true,
+ },
+ ignorePatterns: ['craco.config.js', 'cypress/*'],
+ extends: ['plugin:cypress/recommended', '../../../.eslintrc.js'],
+ plugins: ['cypress'],
+ parserOptions: {
+ project: './tsconfig.json',
+ ecmaVersion: 2020,
+ sourceType: 'module',
+ },
+};
diff --git a/enterprise/packages/web/echo/.gitignore b/enterprise/packages/web/echo/.gitignore
new file mode 100644
index 00000000000..013add19d46
--- /dev/null
+++ b/enterprise/packages/web/echo/.gitignore
@@ -0,0 +1,28 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/.pnp
+.pnp.js
+
+# testing
+/coverage
+
+
+# production
+build
+dist
+
+.npmrc
+.idea/*
+.nyc_output
+
+test
+
+src/**.js
+coverage
+*.log
+package-lock.json
+
+storybook-static
+
diff --git a/enterprise/packages/web/echo/check-ee.mjs b/enterprise/packages/web/echo/check-ee.mjs
new file mode 100644
index 00000000000..0db73052ff4
--- /dev/null
+++ b/enterprise/packages/web/echo/check-ee.mjs
@@ -0,0 +1,65 @@
+import spawn from 'cross-spawn';
+import { fileURLToPath } from 'url';
+import path from 'path';
+import * as fs from 'fs';
+const dirname = path.dirname(fileURLToPath(import.meta.url));
+
+const ROOT_PATH = path.resolve(dirname);
+const ENCODING_TYPE = 'utf8';
+const NEW_LINE_CHAR = '\n';
+
+class CliLogs {
+ constructor() {
+ this._logs = [];
+ this.log = this.log.bind(this);
+ }
+
+ log(log) {
+ const cleanLog = log.trim();
+ if (cleanLog.length) {
+ this._logs.push(cleanLog);
+ }
+ }
+
+ get logs() {
+ return this._logs;
+ }
+
+ get joinedLogs() {
+ return this.logs.join(NEW_LINE_CHAR);
+ }
+}
+
+function pnpmRun(...args) {
+ const logData = new CliLogs();
+ let pnpmProcess;
+
+ return new Promise((resolve, reject) => {
+ const processOptions = {
+ cwd: ROOT_PATH,
+ env: process.env,
+ };
+
+ pnpmProcess = spawn('pnpm', args, processOptions);
+
+ pnpmProcess.stdin.setEncoding(ENCODING_TYPE);
+ pnpmProcess.stdout.setEncoding(ENCODING_TYPE);
+ pnpmProcess.stderr.setEncoding(ENCODING_TYPE);
+ pnpmProcess.stdout.on('data', logData.log);
+ pnpmProcess.stderr.on('data', logData.log);
+
+ pnpmProcess.on('close', (code) => {
+ if (code !== 0) {
+ reject(logData.joinedLogs);
+ } else {
+ resolve(logData.joinedLogs);
+ }
+ });
+ });
+}
+
+const hasSrcFolder = fs.existsSync(path.resolve(ROOT_PATH, 'src'));
+if (hasSrcFolder) {
+ await pnpmRun('build:esm');
+ await pnpmRun('build:types');
+}
diff --git a/enterprise/packages/web/echo/package.json b/enterprise/packages/web/echo/package.json
new file mode 100644
index 00000000000..4262b7a49de
--- /dev/null
+++ b/enterprise/packages/web/echo/package.json
@@ -0,0 +1,54 @@
+{
+ "name": "@novu/ee-echo-web",
+ "version": "0.24.1",
+ "description": "",
+ "repository": "https://github.com/novuhq/novu",
+ "license": "ISC",
+ "author": "",
+ "private": true,
+ "sideEffects": false,
+ "module": "dist/esm/index.js",
+ "types": "dist/types/index.d.ts",
+ "files": [
+ "dist/esm"
+ ],
+ "scripts": {
+ "prebuild": "rimraf dist",
+ "build": "node ./check-ee.mjs",
+ "build:esm": "cross-env node_modules/.bin/tsc -p tsconfig.esm.json",
+ "build:esm:watch": "cross-env node_modules/.bin/tsc -p tsconfig.esm.json -w --preserveWatchOutput",
+ "build:types": "tsc --declaration --emitDeclarationOnly --declarationMap --declarationDir dist/types -p tsconfig.json",
+ "build:watch": "npm run build:esm:watch",
+ "lint": "eslint --ext .ts,.tsx src --no-error-on-unmatched-pattern",
+ "test": "echo 'skip test in the ci'",
+ "start": "npm run build:watch"
+ },
+ "dependencies": {
+ "@mantine/core": "^5.7.1",
+ "@mantine/hooks": "^5.7.1",
+ "@novu/design-system": "^0.24.1",
+ "@novu/shared-web": "^0.24.1",
+ "@rjsf/core": "^5.17.1",
+ "@rjsf/validator-ajv8": "^5.17.1",
+ "@tanstack/react-query": "^4.20.4",
+ "react-router-dom": "6.2.2",
+ "tslib": "^2.3.1"
+ },
+ "devDependencies": {
+ "eslint": "^8.33.0",
+ "eslint-plugin-react-hooks": "^4.4.0",
+ "@types/node": "^18.11.12",
+ "@types/react": "^17.0.0",
+ "@types/react-dom": "^17.0.0",
+ "react": "^17.0.1",
+ "react-dom": "^17.0.1",
+ "rimraf": "^3.0.2",
+ "ts-loader": "~9.4.0",
+ "tslib": "^2.3.1",
+ "typescript": "4.9.5"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0"
+ }
+}
diff --git a/enterprise/packages/web/echo/src b/enterprise/packages/web/echo/src
new file mode 120000
index 00000000000..7edcb0e30e4
--- /dev/null
+++ b/enterprise/packages/web/echo/src
@@ -0,0 +1 @@
+../../../../.source/web/echo/src
\ No newline at end of file
diff --git a/enterprise/packages/web/echo/tsconfig.esm.json b/enterprise/packages/web/echo/tsconfig.esm.json
new file mode 100644
index 00000000000..48e68b0620b
--- /dev/null
+++ b/enterprise/packages/web/echo/tsconfig.esm.json
@@ -0,0 +1,7 @@
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "module": "ESNext",
+ "outDir": "./dist/esm"
+ }
+}
diff --git a/enterprise/packages/web/echo/tsconfig.json b/enterprise/packages/web/echo/tsconfig.json
new file mode 100644
index 00000000000..59907bb89b1
--- /dev/null
+++ b/enterprise/packages/web/echo/tsconfig.json
@@ -0,0 +1,34 @@
+{
+ "include": [
+ "src"
+ ],
+ "extends": "../../../../tsconfig.json",
+ "compilerOptions": {
+ "outDir": "./dist/cjs",
+ "forceConsistentCasingInFileNames": true,
+ "target": "es6",
+ "strict": true,
+ "typeRoots": [
+ "./node_modules/@types"
+ ],
+ "jsx": "react",
+ "module": "commonjs",
+ "lib": [
+ "ESNext",
+ "dom"
+ ],
+ "skipLibCheck": true,
+ "declaration": false,
+ "declarationMap": false,
+ "sourceMap": true,
+ "removeComments": false,
+ "allowSyntheticDefaultImports": true,
+ "baseUrl": "."
+ },
+ "exclude": [
+ "src/**/*.test.*",
+ "src/*.test.*",
+ "node_modules",
+ "**/node_modules/*"
+ ]
+}
diff --git a/lerna.json b/lerna.json
index 7fe0be67c6b..ea0c8406a56 100644
--- a/lerna.json
+++ b/lerna.json
@@ -8,5 +8,5 @@
"message": "chore(release): publish - ci skip"
}
},
- "version": "0.24.0"
+ "version": "0.24.1"
}
diff --git a/libs/dal/package.json b/libs/dal/package.json
index 1f2ed28a6fd..b5491c777ca 100644
--- a/libs/dal/package.json
+++ b/libs/dal/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/dal",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
+ "@novu/shared": "^0.24.1",
"JSONStream": "^1.3.5",
"archiver": "^5.0.0",
"async": "^3.2.0",
diff --git a/libs/dal/src/repositories/change/change.schema.ts b/libs/dal/src/repositories/change/change.schema.ts
index a3bc9f9ae6f..ad4e64605f6 100644
--- a/libs/dal/src/repositories/change/change.schema.ts
+++ b/libs/dal/src/repositories/change/change.schema.ts
@@ -23,7 +23,7 @@ const changeSchema = new Schema(
type: Schema.Types.ObjectId,
ref: 'Organization',
},
- _entityId: Schema.Types.ObjectId,
+ _entityId: { type: Schema.Types.ObjectId, index: true },
_creatorId: {
type: Schema.Types.ObjectId,
ref: 'User',
diff --git a/libs/dal/src/repositories/environment/environment.schema.ts b/libs/dal/src/repositories/environment/environment.schema.ts
index 9e8dd637713..f973cc63f28 100644
--- a/libs/dal/src/repositories/environment/environment.schema.ts
+++ b/libs/dal/src/repositories/environment/environment.schema.ts
@@ -15,7 +15,6 @@ const environmentSchema = new Schema(
_organizationId: {
type: Schema.Types.ObjectId,
ref: 'Organization',
- index: true,
},
apiKeys: [
{
@@ -60,6 +59,22 @@ const environmentSchema = new Schema(
schemaOptions
);
+/*
+ * Path: ./get-platform-notification-usage.usecase.ts
+ * Context: execute()
+ * Query: organizationRepository.aggregate(
+ * $lookup:
+ * {
+ * from: 'environments',
+ * localField: '_id',
+ * foreignField: '_organizationId',
+ * as: 'environments',
+ * }
+ */
+environmentSchema.index({
+ _organizationId: 1,
+});
+
// eslint-disable-next-line @typescript-eslint/naming-convention
export const Environment =
(mongoose.models.Environment as mongoose.Model) ||
diff --git a/libs/dal/src/repositories/integration/integration.schema.ts b/libs/dal/src/repositories/integration/integration.schema.ts
index fe689fea143..bec9530f52a 100644
--- a/libs/dal/src/repositories/integration/integration.schema.ts
+++ b/libs/dal/src/repositories/integration/integration.schema.ts
@@ -15,7 +15,6 @@ const integrationSchema = new Schema(
_organizationId: {
type: Schema.Types.ObjectId,
ref: 'Organization',
- index: true,
},
providerId: Schema.Types.String,
channel: Schema.Types.String,
@@ -95,6 +94,11 @@ const integrationSchema = new Schema(
schemaOptions
);
+integrationSchema.index({
+ _organizationId: 1,
+ active: 1,
+});
+
integrationSchema.plugin(mongooseDelete, { deletedAt: true, deletedBy: true, overrideMethods: 'all' });
// eslint-disable-next-line @typescript-eslint/naming-convention
diff --git a/libs/dal/src/repositories/layout/layout.schema.ts b/libs/dal/src/repositories/layout/layout.schema.ts
index 6a936ffb97b..4713a4b60b5 100644
--- a/libs/dal/src/repositories/layout/layout.schema.ts
+++ b/libs/dal/src/repositories/layout/layout.schema.ts
@@ -10,6 +10,7 @@ const layoutSchema = new Schema(
_environmentId: {
type: Schema.Types.ObjectId,
ref: 'Environment',
+ index: true,
},
_organizationId: {
type: Schema.Types.ObjectId,
diff --git a/libs/dal/src/repositories/message-template/message-template.schema.ts b/libs/dal/src/repositories/message-template/message-template.schema.ts
index 514566289bb..04ec1cbc60c 100644
--- a/libs/dal/src/repositories/message-template/message-template.schema.ts
+++ b/libs/dal/src/repositories/message-template/message-template.schema.ts
@@ -89,6 +89,10 @@ messageTemplateSchema.index({
'triggers.identifier': 1,
});
+messageTemplateSchema.index({
+ _parentId: 1,
+});
+
messageTemplateSchema.plugin(mongooseDelete, { deletedAt: true, deletedBy: true, overrideMethods: 'all' });
// eslint-disable-next-line @typescript-eslint/naming-convention
diff --git a/libs/dal/src/repositories/notification-template/notification-template.repository.ts b/libs/dal/src/repositories/notification-template/notification-template.repository.ts
index 9bc69f81f34..7f1c84e8832 100644
--- a/libs/dal/src/repositories/notification-template/notification-template.repository.ts
+++ b/libs/dal/src/repositories/notification-template/notification-template.repository.ts
@@ -56,7 +56,10 @@ export class NotificationTemplateRepository extends BaseRepository<
_id: id,
};
- const item = await this.MongooseModel.findOne(requestQuery).populate('steps.template').lean();
+ const item = await this.MongooseModel.findOne(requestQuery)
+ .populate('steps.template')
+ .populate('notificationGroup')
+ .lean();
return this.mapEntity(item);
}
@@ -70,7 +73,10 @@ export class NotificationTemplateRepository extends BaseRepository<
triggers: { $elemMatch: { identifier: identifier } },
};
- const item = await this.MongooseModel.findOne(requestQuery).populate('steps.template').lean();
+ const item = await this.MongooseModel.findOne(requestQuery)
+ .populate('steps.template')
+ .populate('notificationGroup')
+ .lean();
return this.mapEntity(item);
}
diff --git a/libs/dal/src/repositories/notification/notification.schema.ts b/libs/dal/src/repositories/notification/notification.schema.ts
index a9c50e2c4d9..61f560233a7 100644
--- a/libs/dal/src/repositories/notification/notification.schema.ts
+++ b/libs/dal/src/repositories/notification/notification.schema.ts
@@ -10,26 +10,21 @@ const notificationSchema = new Schema(
_templateId: {
type: Schema.Types.ObjectId,
ref: 'NotificationTemplate',
- index: true,
},
_environmentId: {
type: Schema.Types.ObjectId,
ref: 'Environment',
- index: true,
},
_organizationId: {
type: Schema.Types.ObjectId,
ref: 'Organization',
- index: true,
},
_subscriberId: {
type: Schema.Types.ObjectId,
ref: 'Subscriber',
- index: true,
},
transactionId: {
type: Schema.Types.String,
- index: true,
},
channels: [
{
@@ -140,6 +135,18 @@ notificationSchema.index({
* _environmentId: this.convertStringToObjectId(environmentId),
* createdAt: {$gte: monthBefore}
* weekly: { $sum: { $cond: [{ $gte: ['$createdAt', weekBefore] }, 1, 0] } },
+ *
+ *
+ * Path: ./get-platform-notification-usage.usecase.ts
+ * Context: execute()
+ * Query: organizationRepository.aggregate(
+ * $lookup:
+ * {
+ * from: 'notifications',
+ * localField: 'environments._id',
+ * foreignField: '_environmentId',
+ * as: 'notifications',
+ * }
*/
notificationSchema.index({
_environmentId: 1,
diff --git a/libs/dal/src/repositories/organization/organization.entity.ts b/libs/dal/src/repositories/organization/organization.entity.ts
index 2d5790fcec4..23669ad663d 100644
--- a/libs/dal/src/repositories/organization/organization.entity.ts
+++ b/libs/dal/src/repositories/organization/organization.entity.ts
@@ -30,6 +30,8 @@ export class OrganizationEntity implements IOrganizationEntity {
createdAt: string;
updatedAt: string;
+
+ externalId?: string;
}
export type OrganizationDBModel = OrganizationEntity;
diff --git a/libs/dal/src/repositories/organization/organization.repository.ts b/libs/dal/src/repositories/organization/organization.repository.ts
index 3d4cf08280b..1c5392590f1 100644
--- a/libs/dal/src/repositories/organization/organization.repository.ts
+++ b/libs/dal/src/repositories/organization/organization.repository.ts
@@ -1,4 +1,4 @@
-import { IPartnerConfiguration, OrganizationEntity, OrganizationDBModel } from './organization.entity';
+import { IPartnerConfiguration, OrganizationDBModel, OrganizationEntity } from './organization.entity';
import { BaseRepository } from '../base-repository';
import { Organization } from './organization.schema';
import { MemberRepository } from '../member';
@@ -12,25 +12,24 @@ export class OrganizationRepository extends BaseRepository {
- const data = await this.MongooseModel.findById(id, select);
+ const data = await this.MongooseModel.findById(id, select).read('secondaryPreferred');
if (!data) return null;
return this.mapEntity(data.toObject());
}
- async findOrganizationById(organizationId: string): Promise {
- const data = await this.MongooseModel.findById(organizationId).read('secondaryPreferred');
- if (!data) return null;
+ async findUserActiveOrganizations(userId: string): Promise {
+ const organizationIds = await this.getUsersMembersOrganizationIds(userId);
- return this.mapEntity(data.toObject());
+ return await this.find({
+ _id: { $in: organizationIds },
+ });
}
- async findUserActiveOrganizations(userId: string): Promise {
+ private async getUsersMembersOrganizationIds(userId: string): Promise {
const members = await this.memberRepository.findUserActiveMembers(userId);
- return await this.find({
- _id: members.map((member) => member._organizationId),
- });
+ return members.map((member) => member._organizationId);
}
async updateBrandingDetails(organizationId: string, branding: { color: string; logo: string }) {
@@ -73,11 +72,11 @@ export class OrganizationRepository extends BaseRepository member._organizationId),
+ _id: { $in: organizationIds },
'partnerConfigurations.configurationId': configurationId,
},
{ 'partnerConfigurations.$': 1 }
@@ -85,11 +84,11 @@ export class OrganizationRepository extends BaseRepository member._organizationId),
+ _id: { $in: organizationIds },
},
{
$push: {
@@ -100,11 +99,10 @@ export class OrganizationRepository extends BaseRepository, configurationId: string) {
- const members = await this.memberRepository.findUserActiveMembers(userId);
- const allOrgs = members.map((member) => member._organizationId);
+ const organizationIds = await this.getUsersMembersOrganizationIds(userId);
const usedOrgIds = Object.keys(data);
- const unusedOrgIds = allOrgs.filter((org) => !usedOrgIds.includes(org));
- const bulkWriteOps = allOrgs.map((orgId) => {
+ const unusedOrgIds = organizationIds.filter((org) => !usedOrgIds.includes(org));
+ const bulkWriteOps = organizationIds.map((orgId) => {
return {
updateOne: {
filter: { _id: orgId, 'partnerConfigurations.configurationId': configurationId },
diff --git a/libs/dal/src/repositories/organization/organization.schema.ts b/libs/dal/src/repositories/organization/organization.schema.ts
index 86113eb7936..90dbdac2ad3 100644
--- a/libs/dal/src/repositories/organization/organization.schema.ts
+++ b/libs/dal/src/repositories/organization/organization.schema.ts
@@ -60,6 +60,7 @@ const organizationSchema = new Schema(
default: false,
},
},
+ externalId: Schema.Types.String,
},
schemaOptions
);
diff --git a/libs/dal/src/repositories/subscriber/subscriber.repository.ts b/libs/dal/src/repositories/subscriber/subscriber.repository.ts
index 3c2fd22aa85..5fc6defe3eb 100644
--- a/libs/dal/src/repositories/subscriber/subscriber.repository.ts
+++ b/libs/dal/src/repositories/subscriber/subscriber.repository.ts
@@ -10,6 +10,8 @@ import type { EnforceEnvOrOrgIds } from '../../types';
import { EnvironmentId, ISubscribersDefine, OrganizationId } from '@novu/shared';
type SubscriberQuery = FilterQuery & EnforceEnvOrOrgIds;
+type SubscriberDeleteQuery = Pick & EnforceEnvOrOrgIds;
+type SubscriberDeleteManyQuery = Pick & EnforceEnvOrOrgIds;
export class SubscriberRepository extends BaseRepository {
private subscriber: SoftDeleteModel;
@@ -151,21 +153,31 @@ export class SubscriberRepository extends BaseRepository(
{
_organizationId: {
type: Schema.Types.ObjectId,
ref: 'Organization',
- index: true,
},
_environmentId: {
type: Schema.Types.ObjectId,
ref: 'Environment',
- index: true,
},
firstName: Schema.Types.String,
lastName: Schema.Types.String,
@@ -165,11 +164,24 @@ subscriberSchema.index({
* subscriberId: /on-boarding-subscriber/i,
* });
*/
-subscriberSchema.index({
- subscriberId: 1,
- _environmentId: 1,
- _id: 1,
-});
+
+/*
+ * This index needs to be unique and exclude "_id" to prevent duplicate subscribers during concurrent creation attempts.
+ * This situation could occur if two attempts are made to create a subscriber with the same subscriberId (e.g., 2022) simultaneously.
+ * We want to ensure that the _id field is not included in the index to avoid scenarios where MongoDB's unique validation fails to prevent duplicates, such as:
+ * subscriberId_2022:environmentId_123:_id_123
+ * subscriberId_2022:environmentId_123:_id_1234
+ * We expect an exception to be thrown when attempting to create two subscribers with the same subscriberId (e.g., 2022) within the same environment.
+ *
+ * We can not add `deleted` field to the index the client wont be able to delete twice subscriber with the same subscriberId.
+ */
+index(
+ {
+ subscriberId: 1,
+ _environmentId: 1,
+ },
+ { unique: true }
+);
subscriberSchema.plugin(mongooseDelete, { deletedAt: true, deletedBy: true, overrideMethods: 'all' });
@@ -177,3 +189,7 @@ subscriberSchema.plugin(mongooseDelete, { deletedAt: true, deletedBy: true, over
export const Subscriber =
(mongoose.models.Subscriber as mongoose.Model) ||
mongoose.model('Subscriber', subscriberSchema);
+
+function index(fields: IndexDefinition, options?: IndexOptions) {
+ subscriberSchema.index(fields, options);
+}
diff --git a/libs/dal/src/repositories/user/user.entity.ts b/libs/dal/src/repositories/user/user.entity.ts
index 3cf131ac94c..d1dce167702 100644
--- a/libs/dal/src/repositories/user/user.entity.ts
+++ b/libs/dal/src/repositories/user/user.entity.ts
@@ -53,6 +53,8 @@ export class UserEntity implements IUserEntity {
servicesHashes?: { intercom?: string };
jobTitle?: JobTitleEnum;
+
+ externalId?: string;
}
export type UserDBModel = UserEntity;
diff --git a/libs/dal/src/repositories/user/user.schema.ts b/libs/dal/src/repositories/user/user.schema.ts
index 26541b276c1..8d55b3909cc 100644
--- a/libs/dal/src/repositories/user/user.schema.ts
+++ b/libs/dal/src/repositories/user/user.schema.ts
@@ -41,6 +41,7 @@ const userSchema = new Schema(
intercom: Schema.Types.String,
},
jobTitle: Schema.Types.String,
+ externalId: Schema.Types.String,
},
schemaOptions
);
diff --git a/libs/dal/src/shared/types/index.ts b/libs/dal/src/shared/types/index.ts
new file mode 100644
index 00000000000..4686f8ab840
--- /dev/null
+++ b/libs/dal/src/shared/types/index.ts
@@ -0,0 +1 @@
+export * from './index.type';
diff --git a/libs/dal/src/shared/types/index.type.ts b/libs/dal/src/shared/types/index.type.ts
new file mode 100644
index 00000000000..9a14db2cab2
--- /dev/null
+++ b/libs/dal/src/shared/types/index.type.ts
@@ -0,0 +1,3 @@
+import { IndexDirection } from 'mongoose';
+
+export type IndexDefinition = Partial>;
diff --git a/libs/dal/src/types/error.enum.ts b/libs/dal/src/types/error.enum.ts
new file mode 100644
index 00000000000..aa09fcf046f
--- /dev/null
+++ b/libs/dal/src/types/error.enum.ts
@@ -0,0 +1,3 @@
+export enum ErrorCodesEnum {
+ DUPLICATE_KEY = '11000',
+}
diff --git a/libs/dal/src/types/index.ts b/libs/dal/src/types/index.ts
index 75cb418f741..e05844d67f1 100644
--- a/libs/dal/src/types/index.ts
+++ b/libs/dal/src/types/index.ts
@@ -1,3 +1,4 @@
export * from './enforce';
export * from './helpers';
export * from './results';
+export * from './error.enum';
diff --git a/libs/design-system/.gitignore b/libs/design-system/.gitignore
index 1b5e637ef2d..0a8b383a027 100644
--- a/libs/design-system/.gitignore
+++ b/libs/design-system/.gitignore
@@ -27,4 +27,7 @@ storybook-static
## Panda
styled-system
-styled-system-studio
\ No newline at end of file
+styled-system-studio
+
+# react-scanner
+src/component-audit/component-scans
diff --git a/libs/design-system/.storybook/NovuTheme.tsx b/libs/design-system/.storybook/NovuTheme.tsx
new file mode 100644
index 00000000000..d8f509b6114
--- /dev/null
+++ b/libs/design-system/.storybook/NovuTheme.tsx
@@ -0,0 +1,23 @@
+import { ThemeVarsPartial } from '@storybook/theming';
+import { create } from '@storybook/theming/create';
+
+const themeBase: ThemeVarsPartial = {
+ base: 'light',
+ brandTitle: 'Novu Design System',
+ brandTarget: '_self',
+}
+/**
+ * Novu Design System theme for Storybook
+ *
+ * @see https://storybook.js.org/docs/configure/theming
+ */
+export const lightTheme = create({
+ ...themeBase,
+ brandImage: './novu-logo-light.svg',
+});
+
+export const darkTheme = create({
+ ...themeBase,
+ base: 'dark',
+ brandImage: './novu-logo-dark.svg',
+});
diff --git a/libs/design-system/.storybook/main.js b/libs/design-system/.storybook/main.ts
similarity index 75%
rename from libs/design-system/.storybook/main.js
rename to libs/design-system/.storybook/main.ts
index a1e2ad206ab..d28b5b1dcfe 100644
--- a/libs/design-system/.storybook/main.js
+++ b/libs/design-system/.storybook/main.ts
@@ -1,5 +1,7 @@
import { dirname, join } from 'path';
-module.exports = {
+import { StorybookConfig } from '@storybook/react-webpack5';
+
+export default {
stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
addons: [
@@ -10,7 +12,7 @@ module.exports = {
],
framework: {
- name: getAbsolutePath('@storybook/react-webpack5'),
+ name: '@storybook/react-webpack5',
options: {},
},
@@ -21,7 +23,9 @@ module.exports = {
docs: {
autodocs: true,
},
-};
+
+ staticDirs: ['./public'],
+} satisfies StorybookConfig;
function getAbsolutePath(value) {
return dirname(require.resolve(join(value, 'package.json')));
diff --git a/libs/design-system/.storybook/manager-head.html b/libs/design-system/.storybook/manager-head.html
new file mode 100644
index 00000000000..62499dd0581
--- /dev/null
+++ b/libs/design-system/.storybook/manager-head.html
@@ -0,0 +1 @@
+
diff --git a/libs/design-system/.storybook/preview.jsx b/libs/design-system/.storybook/preview.tsx
similarity index 69%
rename from libs/design-system/.storybook/preview.jsx
rename to libs/design-system/.storybook/preview.tsx
index 75a12da9c8b..f51174ac66d 100644
--- a/libs/design-system/.storybook/preview.jsx
+++ b/libs/design-system/.storybook/preview.tsx
@@ -4,15 +4,18 @@ import { DARK_MODE_EVENT_NAME } from 'storybook-dark-mode';
import { ThemeProvider } from '../src/ThemeProvider';
import { DocsContainer } from './Doc.container';
import { useLocalThemePreference } from '@novu/shared-web';
+import { lightTheme, darkTheme } from './NovuTheme';
+import { Parameters, Decorator } from '@storybook/react'
// Bring in the Panda-generated stylesheets
import '../styled-system/styles.css';
-export const parameters = {
+export const parameters: Parameters = {
layout: 'fullscreen',
viewMode: 'docs',
docs: {
- container: DocsContainer,
+ // @TODO: fix the container context
+ // container: DocsContainer,
},
actions: { argTypesRegex: '^on[A-Z].*' },
controls: {
@@ -21,6 +24,12 @@ export const parameters = {
date: /Date$/,
},
},
+ darkMode: {
+ // Override the default dark theme
+ dark: darkTheme,
+ // Override the default light theme
+ light: lightTheme
+ }
};
const channel = addons.getChannel();
@@ -43,4 +52,4 @@ function ColorSchemeThemeWrapper({ children }) {
);
}
-export const decorators = [(renderStory) => {renderStory()} ];
+export const decorators: Decorator[] = [(renderStory) => {renderStory()} ];
diff --git a/libs/design-system/.storybook/public/favicon.svg b/libs/design-system/.storybook/public/favicon.svg
new file mode 100644
index 00000000000..b7046b6bb99
--- /dev/null
+++ b/libs/design-system/.storybook/public/favicon.svg
@@ -0,0 +1,3 @@
+
diff --git a/libs/design-system/.storybook/public/novu-logo-dark.svg b/libs/design-system/.storybook/public/novu-logo-dark.svg
new file mode 100644
index 00000000000..cbe6662e368
--- /dev/null
+++ b/libs/design-system/.storybook/public/novu-logo-dark.svg
@@ -0,0 +1,13 @@
+
diff --git a/libs/design-system/.storybook/public/novu-logo-light.svg b/libs/design-system/.storybook/public/novu-logo-light.svg
new file mode 100644
index 00000000000..2c80902b29c
--- /dev/null
+++ b/libs/design-system/.storybook/public/novu-logo-light.svg
@@ -0,0 +1,13 @@
+
diff --git a/libs/design-system/package.json b/libs/design-system/package.json
index fdda4438a7e..290591cb20d 100644
--- a/libs/design-system/package.json
+++ b/libs/design-system/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/design-system",
- "version": "0.24.0",
+ "version": "0.24.1",
"repository": "https://github.com/novuhq/novu",
"description": "",
"private": true,
@@ -16,7 +16,9 @@
"dist/types"
],
"scripts": {
- "prepare": "panda codegen --clean",
+ "prepare": "pnpm prepare:panda && pnpm prepare:audit",
+ "prepare:panda": "panda codegen --clean",
+ "prepare:audit": "pnpm audit-components",
"start": "npm run build:watch",
"prebuild": "rimraf dist",
"lint": "eslint --ext .ts,.tsx src",
@@ -28,11 +30,12 @@
"build:esm:watch": "cross-env node_modules/.bin/tsc -p tsconfig.esm.json -w --preserveWatchOutput",
"build:types": "tsc --declaration --emitDeclarationOnly --declarationMap --declarationDir dist/types -p tsconfig.json",
"storybook": "pnpm panda --watch & storybook dev -p 6006",
- "build-storybook": "storybook build",
+ "build-storybook": "pnpm panda && storybook build",
"cypress:install": "cypress install",
"cypress:open": "cross-env NODE_ENV=test cypress open",
"cypress:run": "cross-env NODE_OPTIONS=--max_old_space_size=4096 NODE_ENV=test cypress run --component",
- "test": "vitest"
+ "test": "vitest",
+ "audit-components": "pnpm react-scanner -c './react-scanner.config.js'"
},
"dependencies": {
"@cypress/react": "^7.0.3",
@@ -42,9 +45,9 @@
"@mantine/core": "^5.7.1",
"@mantine/hooks": "^5.7.1",
"@mantine/notifications": "^5.7.1",
- "@novu/client": "^0.24.0",
- "@novu/shared": "^0.24.0",
- "@novu/shared-web": "^0.24.0",
+ "@novu/client": "^0.24.1",
+ "@novu/shared": "^0.24.1",
+ "@novu/shared-web": "^0.24.1",
"@segment/analytics-next": "1.59.0",
"@sentry/react": "^7.40.0",
"@tanstack/react-query": "^4.20.4",
@@ -80,6 +83,7 @@
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-router-dom": "6.2.2",
+ "react-scanner": "^1.1.0",
"rimraf": "^3.0.2",
"storybook": "^7.4.2",
"ts-loader": "~9.4.0",
@@ -93,5 +97,14 @@
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0",
"react-dom": "^16.8.0 || ^17.0.0"
+ },
+ "nx": {
+ "targets": {
+ "build-storybook": {
+ "dependsOn": ["^build"],
+ "outputs": ["{projectRoot}/storybook-static"],
+ "inputs": ["{projectRoot}/.storybook", "{projectRoot}/src"]
+ }
+ }
}
}
diff --git a/libs/design-system/react-scanner.config.js b/libs/design-system/react-scanner.config.js
new file mode 100644
index 00000000000..16615ba23c9
--- /dev/null
+++ b/libs/design-system/react-scanner.config.js
@@ -0,0 +1,153 @@
+/**
+ * Configuration file for react-scanner: https://github.com/moroshko/react-scanner
+ *
+ * Used to assess usage of Mantine and Design System components in web.
+ *
+ * To use:
+ * 1. Run `pnpm audit-components`
+ * 2. Check `OUTPUT_PATH` for your scan results!
+ */
+
+/** the path of the scan output */
+const OUTPUT_PATH = './src/component-audit/component-scans';
+const OUTPUT_FILE_NAME = 'scan';
+const OUTPUT_FILE_EXTENSION = 'json';
+
+/**
+ * @param {string} suffix Optional filename suffix
+ * @returns file path for the output file
+ */
+const getOutputFilePath = (suffix) => {
+ return `${OUTPUT_PATH}/${OUTPUT_FILE_NAME}${suffix ?? ''}.${OUTPUT_FILE_EXTENSION}`;
+};
+
+const NOVU_ICON_REGEX = /^Icon(?!Button)[A-Z0-9]{1}[a-zA-Z0-9]+$/;
+const RELATIVE_PATH_REGEX = /^(\.(\.){0,}\/)/;
+const ANTD_ICON_MODULE_NAME = '@ant-design/icons';
+
+const COMPONENT_NAME_EXCLUSION_REGEX = /^web\/.*(Page|Container|Provider|Sidebar|Modal)$/;
+
+module.exports = {
+ /** directory to scan */
+ crawlFrom: '../../apps/web/src/',
+ includeSubComponents: true,
+ /**
+ * Regex for determining which imports to include.
+ * Currently includes: novu, antd, mantine, and local imports
+ *
+ * To see only local imports, replace with: /(\.(\.){0,}\/.*)/gim
+ */
+ importedFrom:
+ /(@novu\/(design-system|shared-web|notification-center)|@mantine\/core|@ant-design)(\/[a-z0-9\-)]+){0,}|(\.(\.){0,}\/.*)/gim,
+ exclude: ['/src/api', '/src/styled-system'],
+ processors: [countComponentsAndPropsProcessor({ minNumInstances: 1 }), groupByNamespaceProcessor],
+ /** file patterns to scan */
+ globs: ['**/!(*.test|*.spec|*.stories).@(js|ts)x'],
+ /** function for naming components -- we use the returned name as the "group by" key. */
+ getComponentName,
+};
+
+function getComponentName({ imported, local, moduleName, importType }) {
+ const importedName = imported ?? local;
+
+ // any relative imports should return early and be scoped to "web"
+ if (RELATIVE_PATH_REGEX.test(moduleName)) {
+ return `web/${importedName}`;
+ }
+
+ // get the module namespace / org (AKA novu or mantine), but remove @
+ const moduleOrg = moduleName.split('/').join('_').replace('@', '');
+
+ // group Icons if from Novu Design System or AntD
+ const name =
+ (moduleName === '@novu/design-system' && NOVU_ICON_REGEX.test(importedName)) || moduleName === ANTD_ICON_MODULE_NAME
+ ? 'Icon'
+ : importedName;
+
+ return `${moduleOrg}/${name}`;
+}
+
+/**
+ * @param {object} _ with the following properties:
+ * @param {number} minNumInstances Minimum instance count (inclusive) of a component to include it in the output
+ * @default 1
+ *
+ * Extension of a built-in processor from react-scanner to make it easier to customize.
+ * https://github.com/moroshko/react-scanner/blob/master/src/processors/count-components-and-props.js
+ */
+function countComponentsAndPropsProcessor({ minNumInstances = 1 } = {}) {
+ return function ({ forEachComponent, sortObjectKeysByValue, output }) {
+ let result = {};
+
+ forEachComponent(({ componentName, component }) => {
+ const { instances } = component;
+
+ if (!instances || instances.length < minNumInstances) {
+ return;
+ }
+
+ if (COMPONENT_NAME_EXCLUSION_REGEX.test(componentName)) {
+ console.log('Excluding component ' + componentName);
+
+ return;
+ }
+
+ // include the package source as a prop
+ const [srcPkg] = componentName.split('/');
+
+ result[componentName] = {
+ instances: instances.length,
+ props: {},
+ srcPkg,
+ };
+
+ instances.forEach((instance) => {
+ for (const prop in instance.props) {
+ if (result[componentName].props[prop] === undefined) {
+ result[componentName].props[prop] = 0;
+ }
+
+ result[componentName].props[prop] += 1;
+ }
+
+ // aggregate icon names and output as a prop to stay consistent across all output components.
+ if (componentName.includes('/Icon')) {
+ const iconName = instance.importInfo.imported;
+ const existingIconNames = result[componentName].props.iconNames;
+
+ result[componentName].props.iconNames = existingIconNames ? existingIconNames.concat(iconName) : [iconName];
+ }
+ });
+
+ result[componentName].props = sortObjectKeysByValue(result[componentName].props);
+ });
+
+ result = sortObjectKeysByValue(result, (component) => component.instances);
+
+ output(result, getOutputFilePath());
+
+ return result;
+ };
+}
+
+/**
+ * @precondition Must be called after `countComponentsAndPropsProcessor` in the processors array.
+ * Processor for grouping by namespace (i.e. Novu, Mantine, etc)
+ */
+function groupByNamespaceProcessor({ prevResult, output }) {
+ const result = Object.entries(prevResult).reduce((groupedResult, [compKey, compVal]) => {
+ const [namespace, compName] = compKey.split('/');
+
+ return {
+ ...groupedResult,
+ [namespace]: {
+ ...groupedResult[namespace],
+ [compName]: compVal,
+ },
+ };
+ }, {});
+
+ output(result, getOutputFilePath('.grouped'));
+
+ return result;
+}
diff --git a/libs/design-system/src/component-audit/ComponentAuditTable.stories.tsx b/libs/design-system/src/component-audit/ComponentAuditTable.stories.tsx
new file mode 100644
index 00000000000..5b171fcd987
--- /dev/null
+++ b/libs/design-system/src/component-audit/ComponentAuditTable.stories.tsx
@@ -0,0 +1,43 @@
+import React from 'react';
+import { StoryFn, Meta } from '@storybook/react';
+import { ComponentAuditTable } from './ComponentAuditTable';
+import { css } from '../../styled-system/css';
+
+import scanJson from './component-scans/scan.json';
+
+export default {
+ title: 'ComponentAudit',
+ component: ComponentAuditTable,
+ argTypes: {},
+} as Meta;
+
+const TableWrapper = ({ children }: { children: React.ReactNode }) => {
+ return (
+
+ {children}
+
+ );
+};
+
+const Template: StoryFn = ({ ...args }) => (
+ <>
+
+ If no data is appearing below, please run `pnpm audit-components` in your terminal in the `design-system`
+ directory
+
+
+
+
+
+ >
+);
+
+export const ComponentAudit = Template.bind({});
+ComponentAudit.args = {};
diff --git a/libs/design-system/src/component-audit/ComponentAuditTable.tsx b/libs/design-system/src/component-audit/ComponentAuditTable.tsx
new file mode 100644
index 00000000000..5a3227f97de
--- /dev/null
+++ b/libs/design-system/src/component-audit/ComponentAuditTable.tsx
@@ -0,0 +1,159 @@
+import React, { useMemo, useState } from 'react';
+import { css } from '../../styled-system/css';
+
+interface JsonData {
+ [key: string]: {
+ instances: number;
+ props: {
+ [key: string]: number | string[];
+ };
+ srcPkg: string;
+ };
+}
+
+interface ComponentAuditTableProps {
+ data: JsonData;
+ className?: string;
+}
+
+type SortableKey = keyof Omit | 'name';
+
+export const ComponentAuditTable: React.FC = ({ data: jsonData, className }) => {
+ const [expandedRows, setExpandedRows] = useState([]);
+ const [sortColumn, setSortColumn] = useState(null);
+ const [sortOrder, setSortOrder] = useState<'asc' | 'desc' | null>(null);
+
+ const data = useMemo(() => {
+ return Object.entries(jsonData).map(([key, value]) => ({ ...value, name: key.split('/')[1] }));
+ }, [jsonData]);
+
+ const toggleRow = (name: string) => {
+ setExpandedRows((prevState) =>
+ prevState.includes(name) ? prevState.filter((row) => row !== name) : [...prevState, name]
+ );
+ };
+
+ const sortData = (key: SortableKey) => {
+ if (sortColumn === key) {
+ setSortOrder(sortOrder === 'asc' ? 'desc' : 'asc');
+ } else {
+ setSortColumn(key);
+ setSortOrder('asc');
+ }
+ };
+
+ const getSortIcon = (key: SortableKey) => {
+ if (sortColumn !== key) return null;
+ if (sortOrder === 'asc') return '⬆️';
+ if (sortOrder === 'desc') return '⬇️';
+
+ return null;
+ };
+
+ const sortedData = sortColumn
+ ? data.sort((a, b) => {
+ const aValue = a[sortColumn];
+ const bValue = b[sortColumn];
+
+ if (typeof aValue === 'string' && typeof bValue === 'string') {
+ return sortOrder === 'asc' ? aValue.localeCompare(bValue) : bValue.localeCompare(aValue);
+ }
+
+ if (typeof aValue === 'number' && typeof bValue === 'number') {
+ return sortOrder === 'asc' ? aValue - bValue : bValue - aValue;
+ }
+
+ return 0;
+ })
+ : data;
+
+ return (
+
+
+
+ sortData('name')}
+ >
+ Name {getSortIcon('name')}
+
+ sortData('instances')}
+ >
+ Instance Count {getSortIcon('instances')}
+
+ sortData('srcPkg')}
+ >
+ Source {getSortIcon('srcPkg')}
+
+ Props
+
+
+
+ {sortedData.map(({ name, instances, props, srcPkg }) => (
+
+
+ {name}
+ {instances}
+ {srcPkg}
+
+ toggleRow(name)}
+ >
+ {Object.entries(props)
+ .slice(0, 3)
+ .map(([prop, value]) => `${prop}: ${typeof value === 'number' ? value : value.join(', ')}`)
+ .join(', ')}
+ {Object.keys(props).length > 3 && '...'}
+
+
+
+ {expandedRows.includes(name) && (
+
+
+
+ {Object.entries(props).map(([prop, value]) => (
+
+ {prop}:
+ {typeof value === 'number' ? value : value.join(', ')}
+
+ ))}
+
+
+
+ )}
+
+ ))}
+
+
+ );
+};
diff --git a/libs/design-system/src/panda/colors.tokens.ts b/libs/design-system/src/panda/colors.tokens.ts
index 22a6b42e607..c2c0f80aa2e 100644
--- a/libs/design-system/src/panda/colors.tokens.ts
+++ b/libs/design-system/src/panda/colors.tokens.ts
@@ -1,4 +1,4 @@
-import { defineTokens, defineSemanticTokens } from '@pandacss/dev';
+import { defineTokens } from '@pandacss/dev';
/**
* @deprecated
@@ -280,115 +280,3 @@ export const COLOR_PALETTE_TOKENS = defineTokens.colors({
},
},
});
-
-export const COLOR_SEMANTIC_TOKENS = defineSemanticTokens.colors({
- typography: {
- text: {
- feedback: {
- alert: {
- value: { base: '{colors.red.20.light}', _dark: '{colors.red.20.dark}' },
- type: 'color',
- },
- warning: {
- value: { base: '{colors.amber.30.light}', _dark: '{colors.amber.30.dark}' },
- type: 'color',
- },
- info: {
- value: { base: '{colors.blue.20.light}', _dark: '{colors.blue.20.dark}' },
- type: 'color',
- },
- success: {
- value: { base: '{colors.green.20.light}', _dark: '{colors.green.20.dark}' },
- type: 'color',
- },
- },
- main: {
- value: { base: '{colors.mauve.10.light}', _dark: '{colors.mauve.10.dark}' },
- type: 'color',
- },
- secondary: {
- value: { base: '{colors.mauve.20.light}', _dark: '{colors.mauve.20.dark}' },
- type: 'color',
- },
- disabled: {
- value: { base: '{colors.mauve.30.light}', _dark: '{colors.mauve.30.dark}' },
- type: 'color',
- },
- accent: {
- value: { base: '{colors.blue.20.light}', _dark: '{colors.blue.20.dark}' },
- type: 'color',
- },
- },
- },
- button: {
- hovered: {
- background: {
- value: { base: '{colors.blue.30.light}', _dark: '{colors.blue.30.dark}' },
- type: 'color',
- },
- border: {
- value: { base: '{colors.blue.30.light}', _dark: '{colors.blue.30.dark}' },
- type: 'color',
- },
- text: {
- value: { base: '{colors.blue.120.light}', _dark: '{colors.blue.120.dark}' },
- type: 'color',
- },
- },
- pressed: {
- background: {
- value: { base: '{colors.blue.20.light}', _dark: '{colors.blue.20.dark}' },
- type: 'color',
- },
- border: {
- value: { base: '{colors.blue.20.light}', _dark: '{colors.blue.20.dark}' },
- type: 'color',
- },
- text: {
- value: { base: '{colors.blue.120.light}', _dark: '{colors.blue.120.dark}' },
- type: 'color',
- },
- },
- disabled: {
- background: {
- value: { base: '{colors.mauve.10.light}', _dark: '{colors.mauve.10.dark}' },
- type: 'color',
- },
- border: {
- value: { base: '{colors.mauve.50.light}', _dark: '{colors.mauve.50.dark}' },
- type: 'color',
- },
- text: {
- // this was a self-referential token (referring to semantic.colors.typography.text.disabled)
- value: { base: '{colors.mauve.30.light}', _dark: '{colors.mauve.30.dark}' },
- type: 'color',
- },
- },
- background: {
- value: { base: '{colors.blue.40.light}', _dark: '{colors.blue.40.dark}' },
- type: 'color',
- },
- border: {
- value: { base: '{colors.blue.40.light}', _dark: '{colors.blue.40.dark}' },
- type: 'color',
- },
- text: {
- value: { base: '{colors.blue.120.light}', _dark: '{colors.blue.120.dark}' },
- type: 'color',
- },
- },
- surface: {
- page: {
- value: { base: '{colors.mauve.100.light}', _dark: '{colors.mauve.100.dark}' },
- type: 'color',
- },
- panel: {
- value: { base: '{colors.mauve.110.light}', _dark: '{colors.mauve.110.dark}' },
- type: 'color',
- },
- popover: {
- value: { base: '{colors.mauve.120.light}', _dark: '{colors.mauve.120.dark}' },
- type: 'color',
- },
- },
-});
diff --git a/libs/design-system/src/panda/semanticColors.tokens.ts b/libs/design-system/src/panda/semanticColors.tokens.ts
index 391eebc4dfb..7cec016e1c1 100644
--- a/libs/design-system/src/panda/semanticColors.tokens.ts
+++ b/libs/design-system/src/panda/semanticColors.tokens.ts
@@ -8,11 +8,11 @@ export const LEGACY_COLOR_SEMANTIC_TOKENS = defineSemanticTokens.colors({
type: 'color',
},
panel: {
- value: { base: '{colors.legacy.BGDark}', _dark: '{colors.legacy.BGLight}' },
+ value: { base: '{colors.legacy.BGLight}', _dark: '{colors.legacy.BGDark}' },
type: 'color',
},
popover: {
- value: { base: '{colors.mauve.120.light}', _dark: '{colors.mauve.120.dark}' },
+ value: { base: '{colors.legacy.white}', _dark: '{colors.legacy.B20}' },
type: 'color',
},
},
@@ -30,16 +30,25 @@ export const LEGACY_COLOR_SEMANTIC_TOKENS = defineSemanticTokens.colors({
value: { base: '{colors.legacy.B70}', _dark: '{colors.legacy.B40}' },
type: 'color',
},
- /*
- * disabled: {
- * value: { base: '{colors.legacy.mauve.30.light}', _dark: '{colors.legacy.mauve.30.dark}' },
- * type: 'color',
- * },
- * accent: {
- * value: { base: '{colors.legacy.blue.20.light}', _dark: '{colors.legacy.blue.20.dark}' },
- * type: 'color',
- * },
- */
+ // not actually legacy, but makes the merging of the two easier for now.
+ feedback: {
+ alert: {
+ value: { base: '{colors.red.20.light}', _dark: '{colors.red.20.dark}' },
+ type: 'color',
+ },
+ warning: {
+ value: { base: '{colors.amber.30.light}', _dark: '{colors.amber.30.dark}' },
+ type: 'color',
+ },
+ info: {
+ value: { base: '{colors.blue.20.light}', _dark: '{colors.blue.20.dark}' },
+ type: 'color',
+ },
+ success: {
+ value: { base: '{colors.green.20.light}', _dark: '{colors.green.20.dark}' },
+ type: 'color',
+ },
+ },
},
},
});
diff --git a/libs/embed/package.json b/libs/embed/package.json
index 5b7e53851df..aa90432b5f9 100644
--- a/libs/embed/package.json
+++ b/libs/embed/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/embed",
- "version": "0.24.0",
+ "version": "0.24.1",
"private": true,
"description": "",
"keywords": [],
@@ -117,7 +117,7 @@
"typescript": "4.9.5"
},
"dependencies": {
- "@novu/notification-center": "^0.24.0",
+ "@novu/notification-center": "^0.24.1",
"@types/iframe-resizer": "^3.5.8",
"iframe-resizer": "^4.3.1"
}
diff --git a/libs/shared-web/package.json b/libs/shared-web/package.json
index 96e63f89c38..ae76df0419d 100644
--- a/libs/shared-web/package.json
+++ b/libs/shared-web/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/shared-web",
- "version": "0.24.0",
+ "version": "0.24.1",
"repository": "https://github.com/novuhq/novu",
"description": "",
"private": true,
@@ -29,7 +29,7 @@
},
"dependencies": {
"@mantine/hooks": "^5.7.1",
- "@novu/shared": "^0.24.0",
+ "@novu/shared": "^0.24.1",
"@segment/analytics-next": "1.59.0",
"@emotion/styled": "^11.6.0",
"@sentry/react": "^7.40.0",
diff --git a/libs/shared-web/src/config.ts b/libs/shared-web/src/config.ts
index a8b77f3875d..b2d6e9aba9a 100644
--- a/libs/shared-web/src/config.ts
+++ b/libs/shared-web/src/config.ts
@@ -12,15 +12,17 @@ declare global {
}
const isCypress = (isBrowser() && (window as any).Cypress) || (isBrowser() && (window as any).parent.Cypress);
+const isPlaywright = isBrowser() && (window as any).isPlaywright;
export const API_ROOT =
- window._env_.REACT_APP_API_URL || isCypress
+ window._env_.REACT_APP_API_URL || isCypress || isPlaywright
? window._env_.REACT_APP_API_URL || process.env.REACT_APP_API_URL || 'http://localhost:1336'
: window._env_.REACT_APP_API_URL || process.env.REACT_APP_API_URL || 'http://localhost:3000';
-export const WS_URL = isCypress
- ? window._env_.REACT_APP_WS_URL || process.env.REACT_APP_WS_URL || 'http://localhost:1340'
- : window._env_.REACT_APP_WS_URL || process.env.REACT_APP_WS_URL || 'http://localhost:3002';
+export const WS_URL =
+ isCypress || isPlaywright
+ ? window._env_.REACT_APP_WS_URL || process.env.REACT_APP_WS_URL || 'http://localhost:1340'
+ : window._env_.REACT_APP_WS_URL || process.env.REACT_APP_WS_URL || 'http://localhost:3002';
export const SENTRY_DSN = window._env_.REACT_APP_SENTRY_DSN || process.env.REACT_APP_SENTRY_DSN;
@@ -29,7 +31,7 @@ export const ENV = window._env_.REACT_APP_ENVIRONMENT || process.env.REACT_APP_E
const blueprintApiUrlByEnv = ENV === 'production' || ENV === 'prod' ? 'https://api.novu.co' : 'https://dev.api.novu.co';
export const BLUEPRINTS_API_URL =
- window._env_.REACT_APP_BLUEPRINTS_API_URL || isCypress
+ window._env_.REACT_APP_BLUEPRINTS_API_URL || isCypress || isPlaywright
? window._env_.REACT_APP_BLUEPRINTS_API_URL || process.env.REACT_APP_BLUEPRINTS_API_URL || 'http://localhost:1336'
: blueprintApiUrlByEnv;
@@ -49,9 +51,10 @@ export const INTERCOM_APP_ID = window._env_.REACT_APP_INTERCOM_APP_ID || process
export const CONTEXT_PATH = getContextPath(NovuComponentEnum.WEB);
-export const WEBHOOK_URL = isCypress
- ? window._env_.REACT_APP_WEBHOOK_URL || process.env.REACT_APP_WEBHOOK_URL || 'http://localhost:1341'
- : window._env_.REACT_APP_WEBHOOK_URL || process.env.REACT_APP_WEBHOOK_URL || 'http://localhost:3003';
+export const WEBHOOK_URL =
+ isCypress || isPlaywright
+ ? window._env_.REACT_APP_WEBHOOK_URL || process.env.REACT_APP_WEBHOOK_URL || 'http://localhost:1341'
+ : window._env_.REACT_APP_WEBHOOK_URL || process.env.REACT_APP_WEBHOOK_URL || 'http://localhost:3003';
export const MAIL_SERVER_DOMAIN =
window._env_.REACT_APP_MAIL_SERVER_DOMAIN || process.env.REACT_APP_MAIL_SERVER_DOMAIN || 'dev.inbound-mail.novu.co';
@@ -60,7 +63,7 @@ export const LAUNCH_DARKLY_CLIENT_SIDE_ID =
window._env_.REACT_APP_LAUNCH_DARKLY_CLIENT_SIDE_ID || process.env.REACT_APP_LAUNCH_DARKLY_CLIENT_SIDE_ID;
export const FEATURE_FLAGS = Object.values(FeatureFlagsKeysEnum).reduce((acc, key) => {
- const defaultValue = isCypress ? true : false;
+ const defaultValue = isCypress || isPlaywright ? 'true' : 'false';
acc[key] = window._env_[key] || process.env[key] || defaultValue;
return acc;
diff --git a/libs/shared-web/src/hooks/index.ts b/libs/shared-web/src/hooks/index.ts
index 9242ef71545..74bf13dd77c 100644
--- a/libs/shared-web/src/hooks/index.ts
+++ b/libs/shared-web/src/hooks/index.ts
@@ -4,3 +4,4 @@ export * from './useDataRef';
export * from './useKeyDown';
export * from './useEnvController';
export * from './useFeatureFlags';
+export * from './useProductFeature';
diff --git a/libs/shared-web/src/hooks/useProductFeature.ts b/libs/shared-web/src/hooks/useProductFeature.ts
new file mode 100644
index 00000000000..ca6d736e36d
--- /dev/null
+++ b/libs/shared-web/src/hooks/useProductFeature.ts
@@ -0,0 +1,16 @@
+import { ApiServiceLevelEnum, productFeatureEnabledForServiceLevel, ProductFeatureKeyEnum } from '@novu/shared';
+import { useEffect, useState } from 'react';
+import { useAuthController } from './useAuthController';
+
+export const useProductFeature = (feature: ProductFeatureKeyEnum) => {
+ const { organization } = useAuthController();
+ const [enabled, setEnabled] = useState(false);
+
+ useEffect(() => {
+ setEnabled(
+ productFeatureEnabledForServiceLevel[feature].includes(organization?.apiServiceLevel as ApiServiceLevelEnum)
+ );
+ }, [feature, organization?.apiServiceLevel]);
+
+ return enabled;
+};
diff --git a/libs/shared/package.json b/libs/shared/package.json
index 061dfe27291..0a03d13914c 100644
--- a/libs/shared/package.json
+++ b/libs/shared/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/shared",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "",
"scripts": {
"start": "npm run start:dev",
@@ -25,6 +25,18 @@
"files": [
"dist/"
],
+ "exports": {
+ ".": {
+ "require": "./dist/cjs/index.js",
+ "import": "./dist/esm/index.js",
+ "types": "./dist/esm/index.d.js"
+ },
+ "./utils": {
+ "require": "./dist/cjs/utils/index.js",
+ "import": "./dist/esm/utils/index.js",
+ "types": "./dist/esm/utils/index.d.js"
+ }
+ },
"dependencies": {
"axios": "^1.6.2",
"class-transformer": "0.5.1",
diff --git a/libs/shared/src/consts/handlebar-helpers/getTemplateVariables.ts b/libs/shared/src/consts/handlebar-helpers/getTemplateVariables.ts
index 388f8800751..6551adc9f78 100644
--- a/libs/shared/src/consts/handlebar-helpers/getTemplateVariables.ts
+++ b/libs/shared/src/consts/handlebar-helpers/getTemplateVariables.ts
@@ -10,19 +10,40 @@ export interface IMustacheVariable {
}
export function getTemplateVariables(bod: any[]): IMustacheVariable[] {
+ const pairVariables = bod
+ .filter((body) => body.type === 'HashPair')
+ .flatMap((body) => {
+ const varName = body.value?.original as string;
+
+ if (!shouldAddVariable(varName)) {
+ return [];
+ }
+
+ return {
+ type: TemplateVariableTypeEnum.STRING,
+ name: body.value?.original as string,
+ defaultValue: '',
+ required: false,
+ };
+ });
+
const stringVariables: IMustacheVariable[] = bod
.filter((body) => body.type === 'MustacheStatement')
.flatMap((body) => {
const varName = body.params[0]?.original || (body.path.original as string);
- if (body.path.original === HandlebarHelpersEnum.I18N) {
+ if (body.path?.original === HandlebarHelpersEnum.I18N) {
+ if (body.hash?.pairs) {
+ return getTemplateVariables(body.hash.pairs);
+ }
+
return [];
}
if (!shouldAddVariable(varName)) {
return [];
}
- if (body.params[0]?.original) {
+ if (body.params?.[0]?.original) {
if (!(Object.values(HandlebarHelpersEnum) as string[]).includes(body.path.original)) {
return [];
}
@@ -30,7 +51,7 @@ export function getTemplateVariables(bod: any[]): IMustacheVariable[] {
return {
type: TemplateVariableTypeEnum.STRING,
- name: body.params[0]?.original || (body.path.original as string),
+ name: body.params?.[0]?.original || (body.path?.original as string),
defaultValue: '',
required: false,
};
@@ -89,7 +110,7 @@ export function getTemplateVariables(bod: any[]): IMustacheVariable[] {
];
});
- return stringVariables.concat(arrayVariables).concat(boolVariables);
+ return stringVariables.concat(arrayVariables).concat(boolVariables).concat(pairVariables);
}
const shouldAddVariable = (variableName): boolean => {
diff --git a/libs/shared/src/consts/handlebar-helpers/handlebarHelpers.ts b/libs/shared/src/consts/handlebar-helpers/handlebarHelpers.ts
index 5595ffb44bf..99e855a48df 100644
--- a/libs/shared/src/consts/handlebar-helpers/handlebarHelpers.ts
+++ b/libs/shared/src/consts/handlebar-helpers/handlebarHelpers.ts
@@ -10,6 +10,12 @@ export enum HandlebarHelpersEnum {
SORT_BY = 'sortBy',
NUMBERFORMAT = 'numberFormat',
I18N = 'i18n',
+ GT = 'gt',
+ GTE = 'gte',
+ LT = 'lt',
+ LTE = 'lte',
+ EQ = 'eq',
+ NE = 'ne',
}
// eslint-disable-next-line @typescript-eslint/naming-convention
@@ -25,4 +31,10 @@ export const HandlebarHelpers = {
[HandlebarHelpersEnum.SORT_BY]: { description: 'sort an array of objects by a property' },
[HandlebarHelpersEnum.NUMBERFORMAT]: { description: 'format number' },
[HandlebarHelpersEnum.I18N]: { description: 'translate' },
+ [HandlebarHelpersEnum.GT]: { description: 'greater than' },
+ [HandlebarHelpersEnum.GTE]: { description: 'greater than or equal to' },
+ [HandlebarHelpersEnum.LT]: { description: 'lesser than' },
+ [HandlebarHelpersEnum.LTE]: { description: 'lesser than or equal to' },
+ [HandlebarHelpersEnum.EQ]: { description: 'strict equal' },
+ [HandlebarHelpersEnum.NE]: { description: 'strict not equal to' },
};
diff --git a/libs/shared/src/consts/index.ts b/libs/shared/src/consts/index.ts
index d1430d47ca1..fffcaeea5e0 100644
--- a/libs/shared/src/consts/index.ts
+++ b/libs/shared/src/consts/index.ts
@@ -6,3 +6,4 @@ export * from './password-helper';
export * from './filters';
export * from './template-store';
export * from './rate-limiting';
+export * from './productFeatureEnabledForServiceLevel';
diff --git a/libs/shared/src/consts/productFeatureEnabledForServiceLevel.ts b/libs/shared/src/consts/productFeatureEnabledForServiceLevel.ts
new file mode 100644
index 00000000000..b4671200c0d
--- /dev/null
+++ b/libs/shared/src/consts/productFeatureEnabledForServiceLevel.ts
@@ -0,0 +1,7 @@
+import { ApiServiceLevelEnum, ProductFeatureKeyEnum } from '../types';
+
+export const productFeatureEnabledForServiceLevel: Record = Object.freeze(
+ {
+ [ProductFeatureKeyEnum.TRANSLATIONS]: [ApiServiceLevelEnum.BUSINESS, ApiServiceLevelEnum.ENTERPRISE],
+ }
+);
diff --git a/libs/shared/src/dto/notification-templates/create-template.dto.ts b/libs/shared/src/dto/notification-templates/create-template.dto.ts
index 5e1852d1725..7b0068e432c 100644
--- a/libs/shared/src/dto/notification-templates/create-template.dto.ts
+++ b/libs/shared/src/dto/notification-templates/create-template.dto.ts
@@ -1,6 +1,7 @@
import { NotificationStepDto } from '../workflows';
import { IPreferenceChannels } from '../../entities/subscriber-preference';
import { NotificationTemplateCustomData } from '../../types';
+import { INotificationGroup } from '../../entities/notification-group';
export interface ICreateNotificationTemplateDto {
name: string;
@@ -11,7 +12,9 @@ export interface ICreateNotificationTemplateDto {
steps: NotificationStepDto[];
- notificationGroupId: string;
+ notificationGroupId?: string;
+
+ notificationGroup?: INotificationGroup;
active?: boolean;
diff --git a/libs/shared/src/entities/notification-template/notification-template.interface.ts b/libs/shared/src/entities/notification-template/notification-template.interface.ts
index fd9355ccefd..835c7537a5a 100644
--- a/libs/shared/src/entities/notification-template/notification-template.interface.ts
+++ b/libs/shared/src/entities/notification-template/notification-template.interface.ts
@@ -4,6 +4,7 @@ import type { BuilderFieldType, BuilderGroupValues, TemplateVariableTypeEnum, Fi
import { IMessageTemplate } from '../message-template';
import { IPreferenceChannels } from '../subscriber-preference';
import { IWorkflowStepMetadata } from '../step';
+import { INotificationGroup } from '../notification-group';
export enum NotificationTemplateTypeEnum {
REGULAR = 'REGULAR',
@@ -33,7 +34,11 @@ export interface INotificationTemplate {
export class IGroupedBlueprint {
name: string;
- blueprints: INotificationTemplate[];
+ blueprints: IBlueprint[];
+}
+
+export interface IBlueprint extends INotificationTemplate {
+ notificationGroup: INotificationGroup;
}
export enum TriggerTypeEnum {
diff --git a/libs/shared/src/entities/organization/organization.interface.ts b/libs/shared/src/entities/organization/organization.interface.ts
index d25d89baf19..f46173c6444 100644
--- a/libs/shared/src/entities/organization/organization.interface.ts
+++ b/libs/shared/src/entities/organization/organization.interface.ts
@@ -18,4 +18,5 @@ export interface IOrganizationEntity {
productUseCases?: ProductUseCases;
createdAt: string;
updatedAt: string;
+ externalId?: string;
}
diff --git a/libs/shared/src/entities/user/user.interface.ts b/libs/shared/src/entities/user/user.interface.ts
index 204f7c111ca..e102d331dc6 100644
--- a/libs/shared/src/entities/user/user.interface.ts
+++ b/libs/shared/src/entities/user/user.interface.ts
@@ -14,4 +14,5 @@ export interface IUserEntity {
showOnBoardingTour?: number;
servicesHashes?: IServicesHashes;
jobTitle?: JobTitleEnum;
+ externalId?: string;
}
diff --git a/libs/shared/src/index.ts b/libs/shared/src/index.ts
index 531b483b360..7d096c11120 100644
--- a/libs/shared/src/index.ts
+++ b/libs/shared/src/index.ts
@@ -1,26 +1,29 @@
-export * from './entities/user';
-export * from './entities/organization';
-export * from './entities/notification-template';
+export * from './config';
+export * from './consts';
+export * from './dto';
+export * from './entities/change';
export * from './entities/environment';
export * from './entities/execution-details';
-export * from './entities/messages';
export * from './entities/feed/feed.interface';
-export * from './entities/notification';
-export * from './entities/message-template';
+export * from './entities/integration';
+export * from './entities/job';
+export * from './entities/layout';
export * from './entities/log';
-export * from './entities/change';
+export * from './entities/message-template';
+export * from './entities/messages';
+export * from './entities/notification-group';
+export * from './entities/notification-template';
+export * from './entities/notification';
+export * from './entities/organization';
export * from './entities/step';
-export * from './entities/job';
export * from './entities/subscriber-preference';
export * from './entities/subscriber';
-export * from './entities/layout';
-export * from './entities/notification-group';
-export * from './entities/integration';
export * from './entities/tenant';
+export * from './entities/user';
export * from './entities/workflow-override';
+export * from './services';
export * from './types';
-export * from './dto';
-export * from './consts';
export * from './ui';
+export * from './utils';
export * from './services';
export * from './config';
diff --git a/libs/shared/src/types/index.ts b/libs/shared/src/types/index.ts
index 6d15e971f99..a918a6933ff 100644
--- a/libs/shared/src/types/index.ts
+++ b/libs/shared/src/types/index.ts
@@ -22,3 +22,4 @@ export * from './rate-limiting';
export * from './auth';
export * from './timezones';
export * from './cron';
+export * from './product-features';
diff --git a/libs/shared/src/types/product-features/index.ts b/libs/shared/src/types/product-features/index.ts
new file mode 100644
index 00000000000..8e2fa630c11
--- /dev/null
+++ b/libs/shared/src/types/product-features/index.ts
@@ -0,0 +1,3 @@
+export enum ProductFeatureKeyEnum {
+ TRANSLATIONS,
+}
diff --git a/libs/shared/src/utils/checkIsResponseError.spec.ts b/libs/shared/src/utils/checkIsResponseError.spec.ts
new file mode 100644
index 00000000000..bb5121b452d
--- /dev/null
+++ b/libs/shared/src/utils/checkIsResponseError.spec.ts
@@ -0,0 +1,60 @@
+import { checkIsResponseError } from './checkIsResponseError';
+import { IResponseError } from '../types';
+
+describe('checkIsResponseError', () => {
+ it('should return true for a valid IResponseError object', () => {
+ const error: IResponseError = {
+ error: 'Something went wrong',
+ message: 'An error occurred',
+ statusCode: 500,
+ };
+
+ const result = checkIsResponseError(error);
+ expect(result).toBe(true);
+ });
+
+ it('should return false for null', () => {
+ const result = checkIsResponseError(null);
+ expect(result).toBe(false);
+ });
+
+ it('should return false for undefined', () => {
+ const result = checkIsResponseError(undefined);
+ expect(result).toBe(false);
+ });
+
+ it('should return false for a non-object value', () => {
+ const result = checkIsResponseError('This is a string');
+ expect(result).toBe(false);
+ });
+
+ it('should return false if the object is missing the "error" property', () => {
+ const error = {
+ message: 'An error occurred',
+ statusCode: 500,
+ };
+
+ const result = checkIsResponseError(error);
+ expect(result).toBe(false);
+ });
+
+ it('should return false if the object is missing the "message" property', () => {
+ const error = {
+ error: 'Something went wrong',
+ statusCode: 500,
+ };
+
+ const result = checkIsResponseError(error);
+ expect(result).toBe(false);
+ });
+
+ it('should return false if the object is missing the "statusCode" property', () => {
+ const error = {
+ error: 'Something went wrong',
+ message: 'An error occurred',
+ };
+
+ const result = checkIsResponseError(error);
+ expect(result).toBe(false);
+ });
+});
diff --git a/libs/shared/src/utils/checkIsResponseError.ts b/libs/shared/src/utils/checkIsResponseError.ts
new file mode 100644
index 00000000000..5c78aae4cf1
--- /dev/null
+++ b/libs/shared/src/utils/checkIsResponseError.ts
@@ -0,0 +1,8 @@
+import { IResponseError } from '../types';
+
+/**
+ * Validate (type-guard) that an error response matches our IResponseError interface.
+ */
+export const checkIsResponseError = (err: unknown): err is IResponseError => {
+ return !!err && typeof err === 'object' && 'error' in err && 'message' in err && 'statusCode' in err;
+};
diff --git a/libs/shared/src/utils/env.ts b/libs/shared/src/utils/env.ts
new file mode 100644
index 00000000000..e2698699fce
--- /dev/null
+++ b/libs/shared/src/utils/env.ts
@@ -0,0 +1,51 @@
+type CloudflareEnv = { env: Record };
+
+// https://remix.run/blog/remix-vite-stable#cloudflare-pages-support
+const hasCloudflareProxyContext = (context: any): context is { cloudflare: CloudflareEnv } => {
+ return !!context?.cloudflare?.env;
+};
+
+const hasCloudflareContext = (context: any): context is CloudflareEnv => {
+ return !!context?.env;
+};
+
+/**
+ *
+ * Utility function to get env variables across Node and Edge runtimes.
+ *
+ * @param name Pass the name of the environment variable. The param is case-sensitive.
+ * @returns string Returns the value of the environment variable if exists.
+ */
+export const getEnvVariable = (name: string, context?: any): string => {
+ // Node envs
+ if (typeof process !== 'undefined' && process.env && typeof process.env[name] === 'string') {
+ return process.env[name] as string;
+ }
+
+ /*
+ * Remix + Cloudflare pages
+ * if (typeof (context?.cloudflare as CloudflareEnv)?.env !== 'undefined') {
+ */
+ if (hasCloudflareProxyContext(context)) {
+ return context.cloudflare.env[name] || '';
+ }
+
+ // Cloudflare
+ if (hasCloudflareContext(context)) {
+ return context.env[name] || '';
+ }
+
+ // Check whether the value exists in the context object directly
+ if (context && typeof context[name] === 'string') {
+ return context[name] as string;
+ }
+
+ // Cloudflare workers
+ try {
+ return globalThis[name as keyof typeof globalThis];
+ } catch (_) {
+ // This will raise an error in Cloudflare Pages
+ }
+
+ return '';
+};
diff --git a/libs/shared/src/utils/index.ts b/libs/shared/src/utils/index.ts
new file mode 100644
index 00000000000..53bf04c6082
--- /dev/null
+++ b/libs/shared/src/utils/index.ts
@@ -0,0 +1,2 @@
+export * from './checkIsResponseError';
+export * from './env';
diff --git a/libs/testing/package.json b/libs/testing/package.json
index 083eee4f47e..1ec82462f4c 100644
--- a/libs/testing/package.json
+++ b/libs/testing/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/testing",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "",
"private": true,
"scripts": {
@@ -22,8 +22,8 @@
"types": "dist/index.d.ts",
"dependencies": {
"@faker-js/faker": "^6.0.0",
- "@novu/dal": "^0.24.0",
- "@novu/shared": "^0.24.0",
+ "@novu/dal": "^0.24.1",
+ "@novu/shared": "^0.24.1",
"JSONStream": "^1.3.5",
"async": "^3.2.0",
"axios": "^1.6.2",
diff --git a/package.json b/package.json
index 2add5564652..4044088f66e 100644
--- a/package.json
+++ b/package.json
@@ -13,10 +13,10 @@
"commit": "cz",
"nx": "nx",
"lint-staged": "lint-staged",
- "generate:provider": "npx hygen provider new --version 0.24.0",
- "lint": "nx run-many --target=lint --all",
+ "generate:provider": "npx hygen provider new --version 0.24.1",
+ "lint": "nx run-many --target=lint --all",
"test": "cross-env CI=true lerna run test:watch --parallel",
- "start:dev": "cross-env TZ=UTC lerna run start:dev --parallel --concurrency=20 --scope=@novu/{api,worker,web,widget,ws,notification-center}",
+ "start:dev": "cross-env TZ=UTC lerna run start:dev --stream --parallel --concurrency=20 --scope=@novu/{api,worker,web,widget,ws,notification-center}",
"start:web": "cross-env nx run @novu/web:start",
"start:ws": "cross-env nx run @novu/ws:start",
"start:webhook": "cross-env nx run @novu/webhook:start",
@@ -51,7 +51,7 @@
"build:web": "nx build @novu/web",
"build:widget": "nx build @novu/widget",
"build:embed": "nx build @novu/embed",
- "build:storybook": "nx run @novu/web:build-storybook",
+ "build:storybook": "nx run @novu/design-system:build-storybook",
"test:providers": "cross-env pnpm --filter './providers/**' test",
"release:patch": "lerna version patch --no-push",
"release:minor": "lerna version minor --no-push",
@@ -88,7 +88,7 @@
"@octokit/core": "^4.0.0",
"@pnpm/filter-workspace-packages": "^7.0.6",
"@pnpm/logger": "^5.0.0",
- "@types/inquirer": "8.2.9",
+ "@types/inquirer": "8.2.10",
"@types/jest": "29.5.2",
"@types/node": "16.11.7",
"@typescript-eslint/eslint-plugin": "^5.50.0",
diff --git a/packages/application-generic/package.json b/packages/application-generic/package.json
index 60554d957da..830b1d4954e 100644
--- a/packages/application-generic/package.json
+++ b/packages/application-generic/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/application-generic",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "Generic backend code used inside of Novu's different services",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -52,72 +52,72 @@
"@google-cloud/storage": "^6.2.3",
"@hokify/agenda": "^6.3.0",
"@nestjs/passport": "^10.0.1",
- "@novu/africas-talking": "^0.24.0",
- "@novu/apns": "^0.24.0",
- "@novu/azure-sms": "^0.24.0",
- "@novu/bandwidth": "^0.24.0",
- "@novu/braze": "^0.24.0",
- "@novu/brevo-sms": "^0.24.0",
- "@novu/bulk-sms": "^0.24.0",
- "@novu/burst-sms": "^0.24.0",
- "@novu/clickatell": "^0.24.0",
- "@novu/clicksend": "^0.24.0",
- "@novu/dal": "^0.24.0",
- "@novu/discord": "^0.24.0",
- "@novu/email-webhook": "^0.24.0",
- "@novu/emailjs": "^0.24.0",
- "@novu/expo": "^0.24.0",
- "@novu/fcm": "^0.24.0",
- "@novu/firetext": "^0.24.0",
- "@novu/forty-six-elks": "^0.24.0",
- "@novu/generic-sms": "^0.24.0",
- "@novu/getstream": "^0.24.0",
- "@novu/grafana-on-call": "^0.24.0",
- "@novu/gupshup": "^0.24.0",
- "@novu/infobip": "^0.24.0",
- "@novu/isend-sms": "^0.24.0",
- "@novu/kannel": "^0.24.0",
- "@novu/mailersend": "^0.24.0",
- "@novu/mailgun": "^0.24.0",
- "@novu/mailjet": "^0.24.0",
- "@novu/mailtrap": "^0.24.0",
- "@novu/mandrill": "^0.24.0",
- "@novu/maqsam": "^0.24.0",
- "@novu/mattermost": "^0.24.0",
- "@novu/messagebird": "^0.24.0",
- "@novu/ms-teams": "^0.24.0",
- "@novu/netcore": "^0.24.0",
- "@novu/nexmo": "^0.24.0",
- "@novu/nodemailer": "^0.24.0",
- "@novu/one-signal": "^0.24.0",
- "@novu/outlook365": "^0.24.0",
- "@novu/plivo": "^0.24.0",
- "@novu/plunk": "^0.24.0",
- "@novu/postmark": "^0.24.0",
- "@novu/push-webhook": "^0.24.0",
- "@novu/pusher-beams": "^0.24.0",
- "@novu/pushpad": "^0.24.0",
- "@novu/resend": "^0.24.0",
- "@novu/ring-central": "^0.24.0",
- "@novu/rocket-chat": "^0.24.0",
- "@novu/ryver": "^0.24.0",
- "@novu/sendchamp": "^0.24.0",
- "@novu/sendgrid": "^0.24.0",
- "@novu/sendinblue": "^0.24.0",
- "@novu/ses": "^0.24.0",
- "@novu/shared": "^0.24.0",
- "@novu/simpletexting": "^0.24.0",
- "@novu/slack": "^0.24.0",
- "@novu/sms-central": "^0.24.0",
- "@novu/sms77": "^0.24.0",
- "@novu/sns": "^0.24.0",
- "@novu/sparkpost": "^0.24.0",
- "@novu/stateless": "^0.24.0",
- "@novu/telnyx": "^0.24.0",
- "@novu/termii": "^0.24.0",
- "@novu/testing": "^0.24.0",
- "@novu/twilio": "^0.24.0",
- "@novu/zulip": "^0.24.0",
+ "@novu/africas-talking": "^0.24.1",
+ "@novu/apns": "^0.24.1",
+ "@novu/azure-sms": "^0.24.1",
+ "@novu/bandwidth": "^0.24.1",
+ "@novu/braze": "^0.24.1",
+ "@novu/brevo-sms": "^0.24.1",
+ "@novu/bulk-sms": "^0.24.1",
+ "@novu/burst-sms": "^0.24.1",
+ "@novu/clickatell": "^0.24.1",
+ "@novu/clicksend": "^0.24.1",
+ "@novu/dal": "^0.24.1",
+ "@novu/discord": "^0.24.1",
+ "@novu/email-webhook": "^0.24.1",
+ "@novu/emailjs": "^0.24.1",
+ "@novu/expo": "^0.24.1",
+ "@novu/fcm": "^0.24.1",
+ "@novu/firetext": "^0.24.1",
+ "@novu/forty-six-elks": "^0.24.1",
+ "@novu/generic-sms": "^0.24.1",
+ "@novu/getstream": "^0.24.1",
+ "@novu/grafana-on-call": "^0.24.1",
+ "@novu/gupshup": "^0.24.1",
+ "@novu/infobip": "^0.24.1",
+ "@novu/isend-sms": "^0.24.1",
+ "@novu/kannel": "^0.24.1",
+ "@novu/mailersend": "^0.24.1",
+ "@novu/mailgun": "^0.24.1",
+ "@novu/mailjet": "^0.24.1",
+ "@novu/mailtrap": "^0.24.1",
+ "@novu/mandrill": "^0.24.1",
+ "@novu/maqsam": "^0.24.1",
+ "@novu/mattermost": "^0.24.1",
+ "@novu/messagebird": "^0.24.1",
+ "@novu/ms-teams": "^0.24.1",
+ "@novu/netcore": "^0.24.1",
+ "@novu/nexmo": "^0.24.1",
+ "@novu/nodemailer": "^0.24.1",
+ "@novu/one-signal": "^0.24.1",
+ "@novu/outlook365": "^0.24.1",
+ "@novu/plivo": "^0.24.1",
+ "@novu/plunk": "^0.24.1",
+ "@novu/postmark": "^0.24.1",
+ "@novu/push-webhook": "^0.24.1",
+ "@novu/pusher-beams": "^0.24.1",
+ "@novu/pushpad": "^0.24.1",
+ "@novu/resend": "^0.24.1",
+ "@novu/ring-central": "^0.24.1",
+ "@novu/rocket-chat": "^0.24.1",
+ "@novu/ryver": "^0.24.1",
+ "@novu/sendchamp": "^0.24.1",
+ "@novu/sendgrid": "^0.24.1",
+ "@novu/sendinblue": "^0.24.1",
+ "@novu/ses": "^0.24.1",
+ "@novu/shared": "^0.24.1",
+ "@novu/simpletexting": "^0.24.1",
+ "@novu/slack": "^0.24.1",
+ "@novu/sms-central": "^0.24.1",
+ "@novu/sms77": "^0.24.1",
+ "@novu/sns": "^0.24.1",
+ "@novu/sparkpost": "^0.24.1",
+ "@novu/stateless": "^0.24.1",
+ "@novu/telnyx": "^0.24.1",
+ "@novu/termii": "^0.24.1",
+ "@novu/testing": "^0.24.1",
+ "@novu/twilio": "^0.24.1",
+ "@novu/zulip": "^0.24.1",
"@opentelemetry/api": "^1.7.0",
"@opentelemetry/auto-instrumentations-node": "^0.40.2",
"@opentelemetry/context-async-hooks": "^1.19.0",
@@ -125,6 +125,7 @@
"@opentelemetry/exporter-collector": "^0.25.0",
"@opentelemetry/exporter-jaeger": "^1.19.0",
"@opentelemetry/exporter-prometheus": "^0.46.0",
+ "@opentelemetry/exporter-trace-otlp-http": "^0.49.1",
"@opentelemetry/instrumentation": "^0.46.0",
"@opentelemetry/propagator-b3": "^1.19.0",
"@opentelemetry/propagator-jaeger": "^1.19.0",
@@ -160,8 +161,8 @@
"rxjs": "7.8.1"
},
"optionalDependencies": {
- "@taskforcesh/bullmq-pro": "5.1.14",
- "@novu/ee-chimera-connect": "^0.24.0"
+ "@novu/ee-chimera-connect": "^0.24.1",
+ "@taskforcesh/bullmq-pro": "5.1.14"
},
"devDependencies": {
"@istanbuljs/nyc-config-typescript": "^1.0.1",
diff --git a/packages/application-generic/src/health/cache.health-indicator.ts b/packages/application-generic/src/health/cache.health-indicator.ts
index 1e000b83083..d6d882563ba 100644
--- a/packages/application-generic/src/health/cache.health-indicator.ts
+++ b/packages/application-generic/src/health/cache.health-indicator.ts
@@ -3,34 +3,25 @@ import {
HealthIndicator,
HealthIndicatorResult,
} from '@nestjs/terminus';
-import { Injectable, Logger } from '@nestjs/common';
-
+import { Injectable } from '@nestjs/common';
import { CacheService } from '../services/cache';
-const LOG_CONTEXT = 'CacheServiceHealthIndicator';
-
@Injectable()
export class CacheServiceHealthIndicator extends HealthIndicator {
- private INDICATOR_KEY = 'cacheService';
+ private static KEY = 'cacheService';
constructor(private cacheService: CacheService) {
super();
}
async isHealthy(): Promise {
- const isReady = this.cacheService.cacheEnabled();
+ const isHealthy = this.cacheService.cacheEnabled();
+ const result = this.getStatus(CacheServiceHealthIndicator.KEY, isHealthy);
- if (isReady) {
- Logger.verbose('CacheService is ready', LOG_CONTEXT);
-
- return this.getStatus(this.INDICATOR_KEY, true);
+ if (isHealthy) {
+ return result;
}
- Logger.verbose('CacheServiceHealthIndicator is not ready', LOG_CONTEXT);
-
- throw new HealthCheckError(
- 'Cache Health',
- this.getStatus(this.INDICATOR_KEY, false)
- );
+ throw new HealthCheckError('Cache health check failed', result);
}
}
diff --git a/packages/application-generic/src/health/dal.health-indicator.ts b/packages/application-generic/src/health/dal.health-indicator.ts
index d4e4dab7794..8540a63c282 100644
--- a/packages/application-generic/src/health/dal.health-indicator.ts
+++ b/packages/application-generic/src/health/dal.health-indicator.ts
@@ -1,4 +1,8 @@
-import { HealthIndicator, HealthIndicatorResult } from '@nestjs/terminus';
+import {
+ HealthCheckError,
+ HealthIndicator,
+ HealthIndicatorResult,
+} from '@nestjs/terminus';
import { Injectable } from '@nestjs/common';
import { DalService } from '@novu/dal';
import { IHealthIndicator } from './health-indicator.interface';
@@ -8,16 +12,21 @@ export class DalServiceHealthIndicator
extends HealthIndicator
implements IHealthIndicator
{
- private INDICATOR_KEY = 'db';
+ private static KEY = 'db';
constructor(private dalService: DalService) {
super();
}
async isHealthy(): Promise {
- const status = this.dalService.connection.readyState === 1;
+ const isHealthy = this.dalService.connection.readyState === 1;
+ const result = this.getStatus(DalServiceHealthIndicator.KEY, isHealthy);
- return this.getStatus(this.INDICATOR_KEY, status);
+ if (isHealthy) {
+ return result;
+ }
+
+ throw new HealthCheckError('DAL health check failed', result);
}
isActive(): Promise {
diff --git a/packages/application-generic/src/tracing/tracing.module.ts b/packages/application-generic/src/tracing/tracing.module.ts
index 0938b5efe85..46ce828ce14 100644
--- a/packages/application-generic/src/tracing/tracing.module.ts
+++ b/packages/application-generic/src/tracing/tracing.module.ts
@@ -17,13 +17,14 @@ const OtelModule = OpenTelemetryModule.forRoot({
@Module({})
export class TracingModule {
- static register(serviceName: string): DynamicModule {
+ static register(serviceName: string, version: string): DynamicModule {
return {
module: TracingModule,
imports: [OtelModule],
providers: [
TracingService,
{ provide: 'TRACING_SERVICE_NAME', useValue: serviceName },
+ { provide: 'TRACING_SERVICE_VERSION', useValue: version },
{
provide: 'TRACING_ENABLE_OTEL',
useValue: process.env.ENABLE_OTEL === 'true',
diff --git a/packages/application-generic/src/tracing/tracing.service.ts b/packages/application-generic/src/tracing/tracing.service.ts
index 97f64d9df9b..be06dd84be9 100644
--- a/packages/application-generic/src/tracing/tracing.service.ts
+++ b/packages/application-generic/src/tracing/tracing.service.ts
@@ -13,6 +13,7 @@ export class TracingService implements OnModuleInit, OnModuleDestroy {
constructor(
@Inject('TRACING_SERVICE_NAME') private readonly serviceName: string,
+ @Inject('TRACING_SERVICE_VERSION') private readonly version: string,
@Inject('TRACING_ENABLE_OTEL') private readonly otelEnabled: boolean
) {}
@@ -24,7 +25,7 @@ export class TracingService implements OnModuleInit, OnModuleDestroy {
onModuleInit() {
if (!this.hasValidParameters()) return;
- this.otelSDKInstance = initializeOtelSdk(this.serviceName);
+ this.otelSDKInstance = initializeOtelSdk(this.serviceName, this.version);
this.otelSDKInstance.start();
}
diff --git a/packages/application-generic/src/tracing/tracing.ts b/packages/application-generic/src/tracing/tracing.ts
index 0cd9cf7852c..0521f4fb6ab 100644
--- a/packages/application-generic/src/tracing/tracing.ts
+++ b/packages/application-generic/src/tracing/tracing.ts
@@ -4,21 +4,35 @@ import {
W3CTraceContextPropagator,
} from '@opentelemetry/core';
import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
-import { JaegerExporter } from '@opentelemetry/exporter-jaeger';
+import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { JaegerPropagator } from '@opentelemetry/propagator-jaeger';
import { B3InjectEncoding, B3Propagator } from '@opentelemetry/propagator-b3';
import { PrometheusExporter } from '@opentelemetry/exporter-prometheus';
import { NodeSDK } from '@opentelemetry/sdk-node';
import { AsyncLocalStorageContextManager } from '@opentelemetry/context-async-hooks';
+import { Resource } from '@opentelemetry/resources';
+import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';
// eslint-disable-next-line @typescript-eslint/naming-convention
-export function initializeOtelSdk(serviceName: string) {
+export function initializeOtelSdk(serviceName: string, version: string) {
return new NodeSDK({
+ resource: new Resource({
+ 'service.version': version,
+ 'service.group': 'instrumentation-group',
+ [SemanticResourceAttributes.SERVICE_NAME]: serviceName,
+ }),
metricReader: new PrometheusExporter({
port: 9464,
+ preventServerStart: false,
+ appendTimestamp: true,
+ }),
+ spanProcessor: new BatchSpanProcessor(new OTLPTraceExporter(), {
+ // The maximum queue size. After the size is reached spans are dropped.
+ maxQueueSize: 1000,
+ // The interval between two consecutive exports
+ scheduledDelayMillis: 30000,
}),
- spanProcessor: new BatchSpanProcessor(new JaegerExporter()),
contextManager: new AsyncLocalStorageContextManager(),
serviceName: serviceName,
textMapPropagator: new CompositePropagator({
diff --git a/packages/application-generic/src/usecases/add-job/add-delay-job.usecase.ts b/packages/application-generic/src/usecases/add-job/add-delay-job.usecase.ts
index 8462de9586c..b6efe9d3e31 100644
--- a/packages/application-generic/src/usecases/add-job/add-delay-job.usecase.ts
+++ b/packages/application-generic/src/usecases/add-job/add-delay-job.usecase.ts
@@ -2,6 +2,7 @@ import { forwardRef, Inject, Injectable, Logger } from '@nestjs/common';
import { JobRepository, JobStatusEnum } from '@novu/dal';
import {
+ DelayTypeEnum,
ExecutionDetailsSourceEnum,
ExecutionDetailsStatusEnum,
StepTypeEnum,
@@ -46,7 +47,13 @@ export class AddDelayJob {
stepMetadata: data.step.metadata,
payload: data.payload,
overrides: data.overrides,
- chimeraResponse: command.chimeraResponse?.outputs,
+ // TODO: Remove fallback after other delay types are implemented.
+ chimeraResponse: command.chimeraResponse?.outputs
+ ? {
+ type: DelayTypeEnum.REGULAR,
+ ...command.chimeraResponse?.outputs,
+ }
+ : undefined,
});
await this.jobRepository.updateStatus(
diff --git a/packages/application-generic/src/usecases/add-job/add-job.usecase.ts b/packages/application-generic/src/usecases/add-job/add-job.usecase.ts
index 482bf453622..a433019f9dc 100644
--- a/packages/application-generic/src/usecases/add-job/add-job.usecase.ts
+++ b/packages/application-generic/src/usecases/add-job/add-job.usecase.ts
@@ -5,6 +5,7 @@ import {
ExecutionDetailsStatusEnum,
StepTypeEnum,
DigestCreationResultEnum,
+ DigestTypeEnum,
} from '@novu/shared';
import { AddDelayJob } from './add-delay-job.usecase';
@@ -35,6 +36,7 @@ import {
IUseCaseInterfaceInline,
requireInject,
} from '../../utils/require-inject';
+import { IFilterVariables } from '../../utils/filter-processing-details';
export enum BackoffStrategiesEnum {
WEBHOOK_FILTER_BACKOFF = 'webhookFilterBackoff',
@@ -85,7 +87,7 @@ export class AddJob {
);
let filtered = false;
-
+ let filterVariables: IFilterVariables | undefined;
if (
[StepTypeEnum.DELAY, StepTypeEnum.DIGEST].includes(
job.type as StepTypeEnum
@@ -102,6 +104,7 @@ export class AddJob {
})
);
+ filterVariables = shouldRun.variables;
filtered = !shouldRun.passed;
}
@@ -109,9 +112,12 @@ export class AddJob {
let digestCreationResult: DigestCreationResultEnum | undefined;
if (job.type === StepTypeEnum.DIGEST) {
const chimeraResponse = await this.chimeraConnector.execute<
- AddJobCommand,
+ AddJobCommand & { variables: IFilterVariables },
ExecuteOutput
- >(command);
+ >({
+ ...command,
+ variables: filterVariables,
+ });
validateDigest(job);
@@ -119,7 +125,10 @@ export class AddJob {
stepMetadata: job.digest,
payload: job.payload,
overrides: job.overrides,
- chimeraResponse: chimeraResponse?.outputs,
+ // TODO: Remove fallback after other digest types are implemented.
+ chimeraResponse: chimeraResponse
+ ? { type: DigestTypeEnum.REGULAR, ...chimeraResponse.outputs }
+ : undefined,
});
Logger.debug(`Digest step amount is: ${digestAmount}`, LOG_CONTEXT);
@@ -164,9 +173,12 @@ export class AddJob {
if (job.type === StepTypeEnum.DELAY) {
const chimeraResponse = await this.chimeraConnector.execute<
- AddJobCommand,
+ AddJobCommand & { variables: IFilterVariables },
ExecuteOutput
- >(command);
+ >({
+ ...command,
+ variables: filterVariables,
+ });
command.chimeraResponse = chimeraResponse;
delayAmount = await this.addDelayJob.execute(command);
diff --git a/packages/application-generic/src/usecases/add-job/merge-or-create-digest.usecase.ts b/packages/application-generic/src/usecases/add-job/merge-or-create-digest.usecase.ts
index a0fabba8b0c..9a8600c4775 100644
--- a/packages/application-generic/src/usecases/add-job/merge-or-create-digest.usecase.ts
+++ b/packages/application-generic/src/usecases/add-job/merge-or-create-digest.usecase.ts
@@ -50,7 +50,8 @@ export class MergeOrCreateDigest {
): Promise {
const { job } = command;
- const digestMeta = job.digest as IDigestBaseMetadata | undefined;
+ const digestMeta =
+ command.chimeraData ?? (job.digest as IDigestBaseMetadata | undefined);
const digestKey = command.chimeraData?.digestKey ?? digestMeta?.digestKey;
const digestValue = getNestedValue(job.payload, digestKey);
@@ -73,7 +74,10 @@ export class MergeOrCreateDigest {
case DigestCreationResultEnum.SKIPPED:
return await this.processSkippedDigest(job, command.filtered);
case DigestCreationResultEnum.CREATED:
- return await this.processCreatedDigest(digestMeta, job);
+ return await this.processCreatedDigest(
+ digestMeta as IDigestBaseMetadata,
+ job
+ );
default:
throw new ApiException('Something went wrong with digest creation');
}
diff --git a/packages/application-generic/src/usecases/compile-template/compile-template.spec.ts b/packages/application-generic/src/usecases/compile-template/compile-template.spec.ts
index 4003ac48f29..9b2393168b2 100644
--- a/packages/application-generic/src/usecases/compile-template/compile-template.spec.ts
+++ b/packages/application-generic/src/usecases/compile-template/compile-template.spec.ts
@@ -209,4 +209,148 @@ describe('Compile Template', function () {
expect(result).toEqual('Not a number');
});
});
+
+ describe('gt helper', () => {
+ const template = `{{#gt steps 5 }}gt block{{else}}else block{{/gt}}`;
+ it('shoud render gt block', async () => {
+ const result = await useCase.execute({
+ data: { steps: 6 },
+ template,
+ });
+
+ expect(result).toEqual('gt block');
+ });
+
+ it('shoud render alternative block', async () => {
+ const result = await useCase.execute({
+ data: { steps: 5 },
+ template,
+ });
+
+ expect(result).toEqual('else block');
+ });
+ });
+
+ describe('gte helper', () => {
+ const template = `{{#gte steps 5 }}gte block{{else}}else block{{/gte}}`;
+ it('shoud render gte block', async () => {
+ const result = await useCase.execute({
+ data: { steps: 5 },
+ template,
+ });
+
+ expect(result).toEqual('gte block');
+ });
+
+ it('shoud render alternative block', async () => {
+ const result = await useCase.execute({
+ data: { steps: 4 },
+ template,
+ });
+
+ expect(result).toEqual('else block');
+ });
+ });
+
+ describe('lt helper', () => {
+ const template = `{{#lt steps 5 }}lt block{{else}}else block{{/lt}}`;
+ it('shoud render lt block', async () => {
+ const result = await useCase.execute({
+ data: { steps: 4 },
+ template,
+ });
+
+ expect(result).toEqual('lt block');
+ });
+
+ it('shoud render alternative block', async () => {
+ const result = await useCase.execute({
+ data: { steps: 5 },
+ template,
+ });
+
+ expect(result).toEqual('else block');
+ });
+ });
+
+ describe('lte helper', () => {
+ const template = `{{#lte steps 5 }}lte block{{else}}else block{{/lte}}`;
+ it('shoud render lte block', async () => {
+ const result = await useCase.execute({
+ data: { steps: 5 },
+ template,
+ });
+
+ expect(result).toEqual('lte block');
+ });
+
+ it('shoud render alternative block', async () => {
+ const result = await useCase.execute({
+ data: { steps: 6 },
+ template,
+ });
+
+ expect(result).toEqual('else block');
+ });
+ });
+
+ describe('eq helper', () => {
+ const template = `{{#eq steps 5 }}eq block{{else}}else block{{/eq}}`;
+ it('shoud render eq block', async () => {
+ const result = await useCase.execute({
+ data: { steps: 5 },
+ template,
+ });
+
+ expect(result).toEqual('eq block');
+ });
+
+ it('shoud use strict check and render alternative block', async () => {
+ const result = await useCase.execute({
+ data: { steps: '5' },
+ template,
+ });
+
+ expect(result).toEqual('else block');
+ });
+
+ it('shoud render alternative block', async () => {
+ const result = await useCase.execute({
+ data: { steps: 6 },
+ template,
+ });
+
+ expect(result).toEqual('else block');
+ });
+ });
+
+ describe('ne helper', () => {
+ const template = `{{#ne steps 5 }}ne block{{else}}else block{{/ne}}`;
+ it('shoud render ne block', async () => {
+ const result = await useCase.execute({
+ data: { steps: 6 },
+ template,
+ });
+
+ expect(result).toEqual('ne block');
+ });
+
+ it('shoud use strict check and render ne block', async () => {
+ const result = await useCase.execute({
+ data: { steps: '5' },
+ template,
+ });
+
+ expect(result).toEqual('ne block');
+ });
+
+ it('shoud render alternative block', async () => {
+ const result = await useCase.execute({
+ data: { steps: 5 },
+ template,
+ });
+
+ expect(result).toEqual('else block');
+ });
+ });
});
diff --git a/packages/application-generic/src/usecases/compile-template/compile-template.usecase.ts b/packages/application-generic/src/usecases/compile-template/compile-template.usecase.ts
index 1669e6c0d13..bd78462aa2c 100644
--- a/packages/application-generic/src/usecases/compile-template/compile-template.usecase.ts
+++ b/packages/application-generic/src/usecases/compile-template/compile-template.usecase.ts
@@ -158,6 +158,60 @@ Handlebars.registerHelper(
}
);
+Handlebars.registerHelper(
+ HandlebarHelpersEnum.GT,
+ function (arg1, arg2, options) {
+ // eslint-disable-next-line
+ // @ts-expect-error
+ return arg1 > arg2 ? options.fn(this) : options.inverse(this);
+ }
+);
+
+Handlebars.registerHelper(
+ HandlebarHelpersEnum.GTE,
+ function (arg1, arg2, options) {
+ // eslint-disable-next-line
+ // @ts-expect-error
+ return arg1 >= arg2 ? options.fn(this) : options.inverse(this);
+ }
+);
+
+Handlebars.registerHelper(
+ HandlebarHelpersEnum.LT,
+ function (arg1, arg2, options) {
+ // eslint-disable-next-line
+ // @ts-expect-error
+ return arg1 < arg2 ? options.fn(this) : options.inverse(this);
+ }
+);
+
+Handlebars.registerHelper(
+ HandlebarHelpersEnum.LTE,
+ function (arg1, arg2, options) {
+ // eslint-disable-next-line
+ // @ts-expect-error
+ return arg1 <= arg2 ? options.fn(this) : options.inverse(this);
+ }
+);
+
+Handlebars.registerHelper(
+ HandlebarHelpersEnum.EQ,
+ function (arg1, arg2, options) {
+ // eslint-disable-next-line
+ // @ts-expect-error
+ return arg1 === arg2 ? options.fn(this) : options.inverse(this);
+ }
+);
+
+Handlebars.registerHelper(
+ HandlebarHelpersEnum.NE,
+ function (arg1, arg2, options) {
+ // eslint-disable-next-line
+ // @ts-expect-error
+ return arg1 !== arg2 ? options.fn(this) : options.inverse(this);
+ }
+);
+
@Injectable()
export class CompileTemplate {
async execute(command: CompileTemplateCommand): Promise {
diff --git a/packages/application-generic/src/usecases/create-subscriber/create-subscriber.usecase.ts b/packages/application-generic/src/usecases/create-subscriber/create-subscriber.usecase.ts
index 7ce65018ee5..a49078fd0ac 100644
--- a/packages/application-generic/src/usecases/create-subscriber/create-subscriber.usecase.ts
+++ b/packages/application-generic/src/usecases/create-subscriber/create-subscriber.usecase.ts
@@ -1,6 +1,6 @@
import { Injectable, Logger } from '@nestjs/common';
import { SubscriberRepository } from '@novu/dal';
-import { SubscriberEntity } from '@novu/dal';
+import { SubscriberEntity, ErrorCodesEnum } from '@novu/dal';
import {
CachedEntity,
@@ -30,6 +30,30 @@ export class CreateSubscriber {
}));
if (!subscriber) {
+ subscriber = await this.createSubscriber(command);
+ } else {
+ subscriber = await this.updateSubscriber.execute(
+ UpdateSubscriberCommand.create({
+ environmentId: command.environmentId,
+ organizationId: command.organizationId,
+ firstName: command.firstName,
+ lastName: command.lastName,
+ subscriberId: command.subscriberId,
+ email: command.email,
+ phone: command.phone,
+ avatar: command.avatar,
+ locale: command.locale,
+ data: command.data,
+ subscriber,
+ })
+ );
+ }
+
+ return subscriber;
+ }
+
+ private async createSubscriber(command: CreateSubscriberCommand) {
+ try {
await this.invalidateCache.invalidateByKey({
key: buildSubscriberKey({
subscriberId: command.subscriberId,
@@ -50,26 +74,20 @@ export class CreateSubscriber {
data: command.data,
};
- subscriber = await this.subscriberRepository.create(subscriberPayload);
- } else {
- subscriber = await this.updateSubscriber.execute(
- UpdateSubscriberCommand.create({
- environmentId: command.environmentId,
- organizationId: command.organizationId,
- firstName: command.firstName,
- lastName: command.lastName,
+ return await this.subscriberRepository.create(subscriberPayload);
+ } catch (err: any) {
+ /*
+ * Possible race condition on subscriber creation, try fetch newly created the subscriber
+ */
+ if (err.code === ErrorCodesEnum.DUPLICATE_KEY) {
+ return await this.fetchSubscriber({
+ _environmentId: command.environmentId,
subscriberId: command.subscriberId,
- email: command.email,
- phone: command.phone,
- avatar: command.avatar,
- locale: command.locale,
- data: command.data,
- subscriber,
- })
- );
+ });
+ } else {
+ throw err;
+ }
}
-
- return subscriber;
}
@CachedEntity({
diff --git a/packages/application-generic/src/usecases/subscriber-job-bound/subscriber-job-bound.usecase.ts b/packages/application-generic/src/usecases/subscriber-job-bound/subscriber-job-bound.usecase.ts
index 377ae664eab..181cfc5f77c 100644
--- a/packages/application-generic/src/usecases/subscriber-job-bound/subscriber-job-bound.usecase.ts
+++ b/packages/application-generic/src/usecases/subscriber-job-bound/subscriber-job-bound.usecase.ts
@@ -85,10 +85,20 @@ export class SubscriberJobBound {
await this.validateSubscriberIdProperty(subscriber);
+ /**
+ * Due to Mixpanel HotSharding, we don't want to pass userId for production volume
+ */
+ const segmentUserId = ['test-workflow', 'digest-playground'].includes(
+ command.payload.__source
+ )
+ ? userId
+ : '';
+
this.analyticsService.mixpanelTrack(
'Notification event trigger - [Triggers]',
- '',
+ segmentUserId,
{
+ name: template.name,
type: template?.type || 'REGULAR',
transactionId: command.transactionId,
_template: template._id,
diff --git a/packages/application-generic/src/usecases/trigger-multicast/trigger-multicast.usecase.ts b/packages/application-generic/src/usecases/trigger-multicast/trigger-multicast.usecase.ts
index faba8fabda6..f8c0ae1f8ca 100644
--- a/packages/application-generic/src/usecases/trigger-multicast/trigger-multicast.usecase.ts
+++ b/packages/application-generic/src/usecases/trigger-multicast/trigger-multicast.usecase.ts
@@ -1,6 +1,5 @@
-import { Injectable, NotFoundException } from '@nestjs/common';
+import { Injectable, NotFoundException, Logger } from '@nestjs/common';
import * as _ from 'lodash';
-
import {
TopicEntity,
TopicRepository,
@@ -84,6 +83,11 @@ export class TriggerMulticast {
);
if (!isEnabled) {
+ Logger.log(
+ `The IS_TOPIC_NOTIFICATION_ENABLED feature flag is disabled, skipping trigger multicast`,
+ LOG_CONTEXT
+ );
+
return;
}
diff --git a/packages/cli/README.MD b/packages/cli/README.MD
index c474f236c8d..9e41584d32a 100644
--- a/packages/cli/README.MD
+++ b/packages/cli/README.MD
@@ -89,7 +89,7 @@ Using the Novu API and admin panel you can easily add real-time notification cen
- Read more about how to add a notification center to your app with the Novu API [here](https://docs.novu.co/notification-center/introduction)
+ Read more about how to add a notification center to your app with the Novu API [here](https://docs.novu.co/notification-center/introduction?utm_campaign=inapp-cli-readme)
@@ -140,7 +140,7 @@ Novu provides a single API to manage providers across multiple channels with a s
#### 📱 In-App
-- [x] [Novu](https://docs.novu.co/notification-center/introduction)
+- [x] [Novu](https://docs.novu.co/notification-center/introduction?utm_campaign=inapp-cli-readme)
- [ ] MagicBell
#### Other (Coming Soon...)
diff --git a/packages/cli/package.json b/packages/cli/package.json
index 5dcc0673eda..925808c4ad3 100644
--- a/packages/cli/package.json
+++ b/packages/cli/package.json
@@ -1,6 +1,6 @@
{
"name": "novu",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "On-Boarding Cli",
"main": "index.js",
"scripts": {
@@ -30,7 +30,7 @@
"typescript": "4.9.5"
},
"dependencies": {
- "@novu/shared": "^0.24.0",
+ "@novu/shared": "^0.24.1",
"@segment/analytics-node": "^1.1.4",
"axios": "^1.6.2",
"chalk": "4.1.2",
diff --git a/packages/client/package.json b/packages/client/package.json
index 2771893939b..9bee7ec63c0 100644
--- a/packages/client/package.json
+++ b/packages/client/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/client",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0"
+ "@novu/shared": "^0.24.1"
},
"devDependencies": {
"@types/jest": "29.5.2",
diff --git a/packages/headless/package.json b/packages/headless/package.json
index f49a2a2bd1d..ba838f4da2c 100644
--- a/packages/headless/package.json
+++ b/packages/headless/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/headless",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
- "@novu/shared": "^0.24.0",
+ "@novu/client": "^0.24.1",
+ "@novu/shared": "^0.24.1",
"@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 62c5dd9b7d4..0a952ae52c6 100644
--- a/packages/nest/package.json
+++ b/packages/nest/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/nest",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "A nestjs wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -36,7 +36,7 @@
},
"dependencies": {
"@nestjs/common": "10.2.2",
- "@novu/stateless": "^0.24.0"
+ "@novu/stateless": "^0.24.1"
},
"devDependencies": {
"@istanbuljs/nyc-config-typescript": "^1.0.1",
diff --git a/packages/node/README.md b/packages/node/README.md
index ba07fb028fa..000ee5ab8ee 100644
--- a/packages/node/README.md
+++ b/packages/node/README.md
@@ -126,7 +126,7 @@ Novu provides a single API to manage providers across multiple channels with a s
#### 📱 In-App
-- [x] [Novu](https://docs.novu.co/notification-center/introduction)
+- [x] [Novu](https://docs.novu.co/notification-center/introduction?utm_campaign=node-sdk-readme)
- [ ] MagicBell
#### Other (Coming Soon...)
diff --git a/packages/node/jest.config.js b/packages/node/jest.config.js
new file mode 100644
index 00000000000..f89c15a9700
--- /dev/null
+++ b/packages/node/jest.config.js
@@ -0,0 +1,7 @@
+module.exports = {
+ preset: 'ts-jest',
+ testEnvironment: 'node',
+ moduleNameMapper: {
+ uuid: require.resolve('uuid'),
+ },
+};
diff --git a/packages/node/package.json b/packages/node/package.json
index 54cf94f0775..cce620a51f9 100644
--- a/packages/node/package.json
+++ b/packages/node/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/node",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
+ "@novu/shared": "^0.24.1",
"axios-retry": "^3.8.0",
"handlebars": "^4.7.7",
"lodash.get": "^4.4.2",
@@ -57,13 +57,13 @@
"@types/uuid": "^8.3.4",
"axios": "^1.6.2",
"codecov": "^3.5.0",
- "jest": "^27.0.6",
+ "jest": "^29.7.0",
"nock": "^13.1.3",
"npm-run-all": "^4.1.5",
"open-cli": "^6.0.1",
"rimraf": "^3.0.2",
"run-p": "0.0.0",
- "ts-jest": "^27.0.5",
+ "ts-jest": "^29.1.2",
"typedoc": "^0.24.0",
"typescript": "4.9.5"
},
@@ -76,13 +76,6 @@
"LICENSE",
"README.md"
],
- "jest": {
- "preset": "ts-jest",
- "testEnvironment": "node",
- "moduleNameMapper": {
- "^axios$": "axios/dist/node/axios.cjs"
- }
- },
"prettier": {
"singleQuote": true
}
diff --git a/packages/node/src/lib/novu.interface.ts b/packages/node/src/lib/novu.interface.ts
index 953238f47ec..7058f726538 100644
--- a/packages/node/src/lib/novu.interface.ts
+++ b/packages/node/src/lib/novu.interface.ts
@@ -9,6 +9,7 @@ export interface IRetryConfig {
}
export interface INovuConfiguration {
+ apiKey?: string;
backendUrl?: string;
retryConfig?: IRetryConfig;
}
diff --git a/packages/node/src/lib/novu.spec.ts b/packages/node/src/lib/novu.spec.ts
index 210ecf57c4f..c17e0d0974a 100644
--- a/packages/node/src/lib/novu.spec.ts
+++ b/packages/node/src/lib/novu.spec.ts
@@ -7,6 +7,27 @@ const mockConfig = {
jest.mock('axios');
+describe('test initialization of novu node package', () => {
+ let novu: Novu;
+
+ const originalEnv = process.env;
+
+ beforeEach(() => {
+ process.env = {
+ ...originalEnv,
+ NOVU_API_KEY: 'cafebabe',
+ };
+ });
+
+ afterEach(() => {
+ process.env = originalEnv;
+ });
+
+ test('should use the NOVU_API_KEY when defined', async () => {
+ expect(new Novu().apiKey).toBe('cafebabe');
+ });
+});
+
describe('test use of novu node package', () => {
const mockedAxios = axios as jest.Mocked;
let novu: Novu;
diff --git a/packages/node/src/lib/novu.ts b/packages/node/src/lib/novu.ts
index 250e92388de..c847768b0b3 100644
--- a/packages/node/src/lib/novu.ts
+++ b/packages/node/src/lib/novu.ts
@@ -1,4 +1,5 @@
import axios, { AxiosInstance } from 'axios';
+import { getEnvVariable } from '@novu/shared/utils';
import { Subscribers } from './subscribers/subscribers';
import { EventEmitter } from 'events';
import { Changes } from './changes/changes';
@@ -21,7 +22,7 @@ import { WorkflowOverrides } from './workflow-override/workflow-override';
import { makeRetryable } from './retry';
export class Novu extends EventEmitter {
- private readonly apiKey?: string;
+ public readonly apiKey?: string;
private readonly http: AxiosInstance;
readonly subscribers: Subscribers;
readonly environments: Environments;
@@ -40,8 +41,25 @@ export class Novu extends EventEmitter {
readonly organizations: Organizations;
readonly workflowOverrides: WorkflowOverrides;
- constructor(apiKey: string, config?: INovuConfiguration) {
+ constructor(config?: INovuConfiguration);
+ constructor(apiKey: string, config?: INovuConfiguration);
+ constructor(...args: any) {
super();
+
+ let apiKey: string | undefined;
+ let config: INovuConfiguration | undefined;
+
+ if (arguments.length === 2) {
+ apiKey = args[0];
+ config = args[1];
+ } else if (arguments.length === 1) {
+ const { apiKey: key, ...rest } = args[0];
+ apiKey = key;
+ config = rest;
+ } else {
+ apiKey = getEnvVariable('NOVU_API_KEY');
+ }
+
this.apiKey = apiKey;
const axiosInstance = axios.create({
baseURL: this.buildBackendUrl(config),
diff --git a/packages/node/tsconfig.json b/packages/node/tsconfig.json
index 5543b8179c6..0f033d8a1ab 100644
--- a/packages/node/tsconfig.json
+++ b/packages/node/tsconfig.json
@@ -4,7 +4,8 @@
"strictNullChecks": true,
"allowSyntheticDefaultImports": true,
"outDir": "build/main",
- "module": "commonjs",
+ "module": "CommonJS",
+ "moduleResolution": "NodeNext",
"esModuleInterop": true,
"rootDir": "src",
"strict": true,
diff --git a/packages/notification-center-angular/package.json b/packages/notification-center-angular/package.json
index 8dbc08b6ea3..dd888c168d9 100644
--- a/packages/notification-center-angular/package.json
+++ b/packages/notification-center-angular/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/angular-workspace",
- "version": "0.24.0",
+ "version": "0.24.1",
"scripts": {
"ng": "ng",
"start": "ng serve",
@@ -19,7 +19,7 @@
"@angular/platform-browser": "^16.2.0",
"@angular/platform-browser-dynamic": "^16.2.0",
"@angular/router": "^16.2.0",
- "@novu/notification-center": "^0.24.0",
+ "@novu/notification-center": "^0.24.1",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.13.0"
diff --git a/packages/notification-center-angular/projects/notification-center-angular/README.md b/packages/notification-center-angular/projects/notification-center-angular/README.md
index c774fb4d400..78770371ac7 100644
--- a/packages/notification-center-angular/projects/notification-center-angular/README.md
+++ b/packages/notification-center-angular/projects/notification-center-angular/README.md
@@ -16,7 +16,7 @@ This library contains a wrapper for the Novu Notification Center web component,
## 📖 Client Installation
-For our client installation guide, visit our [Angular Client docs](https://docs.novu.co/notification-center/client/angular).
+For our client installation guide, visit our [Angular Client docs](https://docs.novu.co/notification-center/client/angular?utm_campaign=github-notificationcenter-angular-readme).
## 🏃♂️ Quickstart
diff --git a/packages/notification-center-angular/projects/notification-center-angular/package.json b/packages/notification-center-angular/projects/notification-center-angular/package.json
index 1544c87428d..3bb2c3b296f 100644
--- a/packages/notification-center-angular/projects/notification-center-angular/package.json
+++ b/packages/notification-center-angular/projects/notification-center-angular/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/notification-center-angular",
- "version": "0.24.0",
+ "version": "0.24.1",
"peerDependencies": {
"@angular/common": "^15.0.0 || ^16.0.0 || ^17.0.0",
"@angular/core": "^15.0.0 || ^16.0.0 || ^17.0.0",
@@ -8,7 +8,7 @@
"@angular/platform-browser-dynamic": "^15.0.0 || ^16.0.0 || ^17.0.0"
},
"dependencies": {
- "@novu/notification-center": "^0.24.0",
+ "@novu/notification-center": "^0.24.1",
"@types/react": "^17.0.0",
"react": "^17.0.1",
"react-dom": "^17.0.1",
diff --git a/packages/notification-center-vue/package.json b/packages/notification-center-vue/package.json
index 4369f2ae6dc..9927b969a0e 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.24.0",
+ "version": "0.24.1",
"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.24.0",
+ "@novu/notification-center": "^0.24.1",
"react": "^17.0.1",
"react-dom": "^17.0.1"
},
diff --git a/packages/notification-center/package.json b/packages/notification-center/package.json
index 959093c61fa..5746b338d49 100644
--- a/packages/notification-center/package.json
+++ b/packages/notification-center/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/notification-center",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
- "@novu/shared": "^0.24.0",
+ "@novu/client": "^0.24.1",
+ "@novu/shared": "^0.24.1",
"@tanstack/react-query": "^4.20.4",
"acorn-jsx": "^5.3.2",
"axios": "^1.6.2",
diff --git a/packages/stateless/README.md b/packages/stateless/README.md
index 5aa98cf7972..091c367a0c2 100644
--- a/packages/stateless/README.md
+++ b/packages/stateless/README.md
@@ -99,7 +99,7 @@ Novu provides a single API to manage providers across multiple channels with a s
#### 📱 In-App
-- [x] [Novu](https://docs.novu.co/notification-center/introduction)
+- [x] [Novu](https://docs.novu.co/notification-center/introduction?utm_source=github-stateless-readme)
- [ ] MagicBell
#### Other (Coming Soon...)
diff --git a/packages/stateless/package.json b/packages/stateless/package.json
index daaa10e79c0..3e4b12760dd 100644
--- a/packages/stateless/package.json
+++ b/packages/stateless/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/stateless",
- "version": "0.24.0",
+ "version": "0.24.1",
"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 d1a10ce56f2..9a73594a527 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -79,8 +79,8 @@ importers:
specifier: ^5.0.0
version: 5.0.0
'@types/inquirer':
- specifier: 8.2.9
- version: 8.2.9
+ specifier: 8.2.10
+ version: 8.2.10
'@types/jest':
specifier: 29.5.2
version: 29.5.2
@@ -233,7 +233,7 @@ importers:
version: 6.1.13
ts-jest:
specifier: 27.1.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@16.11.7)(typescript@4.9.5)
@@ -280,22 +280,22 @@ importers:
specifier: ^5.0.1
version: 5.1.1(@nestjs/common@10.2.2)(@nestjs/core@10.2.2)(reflect-metadata@0.1.13)
'@novu/application-generic':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/application-generic
'@novu/dal':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../libs/dal
'@novu/node':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/node
'@novu/shared':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../libs/shared
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
'@novu/testing':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../libs/testing
'@sendgrid/mail':
specifier: ^8.1.0
@@ -428,16 +428,16 @@ importers:
version: 8.3.2
optionalDependencies:
'@novu/ee-auth':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../enterprise/packages/auth
'@novu/ee-billing':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../enterprise/packages/billing
'@novu/ee-chimera':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../enterprise/packages/chimera
'@novu/ee-translation':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../enterprise/packages/translation
devDependencies:
'@faker-js/faker':
@@ -513,10 +513,10 @@ importers:
apps/inbound-mail:
dependencies:
'@novu/application-generic':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/application-generic
'@novu/shared':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../libs/shared
'@sentry/node':
specifier: ^7.12.1
@@ -568,7 +568,7 @@ importers:
version: 3.10.0
devDependencies:
'@novu/testing':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../libs/testing
'@types/chai':
specifier: ^4.2.11
@@ -608,7 +608,7 @@ importers:
version: 9.2.4
ts-jest:
specifier: ^27.0.7
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-loader:
specifier: ~9.4.0
version: 9.4.2(typescript@4.9.5)(webpack@5.78.0)
@@ -629,13 +629,13 @@ importers:
version: 4.6.2(react-dom@17.0.2)(react@17.0.2)
'@babel/plugin-proposal-optional-chaining':
specifier: ^7.20.7
- version: 7.21.0(@babel/core@7.23.2)
+ version: 7.21.0(@babel/core@7.24.4)
'@babel/plugin-transform-react-display-name':
specifier: ^7.18.6
- version: 7.18.6(@babel/core@7.23.2)
+ version: 7.18.6(@babel/core@7.24.4)
'@babel/plugin-transform-runtime':
specifier: ^7.23.2
- version: 7.23.2(@babel/core@7.23.2)
+ version: 7.23.2(@babel/core@7.24.4)
'@cypress/react':
specifier: ^7.0.3
version: 7.0.3(@types/react@17.0.53)(cypress@13.3.1)(react-dom@17.0.2)(react@17.0.2)
@@ -703,16 +703,16 @@ importers:
specifier: ^4.6.0
version: 4.6.0(monaco-editor@0.45.0)(react-dom@17.0.2)(react@17.0.2)
'@novu/design-system':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../libs/design-system
'@novu/notification-center':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/notification-center
'@novu/shared':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../libs/shared
'@novu/shared-web':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../libs/shared-web
'@rive-app/react-canvas':
specifier: ^4.8.1
@@ -914,10 +914,13 @@ importers:
version: 3.22.4
optionalDependencies:
'@novu/ee-billing-web':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../enterprise/packages/billing-web
+ '@novu/ee-echo-web':
+ specifier: ^0.24.1
+ version: link:../../enterprise/packages/web/echo
'@novu/ee-translation-web':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../enterprise/packages/translation-web
devDependencies:
'@babel/polyfill':
@@ -925,25 +928,28 @@ importers:
version: 7.12.1
'@babel/preset-env':
specifier: ^7.23.2
- version: 7.23.2(@babel/core@7.23.2)
+ version: 7.23.2(@babel/core@7.24.4)
'@babel/preset-react':
specifier: ^7.13.13
- version: 7.18.6(@babel/core@7.23.2)
+ version: 7.18.6(@babel/core@7.24.4)
'@babel/preset-typescript':
specifier: ^7.13.0
- version: 7.21.4(@babel/core@7.23.2)
+ version: 7.21.4(@babel/core@7.24.4)
'@babel/runtime':
specifier: ^7.20.13
version: 7.21.0
'@novu/dal':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../libs/dal
'@novu/testing':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../libs/testing
'@pandacss/dev':
specifier: ^0.34.0
version: 0.34.0(jsdom@24.0.0)(typescript@4.9.5)
+ '@playwright/test':
+ specifier: ^1.42.1
+ version: 1.42.1
'@storybook/addon-actions':
specifier: ^7.4.2
version: 7.4.2(@types/react-dom@17.0.19)(@types/react@17.0.53)(react-dom@17.0.2)(react@17.0.2)
@@ -961,13 +967,13 @@ importers:
version: 7.4.2
'@storybook/preset-create-react-app':
specifier: ^7.4.2
- version: 7.4.2(@babel/core@7.23.2)(react-refresh@0.14.0)(react-scripts@5.0.1)(typescript@4.9.5)(webpack-dev-server@4.11.1)(webpack@5.78.0)
+ version: 7.4.2(@babel/core@7.24.4)(react-refresh@0.14.0)(react-scripts@5.0.1)(typescript@4.9.5)(webpack-dev-server@4.11.1)(webpack@5.78.0)
'@storybook/react':
specifier: ^7.4.2
version: 7.4.2(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)
'@storybook/react-webpack5':
specifier: ^7.4.2
- version: 7.4.2(@babel/core@7.23.2)(@swc/core@1.3.49)(@types/react-dom@17.0.19)(@types/react@17.0.53)(esbuild@0.18.20)(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)(webpack-dev-server@4.11.1)
+ version: 7.4.2(@babel/core@7.24.4)(@swc/core@1.3.49)(@types/react-dom@17.0.19)(@types/react@17.0.53)(esbuild@0.18.20)(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)(webpack-dev-server@4.11.1)
'@testing-library/jest-dom':
specifier: ^4.2.4
version: 4.2.4
@@ -1044,19 +1050,19 @@ importers:
specifier: ^10.0.1
version: 10.0.1(@nestjs/axios@2.0.0)(@nestjs/common@10.2.2)(@nestjs/core@10.2.2)(reflect-metadata@0.1.13)(rxjs@7.8.1)
'@novu/application-generic':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/application-generic
'@novu/dal':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../libs/dal
'@novu/shared':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../libs/shared
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
'@novu/testing':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../libs/testing
'@sentry/node':
specifier: ^7.66.0
@@ -1154,7 +1160,7 @@ importers:
version: 6.3.3
ts-jest:
specifier: ^27.0.7
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
ts-loader:
specifier: ~9.4.0
version: 9.4.2(typescript@4.9.5)(webpack@5.78.0)
@@ -1181,15 +1187,15 @@ importers:
version: 11.10.6(@emotion/react@11.10.6)(@types/react@17.0.62)(react@17.0.2)
'@mantine/core':
specifier: 4.2.12
- version: 4.2.12(@babel/core@7.23.2)(@mantine/hooks@4.2.12)(@types/react@17.0.62)(react-dom@17.0.2)(react@17.0.2)
+ version: 4.2.12(@babel/core@7.24.4)(@mantine/hooks@4.2.12)(@types/react@17.0.62)(react-dom@17.0.2)(react@17.0.2)
'@mantine/hooks':
specifier: 4.2.12
version: 4.2.12(react@17.0.2)
'@novu/notification-center':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/notification-center
'@novu/shared':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../libs/shared
antd:
specifier: ^4.10.0
@@ -1248,25 +1254,25 @@ importers:
devDependencies:
'@babel/plugin-proposal-optional-chaining':
specifier: ^7.20.7
- version: 7.21.0(@babel/core@7.23.2)
+ version: 7.21.0(@babel/core@7.24.4)
'@babel/plugin-transform-react-display-name':
specifier: ^7.18.6
- version: 7.22.5(@babel/core@7.23.2)
+ version: 7.22.5(@babel/core@7.24.4)
'@babel/plugin-transform-runtime':
specifier: ^7.23.2
- version: 7.23.2(@babel/core@7.23.2)
+ version: 7.23.2(@babel/core@7.24.4)
'@babel/polyfill':
specifier: ^7.12.1
version: 7.12.1
'@babel/preset-env':
specifier: ^7.23.2
- version: 7.23.2(@babel/core@7.23.2)
+ version: 7.23.2(@babel/core@7.24.4)
'@babel/preset-react':
specifier: ^7.13.13
- version: 7.22.15(@babel/core@7.23.2)
+ version: 7.22.15(@babel/core@7.24.4)
'@babel/preset-typescript':
specifier: ^7.13.0
- version: 7.21.4(@babel/core@7.23.2)
+ version: 7.21.4(@babel/core@7.24.4)
'@babel/runtime':
specifier: ^7.20.13
version: 7.21.0
@@ -1277,10 +1283,10 @@ importers:
specifier: ^6.0.0
version: 6.3.1
'@novu/dal':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../libs/dal
'@novu/testing':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../libs/testing
'@types/jest':
specifier: ^29.5.0
@@ -1364,19 +1370,19 @@ importers:
specifier: ^10.0.1
version: 10.0.1(@nestjs/axios@2.0.0)(@nestjs/common@10.2.2)(@nestjs/core@10.2.2)(reflect-metadata@0.1.13)(rxjs@7.8.1)
'@novu/application-generic':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/application-generic
'@novu/dal':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../libs/dal
'@novu/shared':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../libs/shared
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
'@novu/testing':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../libs/testing
'@sentry/node':
specifier: ^7.40.0
@@ -1452,16 +1458,16 @@ importers:
version: 8.3.2
optionalDependencies:
'@novu/ee-auth':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../enterprise/packages/auth
'@novu/ee-billing':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../enterprise/packages/billing
'@novu/ee-chimera-connect':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../enterprise/packages/chimera-connect
'@novu/ee-translation':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../enterprise/packages/translation
devDependencies:
'@faker-js/faker':
@@ -1558,16 +1564,16 @@ importers:
specifier: ^10.2.2
version: 10.2.2(@nestjs/common@10.2.2)(@nestjs/core@10.2.2)(@nestjs/platform-socket.io@10.2.2)(reflect-metadata@0.1.13)(rxjs@7.8.1)
'@novu/application-generic':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/application-generic
'@novu/dal':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../libs/dal
'@novu/shared':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../libs/shared
'@novu/testing':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../libs/testing
'@sentry/node':
specifier: ^7.30.0
@@ -1694,13 +1700,13 @@ importers:
specifier: 9.0.3
version: 9.0.3(@nestjs/common@10.2.2)(passport@0.6.0)
'@novu/application-generic':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../../packages/application-generic
'@novu/dal':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../../libs/dal
'@novu/shared':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../../libs/shared
passport:
specifier: 0.6.0
@@ -1764,16 +1770,16 @@ importers:
specifier: ^5.0.1
version: 5.1.1(@nestjs/common@10.2.2)(@nestjs/core@10.2.2)(reflect-metadata@0.1.13)
'@novu/application-generic':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../../packages/application-generic
'@novu/dal':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../../libs/dal
'@novu/ee-dal':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../libs/dal
'@novu/shared':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../../libs/shared
class-transformer:
specifier: ^0.5.1
@@ -1852,16 +1858,16 @@ importers:
specifier: ^5.7.1
version: 5.10.5(react@17.0.2)
'@novu/client':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../../packages/client
'@novu/design-system':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../../libs/design-system
'@novu/shared':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../../libs/shared
'@novu/shared-web':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../../libs/shared-web
'@rjsf/chakra-ui':
specifier: ^5.17.1
@@ -1946,22 +1952,22 @@ importers:
specifier: 9.0.3
version: 9.0.3(@nestjs/common@10.2.2)(passport@0.6.0)
'@novu/application-generic':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../../packages/application-generic
'@novu/dal':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../../libs/dal
'@novu/ee-dal':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../libs/dal
'@novu/shared':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../../libs/shared
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../../packages/stateless
'@novu/testing':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../../libs/testing
axios:
specifier: ^1.6.2
@@ -2043,19 +2049,19 @@ importers:
specifier: 9.0.3
version: 9.0.3(@nestjs/common@10.2.2)(passport@0.6.0)
'@novu/dal':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../../libs/dal
'@novu/ee-dal':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../libs/dal
'@novu/shared':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../../libs/shared
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../../packages/stateless
'@novu/testing':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../../libs/testing
axios:
specifier: ^1.6.2
@@ -2128,10 +2134,10 @@ importers:
specifier: 10.2.2
version: 10.2.2(class-transformer@0.5.1)(class-validator@0.14.0)(reflect-metadata@0.1.13)(rxjs@7.8.1)
'@novu/dal':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../../../libs/dal
'@novu/shared':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../../../libs/shared
mongoose:
specifier: ^7.5.0
@@ -2180,16 +2186,16 @@ importers:
specifier: ^7.1.8
version: 7.1.9(@nestjs/common@10.2.2)(@nestjs/core@10.2.2)(class-transformer@0.5.1)(class-validator@0.14.0)(reflect-metadata@0.1.13)
'@novu/application-generic':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../../packages/application-generic
'@novu/dal':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../../libs/dal
'@novu/ee-dal':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../libs/dal
'@novu/shared':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../../libs/shared
class-transformer:
specifier: ^0.5.1
@@ -2274,16 +2280,16 @@ importers:
specifier: ^4.6.0
version: 4.6.0(monaco-editor@0.45.0)(react-dom@17.0.2)(react@17.0.2)
'@novu/client':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../../packages/client
'@novu/design-system':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../../libs/design-system
'@novu/shared':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../../libs/shared
'@novu/shared-web':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../../libs/shared-web
'@tanstack/react-query':
specifier: ^4.20.4
@@ -2341,6 +2347,67 @@ importers:
specifier: 4.9.5
version: 4.9.5
+ enterprise/packages/web/echo:
+ dependencies:
+ '@mantine/core':
+ specifier: ^5.7.1
+ version: 5.10.5(@emotion/react@11.10.6)(@mantine/hooks@5.10.5)(@types/react@17.0.62)(react-dom@17.0.2)(react@17.0.2)
+ '@mantine/hooks':
+ specifier: ^5.7.1
+ version: 5.10.5(react@17.0.2)
+ '@novu/design-system':
+ specifier: ^0.24.1
+ version: link:../../../../libs/design-system
+ '@novu/shared-web':
+ specifier: ^0.24.1
+ version: link:../../../../libs/shared-web
+ '@rjsf/core':
+ specifier: ^5.17.1
+ version: 5.17.1(@rjsf/utils@5.17.1)(react@17.0.2)
+ '@rjsf/validator-ajv8':
+ specifier: ^5.17.1
+ version: 5.17.1(@rjsf/utils@5.17.1)
+ '@tanstack/react-query':
+ specifier: ^4.20.4
+ version: 4.29.1(react-dom@17.0.2)(react@17.0.2)
+ react-router-dom:
+ specifier: 6.2.2
+ version: 6.2.2(react-dom@17.0.2)(react@17.0.2)
+ tslib:
+ specifier: ^2.3.1
+ version: 2.6.2
+ devDependencies:
+ '@types/node':
+ specifier: ^18.11.12
+ version: 18.18.5
+ '@types/react':
+ specifier: ^17.0.0
+ version: 17.0.62
+ '@types/react-dom':
+ specifier: ^17.0.0
+ version: 17.0.20
+ eslint:
+ specifier: ^8.33.0
+ version: 8.51.0
+ eslint-plugin-react-hooks:
+ specifier: ^4.4.0
+ version: 4.6.0(eslint@8.51.0)
+ react:
+ specifier: ^17.0.1
+ version: 17.0.2
+ react-dom:
+ specifier: ^17.0.1
+ version: 17.0.2(react@17.0.2)
+ rimraf:
+ specifier: ^3.0.2
+ version: 3.0.2
+ ts-loader:
+ specifier: ~9.4.0
+ version: 9.4.2(typescript@4.9.5)(webpack@5.78.0)
+ typescript:
+ specifier: 4.9.5
+ version: 4.9.5
+
libs/dal:
dependencies:
'@aws-sdk/client-s3':
@@ -2353,7 +2420,7 @@ importers:
specifier: ^6.0.0
version: 6.3.1
'@novu/shared':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../shared
JSONStream:
specifier: ^1.3.5
@@ -2471,13 +2538,13 @@ importers:
specifier: ^5.7.1
version: 5.10.5(@mantine/core@5.10.5)(@mantine/hooks@5.10.5)(react-dom@17.0.2)(react@17.0.2)
'@novu/client':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/client
'@novu/shared':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../shared
'@novu/shared-web':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../shared-web
'@segment/analytics-next':
specifier: 1.59.0
@@ -2527,7 +2594,7 @@ importers:
version: 7.4.2(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)
'@storybook/react-webpack5':
specifier: ^7.4.2
- version: 7.4.2(@babel/core@7.23.2)(@swc/core@1.3.49)(@types/react-dom@17.0.20)(@types/react@17.0.62)(esbuild@0.18.20)(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)
+ version: 7.4.2(@babel/core@7.24.4)(@swc/core@1.3.49)(@types/react-dom@17.0.20)(@types/react@17.0.62)(esbuild@0.18.20)(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)
'@storybook/theming':
specifier: ^7.4.2
version: 7.4.2(react-dom@17.0.2)(react@17.0.2)
@@ -2579,6 +2646,9 @@ importers:
react-router-dom:
specifier: 6.2.2
version: 6.2.2(react-dom@17.0.2)(react@17.0.2)
+ react-scanner:
+ specifier: ^1.1.0
+ version: 1.1.0
rimraf:
specifier: ^3.0.2
version: 3.0.2
@@ -2607,7 +2677,7 @@ importers:
libs/embed:
dependencies:
'@novu/notification-center':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/notification-center
'@types/iframe-resizer':
specifier: ^3.5.8
@@ -2696,7 +2766,7 @@ importers:
version: 0.8.5
ts-jest:
specifier: ^27.1.3
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -2747,7 +2817,7 @@ importers:
specifier: ^5.7.1
version: 5.10.5(react@17.0.2)
'@novu/shared':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../shared
'@segment/analytics-next':
specifier: 1.59.0
@@ -2802,10 +2872,10 @@ importers:
specifier: ^6.0.0
version: 6.3.1
'@novu/dal':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../dal
'@novu/shared':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../shared
JSONStream:
specifier: ^1.3.5
@@ -2935,202 +3005,202 @@ importers:
specifier: '>=10'
version: 10.2.2(@nestjs/common@10.2.2)(@nestjs/core@10.2.2)(@nestjs/platform-express@10.2.2)
'@novu/africas-talking':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/africas-talking
'@novu/apns':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/apns
'@novu/azure-sms':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/azure-sms
'@novu/bandwidth':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/bandwidth
'@novu/braze':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/braze
'@novu/brevo-sms':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/brevo-sms
'@novu/bulk-sms':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/bulk-sms
'@novu/burst-sms':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/burst-sms
'@novu/clickatell':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/clickatell
'@novu/clicksend':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/clicksend
'@novu/dal':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../libs/dal
'@novu/discord':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/discord
'@novu/email-webhook':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/email-webhook
'@novu/emailjs':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/emailjs
'@novu/expo':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/expo
'@novu/fcm':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/fcm
'@novu/firetext':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/firetext
'@novu/forty-six-elks':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/forty-six-elks
'@novu/generic-sms':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/generic-sms
'@novu/getstream':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/getstream
'@novu/grafana-on-call':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/grafana-on-call
'@novu/gupshup':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/gupshup
'@novu/infobip':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/infobip
'@novu/isend-sms':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/isend-sms
'@novu/kannel':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/kannel
'@novu/mailersend':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/mailersend
'@novu/mailgun':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/mailgun
'@novu/mailjet':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/mailjet
'@novu/mailtrap':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/mailtrap
'@novu/mandrill':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/mandrill
'@novu/maqsam':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/maqsam
'@novu/mattermost':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/mattermost
'@novu/messagebird':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/messagebird
'@novu/ms-teams':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/ms-teams
'@novu/netcore':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/netcore
'@novu/nexmo':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/nexmo
'@novu/nodemailer':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/nodemailer
'@novu/one-signal':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/one-signal
'@novu/outlook365':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/outlook365
'@novu/plivo':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/plivo
'@novu/plunk':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/plunk
'@novu/postmark':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/postmark
'@novu/push-webhook':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/push-webhook
'@novu/pusher-beams':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/pusher-beams
'@novu/pushpad':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/pushpad
'@novu/resend':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/resend
'@novu/ring-central':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/ring-central
'@novu/rocket-chat':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/rocket-chat
'@novu/ryver':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/ryver
'@novu/sendchamp':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/sendchamp
'@novu/sendgrid':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/sendgrid
'@novu/sendinblue':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/sendinblue
'@novu/ses':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/ses
'@novu/shared':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../libs/shared
'@novu/simpletexting':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/simpletexting
'@novu/slack':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/slack
'@novu/sms-central':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/sms-central
'@novu/sms77':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/sms77
'@novu/sns':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/sns
'@novu/sparkpost':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/sparkpost
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../stateless
'@novu/telnyx':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/telnyx
'@novu/termii':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/termii
'@novu/testing':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../libs/testing
'@novu/twilio':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/twilio
'@novu/zulip':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../providers/zulip
'@opentelemetry/api':
specifier: ^1.7.0
@@ -3153,6 +3223,9 @@ importers:
'@opentelemetry/exporter-prometheus':
specifier: ^0.46.0
version: 0.46.0(@opentelemetry/api@1.7.0)
+ '@opentelemetry/exporter-trace-otlp-http':
+ specifier: ^0.49.1
+ version: 0.49.1(@opentelemetry/api@1.7.0)
'@opentelemetry/instrumentation':
specifier: ^0.46.0
version: 0.46.0(@opentelemetry/api@1.7.0)
@@ -3254,7 +3327,7 @@ importers:
version: 7.8.1
optionalDependencies:
'@novu/ee-chimera-connect':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../enterprise/packages/chimera-connect
'@taskforcesh/bullmq-pro':
specifier: 5.1.14
@@ -3307,7 +3380,7 @@ importers:
version: 9.2.4
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -3318,7 +3391,7 @@ importers:
packages/cli:
dependencies:
'@novu/shared':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../libs/shared
'@segment/analytics-node':
specifier: ^1.1.4
@@ -3385,7 +3458,7 @@ importers:
packages/client:
dependencies:
'@novu/shared':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../libs/shared
devDependencies:
'@types/jest':
@@ -3408,7 +3481,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
typedoc:
specifier: ^0.24.0
version: 0.24.6(typescript@4.9.5)
@@ -3419,10 +3492,10 @@ importers:
packages/headless:
dependencies:
'@novu/client':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../client
'@novu/shared':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../libs/shared
'@tanstack/query-core':
specifier: ^4.15.1
@@ -3433,10 +3506,10 @@ importers:
devDependencies:
'@babel/preset-env':
specifier: ^7.23.2
- version: 7.23.2(@babel/core@7.23.2)
+ version: 7.23.2(@babel/core@7.24.4)
'@babel/preset-typescript':
specifier: ^7.13.0
- version: 7.21.4(@babel/core@7.23.2)
+ version: 7.21.4(@babel/core@7.24.4)
'@types/jest':
specifier: ^29.2.3
version: 29.5.0
@@ -3451,7 +3524,7 @@ importers:
version: 29.5.0
ts-jest:
specifier: ^29.0.3
- version: 29.1.0(@babel/core@7.23.2)(jest@29.5.0)(typescript@4.9.5)
+ version: 29.1.0(@babel/core@7.24.4)(jest@29.5.0)(typescript@4.9.5)
typedoc:
specifier: ^0.24.0
version: 0.24.6(typescript@4.9.5)
@@ -3465,7 +3538,7 @@ importers:
specifier: 10.2.2
version: 10.2.2(class-transformer@0.5.1)(class-validator@0.14.0)(reflect-metadata@0.1.13)(rxjs@7.8.1)
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../stateless
devDependencies:
'@istanbuljs/nyc-config-typescript':
@@ -3503,7 +3576,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -3517,7 +3590,7 @@ importers:
packages/node:
dependencies:
'@novu/shared':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../libs/shared
axios-retry:
specifier: ^3.8.0
@@ -3557,8 +3630,8 @@ importers:
specifier: ^3.5.0
version: 3.8.3
jest:
- specifier: ^27.0.6
- version: 27.5.1(ts-node@10.9.1)
+ specifier: ^29.7.0
+ version: 29.7.0(@types/node@14.18.42)(ts-node@10.9.1)
nock:
specifier: ^13.1.3
version: 13.3.0
@@ -3575,8 +3648,8 @@ importers:
specifier: 0.0.0
version: 0.0.0
ts-jest:
- specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
+ specifier: ^29.1.2
+ version: 29.1.2(@babel/core@7.24.4)(jest@29.7.0)(typescript@4.9.5)
typedoc:
specifier: ^0.24.0
version: 0.24.6(typescript@4.9.5)
@@ -3602,10 +3675,10 @@ importers:
specifier: ^5.7.1
version: 5.10.5(react@17.0.2)
'@novu/client':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../client
'@novu/shared':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../libs/shared
'@tanstack/react-query':
specifier: ^4.20.4
@@ -3640,13 +3713,13 @@ importers:
devDependencies:
'@babel/preset-env':
specifier: ^7.23.2
- version: 7.23.2(@babel/core@7.23.2)
+ version: 7.23.2(@babel/core@7.24.4)
'@babel/preset-react':
specifier: ^7.13.13
- version: 7.22.15(@babel/core@7.23.2)
+ version: 7.22.15(@babel/core@7.24.4)
'@babel/preset-typescript':
specifier: ^7.13.0
- version: 7.21.4(@babel/core@7.23.2)
+ version: 7.21.4(@babel/core@7.24.4)
'@storybook/addon-actions':
specifier: ^7.4.2
version: 7.4.2(@types/react-dom@17.0.19)(@types/react@17.0.53)(react-dom@17.0.2)(react@17.0.2)
@@ -3667,7 +3740,7 @@ importers:
version: 7.4.2(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)
'@storybook/react-webpack5':
specifier: ^7.4.2
- version: 7.4.2(@babel/core@7.23.2)(@swc/core@1.3.49)(@types/react-dom@17.0.19)(@types/react@17.0.53)(esbuild@0.18.20)(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)(webpack-cli@5.1.4)
+ version: 7.4.2(@babel/core@7.24.4)(@swc/core@1.3.49)(@types/react-dom@17.0.19)(@types/react@17.0.53)(esbuild@0.18.20)(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)(webpack-cli@5.1.4)
'@testing-library/dom':
specifier: ^9.3.0
version: 9.3.0
@@ -3700,7 +3773,7 @@ importers:
version: 8.8.2
babel-loader:
specifier: ^8.2.4
- version: 8.3.0(@babel/core@7.23.2)(webpack@5.82.1)
+ version: 8.3.0(@babel/core@7.24.4)(webpack@5.82.1)
compression-webpack-plugin:
specifier: ^10.0.0
version: 10.0.0(webpack@5.82.1)
@@ -3733,7 +3806,7 @@ importers:
version: 5.3.9(@swc/core@1.3.49)(esbuild@0.18.20)(webpack@5.82.1)
ts-jest:
specifier: ^29.0.3
- version: 29.1.0(@babel/core@7.23.2)(esbuild@0.18.20)(jest@29.5.0)(typescript@4.9.5)
+ version: 29.1.0(@babel/core@7.24.4)(esbuild@0.18.20)(jest@29.5.0)(typescript@4.9.5)
ts-loader:
specifier: ~9.4.0
version: 9.4.2(typescript@4.9.5)(webpack@5.82.1)
@@ -3780,7 +3853,7 @@ importers:
specifier: ^16.2.0
version: 16.2.11(@angular/common@16.2.11)(@angular/core@16.2.11)(@angular/platform-browser@16.2.11)(rxjs@7.8.1)
'@novu/notification-center':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../notification-center
rxjs:
specifier: ~7.8.0
@@ -3844,7 +3917,7 @@ importers:
specifier: ^15.0.0 || ^16.0.0 || ^17.0.0
version: 16.2.11(@angular/common@16.2.11)(@angular/compiler@16.2.11)(@angular/core@16.2.11)(@angular/platform-browser@16.2.11)
'@novu/notification-center':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../../notification-center
'@types/react':
specifier: ^17.0.0
@@ -3868,7 +3941,7 @@ importers:
specifier: ^2.0.3
version: 2.0.3(vue@3.2.47)
'@novu/notification-center':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../notification-center
react:
specifier: ^17.0.1
@@ -3967,7 +4040,7 @@ importers:
version: 0.0.0
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
typedoc:
specifier: ^0.24.0
version: 0.24.6(typescript@4.9.5)
@@ -3978,7 +4051,7 @@ importers:
providers/africas-talking:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
africastalking:
specifier: ^0.6.2
@@ -4010,7 +4083,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ~27.1.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -4021,7 +4094,7 @@ importers:
providers/apns:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
'@parse/node-apn':
specifier: ^5.2.3
@@ -4059,7 +4132,7 @@ importers:
version: 2.8.7
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -4076,7 +4149,7 @@ importers:
specifier: ^1.0.0
version: 1.0.0
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
devDependencies:
'@istanbuljs/nyc-config-typescript':
@@ -4105,7 +4178,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ~27.1.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -4119,7 +4192,7 @@ importers:
specifier: ^4.1.3
version: 4.1.3
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
devDependencies:
'@istanbuljs/nyc-config-typescript':
@@ -4148,7 +4221,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ~27.1.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -4159,7 +4232,7 @@ importers:
providers/braze:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
braze-api:
specifier: ^2.5.6
@@ -4191,7 +4264,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ~27.1.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -4202,7 +4275,7 @@ importers:
providers/brevo-sms:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
cross-fetch:
specifier: ^4.0.0
@@ -4240,7 +4313,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ~27.1.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -4251,7 +4324,7 @@ importers:
providers/bulk-sms:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
axios:
specifier: ^1.6.0
@@ -4283,7 +4356,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ~27.1.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -4294,7 +4367,7 @@ importers:
providers/burst-sms:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
axios:
specifier: ^1.6.2
@@ -4338,7 +4411,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -4355,7 +4428,7 @@ importers:
providers/clickatell:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
axios:
specifier: ^1.6.2
@@ -4393,7 +4466,7 @@ importers:
version: 2.8.7
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -4407,7 +4480,7 @@ importers:
providers/clicksend:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
axios:
specifier: ^1.6.0
@@ -4439,7 +4512,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ~27.1.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -4450,7 +4523,7 @@ importers:
providers/discord:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
axios:
specifier: ^1.6.2
@@ -4491,7 +4564,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -4505,7 +4578,7 @@ importers:
providers/email-webhook:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
axios:
specifier: ^1.6.2
@@ -4537,7 +4610,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ~27.1.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -4548,7 +4621,7 @@ importers:
providers/emailjs:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
emailjs:
specifier: ^3.6.0
@@ -4589,7 +4662,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -4603,7 +4676,7 @@ importers:
providers/expo:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
expo-server-sdk:
specifier: ^3.6.0
@@ -4644,7 +4717,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -4658,7 +4731,7 @@ importers:
providers/fcm:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
firebase-admin:
specifier: ^11.10.1
@@ -4708,7 +4781,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -4722,7 +4795,7 @@ importers:
providers/firetext:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
node-fetch:
specifier: ^3.2.10
@@ -4730,7 +4803,7 @@ importers:
devDependencies:
'@babel/preset-env':
specifier: ^7.23.2
- version: 7.23.2(@babel/core@7.23.2)
+ version: 7.23.2(@babel/core@7.24.4)
'@istanbuljs/nyc-config-typescript':
specifier: ^1.0.1
version: 1.0.2(nyc@15.1.0)
@@ -4772,7 +4845,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -4786,7 +4859,7 @@ importers:
providers/forty-six-elks:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
axios:
specifier: ^1.6.2
@@ -4818,7 +4891,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ~27.1.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -4829,7 +4902,7 @@ importers:
providers/generic-sms:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
axios:
specifier: ^1.6.2
@@ -4861,7 +4934,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ~27.1.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -4872,7 +4945,7 @@ importers:
providers/getstream:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
axios:
specifier: ^1.6.2
@@ -4904,7 +4977,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ~27.1.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -4915,7 +4988,7 @@ importers:
providers/grafana-on-call:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
axios:
specifier: ^1.6.2
@@ -4950,7 +5023,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ~27.1.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -4961,8 +5034,8 @@ importers:
providers/gupshup:
dependencies:
'@novu/stateless':
- specifier: ^0.23.1
- version: 0.23.1
+ specifier: ^0.24.1
+ version: link:../../packages/stateless
axios:
specifier: ^1.6.7
version: 1.6.7
@@ -4972,7 +5045,7 @@ importers:
devDependencies:
'@babel/preset-env':
specifier: ^7.23.2
- version: 7.23.2(@babel/core@7.23.2)
+ version: 7.23.2(@babel/core@7.24.4)
'@istanbuljs/nyc-config-typescript':
specifier: ^1.0.1
version: 1.0.2(nyc@15.1.0)
@@ -5008,7 +5081,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -5025,7 +5098,7 @@ importers:
specifier: ^0.3.2
version: 0.3.2
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
devDependencies:
'@istanbuljs/nyc-config-typescript':
@@ -5063,7 +5136,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -5077,7 +5150,7 @@ importers:
providers/isend-sms:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
axios:
specifier: ^1.6.0
@@ -5109,7 +5182,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ~27.1.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -5120,7 +5193,7 @@ importers:
providers/kannel:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
axios:
specifier: ^1.6.2
@@ -5161,7 +5234,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -5175,7 +5248,7 @@ importers:
providers/mailersend:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
mailersend:
specifier: ^1.3.1
@@ -5216,7 +5289,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -5230,7 +5303,7 @@ importers:
providers/mailgun:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
form-data:
specifier: ^4.0.0
@@ -5277,7 +5350,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -5291,7 +5364,7 @@ importers:
providers/mailjet:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
node-mailjet:
specifier: ^6.0.5
@@ -5335,7 +5408,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -5349,7 +5422,7 @@ importers:
providers/mailtrap:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
mailtrap:
specifier: ^3.1.1
@@ -5381,7 +5454,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ~27.1.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -5395,7 +5468,7 @@ importers:
specifier: ^1.0.50
version: 1.0.50
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
devDependencies:
'@istanbuljs/nyc-config-typescript':
@@ -5439,7 +5512,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -5453,7 +5526,7 @@ importers:
providers/maqsam:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
axios:
specifier: ^1.6.2
@@ -5491,7 +5564,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ~27.1.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -5502,7 +5575,7 @@ importers:
providers/mattermost:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
axios:
specifier: ^1.6.2
@@ -5534,7 +5607,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ~27.1.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -5545,7 +5618,7 @@ importers:
providers/messagebird:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
messagebird:
specifier: ^4.0.1
@@ -5577,7 +5650,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ~27.1.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -5588,7 +5661,7 @@ importers:
providers/ms-teams:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
axios:
specifier: ^1.6.2
@@ -5629,7 +5702,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -5646,7 +5719,7 @@ importers:
providers/netcore:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
axios:
specifier: ^1.6.2
@@ -5687,7 +5760,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.7
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -5701,7 +5774,7 @@ importers:
providers/nexmo:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
'@vonage/auth':
specifier: ^1.7.0
@@ -5745,7 +5818,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -5759,7 +5832,7 @@ importers:
providers/nodemailer:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
nodemailer:
specifier: ^6.6.5
@@ -5803,7 +5876,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.7
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -5817,7 +5890,7 @@ importers:
providers/one-signal:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
axios:
specifier: ^1.6.0
@@ -5849,7 +5922,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ~27.1.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -5860,7 +5933,7 @@ importers:
providers/outlook365:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
nodemailer:
specifier: ^6.6.5
@@ -5904,7 +5977,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -5918,7 +5991,7 @@ importers:
providers/plivo:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
plivo:
specifier: ^4.60.1
@@ -5959,7 +6032,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -5973,7 +6046,7 @@ importers:
providers/plunk:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
'@plunk/node':
specifier: 2.0.0
@@ -6005,7 +6078,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ~27.1.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -6016,7 +6089,7 @@ importers:
providers/postmark:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
axios:
specifier: ^1.6.2
@@ -6060,7 +6133,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -6074,7 +6147,7 @@ importers:
providers/push-webhook:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
axios:
specifier: ^1.6.2
@@ -6106,7 +6179,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ~27.1.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -6117,7 +6190,7 @@ importers:
providers/pusher-beams:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
axios:
specifier: ^1.6.0
@@ -6149,7 +6222,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ~27.1.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -6160,7 +6233,7 @@ importers:
providers/pushpad:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
pushpad:
specifier: 1.0.0
@@ -6192,7 +6265,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ~27.1.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -6203,7 +6276,7 @@ importers:
providers/resend:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
resend:
specifier: ^2.1.0
@@ -6244,7 +6317,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -6258,7 +6331,7 @@ importers:
providers/ring-central:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
'@ringcentral/sdk':
specifier: ^5.0.1
@@ -6290,7 +6363,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ~27.1.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -6301,7 +6374,7 @@ importers:
providers/rocket-chat:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
axios:
specifier: ^1.6.2
@@ -6333,7 +6406,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ~27.1.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -6344,7 +6417,7 @@ importers:
providers/ryver:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
axios:
specifier: ^1.6.2
@@ -6376,7 +6449,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ~27.1.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -6387,7 +6460,7 @@ importers:
providers/sendchamp:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
axios:
specifier: ^1.6.2
@@ -6419,7 +6492,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ~27.1.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -6430,7 +6503,7 @@ importers:
providers/sendgrid:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
'@sendgrid/mail':
specifier: ^8.1.0
@@ -6471,7 +6544,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -6485,7 +6558,7 @@ importers:
providers/sendinblue:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
axios:
specifier: ^1.6.2
@@ -6526,7 +6599,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -6543,7 +6616,7 @@ importers:
specifier: 3.382.0
version: 3.382.0
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
nodemailer:
specifier: ^6.6.5
@@ -6584,7 +6657,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -6598,7 +6671,7 @@ importers:
providers/simpletexting:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
axios:
specifier: ^1.6.2
@@ -6630,7 +6703,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ~27.1.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -6641,7 +6714,7 @@ importers:
providers/slack:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
axios:
specifier: ^1.6.2
@@ -6682,7 +6755,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -6696,7 +6769,7 @@ importers:
providers/sms-central:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
axios:
specifier: ^1.6.2
@@ -6728,7 +6801,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ~27.1.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -6739,7 +6812,7 @@ importers:
providers/sms77:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
node-fetch:
specifier: ^2.6.7
@@ -6750,7 +6823,7 @@ importers:
devDependencies:
'@babel/preset-env':
specifier: ^7.23.2
- version: 7.23.2(@babel/core@7.23.2)
+ version: 7.23.2(@babel/core@7.24.4)
'@istanbuljs/nyc-config-typescript':
specifier: ^1.0.1
version: 1.0.2(nyc@15.1.0)
@@ -6786,7 +6859,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -6803,7 +6876,7 @@ importers:
specifier: ^3.382.0
version: 3.388.0
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
devDependencies:
'@istanbuljs/nyc-config-typescript':
@@ -6841,7 +6914,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -6855,7 +6928,7 @@ importers:
providers/sparkpost:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
axios:
specifier: ^1.6.2
@@ -6899,7 +6972,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -6913,7 +6986,7 @@ importers:
providers/telnyx:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
telnyx:
specifier: ^1.23.0
@@ -6954,7 +7027,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -6968,7 +7041,7 @@ importers:
providers/termii:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
node-fetch:
specifier: ^3.2.10
@@ -6976,7 +7049,7 @@ importers:
devDependencies:
'@babel/preset-env':
specifier: ^7.23.2
- version: 7.23.2(@babel/core@7.23.2)
+ version: 7.23.2(@babel/core@7.24.4)
'@istanbuljs/nyc-config-typescript':
specifier: ^1.0.1
version: 1.0.2(nyc@15.1.0)
@@ -7012,7 +7085,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -7026,7 +7099,7 @@ importers:
providers/twilio:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
twilio:
specifier: ^4.19.3
@@ -7067,7 +7140,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ^27.0.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -7081,7 +7154,7 @@ importers:
providers/zulip:
dependencies:
'@novu/stateless':
- specifier: ^0.24.0
+ specifier: ^0.24.1
version: link:../../packages/stateless
axios:
specifier: ^1.6.2
@@ -7113,7 +7186,7 @@ importers:
version: 3.0.2
ts-jest:
specifier: ~27.1.5
- version: 27.1.5(@babel/core@7.23.2)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
+ version: 27.1.5(@babel/core@7.24.4)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5)
ts-node:
specifier: ~10.9.1
version: 10.9.1(@types/node@14.18.42)(typescript@4.9.5)
@@ -9896,10 +9969,21 @@ packages:
'@babel/highlight': 7.22.13
chalk: 2.4.2
+ /@babel/code-frame@7.24.2:
+ resolution: {integrity: sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/highlight': 7.24.2
+ picocolors: 1.0.0
+
/@babel/compat-data@7.23.2:
resolution: {integrity: sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ==}
engines: {node: '>=6.9.0'}
+ /@babel/compat-data@7.24.4:
+ resolution: {integrity: sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==}
+ engines: {node: '>=6.9.0'}
+
/@babel/core@7.21.4:
resolution: {integrity: sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA==}
engines: {node: '>=6.9.0'}
@@ -9991,6 +10075,28 @@ packages:
transitivePeerDependencies:
- supports-color
+ /@babel/core@7.24.4:
+ resolution: {integrity: sha512-MBVlMXP+kkl5394RBLSxxk/iLTeVGuXTV3cIDXavPpMMqnSnt6apKgan/U8O3USWZCWZT/TbgfEpKa4uMgN4Dg==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@ampproject/remapping': 2.2.1
+ '@babel/code-frame': 7.24.2
+ '@babel/generator': 7.24.4
+ '@babel/helper-compilation-targets': 7.23.6
+ '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.4)
+ '@babel/helpers': 7.24.4
+ '@babel/parser': 7.24.4
+ '@babel/template': 7.24.0
+ '@babel/traverse': 7.24.1
+ '@babel/types': 7.24.0
+ convert-source-map: 2.0.0
+ debug: 4.3.4(supports-color@8.1.1)
+ gensync: 1.0.0-beta.2
+ json5: 2.2.3
+ semver: 6.3.1
+ transitivePeerDependencies:
+ - supports-color
+
/@babel/eslint-parser@7.21.3(@babel/core@7.23.2)(eslint@8.51.0):
resolution: {integrity: sha512-kfhmPimwo6k4P8zxNs8+T7yR44q1LdpsZdE1NkCsVlfiuTPRfnGgjaF8Qgug9q9Pou17u6wneYF0lDCZJATMFg==}
engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0}
@@ -10024,6 +10130,15 @@ packages:
'@jridgewell/trace-mapping': 0.3.19
jsesc: 2.5.2
+ /@babel/generator@7.24.4:
+ resolution: {integrity: sha512-Xd6+v6SnjWVx/nus+y0l1sxMOTOMBkyL4+BIdbALyatQnAe/SRVjANeDPSCYaX+i1iJmuGSKf3Z+E+V/va1Hvw==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/types': 7.24.0
+ '@jridgewell/gen-mapping': 0.3.5
+ '@jridgewell/trace-mapping': 0.3.25
+ jsesc: 2.5.2
+
/@babel/helper-annotate-as-pure@7.18.6:
resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==}
engines: {node: '>=6.9.0'}
@@ -10055,6 +10170,16 @@ packages:
lru-cache: 5.1.1
semver: 6.3.1
+ /@babel/helper-compilation-targets@7.23.6:
+ resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/compat-data': 7.24.4
+ '@babel/helper-validator-option': 7.23.5
+ browserslist: 4.23.0
+ lru-cache: 5.1.1
+ semver: 6.3.1
+
/@babel/helper-create-class-features-plugin@7.22.15(@babel/core@7.21.4):
resolution: {integrity: sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==}
engines: {node: '>=6.9.0'}
@@ -10127,6 +10252,24 @@ packages:
semver: 6.3.1
dev: true
+ /@babel/helper-create-class-features-plugin@7.22.15(@babel/core@7.24.4):
+ resolution: {integrity: sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-annotate-as-pure': 7.22.5
+ '@babel/helper-environment-visitor': 7.22.20
+ '@babel/helper-function-name': 7.23.0
+ '@babel/helper-member-expression-to-functions': 7.22.15
+ '@babel/helper-optimise-call-expression': 7.22.5
+ '@babel/helper-replace-supers': 7.22.20(@babel/core@7.24.4)
+ '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
+ '@babel/helper-split-export-declaration': 7.22.6
+ semver: 6.3.1
+ dev: true
+
/@babel/helper-create-regexp-features-plugin@7.22.15(@babel/core@7.22.11):
resolution: {integrity: sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==}
engines: {node: '>=6.9.0'}
@@ -10163,6 +10306,18 @@ packages:
semver: 6.3.1
dev: true
+ /@babel/helper-create-regexp-features-plugin@7.22.15(@babel/core@7.24.4):
+ resolution: {integrity: sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-annotate-as-pure': 7.22.5
+ regexpu-core: 5.3.2
+ semver: 6.3.1
+ dev: true
+
/@babel/helper-define-polyfill-provider@0.4.3(@babel/core@7.22.11):
resolution: {integrity: sha512-WBrLmuPP47n7PNwsZ57pqam6G/RGo1vw/87b0Blc53tZNGZ4x7YvZ6HgQe2vo1W/FR20OgjeZuGXzudPiXHFug==}
peerDependencies:
@@ -10206,6 +10361,21 @@ packages:
resolve: 1.22.2
transitivePeerDependencies:
- supports-color
+ dev: true
+
+ /@babel/helper-define-polyfill-provider@0.4.3(@babel/core@7.24.4):
+ resolution: {integrity: sha512-WBrLmuPP47n7PNwsZ57pqam6G/RGo1vw/87b0Blc53tZNGZ4x7YvZ6HgQe2vo1W/FR20OgjeZuGXzudPiXHFug==}
+ peerDependencies:
+ '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-compilation-targets': 7.22.15
+ '@babel/helper-plugin-utils': 7.22.5
+ debug: 4.3.4(supports-color@8.1.1)
+ lodash.debounce: 4.0.8
+ resolve: 1.22.2
+ transitivePeerDependencies:
+ - supports-color
/@babel/helper-environment-visitor@7.22.20:
resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==}
@@ -10271,6 +10441,20 @@ packages:
'@babel/helper-validator-identifier': 7.22.20
dev: true
+ /@babel/helper-module-transforms@7.22.20(@babel/core@7.24.4):
+ resolution: {integrity: sha512-dLT7JVWIUUxKOs1UnJUBR3S70YK+pKX6AbJgB2vMIvEkZkrfJDbYDJesnPshtKV4LhDOR3Oc5YULeDizRek+5A==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@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.23.0(@babel/core@7.22.11):
resolution: {integrity: sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==}
engines: {node: '>=6.9.0'}
@@ -10312,6 +10496,33 @@ packages:
'@babel/helper-split-export-declaration': 7.22.6
'@babel/helper-validator-identifier': 7.22.20
+ /@babel/helper-module-transforms@7.23.0(@babel/core@7.24.4):
+ resolution: {integrity: sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@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.23.3(@babel/core@7.24.4):
+ resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@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
+
/@babel/helper-optimise-call-expression@7.22.5:
resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==}
engines: {node: '>=6.9.0'}
@@ -10363,6 +10574,18 @@ packages:
'@babel/helper-wrap-function': 7.22.20
dev: true
+ /@babel/helper-remap-async-to-generator@7.22.20(@babel/core@7.24.4):
+ resolution: {integrity: sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-annotate-as-pure': 7.22.5
+ '@babel/helper-environment-visitor': 7.22.20
+ '@babel/helper-wrap-function': 7.22.20
+ dev: true
+
/@babel/helper-replace-supers@7.22.20(@babel/core@7.21.4):
resolution: {integrity: sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==}
engines: {node: '>=6.9.0'}
@@ -10411,6 +10634,18 @@ packages:
'@babel/helper-optimise-call-expression': 7.22.5
dev: true
+ /@babel/helper-replace-supers@7.22.20(@babel/core@7.24.4):
+ resolution: {integrity: sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-environment-visitor': 7.22.20
+ '@babel/helper-member-expression-to-functions': 7.22.15
+ '@babel/helper-optimise-call-expression': 7.22.5
+ dev: true
+
/@babel/helper-simple-access@7.22.5:
resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==}
engines: {node: '>=6.9.0'}
@@ -10433,6 +10668,10 @@ packages:
resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==}
engines: {node: '>=6.9.0'}
+ /@babel/helper-string-parser@7.24.1:
+ resolution: {integrity: sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==}
+ engines: {node: '>=6.9.0'}
+
/@babel/helper-validator-identifier@7.22.20:
resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==}
engines: {node: '>=6.9.0'}
@@ -10446,6 +10685,10 @@ packages:
resolution: {integrity: sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==}
engines: {node: '>=6.9.0'}
+ /@babel/helper-validator-option@7.23.5:
+ resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==}
+ engines: {node: '>=6.9.0'}
+
/@babel/helper-wrap-function@7.22.20:
resolution: {integrity: sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==}
engines: {node: '>=6.9.0'}
@@ -10476,6 +10719,16 @@ packages:
transitivePeerDependencies:
- supports-color
+ /@babel/helpers@7.24.4:
+ resolution: {integrity: sha512-FewdlZbSiwaVGlgT1DPANDuCHaDMiOo+D/IDYRFYjHOuv66xMSJ7fQwwODwRNAPkADIO/z1EoF/l2BCWlWABDw==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/template': 7.24.0
+ '@babel/traverse': 7.24.1
+ '@babel/types': 7.24.0
+ transitivePeerDependencies:
+ - supports-color
+
/@babel/highlight@7.22.13:
resolution: {integrity: sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==}
engines: {node: '>=6.9.0'}
@@ -10484,6 +10737,15 @@ packages:
chalk: 2.4.2
js-tokens: 4.0.0
+ /@babel/highlight@7.24.2:
+ resolution: {integrity: sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/helper-validator-identifier': 7.22.20
+ chalk: 2.4.2
+ js-tokens: 4.0.0
+ picocolors: 1.0.0
+
/@babel/parser@7.22.16:
resolution: {integrity: sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==}
engines: {node: '>=6.0.0'}
@@ -10504,7 +10766,13 @@ packages:
hasBin: true
dependencies:
'@babel/types': 7.23.0
- dev: true
+
+ /@babel/parser@7.24.4:
+ resolution: {integrity: sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+ dependencies:
+ '@babel/types': 7.24.0
/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.22.15(@babel/core@7.22.11):
resolution: {integrity: sha512-FB9iYlz7rURmRJyXRKEnalYPPdn87H5no108cyuQQyMwlpJ2SJtpIUBI27kdTin956pz+LPypkPVPUTlxOmrsg==}
@@ -10536,6 +10804,16 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.22.15(@babel/core@7.24.4):
+ resolution: {integrity: sha512-FB9iYlz7rURmRJyXRKEnalYPPdn87H5no108cyuQQyMwlpJ2SJtpIUBI27kdTin956pz+LPypkPVPUTlxOmrsg==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.22.15(@babel/core@7.22.11):
resolution: {integrity: sha512-Hyph9LseGvAeeXzikV88bczhsrLrIZqDPxO+sSmAunMPaGrBGhfMWzCPYTtiW9t+HzSE2wtV8e5cc5P6r1xMDQ==}
engines: {node: '>=6.9.0'}
@@ -10572,6 +10850,18 @@ packages:
'@babel/plugin-transform-optional-chaining': 7.23.0(@babel/core@7.23.2)
dev: true
+ /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.22.15(@babel/core@7.24.4):
+ resolution: {integrity: sha512-Hyph9LseGvAeeXzikV88bczhsrLrIZqDPxO+sSmAunMPaGrBGhfMWzCPYTtiW9t+HzSE2wtV8e5cc5P6r1xMDQ==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.13.0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
+ '@babel/plugin-transform-optional-chaining': 7.23.0(@babel/core@7.24.4)
+ dev: true
+
/@babel/plugin-proposal-async-generator-functions@7.20.7(@babel/core@7.22.9):
resolution: {integrity: sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==}
engines: {node: '>=6.9.0'}
@@ -10656,6 +10946,18 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
'@babel/helper-skip-transparent-expression-wrappers': 7.22.5
'@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.2)
+ dev: true
+
+ /@babel/plugin-proposal-optional-chaining@7.21.0(@babel/core@7.24.4):
+ resolution: {integrity: sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
+ '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.4)
/@babel/plugin-proposal-private-methods@7.18.6(@babel/core@7.23.2):
resolution: {integrity: sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==}
@@ -10709,6 +11011,15 @@ packages:
'@babel/core': 7.23.2
dev: true
+ /@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.4):
+ resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ dev: true
+
/@babel/plugin-proposal-unicode-property-regex@7.18.6(@babel/core@7.22.9):
resolution: {integrity: sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==}
engines: {node: '>=4'}
@@ -10757,6 +11068,15 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.24.4):
+ resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.21.4):
resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==}
peerDependencies:
@@ -10811,6 +11131,15 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.4):
+ resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.22.11):
resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==}
engines: {node: '>=6.9.0'}
@@ -10841,6 +11170,16 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-syntax-decorators@7.21.0(@babel/core@7.23.2):
resolution: {integrity: sha512-tIoPpGBR8UuM4++ccWN3gifhVvQu7ZizuR1fklhRJrd5ewgbkUS+0KVFeWWxELtn18NTLoW32XV7zyOgIAiz+w==}
engines: {node: '>=6.9.0'}
@@ -10888,6 +11227,15 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.24.4):
+ resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.22.11):
resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==}
peerDependencies:
@@ -10915,6 +11263,15 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.24.4):
+ resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-syntax-flow@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-9RdCl0i+q0QExayk2nOS7853w08yLucnnPML6EN9S8fgMPVtdLDCdx/cOQ/i44Lb9UeQX9A35yaqBBOMMZxPxQ==}
engines: {node: '>=6.9.0'}
@@ -10925,6 +11282,16 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-syntax-flow@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-9RdCl0i+q0QExayk2nOS7853w08yLucnnPML6EN9S8fgMPVtdLDCdx/cOQ/i44Lb9UeQX9A35yaqBBOMMZxPxQ==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-syntax-import-assertions@7.22.5(@babel/core@7.22.11):
resolution: {integrity: sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==}
engines: {node: '>=6.9.0'}
@@ -10955,6 +11322,16 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-syntax-import-assertions@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-syntax-import-attributes@7.22.5(@babel/core@7.22.11):
resolution: {integrity: sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==}
engines: {node: '>=6.9.0'}
@@ -10985,6 +11362,16 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-syntax-import-attributes@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.21.4):
resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==}
peerDependencies:
@@ -11021,6 +11408,15 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.4):
+ resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.21.4):
resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==}
peerDependencies:
@@ -11057,6 +11453,15 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.4):
+ resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.21.4):
resolution: {integrity: sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==}
engines: {node: '>=6.9.0'}
@@ -11077,6 +11482,16 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.21.4):
resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==}
peerDependencies:
@@ -11113,6 +11528,15 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.24.4):
+ resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.21.4):
resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==}
peerDependencies:
@@ -11149,6 +11573,15 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.4):
+ resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.21.4):
resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==}
peerDependencies:
@@ -11185,6 +11618,15 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.4):
+ resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.21.4):
resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==}
peerDependencies:
@@ -11221,6 +11663,15 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.4):
+ resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.21.4):
resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==}
peerDependencies:
@@ -11257,6 +11708,15 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.4):
+ resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.21.4):
resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==}
peerDependencies:
@@ -11291,6 +11751,15 @@ packages:
dependencies:
'@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
+ /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.4):
+ resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
/@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.22.11):
resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==}
@@ -11322,6 +11791,16 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.21.4):
resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==}
engines: {node: '>=6.9.0'}
@@ -11362,23 +11841,33 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-typescript@7.21.4(@babel/core@7.21.4):
- resolution: {integrity: sha512-xz0D39NvhQn4t4RNsHmDnnsaQizIlUkdtYvLs8La1BlfjQ6JEwxkJGeqJMW2tAXx+q6H+WFuUTXNdYVpEya0YA==}
+ /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.21.4
+ '@babel/core': 7.24.4
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-typescript@7.21.4(@babel/core@7.23.2):
+ /@babel/plugin-syntax-typescript@7.21.4(@babel/core@7.24.4):
resolution: {integrity: sha512-xz0D39NvhQn4t4RNsHmDnnsaQizIlUkdtYvLs8La1BlfjQ6JEwxkJGeqJMW2tAXx+q6H+WFuUTXNdYVpEya0YA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.23.2
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
+ /@babel/plugin-syntax-typescript@7.22.5(@babel/core@7.21.4):
+ resolution: {integrity: sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.21.4
'@babel/helper-plugin-utils': 7.22.5
dev: true
@@ -11425,6 +11914,17 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.24.4):
+ resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.4)
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-transform-arrow-functions@7.22.5(@babel/core@7.22.11):
resolution: {integrity: sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==}
engines: {node: '>=6.9.0'}
@@ -11455,6 +11955,16 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-transform-arrow-functions@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-transform-async-generator-functions@7.23.2(@babel/core@7.22.11):
resolution: {integrity: sha512-BBYVGxbDVHfoeXbOwcagAkOQAm9NxoTdMGfTqghu1GrvadSaw6iW3Je6IcL5PNOw8VwjxqBECXy50/iCQSY/lQ==}
engines: {node: '>=6.9.0'}
@@ -11494,6 +12004,19 @@ packages:
'@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.2)
dev: true
+ /@babel/plugin-transform-async-generator-functions@7.23.2(@babel/core@7.24.4):
+ resolution: {integrity: sha512-BBYVGxbDVHfoeXbOwcagAkOQAm9NxoTdMGfTqghu1GrvadSaw6iW3Je6IcL5PNOw8VwjxqBECXy50/iCQSY/lQ==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-environment-visitor': 7.22.20
+ '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.24.4)
+ '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.4)
+ dev: true
+
/@babel/plugin-transform-async-to-generator@7.22.5(@babel/core@7.22.11):
resolution: {integrity: sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==}
engines: {node: '>=6.9.0'}
@@ -11530,6 +12053,18 @@ packages:
'@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.23.2)
dev: true
+ /@babel/plugin-transform-async-to-generator@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-module-imports': 7.22.15
+ '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.24.4)
+ dev: true
+
/@babel/plugin-transform-block-scoped-functions@7.22.5(@babel/core@7.22.11):
resolution: {integrity: sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==}
engines: {node: '>=6.9.0'}
@@ -11560,6 +12095,16 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-transform-block-scoped-functions@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-transform-block-scoping@7.23.0(@babel/core@7.22.11):
resolution: {integrity: sha512-cOsrbmIOXmf+5YbL99/S49Y3j46k/T16b9ml8bm9lP6N9US5iQ2yBK7gpui1pg0V/WMcXdkfKbTb7HXq9u+v4g==}
engines: {node: '>=6.9.0'}
@@ -11590,6 +12135,16 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-transform-block-scoping@7.23.0(@babel/core@7.24.4):
+ resolution: {integrity: sha512-cOsrbmIOXmf+5YbL99/S49Y3j46k/T16b9ml8bm9lP6N9US5iQ2yBK7gpui1pg0V/WMcXdkfKbTb7HXq9u+v4g==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-transform-class-properties@7.22.5(@babel/core@7.22.11):
resolution: {integrity: sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==}
engines: {node: '>=6.9.0'}
@@ -11623,6 +12178,17 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-transform-class-properties@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.24.4)
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-transform-class-static-block@7.22.11(@babel/core@7.22.11):
resolution: {integrity: sha512-GMM8gGmqI7guS/llMFk1bJDkKfn3v3C4KHK9Yg1ey5qcHcOlKb0QvcMrgzvxo+T03/4szNh5lghY+fEC98Kq9g==}
engines: {node: '>=6.9.0'}
@@ -11659,6 +12225,18 @@ packages:
'@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.23.2)
dev: true
+ /@babel/plugin-transform-class-static-block@7.22.11(@babel/core@7.24.4):
+ resolution: {integrity: sha512-GMM8gGmqI7guS/llMFk1bJDkKfn3v3C4KHK9Yg1ey5qcHcOlKb0QvcMrgzvxo+T03/4szNh5lghY+fEC98Kq9g==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.12.0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.24.4)
+ '@babel/helper-plugin-utils': 7.22.5
+ '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.4)
+ dev: true
+
/@babel/plugin-transform-classes@7.22.15(@babel/core@7.22.11):
resolution: {integrity: sha512-VbbC3PGjBdE0wAWDdHM9G8Gm977pnYI0XpqMd6LrKISj8/DJXEsWqgRuTYaNE9Bv0JGhTZUzHDlMk18IpOuoqw==}
engines: {node: '>=6.9.0'}
@@ -11713,6 +12291,24 @@ packages:
globals: 11.12.0
dev: true
+ /@babel/plugin-transform-classes@7.22.15(@babel/core@7.24.4):
+ resolution: {integrity: sha512-VbbC3PGjBdE0wAWDdHM9G8Gm977pnYI0XpqMd6LrKISj8/DJXEsWqgRuTYaNE9Bv0JGhTZUzHDlMk18IpOuoqw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-annotate-as-pure': 7.22.5
+ '@babel/helper-compilation-targets': 7.22.15
+ '@babel/helper-environment-visitor': 7.22.20
+ '@babel/helper-function-name': 7.23.0
+ '@babel/helper-optimise-call-expression': 7.22.5
+ '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-replace-supers': 7.22.20(@babel/core@7.24.4)
+ '@babel/helper-split-export-declaration': 7.22.6
+ globals: 11.12.0
+ dev: true
+
/@babel/plugin-transform-computed-properties@7.22.5(@babel/core@7.22.11):
resolution: {integrity: sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==}
engines: {node: '>=6.9.0'}
@@ -11746,6 +12342,17 @@ packages:
'@babel/template': 7.22.15
dev: true
+ /@babel/plugin-transform-computed-properties@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ '@babel/template': 7.22.15
+ dev: true
+
/@babel/plugin-transform-destructuring@7.23.0(@babel/core@7.22.11):
resolution: {integrity: sha512-vaMdgNXFkYrB+8lbgniSYWHsgqK5gjaMNcc84bMIOMRLH0L9AqYq3hwMdvnyqj1OPqea8UtjPEuS/DCenah1wg==}
engines: {node: '>=6.9.0'}
@@ -11776,6 +12383,16 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-transform-destructuring@7.23.0(@babel/core@7.24.4):
+ resolution: {integrity: sha512-vaMdgNXFkYrB+8lbgniSYWHsgqK5gjaMNcc84bMIOMRLH0L9AqYq3hwMdvnyqj1OPqea8UtjPEuS/DCenah1wg==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-transform-dotall-regex@7.22.5(@babel/core@7.22.11):
resolution: {integrity: sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==}
engines: {node: '>=6.9.0'}
@@ -11809,6 +12426,17 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-transform-dotall-regex@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.4)
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-transform-duplicate-keys@7.22.5(@babel/core@7.22.11):
resolution: {integrity: sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==}
engines: {node: '>=6.9.0'}
@@ -11839,6 +12467,16 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-transform-duplicate-keys@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-transform-dynamic-import@7.22.11(@babel/core@7.22.11):
resolution: {integrity: sha512-g/21plo58sfteWjaO0ZNVb+uEOkJNjAaHhbejrnBmu011l/eNDScmkbjCC3l4FKb10ViaGU4aOkFznSu2zRHgA==}
engines: {node: '>=6.9.0'}
@@ -11872,6 +12510,17 @@ packages:
'@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.23.2)
dev: true
+ /@babel/plugin-transform-dynamic-import@7.22.11(@babel/core@7.24.4):
+ resolution: {integrity: sha512-g/21plo58sfteWjaO0ZNVb+uEOkJNjAaHhbejrnBmu011l/eNDScmkbjCC3l4FKb10ViaGU4aOkFznSu2zRHgA==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.4)
+ dev: true
+
/@babel/plugin-transform-exponentiation-operator@7.22.5(@babel/core@7.22.11):
resolution: {integrity: sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==}
engines: {node: '>=6.9.0'}
@@ -11905,6 +12554,17 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-transform-exponentiation-operator@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-builder-binary-assignment-operator-visitor': 7.22.15
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-transform-export-namespace-from@7.22.11(@babel/core@7.22.11):
resolution: {integrity: sha512-xa7aad7q7OiT8oNZ1mU7NrISjlSkVdMbNxn9IuLZyL9AJEhs1Apba3I+u5riX1dIkdptP5EKDG5XDPByWxtehw==}
engines: {node: '>=6.9.0'}
@@ -11938,6 +12598,17 @@ packages:
'@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.23.2)
dev: true
+ /@babel/plugin-transform-export-namespace-from@7.22.11(@babel/core@7.24.4):
+ resolution: {integrity: sha512-xa7aad7q7OiT8oNZ1mU7NrISjlSkVdMbNxn9IuLZyL9AJEhs1Apba3I+u5riX1dIkdptP5EKDG5XDPByWxtehw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.4)
+ dev: true
+
/@babel/plugin-transform-flow-strip-types@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-tujNbZdxdG0/54g/oua8ISToaXTFBf8EnSb5PgQSciIXWOWKX3S4+JR7ZE9ol8FZwf9kxitzkGQ+QWeov/mCiA==}
engines: {node: '>=6.9.0'}
@@ -11949,6 +12620,17 @@ packages:
'@babel/plugin-syntax-flow': 7.22.5(@babel/core@7.23.2)
dev: true
+ /@babel/plugin-transform-flow-strip-types@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-tujNbZdxdG0/54g/oua8ISToaXTFBf8EnSb5PgQSciIXWOWKX3S4+JR7ZE9ol8FZwf9kxitzkGQ+QWeov/mCiA==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ '@babel/plugin-syntax-flow': 7.22.5(@babel/core@7.24.4)
+ dev: true
+
/@babel/plugin-transform-for-of@7.22.15(@babel/core@7.22.11):
resolution: {integrity: sha512-me6VGeHsx30+xh9fbDLLPi0J1HzmeIIyenoOQHuw2D4m2SAU3NrspX5XxJLBpqn5yrLzrlw2Iy3RA//Bx27iOA==}
engines: {node: '>=6.9.0'}
@@ -11979,6 +12661,16 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-transform-for-of@7.22.15(@babel/core@7.24.4):
+ resolution: {integrity: sha512-me6VGeHsx30+xh9fbDLLPi0J1HzmeIIyenoOQHuw2D4m2SAU3NrspX5XxJLBpqn5yrLzrlw2Iy3RA//Bx27iOA==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-transform-function-name@7.22.5(@babel/core@7.22.11):
resolution: {integrity: sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==}
engines: {node: '>=6.9.0'}
@@ -12015,6 +12707,18 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-transform-function-name@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-compilation-targets': 7.22.15
+ '@babel/helper-function-name': 7.23.0
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-transform-json-strings@7.22.11(@babel/core@7.22.11):
resolution: {integrity: sha512-CxT5tCqpA9/jXFlme9xIBCc5RPtdDq3JpkkhgHQqtDdiTnTI0jtZ0QzXhr5DILeYifDPp2wvY2ad+7+hLMW5Pw==}
engines: {node: '>=6.9.0'}
@@ -12048,6 +12752,17 @@ packages:
'@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.2)
dev: true
+ /@babel/plugin-transform-json-strings@7.22.11(@babel/core@7.24.4):
+ resolution: {integrity: sha512-CxT5tCqpA9/jXFlme9xIBCc5RPtdDq3JpkkhgHQqtDdiTnTI0jtZ0QzXhr5DILeYifDPp2wvY2ad+7+hLMW5Pw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.4)
+ dev: true
+
/@babel/plugin-transform-literals@7.22.5(@babel/core@7.22.11):
resolution: {integrity: sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==}
engines: {node: '>=6.9.0'}
@@ -12078,6 +12793,16 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-transform-literals@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-transform-logical-assignment-operators@7.22.11(@babel/core@7.22.11):
resolution: {integrity: sha512-qQwRTP4+6xFCDV5k7gZBF3C31K34ut0tbEcTKxlX/0KXxm9GLcO14p570aWxFvVzx6QAfPgq7gaeIHXJC8LswQ==}
engines: {node: '>=6.9.0'}
@@ -12111,6 +12836,17 @@ packages:
'@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.2)
dev: true
+ /@babel/plugin-transform-logical-assignment-operators@7.22.11(@babel/core@7.24.4):
+ resolution: {integrity: sha512-qQwRTP4+6xFCDV5k7gZBF3C31K34ut0tbEcTKxlX/0KXxm9GLcO14p570aWxFvVzx6QAfPgq7gaeIHXJC8LswQ==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.4)
+ dev: true
+
/@babel/plugin-transform-member-expression-literals@7.22.5(@babel/core@7.22.11):
resolution: {integrity: sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==}
engines: {node: '>=6.9.0'}
@@ -12141,6 +12877,16 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-transform-member-expression-literals@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-transform-modules-amd@7.23.0(@babel/core@7.22.11):
resolution: {integrity: sha512-xWT5gefv2HGSm4QHtgc1sYPbseOyf+FFDo2JbpE25GWl5BqTGO9IMwTYJRoIdjsF85GE+VegHxSCUt5EvoYTAw==}
engines: {node: '>=6.9.0'}
@@ -12174,6 +12920,17 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-transform-modules-amd@7.23.0(@babel/core@7.24.4):
+ resolution: {integrity: sha512-xWT5gefv2HGSm4QHtgc1sYPbseOyf+FFDo2JbpE25GWl5BqTGO9IMwTYJRoIdjsF85GE+VegHxSCUt5EvoYTAw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-module-transforms': 7.23.0(@babel/core@7.24.4)
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-transform-modules-commonjs@7.22.15(@babel/core@7.23.2):
resolution: {integrity: sha512-jWL4eh90w0HQOTKP2MoXXUpVxilxsB2Vl4ji69rSjS3EcZ/v4sBmn+A3NpepuJzBhOaEBbR7udonlHHn5DWidg==}
engines: {node: '>=6.9.0'}
@@ -12186,6 +12943,18 @@ packages:
'@babel/helper-simple-access': 7.22.5
dev: true
+ /@babel/plugin-transform-modules-commonjs@7.22.15(@babel/core@7.24.4):
+ resolution: {integrity: sha512-jWL4eh90w0HQOTKP2MoXXUpVxilxsB2Vl4ji69rSjS3EcZ/v4sBmn+A3NpepuJzBhOaEBbR7udonlHHn5DWidg==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-module-transforms': 7.22.20(@babel/core@7.24.4)
+ '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-simple-access': 7.22.5
+ dev: true
+
/@babel/plugin-transform-modules-commonjs@7.23.0(@babel/core@7.22.11):
resolution: {integrity: sha512-32Xzss14/UVc7k9g775yMIvkVK8xwKE0DPdP5JTapr3+Z9w4tzeOuLNY6BXDQR6BdnzIlXnCGAzsk/ICHBLVWQ==}
engines: {node: '>=6.9.0'}
@@ -12222,6 +12991,18 @@ packages:
'@babel/helper-simple-access': 7.22.5
dev: true
+ /@babel/plugin-transform-modules-commonjs@7.23.0(@babel/core@7.24.4):
+ resolution: {integrity: sha512-32Xzss14/UVc7k9g775yMIvkVK8xwKE0DPdP5JTapr3+Z9w4tzeOuLNY6BXDQR6BdnzIlXnCGAzsk/ICHBLVWQ==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-module-transforms': 7.23.0(@babel/core@7.24.4)
+ '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-simple-access': 7.22.5
+ dev: true
+
/@babel/plugin-transform-modules-systemjs@7.23.0(@babel/core@7.22.11):
resolution: {integrity: sha512-qBej6ctXZD2f+DhlOC9yO47yEYgUh5CZNz/aBoH4j/3NOlRfJXJbY7xDQCqQVf9KbrqGzIWER1f23doHGrIHFg==}
engines: {node: '>=6.9.0'}
@@ -12261,6 +13042,19 @@ packages:
'@babel/helper-validator-identifier': 7.22.20
dev: true
+ /@babel/plugin-transform-modules-systemjs@7.23.0(@babel/core@7.24.4):
+ resolution: {integrity: sha512-qBej6ctXZD2f+DhlOC9yO47yEYgUh5CZNz/aBoH4j/3NOlRfJXJbY7xDQCqQVf9KbrqGzIWER1f23doHGrIHFg==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-hoist-variables': 7.22.5
+ '@babel/helper-module-transforms': 7.23.0(@babel/core@7.24.4)
+ '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-validator-identifier': 7.22.20
+ dev: true
+
/@babel/plugin-transform-modules-umd@7.22.5(@babel/core@7.22.11):
resolution: {integrity: sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==}
engines: {node: '>=6.9.0'}
@@ -12294,6 +13088,17 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-transform-modules-umd@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-module-transforms': 7.23.0(@babel/core@7.24.4)
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.22.11):
resolution: {integrity: sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==}
engines: {node: '>=6.9.0'}
@@ -12327,6 +13132,17 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.4)
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-transform-new-target@7.22.5(@babel/core@7.22.11):
resolution: {integrity: sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==}
engines: {node: '>=6.9.0'}
@@ -12357,6 +13173,16 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-transform-new-target@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-transform-nullish-coalescing-operator@7.22.11(@babel/core@7.22.11):
resolution: {integrity: sha512-YZWOw4HxXrotb5xsjMJUDlLgcDXSfO9eCmdl1bgW4+/lAGdkjaEvOnQ4p5WKKdUgSzO39dgPl0pTnfxm0OAXcg==}
engines: {node: '>=6.9.0'}
@@ -12390,6 +13216,17 @@ packages:
'@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.2)
dev: true
+ /@babel/plugin-transform-nullish-coalescing-operator@7.22.11(@babel/core@7.24.4):
+ resolution: {integrity: sha512-YZWOw4HxXrotb5xsjMJUDlLgcDXSfO9eCmdl1bgW4+/lAGdkjaEvOnQ4p5WKKdUgSzO39dgPl0pTnfxm0OAXcg==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.4)
+ dev: true
+
/@babel/plugin-transform-numeric-separator@7.22.11(@babel/core@7.22.11):
resolution: {integrity: sha512-3dzU4QGPsILdJbASKhF/V2TVP+gJya1PsueQCxIPCEcerqF21oEcrob4mzjsp2Py/1nLfF5m+xYNMDpmA8vffg==}
engines: {node: '>=6.9.0'}
@@ -12423,6 +13260,17 @@ packages:
'@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.2)
dev: true
+ /@babel/plugin-transform-numeric-separator@7.22.11(@babel/core@7.24.4):
+ resolution: {integrity: sha512-3dzU4QGPsILdJbASKhF/V2TVP+gJya1PsueQCxIPCEcerqF21oEcrob4mzjsp2Py/1nLfF5m+xYNMDpmA8vffg==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.4)
+ dev: true
+
/@babel/plugin-transform-object-rest-spread@7.22.15(@babel/core@7.22.11):
resolution: {integrity: sha512-fEB+I1+gAmfAyxZcX1+ZUwLeAuuf8VIg67CTznZE0MqVFumWkh8xWtn58I4dxdVf080wn7gzWoF8vndOViJe9Q==}
engines: {node: '>=6.9.0'}
@@ -12465,6 +13313,20 @@ packages:
'@babel/plugin-transform-parameters': 7.22.15(@babel/core@7.23.2)
dev: true
+ /@babel/plugin-transform-object-rest-spread@7.22.15(@babel/core@7.24.4):
+ resolution: {integrity: sha512-fEB+I1+gAmfAyxZcX1+ZUwLeAuuf8VIg67CTznZE0MqVFumWkh8xWtn58I4dxdVf080wn7gzWoF8vndOViJe9Q==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/compat-data': 7.23.2
+ '@babel/core': 7.24.4
+ '@babel/helper-compilation-targets': 7.22.15
+ '@babel/helper-plugin-utils': 7.22.5
+ '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.4)
+ '@babel/plugin-transform-parameters': 7.22.15(@babel/core@7.24.4)
+ dev: true
+
/@babel/plugin-transform-object-super@7.22.5(@babel/core@7.22.11):
resolution: {integrity: sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==}
engines: {node: '>=6.9.0'}
@@ -12498,6 +13360,17 @@ packages:
'@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.2)
dev: true
+ /@babel/plugin-transform-object-super@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-replace-supers': 7.22.20(@babel/core@7.24.4)
+ dev: true
+
/@babel/plugin-transform-optional-catch-binding@7.22.11(@babel/core@7.22.11):
resolution: {integrity: sha512-rli0WxesXUeCJnMYhzAglEjLWVDF6ahb45HuprcmQuLidBJFWjNnOzssk2kuc6e33FlLaiZhG/kUIzUMWdBKaQ==}
engines: {node: '>=6.9.0'}
@@ -12531,6 +13404,17 @@ packages:
'@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.2)
dev: true
+ /@babel/plugin-transform-optional-catch-binding@7.22.11(@babel/core@7.24.4):
+ resolution: {integrity: sha512-rli0WxesXUeCJnMYhzAglEjLWVDF6ahb45HuprcmQuLidBJFWjNnOzssk2kuc6e33FlLaiZhG/kUIzUMWdBKaQ==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.4)
+ dev: true
+
/@babel/plugin-transform-optional-chaining@7.23.0(@babel/core@7.22.11):
resolution: {integrity: sha512-sBBGXbLJjxTzLBF5rFWaikMnOGOk/BmK6vVByIdEggZ7Vn6CvWXZyRkkLFK6WE0IF8jSliyOkUN6SScFgzCM0g==}
engines: {node: '>=6.9.0'}
@@ -12567,6 +13451,18 @@ packages:
'@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.2)
dev: true
+ /@babel/plugin-transform-optional-chaining@7.23.0(@babel/core@7.24.4):
+ resolution: {integrity: sha512-sBBGXbLJjxTzLBF5rFWaikMnOGOk/BmK6vVByIdEggZ7Vn6CvWXZyRkkLFK6WE0IF8jSliyOkUN6SScFgzCM0g==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
+ '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.4)
+ dev: true
+
/@babel/plugin-transform-parameters@7.22.15(@babel/core@7.22.11):
resolution: {integrity: sha512-hjk7qKIqhyzhhUvRT683TYQOFa/4cQKwQy7ALvTpODswN40MljzNDa0YldevS6tGbxwaEKVn502JmY0dP7qEtQ==}
engines: {node: '>=6.9.0'}
@@ -12597,6 +13493,16 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-transform-parameters@7.22.15(@babel/core@7.24.4):
+ resolution: {integrity: sha512-hjk7qKIqhyzhhUvRT683TYQOFa/4cQKwQy7ALvTpODswN40MljzNDa0YldevS6tGbxwaEKVn502JmY0dP7qEtQ==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-transform-private-methods@7.22.5(@babel/core@7.22.11):
resolution: {integrity: sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==}
engines: {node: '>=6.9.0'}
@@ -12630,6 +13536,17 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-transform-private-methods@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.24.4)
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-transform-private-property-in-object@7.22.11(@babel/core@7.22.11):
resolution: {integrity: sha512-sSCbqZDBKHetvjSwpyWzhuHkmW5RummxJBVbYLkGkaiTOWGxml7SXt0iWa03bzxFIx7wOj3g/ILRd0RcJKBeSQ==}
engines: {node: '>=6.9.0'}
@@ -12669,6 +13586,19 @@ packages:
'@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.23.2)
dev: true
+ /@babel/plugin-transform-private-property-in-object@7.22.11(@babel/core@7.24.4):
+ resolution: {integrity: sha512-sSCbqZDBKHetvjSwpyWzhuHkmW5RummxJBVbYLkGkaiTOWGxml7SXt0iWa03bzxFIx7wOj3g/ILRd0RcJKBeSQ==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-annotate-as-pure': 7.22.5
+ '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.24.4)
+ '@babel/helper-plugin-utils': 7.22.5
+ '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.4)
+ dev: true
+
/@babel/plugin-transform-property-literals@7.22.5(@babel/core@7.22.11):
resolution: {integrity: sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==}
engines: {node: '>=6.9.0'}
@@ -12699,6 +13629,16 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-transform-property-literals@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-transform-react-constant-elements@7.21.3(@babel/core@7.23.2):
resolution: {integrity: sha512-4DVcFeWe/yDYBLp0kBmOGFJ6N2UYg7coGid1gdxb4co62dy/xISDMaYBXBVXEDhfgMk7qkbcYiGtwd5Q/hwDDQ==}
engines: {node: '>=6.9.0'}
@@ -12709,13 +13649,13 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-react-display-name@7.18.6(@babel/core@7.23.2):
+ /@babel/plugin-transform-react-display-name@7.18.6(@babel/core@7.24.4):
resolution: {integrity: sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.23.2
+ '@babel/core': 7.24.4
'@babel/helper-plugin-utils': 7.20.2
/@babel/plugin-transform-react-display-name@7.22.5(@babel/core@7.23.2):
@@ -12728,14 +13668,24 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-react-jsx-development@7.18.6(@babel/core@7.23.2):
+ /@babel/plugin-transform-react-display-name@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-PVk3WPYudRF5z4GKMEYUrLjPl38fJSKNaEOkFuoprioowGuWN6w2RKznuFNSlJx7pzzXXStPUnNSOEO0jL5EVw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
+ /@babel/plugin-transform-react-jsx-development@7.18.6(@babel/core@7.24.4):
resolution: {integrity: sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.23.2
- '@babel/plugin-transform-react-jsx': 7.21.0(@babel/core@7.23.2)
+ '@babel/core': 7.24.4
+ '@babel/plugin-transform-react-jsx': 7.21.0(@babel/core@7.24.4)
dev: true
/@babel/plugin-transform-react-jsx-development@7.22.5(@babel/core@7.23.2):
@@ -12748,6 +13698,16 @@ packages:
'@babel/plugin-transform-react-jsx': 7.22.15(@babel/core@7.23.2)
dev: true
+ /@babel/plugin-transform-react-jsx-development@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/plugin-transform-react-jsx': 7.22.15(@babel/core@7.24.4)
+ dev: true
+
/@babel/plugin-transform-react-jsx-self@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-nTh2ogNUtxbiSbxaT4Ds6aXnXEipHweN9YRgOX/oNXdf0cCrGn/+2LozFa3lnPV5D90MkjhgckCPBrsoSc1a7g==}
engines: {node: '>=6.9.0'}
@@ -12768,17 +13728,17 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-react-jsx@7.21.0(@babel/core@7.23.2):
+ /@babel/plugin-transform-react-jsx@7.21.0(@babel/core@7.24.4):
resolution: {integrity: sha512-6OAWljMvQrZjR2DaNhVfRz6dkCAVV+ymcLUmaf8bccGOHn2v5rHJK3tTpij0BuhdYWP4LLaqj5lwcdlpAAPuvg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.23.2
+ '@babel/core': 7.24.4
'@babel/helper-annotate-as-pure': 7.18.6
'@babel/helper-module-imports': 7.22.15
'@babel/helper-plugin-utils': 7.22.5
- '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.24.4)
'@babel/types': 7.22.19
dev: true
@@ -12796,13 +13756,27 @@ packages:
'@babel/types': 7.23.0
dev: true
- /@babel/plugin-transform-react-pure-annotations@7.18.6(@babel/core@7.23.2):
+ /@babel/plugin-transform-react-jsx@7.22.15(@babel/core@7.24.4):
+ resolution: {integrity: sha512-oKckg2eZFa8771O/5vi7XeTvmM6+O9cxZu+kanTU7tD4sin5nO/G8jGJhq8Hvt2Z0kUoEDRayuZLaUlYl8QuGA==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-annotate-as-pure': 7.22.5
+ '@babel/helper-module-imports': 7.22.15
+ '@babel/helper-plugin-utils': 7.22.5
+ '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.24.4)
+ '@babel/types': 7.23.0
+ dev: true
+
+ /@babel/plugin-transform-react-pure-annotations@7.18.6(@babel/core@7.24.4):
resolution: {integrity: sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.23.2
+ '@babel/core': 7.24.4
'@babel/helper-annotate-as-pure': 7.18.6
'@babel/helper-plugin-utils': 7.22.5
dev: true
@@ -12818,6 +13792,17 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-transform-react-pure-annotations@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-gP4k85wx09q+brArVinTXhWiyzLl9UpmGva0+mWyKxk6JZequ05x3eUcIUE+FyttPKJFRRVtAvQaJ6YF9h1ZpA==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-annotate-as-pure': 7.22.5
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-transform-regenerator@7.22.10(@babel/core@7.22.11):
resolution: {integrity: sha512-F28b1mDt8KcT5bUyJc/U9nwzw6cV+UmTeRlXYIl2TNqMMJif0Jeey9/RQ3C4NOd2zp0/TRsDns9ttj2L523rsw==}
engines: {node: '>=6.9.0'}
@@ -12851,6 +13836,17 @@ packages:
regenerator-transform: 0.15.2
dev: true
+ /@babel/plugin-transform-regenerator@7.22.10(@babel/core@7.24.4):
+ resolution: {integrity: sha512-F28b1mDt8KcT5bUyJc/U9nwzw6cV+UmTeRlXYIl2TNqMMJif0Jeey9/RQ3C4NOd2zp0/TRsDns9ttj2L523rsw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ regenerator-transform: 0.15.2
+ dev: true
+
/@babel/plugin-transform-reserved-words@7.22.5(@babel/core@7.22.11):
resolution: {integrity: sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==}
engines: {node: '>=6.9.0'}
@@ -12881,6 +13877,16 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-transform-reserved-words@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-transform-runtime@7.22.9(@babel/core@7.22.9):
resolution: {integrity: sha512-9KjBH61AGJetCPYp/IEyLEp47SyybZb0nDRpBvmtEkm+rUIwxdlKpyNHI1TmsGkeuLclJdleQHRZ8XLBnnh8CQ==}
engines: {node: '>=6.9.0'}
@@ -12913,6 +13919,23 @@ packages:
semver: 6.3.1
transitivePeerDependencies:
- supports-color
+ dev: true
+
+ /@babel/plugin-transform-runtime@7.23.2(@babel/core@7.24.4):
+ resolution: {integrity: sha512-XOntj6icgzMS58jPVtQpiuF6ZFWxQiJavISGx5KGjRj+3gqZr8+N6Kx+N9BApWzgS+DOjIZfXXj0ZesenOWDyA==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-module-imports': 7.22.15
+ '@babel/helper-plugin-utils': 7.22.5
+ babel-plugin-polyfill-corejs2: 0.4.6(@babel/core@7.24.4)
+ babel-plugin-polyfill-corejs3: 0.8.5(@babel/core@7.24.4)
+ babel-plugin-polyfill-regenerator: 0.5.3(@babel/core@7.24.4)
+ semver: 6.3.1
+ transitivePeerDependencies:
+ - supports-color
/@babel/plugin-transform-shorthand-properties@7.22.5(@babel/core@7.22.11):
resolution: {integrity: sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==}
@@ -12944,6 +13967,16 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-transform-shorthand-properties@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-transform-spread@7.22.5(@babel/core@7.22.11):
resolution: {integrity: sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==}
engines: {node: '>=6.9.0'}
@@ -12977,6 +14010,17 @@ packages:
'@babel/helper-skip-transparent-expression-wrappers': 7.22.5
dev: true
+ /@babel/plugin-transform-spread@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
+ dev: true
+
/@babel/plugin-transform-sticky-regex@7.22.5(@babel/core@7.22.11):
resolution: {integrity: sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==}
engines: {node: '>=6.9.0'}
@@ -13007,6 +14051,16 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-transform-sticky-regex@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-transform-template-literals@7.22.5(@babel/core@7.22.11):
resolution: {integrity: sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==}
engines: {node: '>=6.9.0'}
@@ -13037,6 +14091,16 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-transform-template-literals@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-transform-typeof-symbol@7.22.5(@babel/core@7.22.11):
resolution: {integrity: sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==}
engines: {node: '>=6.9.0'}
@@ -13067,6 +14131,16 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-transform-typeof-symbol@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-transform-typescript@7.21.3(@babel/core@7.21.4):
resolution: {integrity: sha512-RQxPz6Iqt8T0uw/WsJNReuBpWpBqs/n7mNo18sKLoTbMp+UrEekhH+pKSVC7gWz+DNjo9gryfV8YzCiT45RgMw==}
engines: {node: '>=6.9.0'}
@@ -13077,7 +14151,7 @@ packages:
'@babel/helper-annotate-as-pure': 7.22.5
'@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.21.4)
'@babel/helper-plugin-utils': 7.22.5
- '@babel/plugin-syntax-typescript': 7.21.4(@babel/core@7.21.4)
+ '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.21.4)
dev: true
/@babel/plugin-transform-typescript@7.21.3(@babel/core@7.23.2):
@@ -13090,7 +14164,20 @@ packages:
'@babel/helper-annotate-as-pure': 7.22.5
'@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.2)
'@babel/helper-plugin-utils': 7.22.5
- '@babel/plugin-syntax-typescript': 7.21.4(@babel/core@7.23.2)
+ '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.23.2)
+ dev: true
+
+ /@babel/plugin-transform-typescript@7.21.3(@babel/core@7.24.4):
+ resolution: {integrity: sha512-RQxPz6Iqt8T0uw/WsJNReuBpWpBqs/n7mNo18sKLoTbMp+UrEekhH+pKSVC7gWz+DNjo9gryfV8YzCiT45RgMw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-annotate-as-pure': 7.22.5
+ '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.24.4)
+ '@babel/helper-plugin-utils': 7.22.5
+ '@babel/plugin-syntax-typescript': 7.21.4(@babel/core@7.24.4)
dev: true
/@babel/plugin-transform-typescript@7.22.15(@babel/core@7.23.2):
@@ -13136,6 +14223,16 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-transform-unicode-escapes@7.22.10(@babel/core@7.24.4):
+ resolution: {integrity: sha512-lRfaRKGZCBqDlRU3UIFovdp9c9mEvlylmpod0/OatICsSfuQ9YFthRo1tpTkGsklEefZdqlEFdY4A2dwTb6ohg==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-transform-unicode-property-regex@7.22.5(@babel/core@7.22.11):
resolution: {integrity: sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==}
engines: {node: '>=6.9.0'}
@@ -13169,6 +14266,17 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-transform-unicode-property-regex@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.4)
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-transform-unicode-regex@7.22.5(@babel/core@7.22.11):
resolution: {integrity: sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==}
engines: {node: '>=6.9.0'}
@@ -13202,6 +14310,17 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-transform-unicode-regex@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.4)
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/plugin-transform-unicode-sets-regex@7.22.5(@babel/core@7.22.11):
resolution: {integrity: sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==}
engines: {node: '>=6.9.0'}
@@ -13235,6 +14354,17 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
+ /@babel/plugin-transform-unicode-sets-regex@7.22.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.4)
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
/@babel/polyfill@7.12.1:
resolution: {integrity: sha512-X0pi0V6gxLi6lFZpGmeNa4zxtwEmCs42isWLNjZZDE0Y8yVfgu0T2OAHlzBbdYlqbW/YXVvoBHpATEM+goCj8g==}
deprecated: 🚨 This package has been deprecated in favor of separate inclusion of a polyfill and regenerator-runtime (when needed). See the @babel/polyfill docs (https://babeljs.io/docs/en/babel-polyfill) for more information.
@@ -13516,6 +14646,97 @@ packages:
- supports-color
dev: true
+ /@babel/preset-env@7.23.2(@babel/core@7.24.4):
+ resolution: {integrity: sha512-BW3gsuDD+rvHL2VO2SjAUNTBe5YrjsTiDyqamPDWY723na3/yPQ65X5oQkFVJZ0o50/2d+svm1rkPoJeR1KxVQ==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/compat-data': 7.23.2
+ '@babel/core': 7.24.4
+ '@babel/helper-compilation-targets': 7.22.15
+ '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-validator-option': 7.22.15
+ '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.22.15(@babel/core@7.24.4)
+ '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.22.15(@babel/core@7.24.4)
+ '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.4)
+ '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.4)
+ '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.4)
+ '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.4)
+ '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.4)
+ '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.4)
+ '@babel/plugin-syntax-import-assertions': 7.22.5(@babel/core@7.24.4)
+ '@babel/plugin-syntax-import-attributes': 7.22.5(@babel/core@7.24.4)
+ '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.4)
+ '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.4)
+ '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.4)
+ '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.4)
+ '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.4)
+ '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.4)
+ '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.4)
+ '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.4)
+ '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.4)
+ '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.4)
+ '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.24.4)
+ '@babel/plugin-transform-arrow-functions': 7.22.5(@babel/core@7.24.4)
+ '@babel/plugin-transform-async-generator-functions': 7.23.2(@babel/core@7.24.4)
+ '@babel/plugin-transform-async-to-generator': 7.22.5(@babel/core@7.24.4)
+ '@babel/plugin-transform-block-scoped-functions': 7.22.5(@babel/core@7.24.4)
+ '@babel/plugin-transform-block-scoping': 7.23.0(@babel/core@7.24.4)
+ '@babel/plugin-transform-class-properties': 7.22.5(@babel/core@7.24.4)
+ '@babel/plugin-transform-class-static-block': 7.22.11(@babel/core@7.24.4)
+ '@babel/plugin-transform-classes': 7.22.15(@babel/core@7.24.4)
+ '@babel/plugin-transform-computed-properties': 7.22.5(@babel/core@7.24.4)
+ '@babel/plugin-transform-destructuring': 7.23.0(@babel/core@7.24.4)
+ '@babel/plugin-transform-dotall-regex': 7.22.5(@babel/core@7.24.4)
+ '@babel/plugin-transform-duplicate-keys': 7.22.5(@babel/core@7.24.4)
+ '@babel/plugin-transform-dynamic-import': 7.22.11(@babel/core@7.24.4)
+ '@babel/plugin-transform-exponentiation-operator': 7.22.5(@babel/core@7.24.4)
+ '@babel/plugin-transform-export-namespace-from': 7.22.11(@babel/core@7.24.4)
+ '@babel/plugin-transform-for-of': 7.22.15(@babel/core@7.24.4)
+ '@babel/plugin-transform-function-name': 7.22.5(@babel/core@7.24.4)
+ '@babel/plugin-transform-json-strings': 7.22.11(@babel/core@7.24.4)
+ '@babel/plugin-transform-literals': 7.22.5(@babel/core@7.24.4)
+ '@babel/plugin-transform-logical-assignment-operators': 7.22.11(@babel/core@7.24.4)
+ '@babel/plugin-transform-member-expression-literals': 7.22.5(@babel/core@7.24.4)
+ '@babel/plugin-transform-modules-amd': 7.23.0(@babel/core@7.24.4)
+ '@babel/plugin-transform-modules-commonjs': 7.23.0(@babel/core@7.24.4)
+ '@babel/plugin-transform-modules-systemjs': 7.23.0(@babel/core@7.24.4)
+ '@babel/plugin-transform-modules-umd': 7.22.5(@babel/core@7.24.4)
+ '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.24.4)
+ '@babel/plugin-transform-new-target': 7.22.5(@babel/core@7.24.4)
+ '@babel/plugin-transform-nullish-coalescing-operator': 7.22.11(@babel/core@7.24.4)
+ '@babel/plugin-transform-numeric-separator': 7.22.11(@babel/core@7.24.4)
+ '@babel/plugin-transform-object-rest-spread': 7.22.15(@babel/core@7.24.4)
+ '@babel/plugin-transform-object-super': 7.22.5(@babel/core@7.24.4)
+ '@babel/plugin-transform-optional-catch-binding': 7.22.11(@babel/core@7.24.4)
+ '@babel/plugin-transform-optional-chaining': 7.23.0(@babel/core@7.24.4)
+ '@babel/plugin-transform-parameters': 7.22.15(@babel/core@7.24.4)
+ '@babel/plugin-transform-private-methods': 7.22.5(@babel/core@7.24.4)
+ '@babel/plugin-transform-private-property-in-object': 7.22.11(@babel/core@7.24.4)
+ '@babel/plugin-transform-property-literals': 7.22.5(@babel/core@7.24.4)
+ '@babel/plugin-transform-regenerator': 7.22.10(@babel/core@7.24.4)
+ '@babel/plugin-transform-reserved-words': 7.22.5(@babel/core@7.24.4)
+ '@babel/plugin-transform-shorthand-properties': 7.22.5(@babel/core@7.24.4)
+ '@babel/plugin-transform-spread': 7.22.5(@babel/core@7.24.4)
+ '@babel/plugin-transform-sticky-regex': 7.22.5(@babel/core@7.24.4)
+ '@babel/plugin-transform-template-literals': 7.22.5(@babel/core@7.24.4)
+ '@babel/plugin-transform-typeof-symbol': 7.22.5(@babel/core@7.24.4)
+ '@babel/plugin-transform-unicode-escapes': 7.22.10(@babel/core@7.24.4)
+ '@babel/plugin-transform-unicode-property-regex': 7.22.5(@babel/core@7.24.4)
+ '@babel/plugin-transform-unicode-regex': 7.22.5(@babel/core@7.24.4)
+ '@babel/plugin-transform-unicode-sets-regex': 7.22.5(@babel/core@7.24.4)
+ '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.24.4)
+ '@babel/types': 7.23.0
+ babel-plugin-polyfill-corejs2: 0.4.6(@babel/core@7.24.4)
+ babel-plugin-polyfill-corejs3: 0.8.5(@babel/core@7.24.4)
+ babel-plugin-polyfill-regenerator: 0.5.3(@babel/core@7.24.4)
+ core-js-compat: 3.32.2
+ semver: 6.3.1
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
/@babel/preset-flow@7.22.15(@babel/core@7.23.2):
resolution: {integrity: sha512-dB5aIMqpkgbTfN5vDdTRPzjqtWiZcRESNR88QYnoPR+bmdYoluOzMX9tQerTv0XzSgZYctPfO1oc0N5zdog1ew==}
engines: {node: '>=6.9.0'}
@@ -13528,6 +14749,18 @@ packages:
'@babel/plugin-transform-flow-strip-types': 7.22.5(@babel/core@7.23.2)
dev: true
+ /@babel/preset-flow@7.22.15(@babel/core@7.24.4):
+ resolution: {integrity: sha512-dB5aIMqpkgbTfN5vDdTRPzjqtWiZcRESNR88QYnoPR+bmdYoluOzMX9tQerTv0XzSgZYctPfO1oc0N5zdog1ew==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-validator-option': 7.22.15
+ '@babel/plugin-transform-flow-strip-types': 7.22.5(@babel/core@7.24.4)
+ dev: true
+
/@babel/preset-modules@0.1.5(@babel/core@7.22.9):
resolution: {integrity: sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==}
peerDependencies:
@@ -13563,19 +14796,30 @@ packages:
esutils: 2.0.3
dev: true
- /@babel/preset-react@7.18.6(@babel/core@7.23.2):
+ /@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.24.4):
+ resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ '@babel/types': 7.23.0
+ esutils: 2.0.3
+ dev: true
+
+ /@babel/preset-react@7.18.6(@babel/core@7.24.4):
resolution: {integrity: sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.23.2
+ '@babel/core': 7.24.4
'@babel/helper-plugin-utils': 7.20.2
'@babel/helper-validator-option': 7.21.0
- '@babel/plugin-transform-react-display-name': 7.18.6(@babel/core@7.23.2)
- '@babel/plugin-transform-react-jsx': 7.21.0(@babel/core@7.23.2)
- '@babel/plugin-transform-react-jsx-development': 7.18.6(@babel/core@7.23.2)
- '@babel/plugin-transform-react-pure-annotations': 7.18.6(@babel/core@7.23.2)
+ '@babel/plugin-transform-react-display-name': 7.18.6(@babel/core@7.24.4)
+ '@babel/plugin-transform-react-jsx': 7.21.0(@babel/core@7.24.4)
+ '@babel/plugin-transform-react-jsx-development': 7.18.6(@babel/core@7.24.4)
+ '@babel/plugin-transform-react-pure-annotations': 7.18.6(@babel/core@7.24.4)
dev: true
/@babel/preset-react@7.22.15(@babel/core@7.23.2):
@@ -13593,6 +14837,21 @@ packages:
'@babel/plugin-transform-react-pure-annotations': 7.22.5(@babel/core@7.23.2)
dev: true
+ /@babel/preset-react@7.22.15(@babel/core@7.24.4):
+ resolution: {integrity: sha512-Csy1IJ2uEh/PecCBXXoZGAZBeCATTuePzCSB7dLYWS0vOEj6CNpjxIhW4duWwZodBNueH7QO14WbGn8YyeuN9w==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-validator-option': 7.22.15
+ '@babel/plugin-transform-react-display-name': 7.22.5(@babel/core@7.24.4)
+ '@babel/plugin-transform-react-jsx': 7.22.15(@babel/core@7.24.4)
+ '@babel/plugin-transform-react-jsx-development': 7.22.5(@babel/core@7.24.4)
+ '@babel/plugin-transform-react-pure-annotations': 7.22.5(@babel/core@7.24.4)
+ dev: true
+
/@babel/preset-typescript@7.21.4(@babel/core@7.23.2):
resolution: {integrity: sha512-sMLNWY37TCdRH/bJ6ZeeOH1nPuanED7Ai9Y/vH31IPqalioJ6ZNFUWONsakhv4r4n+I6gm5lmoE0olkgib/j/A==}
engines: {node: '>=6.9.0'}
@@ -13607,6 +14866,20 @@ packages:
'@babel/plugin-transform-typescript': 7.21.3(@babel/core@7.23.2)
dev: true
+ /@babel/preset-typescript@7.21.4(@babel/core@7.24.4):
+ resolution: {integrity: sha512-sMLNWY37TCdRH/bJ6ZeeOH1nPuanED7Ai9Y/vH31IPqalioJ6ZNFUWONsakhv4r4n+I6gm5lmoE0olkgib/j/A==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-validator-option': 7.22.15
+ '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.24.4)
+ '@babel/plugin-transform-modules-commonjs': 7.22.15(@babel/core@7.24.4)
+ '@babel/plugin-transform-typescript': 7.21.3(@babel/core@7.24.4)
+ dev: true
+
/@babel/preset-typescript@7.23.2(@babel/core@7.23.2):
resolution: {integrity: sha512-u4UJc1XsS1GhIGteM8rnGiIvf9rJpiVgMEeCnwlLA7WJPC+jcXWJAGxYmeqs5hOZD8BbAfnV5ezBOxQbb4OUxA==}
engines: {node: '>=6.9.0'}
@@ -13682,6 +14955,14 @@ packages:
'@babel/types': 7.23.0
dev: true
+ /@babel/template@7.24.0:
+ resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/code-frame': 7.24.2
+ '@babel/parser': 7.24.4
+ '@babel/types': 7.24.0
+
/@babel/traverse@7.23.2:
resolution: {integrity: sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==}
engines: {node: '>=6.9.0'}
@@ -13699,6 +14980,23 @@ packages:
transitivePeerDependencies:
- supports-color
+ /@babel/traverse@7.24.1:
+ resolution: {integrity: sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/code-frame': 7.24.2
+ '@babel/generator': 7.24.4
+ '@babel/helper-environment-visitor': 7.22.20
+ '@babel/helper-function-name': 7.23.0
+ '@babel/helper-hoist-variables': 7.22.5
+ '@babel/helper-split-export-declaration': 7.22.6
+ '@babel/parser': 7.24.4
+ '@babel/types': 7.24.0
+ debug: 4.3.4(supports-color@8.1.1)
+ globals: 11.12.0
+ transitivePeerDependencies:
+ - supports-color
+
/@babel/types@7.22.19:
resolution: {integrity: sha512-P7LAw/LbojPzkgp5oznjE6tQEIWbp4PkkfrZDINTro9zgBRtI324/EYsiSI7lhPbpIQ+DCeR2NNmMWANGGfZsg==}
engines: {node: '>=6.9.0'}
@@ -13715,6 +15013,14 @@ packages:
'@babel/helper-validator-identifier': 7.22.20
to-fast-properties: 2.0.0
+ /@babel/types@7.24.0:
+ resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/helper-string-parser': 7.24.1
+ '@babel/helper-validator-identifier': 7.22.20
+ to-fast-properties: 2.0.0
+
/@bandwidth/messaging@4.1.3:
resolution: {integrity: sha512-cc1qLocHGxxqV7YNGOBxt6VhO+iGLfZnIq2htMP/xCgGOHqCtOVqHlQs80AETIMNEClXapShvn4TQrakx2h1/A==}
engines: {node: '>=10'}
@@ -16150,7 +17456,7 @@ packages:
react: 17.0.2
dev: false
- /@emotion/react@11.7.1(@babel/core@7.23.2)(@types/react@17.0.62)(react@17.0.2):
+ /@emotion/react@11.7.1(@babel/core@7.24.4)(@types/react@17.0.62)(react@17.0.2):
resolution: {integrity: sha512-DV2Xe3yhkF1yT4uAUoJcYL1AmrnO5SVsdfvu+fBuS7IbByDeTVx9+wFmvx9Idzv7/78+9Mgx2Hcmr7Fex3tIyw==}
peerDependencies:
'@babel/core': ^7.0.0
@@ -16162,7 +17468,7 @@ packages:
'@types/react':
optional: true
dependencies:
- '@babel/core': 7.23.2
+ '@babel/core': 7.24.4
'@babel/runtime': 7.23.2
'@emotion/cache': 11.10.7
'@emotion/serialize': 1.1.1
@@ -17789,6 +19095,18 @@ packages:
slash: 3.0.0
dev: true
+ /@jest/console@29.7.0:
+ resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ '@jest/types': 29.6.3
+ '@types/node': 14.18.42
+ chalk: 4.1.2
+ jest-message-util: 29.7.0
+ jest-util: 29.7.0
+ slash: 3.0.0
+ dev: true
+
/@jest/core@27.5.1(ts-node@10.9.1):
resolution: {integrity: sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
@@ -17876,6 +19194,49 @@ packages:
- ts-node
dev: true
+ /@jest/core@29.7.0(ts-node@10.9.1):
+ resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ peerDependencies:
+ node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
+ peerDependenciesMeta:
+ node-notifier:
+ optional: true
+ dependencies:
+ '@jest/console': 29.7.0
+ '@jest/reporters': 29.7.0
+ '@jest/test-result': 29.7.0
+ '@jest/transform': 29.7.0
+ '@jest/types': 29.6.3
+ '@types/node': 14.18.42
+ ansi-escapes: 4.3.2
+ chalk: 4.1.2
+ ci-info: 3.8.0
+ exit: 0.1.2
+ graceful-fs: 4.2.11
+ jest-changed-files: 29.7.0
+ jest-config: 29.7.0(@types/node@14.18.42)(ts-node@10.9.1)
+ jest-haste-map: 29.7.0
+ jest-message-util: 29.7.0
+ jest-regex-util: 29.6.3
+ jest-resolve: 29.7.0
+ jest-resolve-dependencies: 29.7.0
+ jest-runner: 29.7.0
+ jest-runtime: 29.7.0
+ jest-snapshot: 29.7.0
+ jest-util: 29.7.0
+ jest-validate: 29.7.0
+ jest-watcher: 29.7.0
+ micromatch: 4.0.5
+ pretty-format: 29.7.0
+ slash: 3.0.0
+ strip-ansi: 6.0.1
+ transitivePeerDependencies:
+ - babel-plugin-macros
+ - supports-color
+ - ts-node
+ dev: true
+
/@jest/environment@27.5.1:
resolution: {integrity: sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
@@ -17896,12 +19257,29 @@ packages:
jest-mock: 29.5.0
dev: true
+ /@jest/environment@29.7.0:
+ resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ '@jest/fake-timers': 29.7.0
+ '@jest/types': 29.6.3
+ '@types/node': 14.18.42
+ jest-mock: 29.7.0
+ dev: true
+
/@jest/expect-utils@29.5.0:
resolution: {integrity: sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
jest-get-type: 29.4.3
+ /@jest/expect-utils@29.7.0:
+ resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ jest-get-type: 29.6.3
+ dev: true
+
/@jest/expect@29.5.0:
resolution: {integrity: sha512-PueDR2HGihN3ciUNGr4uelropW7rqUfTiOn+8u0leg/42UhblPxHkfoh0Ruu3I9Y1962P3u2DY4+h7GVTSVU6g==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@@ -17912,6 +19290,16 @@ packages:
- supports-color
dev: true
+ /@jest/expect@29.7.0:
+ resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ expect: 29.7.0
+ jest-snapshot: 29.7.0
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
/@jest/fake-timers@27.5.1:
resolution: {integrity: sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
@@ -17936,6 +19324,18 @@ packages:
jest-util: 29.5.0
dev: true
+ /@jest/fake-timers@29.7.0:
+ resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ '@jest/types': 29.6.3
+ '@sinonjs/fake-timers': 10.0.2
+ '@types/node': 14.18.42
+ jest-message-util: 29.7.0
+ jest-mock: 29.7.0
+ jest-util: 29.7.0
+ dev: true
+
/@jest/globals@27.5.1:
resolution: {integrity: sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
@@ -17957,6 +19357,18 @@ packages:
- supports-color
dev: true
+ /@jest/globals@29.7.0:
+ resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ '@jest/environment': 29.7.0
+ '@jest/expect': 29.7.0
+ '@jest/types': 29.6.3
+ jest-mock: 29.7.0
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
/@jest/reporters@27.5.1:
resolution: {integrity: sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
@@ -18032,6 +19444,43 @@ packages:
- supports-color
dev: true
+ /@jest/reporters@29.7.0:
+ resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ peerDependencies:
+ node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
+ peerDependenciesMeta:
+ node-notifier:
+ optional: true
+ dependencies:
+ '@bcoe/v8-coverage': 0.2.3
+ '@jest/console': 29.7.0
+ '@jest/test-result': 29.7.0
+ '@jest/transform': 29.7.0
+ '@jest/types': 29.6.3
+ '@jridgewell/trace-mapping': 0.3.19
+ '@types/node': 14.18.42
+ chalk: 4.1.2
+ collect-v8-coverage: 1.0.1
+ exit: 0.1.2
+ glob: 7.2.3
+ graceful-fs: 4.2.11
+ istanbul-lib-coverage: 3.2.0
+ istanbul-lib-instrument: 6.0.2
+ istanbul-lib-report: 3.0.0
+ istanbul-lib-source-maps: 4.0.1
+ istanbul-reports: 3.1.5
+ jest-message-util: 29.7.0
+ jest-util: 29.7.0
+ jest-worker: 29.7.0
+ slash: 3.0.0
+ string-length: 4.0.2
+ strip-ansi: 6.0.1
+ v8-to-istanbul: 9.1.0
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
/@jest/schemas@28.1.3:
resolution: {integrity: sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==}
engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
@@ -18069,6 +19518,15 @@ packages:
graceful-fs: 4.2.11
dev: true
+ /@jest/source-map@29.6.3:
+ resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ '@jridgewell/trace-mapping': 0.3.19
+ callsites: 3.1.0
+ graceful-fs: 4.2.11
+ dev: true
+
/@jest/test-result@27.5.1:
resolution: {integrity: sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
@@ -18099,6 +19557,16 @@ packages:
collect-v8-coverage: 1.0.1
dev: true
+ /@jest/test-result@29.7.0:
+ resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ '@jest/console': 29.7.0
+ '@jest/types': 29.6.3
+ '@types/istanbul-lib-coverage': 2.0.4
+ collect-v8-coverage: 1.0.1
+ dev: true
+
/@jest/test-sequencer@27.5.1:
resolution: {integrity: sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
@@ -18121,6 +19589,16 @@ packages:
slash: 3.0.0
dev: true
+ /@jest/test-sequencer@29.7.0:
+ resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ '@jest/test-result': 29.7.0
+ graceful-fs: 4.2.11
+ jest-haste-map: 29.7.0
+ slash: 3.0.0
+ dev: true
+
/@jest/transform@27.5.1:
resolution: {integrity: sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
@@ -18166,6 +19644,29 @@ packages:
transitivePeerDependencies:
- supports-color
+ /@jest/transform@29.7.0:
+ resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ '@babel/core': 7.23.2
+ '@jest/types': 29.6.3
+ '@jridgewell/trace-mapping': 0.3.19
+ babel-plugin-istanbul: 6.1.1
+ chalk: 4.1.2
+ convert-source-map: 2.0.0
+ fast-json-stable-stringify: 2.1.0
+ graceful-fs: 4.2.11
+ jest-haste-map: 29.7.0
+ jest-regex-util: 29.6.3
+ jest-util: 29.7.0
+ micromatch: 4.0.5
+ pirates: 4.0.5
+ slash: 3.0.0
+ write-file-atomic: 4.0.2
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
/@jest/types@24.9.0:
resolution: {integrity: sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==}
engines: {node: '>= 6'}
@@ -18212,13 +19713,25 @@ packages:
resolution: {integrity: sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
- '@jest/schemas': 29.4.3
+ '@jest/schemas': 29.6.3
'@types/istanbul-lib-coverage': 2.0.4
'@types/istanbul-reports': 3.0.1
'@types/node': 14.18.42
'@types/yargs': 17.0.24
chalk: 4.1.2
+ /@jest/types@29.6.3:
+ resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ '@jest/schemas': 29.6.3
+ '@types/istanbul-lib-coverage': 2.0.4
+ '@types/istanbul-reports': 3.0.1
+ '@types/node': 14.18.42
+ '@types/yargs': 17.0.24
+ chalk: 4.1.2
+ dev: true
+
/@jonkemp/package-utils@1.0.8:
resolution: {integrity: sha512-bIcKnH5YmtTYr7S6J3J86dn/rFiklwRpOqbTOQ9C0WMmR9FKHVb3bxs2UYfqEmNb93O4nbA97sb6rtz33i9SyA==}
dev: false
@@ -18231,6 +19744,14 @@ packages:
'@jridgewell/sourcemap-codec': 1.4.15
'@jridgewell/trace-mapping': 0.3.19
+ /@jridgewell/gen-mapping@0.3.5:
+ resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==}
+ engines: {node: '>=6.0.0'}
+ dependencies:
+ '@jridgewell/set-array': 1.2.1
+ '@jridgewell/sourcemap-codec': 1.4.15
+ '@jridgewell/trace-mapping': 0.3.25
+
/@jridgewell/resolve-uri@3.1.0:
resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==}
engines: {node: '>=6.0.0'}
@@ -18243,6 +19764,10 @@ packages:
resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==}
engines: {node: '>=6.0.0'}
+ /@jridgewell/set-array@1.2.1:
+ resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
+ engines: {node: '>=6.0.0'}
+
/@jridgewell/source-map@0.3.3:
resolution: {integrity: sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==}
dependencies:
@@ -18267,6 +19792,12 @@ packages:
'@jridgewell/resolve-uri': 3.1.1
'@jridgewell/sourcemap-codec': 1.4.15
+ /@jridgewell/trace-mapping@0.3.25:
+ resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.1
+ '@jridgewell/sourcemap-codec': 1.4.15
+
/@jridgewell/trace-mapping@0.3.9:
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
dependencies:
@@ -19044,7 +20575,7 @@ packages:
- debug
dev: false
- /@mantine/core@4.2.12(@babel/core@7.23.2)(@mantine/hooks@4.2.12)(@types/react@17.0.62)(react-dom@17.0.2)(react@17.0.2):
+ /@mantine/core@4.2.12(@babel/core@7.24.4)(@mantine/hooks@4.2.12)(@types/react@17.0.62)(react-dom@17.0.2)(react@17.0.2):
resolution: {integrity: sha512-PZcVUvcSZiZmLR1moKBJFdFIh6a4C+TE2ao91kzTAlH5Qb8t/V3ONbfPk3swHoYr7OSLJQM8vZ7UD5sFDiq0/g==}
peerDependencies:
'@mantine/hooks': 4.2.12
@@ -19052,7 +20583,7 @@ packages:
react-dom: '>=16.8.0'
dependencies:
'@mantine/hooks': 4.2.12(react@17.0.2)
- '@mantine/styles': 4.2.12(@babel/core@7.23.2)(@types/react@17.0.62)(react-dom@17.0.2)(react@17.0.2)
+ '@mantine/styles': 4.2.12(@babel/core@7.24.4)(@types/react@17.0.62)(react-dom@17.0.2)(react@17.0.2)
'@popperjs/core': 2.11.7
'@radix-ui/react-scroll-area': 0.1.4(react@17.0.2)
react: 17.0.2
@@ -19193,14 +20724,14 @@ packages:
react-dom: 17.0.2(react@17.0.2)
dev: false
- /@mantine/styles@4.2.12(@babel/core@7.23.2)(@types/react@17.0.62)(react-dom@17.0.2)(react@17.0.2):
+ /@mantine/styles@4.2.12(@babel/core@7.24.4)(@types/react@17.0.62)(react-dom@17.0.2)(react@17.0.2):
resolution: {integrity: sha512-9q1DzW0UNW/ORMGLHfN2XABOSEm0ZQebhNlLD757R6OQouoLuUf9elUwgGOXSyogMlsAYoy84XbJ3ZbbTm4YCA==}
peerDependencies:
react: '>=16.8.0'
react-dom: '>=16.8.0'
dependencies:
'@emotion/cache': 11.7.1
- '@emotion/react': 11.7.1(@babel/core@7.23.2)(@types/react@17.0.62)(react@17.0.2)
+ '@emotion/react': 11.7.1(@babel/core@7.24.4)(@types/react@17.0.62)(react@17.0.2)
'@emotion/serialize': 1.0.2
'@emotion/utils': 1.0.0
clsx: 1.2.1
@@ -19879,15 +21410,6 @@ packages:
vue-resize: 2.0.0-alpha.1(vue@3.2.47)
dev: false
- /@novu/stateless@0.23.1:
- resolution: {integrity: sha512-eb0uMvAHyjvabx4+7TaZQ77gfdHDAJh9UJmBQ98lilB5/2+hH30LAC8Co7sVZOpwrhBy0LUpQn5/xaTqyd8oVQ==}
- engines: {node: '>=10'}
- dependencies:
- handlebars: 4.7.7
- lodash.get: 4.4.2
- lodash.merge: 4.6.2
- dev: false
-
/@npmcli/arborist@5.3.0:
resolution: {integrity: sha512-+rZ9zgL1lnbl8Xbb1NQdMjveOMwj4lIYfcDtyJHHi5x4X8jtR6m8SXooJMZy5vmFVZ8w7A2Bnd/oX9eTuU8w5A==}
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
@@ -21031,6 +22553,13 @@ packages:
'@opentelemetry/api': 1.7.0
dev: false
+ /@opentelemetry/api-logs@0.49.1:
+ resolution: {integrity: sha512-kaNl/T7WzyMUQHQlVq7q0oV4Kev6+0xFwqzofryC66jgGMacd0QH5TwfpbUwSTby+SdAdprAe5UKMvBw4tKS5Q==}
+ engines: {node: '>=14'}
+ dependencies:
+ '@opentelemetry/api': 1.7.0
+ dev: false
+
/@opentelemetry/api-metrics@0.25.0(@opentelemetry/api@1.7.0):
resolution: {integrity: sha512-9T0c9NQAEGRujUC7HzPa2/qZ5px/UvB2sfSU5CAKFRrAlDl2gn25B0oUbDqSRHW/IG1X2rnQ3z2bBQkJyJvE4g==}
engines: {node: '>=8.0.0'}
@@ -21149,6 +22678,16 @@ packages:
'@opentelemetry/semantic-conventions': 1.19.0
dev: false
+ /@opentelemetry/core@1.22.0(@opentelemetry/api@1.7.0):
+ resolution: {integrity: sha512-0VoAlT6x+Xzik1v9goJ3pZ2ppi6+xd3aUfg4brfrLkDBHRIVjMP0eBHrKrhB+NKcDyMAg8fAbGL3Npg/F6AwWA==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@opentelemetry/api': '>=1.0.0 <1.9.0'
+ dependencies:
+ '@opentelemetry/api': 1.7.0
+ '@opentelemetry/semantic-conventions': 1.22.0
+ dev: false
+
/@opentelemetry/exporter-collector@0.25.0(@opentelemetry/api@1.7.0):
resolution: {integrity: sha512-xZYstLt4hz1aTloJaepWdjMMf9305MqwqbUWjcU/X9pOxvgFWRlchO6x/HQTw7ow0i/S+ShzC+greKnb+1WvLA==}
engines: {node: '>=8.0.0'}
@@ -21218,6 +22757,20 @@ packages:
'@opentelemetry/sdk-trace-base': 1.19.0(@opentelemetry/api@1.7.0)
dev: false
+ /@opentelemetry/exporter-trace-otlp-http@0.49.1(@opentelemetry/api@1.7.0):
+ resolution: {integrity: sha512-KOLtZfZvIrpGZLVvblKsiVQT7gQUZNKcUUH24Zz6Xbi7LJb9Vt6xtUZFYdR5IIjvt47PIqBKDWUQlU0o1wAsRw==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@opentelemetry/api': ^1.0.0
+ dependencies:
+ '@opentelemetry/api': 1.7.0
+ '@opentelemetry/core': 1.22.0(@opentelemetry/api@1.7.0)
+ '@opentelemetry/otlp-exporter-base': 0.49.1(@opentelemetry/api@1.7.0)
+ '@opentelemetry/otlp-transformer': 0.49.1(@opentelemetry/api@1.7.0)
+ '@opentelemetry/resources': 1.22.0(@opentelemetry/api@1.7.0)
+ '@opentelemetry/sdk-trace-base': 1.22.0(@opentelemetry/api@1.7.0)
+ dev: false
+
/@opentelemetry/exporter-trace-otlp-proto@0.46.0(@opentelemetry/api@1.7.0):
resolution: {integrity: sha512-A7PftDM57w1TLiirrhi8ceAnCpYkpUBObELdn239IyYF67zwngImGfBLf5Yo3TTAOA2Oj1TL76L8zWVL8W+Suw==}
engines: {node: '>=14'}
@@ -21253,7 +22806,7 @@ packages:
'@opentelemetry/api': ^1.3.0
dependencies:
'@opentelemetry/api': 1.7.0
- '@opentelemetry/sdk-metrics': 1.19.0(@opentelemetry/api@1.7.0)
+ '@opentelemetry/sdk-metrics': 1.22.0(@opentelemetry/api@1.7.0)
systeminformation: 5.21.22
dev: false
@@ -21266,7 +22819,7 @@ packages:
'@opentelemetry/api': 1.7.0
'@opentelemetry/core': 1.19.0(@opentelemetry/api@1.7.0)
'@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.7.0)
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
transitivePeerDependencies:
- supports-color
dev: false
@@ -21281,7 +22834,7 @@ packages:
'@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.7.0)
'@opentelemetry/propagator-aws-xray': 1.3.1(@opentelemetry/api@1.7.0)
'@opentelemetry/resources': 1.19.0(@opentelemetry/api@1.7.0)
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
'@types/aws-lambda': 8.10.122
transitivePeerDependencies:
- supports-color
@@ -21297,7 +22850,7 @@ packages:
'@opentelemetry/core': 1.19.0(@opentelemetry/api@1.7.0)
'@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.7.0)
'@opentelemetry/propagation-utils': 0.30.5(@opentelemetry/api@1.7.0)
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
transitivePeerDependencies:
- supports-color
dev: false
@@ -21324,7 +22877,7 @@ packages:
dependencies:
'@opentelemetry/api': 1.7.0
'@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.7.0)
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
transitivePeerDependencies:
- supports-color
dev: false
@@ -21338,7 +22891,7 @@ packages:
'@opentelemetry/api': 1.7.0
'@opentelemetry/core': 1.19.0(@opentelemetry/api@1.7.0)
'@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.7.0)
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
'@types/connect': 3.4.36
transitivePeerDependencies:
- supports-color
@@ -21352,7 +22905,7 @@ packages:
dependencies:
'@opentelemetry/api': 1.7.0
'@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.7.0)
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
transitivePeerDependencies:
- supports-color
dev: false
@@ -21377,7 +22930,7 @@ packages:
dependencies:
'@opentelemetry/api': 1.7.0
'@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.7.0)
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
semver: 7.5.4
transitivePeerDependencies:
- supports-color
@@ -21392,7 +22945,7 @@ packages:
'@opentelemetry/api': 1.7.0
'@opentelemetry/core': 1.19.0(@opentelemetry/api@1.7.0)
'@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.7.0)
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
transitivePeerDependencies:
- supports-color
dev: false
@@ -21406,7 +22959,7 @@ packages:
'@opentelemetry/api': 1.7.0
'@opentelemetry/core': 1.19.0(@opentelemetry/api@1.7.0)
'@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.7.0)
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
transitivePeerDependencies:
- supports-color
dev: false
@@ -21420,7 +22973,7 @@ packages:
'@opentelemetry/api': 1.7.0
'@opentelemetry/core': 1.19.0(@opentelemetry/api@1.7.0)
'@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.7.0)
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
transitivePeerDependencies:
- supports-color
dev: false
@@ -21433,7 +22986,7 @@ packages:
dependencies:
'@opentelemetry/api': 1.7.0
'@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.7.0)
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
transitivePeerDependencies:
- supports-color
dev: false
@@ -21472,7 +23025,7 @@ packages:
'@opentelemetry/api': 1.7.0
'@opentelemetry/core': 1.19.0(@opentelemetry/api@1.7.0)
'@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.7.0)
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
'@types/hapi__hapi': 20.0.13
transitivePeerDependencies:
- supports-color
@@ -21502,7 +23055,7 @@ packages:
'@opentelemetry/api': 1.7.0
'@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.7.0)
'@opentelemetry/redis-common': 0.36.1
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
'@types/ioredis4': /@types/ioredis@4.28.10
transitivePeerDependencies:
- supports-color
@@ -21516,7 +23069,7 @@ packages:
dependencies:
'@opentelemetry/api': 1.7.0
'@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.7.0)
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
transitivePeerDependencies:
- supports-color
dev: false
@@ -21530,7 +23083,7 @@ packages:
'@opentelemetry/api': 1.7.0
'@opentelemetry/core': 1.19.0(@opentelemetry/api@1.7.0)
'@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.7.0)
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
'@types/koa': 2.13.9
'@types/koa__router': 12.0.3
transitivePeerDependencies:
@@ -21557,7 +23110,7 @@ packages:
dependencies:
'@opentelemetry/api': 1.7.0
'@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.7.0)
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
'@types/memcached': 2.2.10
transitivePeerDependencies:
- supports-color
@@ -21571,8 +23124,8 @@ packages:
dependencies:
'@opentelemetry/api': 1.7.0
'@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.7.0)
- '@opentelemetry/sdk-metrics': 1.19.0(@opentelemetry/api@1.7.0)
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/sdk-metrics': 1.22.0(@opentelemetry/api@1.7.0)
+ '@opentelemetry/semantic-conventions': 1.22.0
transitivePeerDependencies:
- supports-color
dev: false
@@ -21586,7 +23139,7 @@ packages:
'@opentelemetry/api': 1.7.0
'@opentelemetry/core': 1.19.0(@opentelemetry/api@1.7.0)
'@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.7.0)
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
transitivePeerDependencies:
- supports-color
dev: false
@@ -21599,7 +23152,7 @@ packages:
dependencies:
'@opentelemetry/api': 1.7.0
'@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.7.0)
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
'@opentelemetry/sql-common': 0.40.0(@opentelemetry/api@1.7.0)
transitivePeerDependencies:
- supports-color
@@ -21613,7 +23166,7 @@ packages:
dependencies:
'@opentelemetry/api': 1.7.0
'@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.7.0)
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
'@types/mysql': 2.15.22
transitivePeerDependencies:
- supports-color
@@ -21627,7 +23180,7 @@ packages:
dependencies:
'@opentelemetry/api': 1.7.0
'@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.7.0)
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
transitivePeerDependencies:
- supports-color
dev: false
@@ -21640,7 +23193,7 @@ packages:
dependencies:
'@opentelemetry/api': 1.7.0
'@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.7.0)
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
transitivePeerDependencies:
- supports-color
dev: false
@@ -21654,7 +23207,7 @@ packages:
'@opentelemetry/api': 1.7.0
'@opentelemetry/core': 1.19.0(@opentelemetry/api@1.7.0)
'@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.7.0)
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
'@opentelemetry/sql-common': 0.40.0(@opentelemetry/api@1.7.0)
'@types/pg': 8.6.1
'@types/pg-pool': 2.0.4
@@ -21683,7 +23236,7 @@ packages:
'@opentelemetry/api': 1.7.0
'@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.7.0)
'@opentelemetry/redis-common': 0.36.1
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
transitivePeerDependencies:
- supports-color
dev: false
@@ -21697,7 +23250,7 @@ packages:
'@opentelemetry/api': 1.7.0
'@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.7.0)
'@opentelemetry/redis-common': 0.36.1
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
transitivePeerDependencies:
- supports-color
dev: false
@@ -21711,7 +23264,7 @@ packages:
'@opentelemetry/api': 1.7.0
'@opentelemetry/core': 1.19.0(@opentelemetry/api@1.7.0)
'@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.7.0)
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
transitivePeerDependencies:
- supports-color
dev: false
@@ -21724,7 +23277,7 @@ packages:
dependencies:
'@opentelemetry/api': 1.7.0
'@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.7.0)
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
transitivePeerDependencies:
- supports-color
dev: false
@@ -21737,7 +23290,7 @@ packages:
dependencies:
'@opentelemetry/api': 1.7.0
'@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.7.0)
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
transitivePeerDependencies:
- supports-color
dev: false
@@ -21750,7 +23303,7 @@ packages:
dependencies:
'@opentelemetry/api': 1.7.0
'@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.7.0)
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
'@types/tedious': 4.0.14
transitivePeerDependencies:
- supports-color
@@ -21794,6 +23347,16 @@ packages:
'@opentelemetry/core': 1.19.0(@opentelemetry/api@1.7.0)
dev: false
+ /@opentelemetry/otlp-exporter-base@0.49.1(@opentelemetry/api@1.7.0):
+ resolution: {integrity: sha512-z6sHliPqDgJU45kQatAettY9/eVF58qVPaTuejw9YWfSRqid9pXPYeegDCSdyS47KAUgAtm+nC28K3pfF27HWg==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@opentelemetry/api': ^1.0.0
+ dependencies:
+ '@opentelemetry/api': 1.7.0
+ '@opentelemetry/core': 1.22.0(@opentelemetry/api@1.7.0)
+ dev: false
+
/@opentelemetry/otlp-grpc-exporter-base@0.46.0(@opentelemetry/api@1.7.0):
resolution: {integrity: sha512-/KB/xfZZiWIY2JknvCoT/e9paIzQO3QCBN5gR6RyxpXM/AGx3YTAOKvB/Ts9Va19jo5aE74gB7emhFaCNy4Rmw==}
engines: {node: '>=14'}
@@ -21834,6 +23397,21 @@ packages:
'@opentelemetry/sdk-trace-base': 1.19.0(@opentelemetry/api@1.7.0)
dev: false
+ /@opentelemetry/otlp-transformer@0.49.1(@opentelemetry/api@1.7.0):
+ resolution: {integrity: sha512-Z+koA4wp9L9e3jkFacyXTGphSWTbOKjwwXMpb0CxNb0kjTHGUxhYRN8GnkLFsFo5NbZPjP07hwAqeEG/uCratQ==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@opentelemetry/api': '>=1.3.0 <1.9.0'
+ dependencies:
+ '@opentelemetry/api': 1.7.0
+ '@opentelemetry/api-logs': 0.49.1
+ '@opentelemetry/core': 1.22.0(@opentelemetry/api@1.7.0)
+ '@opentelemetry/resources': 1.22.0(@opentelemetry/api@1.7.0)
+ '@opentelemetry/sdk-logs': 0.49.1(@opentelemetry/api-logs@0.49.1)(@opentelemetry/api@1.7.0)
+ '@opentelemetry/sdk-metrics': 1.22.0(@opentelemetry/api@1.7.0)
+ '@opentelemetry/sdk-trace-base': 1.22.0(@opentelemetry/api@1.7.0)
+ dev: false
+
/@opentelemetry/propagation-utils@0.30.5(@opentelemetry/api@1.7.0):
resolution: {integrity: sha512-9ENyx6ptmjyYzL7le3FXk/lJc3cFFTrh9Y/ubO9velQZ64BdjpF9kOMJN3Z8KLJFVt66HYoWy9xlWoSIfS/ICg==}
engines: {node: '>=14'}
@@ -21850,7 +23428,7 @@ packages:
'@opentelemetry/api': ^1.0.0
dependencies:
'@opentelemetry/api': 1.7.0
- '@opentelemetry/core': 1.19.0(@opentelemetry/api@1.7.0)
+ '@opentelemetry/core': 1.22.0(@opentelemetry/api@1.7.0)
dev: false
/@opentelemetry/propagator-b3@1.19.0(@opentelemetry/api@1.7.0):
@@ -21886,7 +23464,7 @@ packages:
dependencies:
'@opentelemetry/api': 1.7.0
'@opentelemetry/resources': 1.19.0(@opentelemetry/api@1.7.0)
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
dev: false
/@opentelemetry/resource-detector-aws@1.3.5(@opentelemetry/api@1.7.0):
@@ -21898,7 +23476,7 @@ packages:
'@opentelemetry/api': 1.7.0
'@opentelemetry/core': 1.19.0(@opentelemetry/api@1.7.0)
'@opentelemetry/resources': 1.19.0(@opentelemetry/api@1.7.0)
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
dev: false
/@opentelemetry/resource-detector-container@0.3.5(@opentelemetry/api@1.7.0):
@@ -21909,7 +23487,7 @@ packages:
dependencies:
'@opentelemetry/api': 1.7.0
'@opentelemetry/resources': 1.19.0(@opentelemetry/api@1.7.0)
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
dev: false
/@opentelemetry/resource-detector-gcp@0.29.5(@opentelemetry/api@1.7.0):
@@ -21921,7 +23499,7 @@ packages:
'@opentelemetry/api': 1.7.0
'@opentelemetry/core': 1.19.0(@opentelemetry/api@1.7.0)
'@opentelemetry/resources': 1.19.0(@opentelemetry/api@1.7.0)
- '@opentelemetry/semantic-conventions': 1.19.0
+ '@opentelemetry/semantic-conventions': 1.22.0
gcp-metadata: 6.1.0
transitivePeerDependencies:
- encoding
@@ -21950,6 +23528,17 @@ packages:
'@opentelemetry/semantic-conventions': 1.19.0
dev: false
+ /@opentelemetry/resources@1.22.0(@opentelemetry/api@1.7.0):
+ resolution: {integrity: sha512-+vNeIFPH2hfcNL0AJk/ykJXoUCtR1YaDUZM+p3wZNU4Hq98gzq+7b43xbkXjadD9VhWIUQqEwXyY64q6msPj6A==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@opentelemetry/api': '>=1.0.0 <1.9.0'
+ dependencies:
+ '@opentelemetry/api': 1.7.0
+ '@opentelemetry/core': 1.22.0(@opentelemetry/api@1.7.0)
+ '@opentelemetry/semantic-conventions': 1.22.0
+ dev: false
+
/@opentelemetry/sdk-logs@0.46.0(@opentelemetry/api-logs@0.46.0)(@opentelemetry/api@1.7.0):
resolution: {integrity: sha512-Knlyk4+G72uEzNh6GRN1Fhmrj+/rkATI5/lOrevN7zRDLgp4kfyZBGGoWk7w+qQjlYvwhIIdPVxlIcipivdZIg==}
engines: {node: '>=14'}
@@ -21963,6 +23552,19 @@ packages:
'@opentelemetry/resources': 1.19.0(@opentelemetry/api@1.7.0)
dev: false
+ /@opentelemetry/sdk-logs@0.49.1(@opentelemetry/api-logs@0.49.1)(@opentelemetry/api@1.7.0):
+ resolution: {integrity: sha512-gCzYWsJE0h+3cuh3/cK+9UwlVFyHvj3PReIOCDOmdeXOp90ZjKRoDOJBc3mvk1LL6wyl1RWIivR8Rg9OToyesw==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@opentelemetry/api': '>=1.4.0 <1.9.0'
+ '@opentelemetry/api-logs': '>=0.39.1'
+ dependencies:
+ '@opentelemetry/api': 1.7.0
+ '@opentelemetry/api-logs': 0.49.1
+ '@opentelemetry/core': 1.22.0(@opentelemetry/api@1.7.0)
+ '@opentelemetry/resources': 1.22.0(@opentelemetry/api@1.7.0)
+ dev: false
+
/@opentelemetry/sdk-metrics-base@0.25.0(@opentelemetry/api@1.7.0):
resolution: {integrity: sha512-7fwPlAFB5Xw8mnVQfq0wqKNw3RXiAMad9T1bk5Sza9LK/L6hz8RTuHWCsFMsj+1OOSAaiPFuUMYrK1J75+2IAg==}
engines: {node: '>=8.0.0'}
@@ -21989,6 +23591,18 @@ packages:
lodash.merge: 4.6.2
dev: false
+ /@opentelemetry/sdk-metrics@1.22.0(@opentelemetry/api@1.7.0):
+ resolution: {integrity: sha512-k6iIx6H3TZ+BVMr2z8M16ri2OxWaljg5h8ihGJxi/KQWcjign6FEaEzuigXt5bK9wVEhqAcWLCfarSftaNWkkg==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@opentelemetry/api': '>=1.3.0 <1.9.0'
+ dependencies:
+ '@opentelemetry/api': 1.7.0
+ '@opentelemetry/core': 1.22.0(@opentelemetry/api@1.7.0)
+ '@opentelemetry/resources': 1.22.0(@opentelemetry/api@1.7.0)
+ lodash.merge: 4.6.2
+ dev: false
+
/@opentelemetry/sdk-node@0.46.0(@opentelemetry/api@1.7.0):
resolution: {integrity: sha512-BQhzdCRZXchhKjZaFkgxlgoowjOt/QXekJ1CZgfvFO9Yg5GV15LyJFUEyQkDyD8XbshGo3Cnj0WZMBnDWtWY1A==}
engines: {node: '>=14'}
@@ -22038,6 +23652,18 @@ packages:
'@opentelemetry/semantic-conventions': 1.19.0
dev: false
+ /@opentelemetry/sdk-trace-base@1.22.0(@opentelemetry/api@1.7.0):
+ resolution: {integrity: sha512-pfTuSIpCKONC6vkTpv6VmACxD+P1woZf4q0K46nSUvXFvOFqjBYKFaAMkKD3M1mlKUUh0Oajwj35qNjMl80m1Q==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@opentelemetry/api': '>=1.0.0 <1.9.0'
+ dependencies:
+ '@opentelemetry/api': 1.7.0
+ '@opentelemetry/core': 1.22.0(@opentelemetry/api@1.7.0)
+ '@opentelemetry/resources': 1.22.0(@opentelemetry/api@1.7.0)
+ '@opentelemetry/semantic-conventions': 1.22.0
+ dev: false
+
/@opentelemetry/sdk-trace-node@1.19.0(@opentelemetry/api@1.7.0):
resolution: {integrity: sha512-TCiEq/cUjM15RFqBRwWomTVbOqzndWL4ILa7ZCu0zbjU1/XY6AgHkgrgAc7vGP6TjRqH4Xryuglol8tcIfbBUQ==}
engines: {node: '>=14'}
@@ -22063,6 +23689,11 @@ packages:
engines: {node: '>=14'}
dev: false
+ /@opentelemetry/semantic-conventions@1.22.0:
+ resolution: {integrity: sha512-CAOgFOKLybd02uj/GhCdEeeBjOS0yeoDeo/CA7ASBSmenpZHAKGB3iDm/rv3BQLcabb/OprDEsSQ1y0P8A7Siw==}
+ engines: {node: '>=14'}
+ dev: false
+
/@opentelemetry/sql-common@0.40.0(@opentelemetry/api@1.7.0):
resolution: {integrity: sha512-vSqRJYUPJVjMFQpYkQS3ruexCPSZJ8esne3LazLwtCPaPRvzZ7WG3tX44RouAn7w4wMp8orKguBqtt+ng2UTnw==}
engines: {node: '>=14'}
@@ -22070,7 +23701,7 @@ packages:
'@opentelemetry/api': ^1.1.0
dependencies:
'@opentelemetry/api': 1.7.0
- '@opentelemetry/core': 1.19.0(@opentelemetry/api@1.7.0)
+ '@opentelemetry/core': 1.22.0(@opentelemetry/api@1.7.0)
dev: false
/@pandacss/config@0.34.0:
@@ -22321,6 +23952,14 @@ packages:
tslib: 2.6.2
dev: true
+ /@playwright/test@1.42.1:
+ resolution: {integrity: sha512-Gq9rmS54mjBL/7/MvBaNOBwbfnh7beHvS6oS4srqXFcQHpQCV1+c8JXWE8VLPyRDhgS3H8x8A7hztqI9VnwrAQ==}
+ engines: {node: '>=16'}
+ hasBin: true
+ dependencies:
+ playwright: 1.42.1
+ dev: true
+
/@plunk/node@2.0.0:
resolution: {integrity: sha512-53lgots3fWGAo1QdS18BdEpJl7A29O1F9rYVn/7DfJ07SpJ1ZlzUeeWGVrWGL7PRRZb4a9Tw7Tt8Wnw0Xorhjg==}
dependencies:
@@ -24482,7 +26121,7 @@ packages:
rollup:
optional: true
dependencies:
- '@types/estree': 1.0.1
+ '@types/estree': 1.0.5
estree-walker: 2.0.2
picomatch: 2.3.1
dev: true
@@ -28852,13 +30491,13 @@ packages:
/@storybook/postinstall@7.4.2:
resolution: {integrity: sha512-L9r14KqS87HPyXw0S3pK2X29ckel/4sdBSmy9nVF8n/ADafKE0pSLKB935VL0+88eMx06aT32SMcQoqjubGKWw==}
- /@storybook/preset-create-react-app@7.4.2(@babel/core@7.23.2)(react-refresh@0.14.0)(react-scripts@5.0.1)(typescript@4.9.5)(webpack-dev-server@4.11.1)(webpack@5.78.0):
+ /@storybook/preset-create-react-app@7.4.2(@babel/core@7.24.4)(react-refresh@0.14.0)(react-scripts@5.0.1)(typescript@4.9.5)(webpack-dev-server@4.11.1)(webpack@5.78.0):
resolution: {integrity: sha512-rHRaiWmNAFXVHlRBG4iQE0Vsg3n4ZUyRWqddV2NuqZnHYQYUP07Rp0c3TFigGeTqF/gNbj8rTBDawcwpc8VkqQ==}
peerDependencies:
'@babel/core': '*'
react-scripts: '>=5.0.0'
dependencies:
- '@babel/core': 7.23.2
+ '@babel/core': 7.24.4
'@pmmmwh/react-refresh-webpack-plugin': 0.5.10(react-refresh@0.14.0)(webpack-dev-server@4.11.1)(webpack@5.78.0)
'@storybook/react-docgen-typescript-plugin': 1.0.6--canary.9.0c3f3b7.0(typescript@4.9.5)(webpack@5.78.0)
'@storybook/types': 7.4.2
@@ -28880,7 +30519,7 @@ packages:
- webpack-plugin-serve
dev: true
- /@storybook/preset-react-webpack@7.4.2(@babel/core@7.23.2)(@swc/core@1.3.49)(esbuild@0.18.20)(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)(webpack-cli@5.1.4):
+ /@storybook/preset-react-webpack@7.4.2(@babel/core@7.24.4)(@swc/core@1.3.49)(esbuild@0.18.20)(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)(webpack-cli@5.1.4):
resolution: {integrity: sha512-CWWiwZa3/0zHnc6zLvI9Sgj12gJDTktZO87/gfwq2VfbWqAEUYsKs6NE4Pm0Yg9O4/IG8DHoHIB+bTNlLp/lCA==}
engines: {node: '>=16.0.0'}
peerDependencies:
@@ -28894,9 +30533,9 @@ packages:
typescript:
optional: true
dependencies:
- '@babel/core': 7.23.2
- '@babel/preset-flow': 7.22.15(@babel/core@7.23.2)
- '@babel/preset-react': 7.22.15(@babel/core@7.23.2)
+ '@babel/core': 7.24.4
+ '@babel/preset-flow': 7.22.15(@babel/core@7.24.4)
+ '@babel/preset-react': 7.22.15(@babel/core@7.24.4)
'@pmmmwh/react-refresh-webpack-plugin': 0.5.10(react-refresh@0.11.0)(webpack-dev-server@4.11.1)(webpack@5.78.0)
'@storybook/core-webpack': 7.4.2
'@storybook/docs-tools': 7.4.2
@@ -28929,7 +30568,7 @@ packages:
- webpack-plugin-serve
dev: true
- /@storybook/preset-react-webpack@7.4.2(@babel/core@7.23.2)(@swc/core@1.3.49)(esbuild@0.18.20)(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)(webpack-dev-server@4.11.1):
+ /@storybook/preset-react-webpack@7.4.2(@babel/core@7.24.4)(@swc/core@1.3.49)(esbuild@0.18.20)(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)(webpack-dev-server@4.11.1):
resolution: {integrity: sha512-CWWiwZa3/0zHnc6zLvI9Sgj12gJDTktZO87/gfwq2VfbWqAEUYsKs6NE4Pm0Yg9O4/IG8DHoHIB+bTNlLp/lCA==}
engines: {node: '>=16.0.0'}
peerDependencies:
@@ -28943,9 +30582,9 @@ packages:
typescript:
optional: true
dependencies:
- '@babel/core': 7.23.2
- '@babel/preset-flow': 7.22.15(@babel/core@7.23.2)
- '@babel/preset-react': 7.22.15(@babel/core@7.23.2)
+ '@babel/core': 7.24.4
+ '@babel/preset-flow': 7.22.15(@babel/core@7.24.4)
+ '@babel/preset-react': 7.22.15(@babel/core@7.24.4)
'@pmmmwh/react-refresh-webpack-plugin': 0.5.10(react-refresh@0.11.0)(webpack-dev-server@4.11.1)(webpack@5.78.0)
'@storybook/core-webpack': 7.4.2
'@storybook/docs-tools': 7.4.2
@@ -29066,7 +30705,7 @@ packages:
react: 17.0.2
react-dom: 17.0.2(react@17.0.2)
- /@storybook/react-webpack5@7.4.2(@babel/core@7.23.2)(@swc/core@1.3.49)(@types/react-dom@17.0.19)(@types/react@17.0.53)(esbuild@0.18.20)(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)(webpack-cli@5.1.4):
+ /@storybook/react-webpack5@7.4.2(@babel/core@7.24.4)(@swc/core@1.3.49)(@types/react-dom@17.0.19)(@types/react@17.0.53)(esbuild@0.18.20)(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)(webpack-cli@5.1.4):
resolution: {integrity: sha512-pnl11MYKM3jRmHQz2dSnEDfDiApdH7ys3zH/FjImsTK6S8etMKlxGnZ58Puxj05qvrBRgpxnQSL+ZazfrEX/6w==}
engines: {node: '>=16.0.0'}
peerDependencies:
@@ -29080,9 +30719,9 @@ packages:
typescript:
optional: true
dependencies:
- '@babel/core': 7.23.2
+ '@babel/core': 7.24.4
'@storybook/builder-webpack5': 7.4.2(@types/react-dom@17.0.19)(@types/react@17.0.53)(esbuild@0.18.20)(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)(webpack-cli@5.1.4)
- '@storybook/preset-react-webpack': 7.4.2(@babel/core@7.23.2)(@swc/core@1.3.49)(esbuild@0.18.20)(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)(webpack-cli@5.1.4)
+ '@storybook/preset-react-webpack': 7.4.2(@babel/core@7.24.4)(@swc/core@1.3.49)(esbuild@0.18.20)(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)(webpack-cli@5.1.4)
'@storybook/react': 7.4.2(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)
'@types/node': 16.11.7
react: 17.0.2
@@ -29106,7 +30745,7 @@ packages:
- webpack-plugin-serve
dev: true
- /@storybook/react-webpack5@7.4.2(@babel/core@7.23.2)(@swc/core@1.3.49)(@types/react-dom@17.0.19)(@types/react@17.0.53)(esbuild@0.18.20)(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)(webpack-dev-server@4.11.1):
+ /@storybook/react-webpack5@7.4.2(@babel/core@7.24.4)(@swc/core@1.3.49)(@types/react-dom@17.0.19)(@types/react@17.0.53)(esbuild@0.18.20)(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)(webpack-dev-server@4.11.1):
resolution: {integrity: sha512-pnl11MYKM3jRmHQz2dSnEDfDiApdH7ys3zH/FjImsTK6S8etMKlxGnZ58Puxj05qvrBRgpxnQSL+ZazfrEX/6w==}
engines: {node: '>=16.0.0'}
peerDependencies:
@@ -29120,9 +30759,9 @@ packages:
typescript:
optional: true
dependencies:
- '@babel/core': 7.23.2
+ '@babel/core': 7.24.4
'@storybook/builder-webpack5': 7.4.2(@types/react-dom@17.0.19)(@types/react@17.0.53)(esbuild@0.18.20)(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)(webpack-cli@5.1.4)
- '@storybook/preset-react-webpack': 7.4.2(@babel/core@7.23.2)(@swc/core@1.3.49)(esbuild@0.18.20)(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)(webpack-dev-server@4.11.1)
+ '@storybook/preset-react-webpack': 7.4.2(@babel/core@7.24.4)(@swc/core@1.3.49)(esbuild@0.18.20)(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)(webpack-dev-server@4.11.1)
'@storybook/react': 7.4.2(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)
'@types/node': 16.11.7
react: 17.0.2
@@ -29146,7 +30785,7 @@ packages:
- webpack-plugin-serve
dev: true
- /@storybook/react-webpack5@7.4.2(@babel/core@7.23.2)(@swc/core@1.3.49)(@types/react-dom@17.0.20)(@types/react@17.0.62)(esbuild@0.18.20)(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5):
+ /@storybook/react-webpack5@7.4.2(@babel/core@7.24.4)(@swc/core@1.3.49)(@types/react-dom@17.0.20)(@types/react@17.0.62)(esbuild@0.18.20)(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5):
resolution: {integrity: sha512-pnl11MYKM3jRmHQz2dSnEDfDiApdH7ys3zH/FjImsTK6S8etMKlxGnZ58Puxj05qvrBRgpxnQSL+ZazfrEX/6w==}
engines: {node: '>=16.0.0'}
peerDependencies:
@@ -29160,9 +30799,9 @@ packages:
typescript:
optional: true
dependencies:
- '@babel/core': 7.23.2
+ '@babel/core': 7.24.4
'@storybook/builder-webpack5': 7.4.2(@types/react-dom@17.0.20)(@types/react@17.0.62)(esbuild@0.18.20)(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)
- '@storybook/preset-react-webpack': 7.4.2(@babel/core@7.23.2)(@swc/core@1.3.49)(esbuild@0.18.20)(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)(webpack-cli@5.1.4)
+ '@storybook/preset-react-webpack': 7.4.2(@babel/core@7.24.4)(@swc/core@1.3.49)(esbuild@0.18.20)(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)(webpack-cli@5.1.4)
'@storybook/react': 7.4.2(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)
'@types/node': 16.11.7
react: 17.0.2
@@ -29674,7 +31313,7 @@ packages:
resolution: {integrity: sha512-fB0R+fa3AUqbLHWyxXa2kGVtf1Fe1ZZFr0Zp6AIbIAzXb2mKbEXl+PCQNUOaq5lbTab5tfctfXRNsWXxa2f7Aw==}
engines: {node: '>=14'}
dependencies:
- '@babel/code-frame': 7.22.13
+ '@babel/code-frame': 7.24.2
'@babel/runtime': 7.23.2
'@types/aria-query': 5.0.2
aria-query: 5.1.3
@@ -30295,16 +31934,18 @@ packages:
resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==}
dev: true
+ /@types/estree@0.0.45:
+ resolution: {integrity: sha512-jnqIUKDUqJbDIUxm0Uj7bnlMnRm1T/eZ9N+AVMqhPgzrba2GhGG5o/jCTwmdPK709nEZsGoMzXEDUjcXHa3W0g==}
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@types/estree@0.0.51:
resolution: {integrity: sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==}
/@types/estree@1.0.0:
resolution: {integrity: sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==}
- /@types/estree@1.0.1:
- resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==}
- dev: true
-
/@types/estree@1.0.5:
resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
@@ -30423,15 +32064,15 @@ packages:
resolution: {integrity: sha512-RQUBI75F+uXruB95BFpC/8V8lPgJg4MQ6HxOCtAZYBB/h0FNCfrFfb4I+u2pZJIV7sKeszZbFqy1UnGeBMrvsA==}
dev: false
- /@types/inquirer@8.2.6:
- resolution: {integrity: sha512-3uT88kxg8lNzY8ay2ZjP44DKcRaTGztqeIvN2zHvhzIBH/uAPaL75aBtdNRKbA7xXoMbBt5kX0M00VKAnfOYlA==}
+ /@types/inquirer@8.2.10:
+ resolution: {integrity: sha512-IdD5NmHyVjWM8SHWo/kPBgtzXatwPkfwzyP3fN1jF2g9BWt5WO+8hL2F4o2GKIYsU40PpqeevuUWvkS/roXJkA==}
dependencies:
'@types/through': 0.0.30
rxjs: 7.8.1
dev: true
- /@types/inquirer@8.2.9:
- resolution: {integrity: sha512-5IEO2PwCy4NZDgj977dho4Qbdiw6dJZJzD4ZaB/9j7dfppf7z0xxFPKZz/FtTAUQbDjmWHJ6Jlz/gn0YzWHPsw==}
+ /@types/inquirer@8.2.6:
+ resolution: {integrity: sha512-3uT88kxg8lNzY8ay2ZjP44DKcRaTGztqeIvN2zHvhzIBH/uAPaL75aBtdNRKbA7xXoMbBt5kX0M00VKAnfOYlA==}
dependencies:
'@types/through': 0.0.30
rxjs: 7.8.1
@@ -31220,7 +32861,7 @@ packages:
typescript:
optional: true
dependencies:
- '@eslint-community/regexpp': 4.5.0
+ '@eslint-community/regexpp': 4.9.1
'@typescript-eslint/parser': 5.58.0(eslint@8.51.0)(typescript@4.9.5)
'@typescript-eslint/scope-manager': 5.58.0
'@typescript-eslint/type-utils': 5.58.0(eslint@8.51.0)(typescript@4.9.5)
@@ -31417,6 +33058,11 @@ packages:
engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1}
dev: true
+ /@typescript-eslint/types@5.20.0:
+ resolution: {integrity: sha512-+d8wprF9GyvPwtoB4CxBAR/s0rpP25XKgnOvMf/gMXYDvlUC3rPFHupdTQ/ow9vn7UDe5rX02ovGYQbv/IUCbg==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dev: true
+
/@typescript-eslint/types@5.58.0:
resolution: {integrity: sha512-JYV4eITHPzVQMnHZcYJXl2ZloC7thuUHrcUmxtzvItyKPvQ50kb9QXBkgNAt90OYMqwaodQh2kHutWZl1fc+1g==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -31448,6 +33094,27 @@ packages:
- supports-color
dev: true
+ /@typescript-eslint/typescript-estree@5.20.0(typescript@4.6.3):
+ resolution: {integrity: sha512-36xLjP/+bXusLMrT9fMMYy1KJAGgHhlER2TqpUVDYUQg4w0q/NW/sg4UGAgVwAqb8V4zYg43KMUpM8vV2lve6w==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@typescript-eslint/types': 5.20.0
+ '@typescript-eslint/visitor-keys': 5.20.0
+ debug: 4.3.4(supports-color@8.1.1)
+ globby: 11.1.0
+ is-glob: 4.0.3
+ semver: 7.5.4
+ tsutils: 3.21.0(typescript@4.6.3)
+ typescript: 4.6.3
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
/@typescript-eslint/typescript-estree@5.58.0(typescript@4.9.5):
resolution: {integrity: sha512-cRACvGTodA+UxnYM2uwA2KCwRL7VAzo45syNysqlMyNyjw0Z35Icc9ihPJZjIYuA5bXJYiJ2YGUB59BqlOZT1Q==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -31578,6 +33245,14 @@ packages:
eslint-visitor-keys: 2.1.0
dev: true
+ /@typescript-eslint/visitor-keys@5.20.0:
+ resolution: {integrity: sha512-1flRpNF+0CAQkMNlTJ6L/Z5jiODG/e5+7mk6XwtPOUS3UrTz3UOiAg9jG2VtKsWI6rZQfy4C6a232QNRZTRGlg==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dependencies:
+ '@typescript-eslint/types': 5.20.0
+ eslint-visitor-keys: 3.4.3
+ dev: true
+
/@typescript-eslint/visitor-keys@5.58.0:
resolution: {integrity: sha512-/fBraTlPj0jwdyTwLyrRTxv/3lnU2H96pNTVM6z3esTWLtA5MZ9ghSMJ7Rb+TtUAdtEw9EyJzJ0EydIMKxQ9gA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -32011,7 +33686,7 @@ packages:
/@vue/compiler-core@3.3.7:
resolution: {integrity: sha512-pACdY6YnTNVLXsB86YD8OF9ihwpolzhhtdLVHhBL6do/ykr6kKXNYABRtNMGrsQXpEXXyAdwvWWkuTbs4MFtPQ==}
dependencies:
- '@babel/parser': 7.23.0
+ '@babel/parser': 7.23.9
'@vue/shared': 3.3.7
estree-walker: 2.0.2
source-map-js: 1.0.2
@@ -33463,6 +35138,13 @@ packages:
resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==}
engines: {node: '>=8'}
+ /astray@1.1.1:
+ resolution: {integrity: sha512-LizvbENqdc8tdvrms/YyYoTtlr43INJni4YZSFr8nNdfOgafi82Hcrfhjm0MdwLhRFBrDhRwtH/0fnntlESxsQ==}
+ engines: {node: '>=8'}
+ optionalDependencies:
+ '@types/estree': 0.0.45
+ dev: true
+
/astring@1.8.6:
resolution: {integrity: sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==}
hasBin: true
@@ -33644,7 +35326,7 @@ packages:
/axios@0.21.4:
resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==}
dependencies:
- follow-redirects: 1.15.2(debug@4.3.4)
+ follow-redirects: 1.15.5(debug@4.3.4)
transitivePeerDependencies:
- debug
dev: false
@@ -33652,7 +35334,7 @@ packages:
/axios@0.26.1:
resolution: {integrity: sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==}
dependencies:
- follow-redirects: 1.15.2(debug@4.3.4)
+ follow-redirects: 1.15.2
transitivePeerDependencies:
- debug
dev: false
@@ -33660,7 +35342,7 @@ packages:
/axios@0.28.0(debug@4.3.4):
resolution: {integrity: sha512-Tu7NYoGY4Yoc7I+Npf9HhUMtEEpV7ZiLH9yndTCoNhcpBH0kwcvFbzYN9/u5QKI5A6uefjsNNWaz5olJVYS62Q==}
dependencies:
- follow-redirects: 1.15.2(debug@4.3.4)
+ follow-redirects: 1.15.5(debug@4.3.4)
form-data: 4.0.0
proxy-from-env: 1.1.0
transitivePeerDependencies:
@@ -33670,7 +35352,7 @@ packages:
/axios@1.1.3:
resolution: {integrity: sha512-00tXVRwKx/FZr/IDVFt4C+f9FYairX517WoGCL6dpOntqLkZofjhu43F/Xl44UOpqa+9sLFDrG/XAnFsUYgkDA==}
dependencies:
- follow-redirects: 1.15.2(debug@4.3.4)
+ follow-redirects: 1.15.5(debug@4.3.4)
form-data: 4.0.0
proxy-from-env: 1.1.0
transitivePeerDependencies:
@@ -33680,7 +35362,7 @@ packages:
/axios@1.6.0:
resolution: {integrity: sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==}
dependencies:
- follow-redirects: 1.15.2(debug@4.3.4)
+ follow-redirects: 1.15.2
form-data: 4.0.0
proxy-from-env: 1.1.0
transitivePeerDependencies:
@@ -33690,7 +35372,7 @@ packages:
/axios@1.6.2:
resolution: {integrity: sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==}
dependencies:
- follow-redirects: 1.15.2(debug@4.3.4)
+ follow-redirects: 1.15.2
form-data: 4.0.0
proxy-from-env: 1.1.0
transitivePeerDependencies:
@@ -33699,7 +35381,7 @@ packages:
/axios@1.6.7:
resolution: {integrity: sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==}
dependencies:
- follow-redirects: 1.15.5
+ follow-redirects: 1.15.5(debug@4.3.4)
form-data: 4.0.0
proxy-from-env: 1.1.0
transitivePeerDependencies:
@@ -33775,6 +35457,24 @@ packages:
- supports-color
dev: true
+ /babel-jest@29.7.0(@babel/core@7.23.2):
+ resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ peerDependencies:
+ '@babel/core': ^7.8.0
+ dependencies:
+ '@babel/core': 7.23.2
+ '@jest/transform': 29.7.0
+ '@types/babel__core': 7.20.3
+ babel-plugin-istanbul: 6.1.1
+ babel-preset-jest: 29.6.3(@babel/core@7.23.2)
+ chalk: 4.1.2
+ graceful-fs: 4.2.11
+ slash: 3.0.0
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
/babel-loader@8.3.0(@babel/core@7.21.4)(webpack@5.78.0):
resolution: {integrity: sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==}
engines: {node: '>= 8.9'}
@@ -33790,14 +35490,14 @@ packages:
webpack: 5.78.0(@swc/core@1.3.49)(esbuild@0.18.20)(webpack-cli@5.1.4)
dev: true
- /babel-loader@8.3.0(@babel/core@7.23.2)(webpack@5.82.1):
+ /babel-loader@8.3.0(@babel/core@7.24.4)(webpack@5.82.1):
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.23.2
+ '@babel/core': 7.24.4
find-cache-dir: 3.3.2
loader-utils: 2.0.4
make-dir: 3.1.0
@@ -33886,6 +35586,16 @@ packages:
'@types/babel__traverse': 7.18.3
dev: true
+ /babel-plugin-jest-hoist@29.6.3:
+ resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ '@babel/template': 7.22.15
+ '@babel/types': 7.23.0
+ '@types/babel__core': 7.20.3
+ '@types/babel__traverse': 7.18.3
+ dev: true
+
/babel-plugin-macros@2.8.0:
resolution: {integrity: sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==}
dependencies:
@@ -33951,6 +35661,19 @@ packages:
semver: 6.3.1
transitivePeerDependencies:
- supports-color
+ dev: true
+
+ /babel-plugin-polyfill-corejs2@0.4.6(@babel/core@7.24.4):
+ resolution: {integrity: sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q==}
+ peerDependencies:
+ '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
+ dependencies:
+ '@babel/compat-data': 7.23.2
+ '@babel/core': 7.24.4
+ '@babel/helper-define-polyfill-provider': 0.4.3(@babel/core@7.24.4)
+ semver: 6.3.1
+ transitivePeerDependencies:
+ - supports-color
/babel-plugin-polyfill-corejs3@0.8.5(@babel/core@7.22.11):
resolution: {integrity: sha512-Q6CdATeAvbScWPNLB8lzSO7fgUVBkQt6zLgNlfyeCr/EQaEQR+bWiBYYPYAFyE528BMjRhL+1QBMOI4jc/c5TA==}
@@ -33986,6 +35709,18 @@ packages:
core-js-compat: 3.32.2
transitivePeerDependencies:
- supports-color
+ dev: true
+
+ /babel-plugin-polyfill-corejs3@0.8.5(@babel/core@7.24.4):
+ resolution: {integrity: sha512-Q6CdATeAvbScWPNLB8lzSO7fgUVBkQt6zLgNlfyeCr/EQaEQR+bWiBYYPYAFyE528BMjRhL+1QBMOI4jc/c5TA==}
+ peerDependencies:
+ '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-define-polyfill-provider': 0.4.3(@babel/core@7.24.4)
+ core-js-compat: 3.32.2
+ transitivePeerDependencies:
+ - supports-color
/babel-plugin-polyfill-regenerator@0.5.3(@babel/core@7.22.11):
resolution: {integrity: sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw==}
@@ -34018,6 +35753,17 @@ packages:
'@babel/helper-define-polyfill-provider': 0.4.3(@babel/core@7.23.2)
transitivePeerDependencies:
- supports-color
+ dev: true
+
+ /babel-plugin-polyfill-regenerator@0.5.3(@babel/core@7.24.4):
+ resolution: {integrity: sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw==}
+ peerDependencies:
+ '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/helper-define-polyfill-provider': 0.4.3(@babel/core@7.24.4)
+ transitivePeerDependencies:
+ - supports-color
/babel-plugin-react-docgen@4.2.1:
resolution: {integrity: sha512-UQ0NmGHj/HAqi5Bew8WvNfCk8wSsmdgNd8ZdMjBCICtyCJCq9LiqgqvjCYe570/Wg7AQArSq1VQ60Dd/CHN7mQ==}
@@ -34119,6 +35865,17 @@ packages:
babel-preset-current-node-syntax: 1.0.1(@babel/core@7.23.2)
dev: true
+ /babel-preset-jest@29.6.3(@babel/core@7.23.2):
+ resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ peerDependencies:
+ '@babel/core': ^7.0.0
+ dependencies:
+ '@babel/core': 7.23.2
+ babel-plugin-jest-hoist: 29.6.3
+ babel-preset-current-node-syntax: 1.0.1(@babel/core@7.23.2)
+ dev: true
+
/babel-preset-react-app@10.0.1:
resolution: {integrity: sha512-b0D9IZ1WhhCWkrTXyFuIIgqGzSkRIH5D5AmB0bXbzYAB1OBAwHcUeyWW2LorutLWF5btNo/N7r/cIdmvvKJlYg==}
dependencies:
@@ -36201,6 +37958,25 @@ packages:
readable-stream: 3.6.2
dev: false
+ /create-jest@29.7.0(@types/node@14.18.42)(ts-node@10.9.1):
+ resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ hasBin: true
+ dependencies:
+ '@jest/types': 29.6.3
+ chalk: 4.1.2
+ exit: 0.1.2
+ graceful-fs: 4.2.11
+ jest-config: 29.7.0(@types/node@14.18.42)(ts-node@10.9.1)
+ jest-util: 29.7.0
+ prompts: 2.4.2
+ transitivePeerDependencies:
+ - '@types/node'
+ - babel-plugin-macros
+ - supports-color
+ - ts-node
+ dev: true
+
/create-require@1.1.1:
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
@@ -36943,7 +38719,7 @@ packages:
/cypress-intellij-reporter@0.0.7:
resolution: {integrity: sha512-P4A0BPz5h9TWLZFVhMJsAMktqCEdeKA0+bS+zfTGLohUtM89pmU5kAWLEGFOYRcRlVR39XbUWhyFyTjs8AoFLA==}
dependencies:
- mocha: 10.3.0
+ mocha: 10.4.0
dev: true
/cypress-localstorage-commands@2.2.4(cypress@13.3.1):
@@ -37270,7 +39046,6 @@ packages:
dependencies:
ms: 2.1.3
supports-color: 5.5.0
- dev: true
/debug@3.2.7(supports-color@8.1.1):
resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
@@ -37372,6 +39147,15 @@ packages:
resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==}
dev: true
+ /dedent@1.5.1:
+ resolution: {integrity: sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==}
+ peerDependencies:
+ babel-plugin-macros: ^3.1.0
+ peerDependenciesMeta:
+ babel-plugin-macros:
+ optional: true
+ dev: true
+
/deep-eql@4.1.3:
resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==}
engines: {node: '>=6'}
@@ -37877,7 +39661,6 @@ packages:
/dset@3.1.2:
resolution: {integrity: sha512-g/M9sqy3oHe477Ar4voQxWtaPIFw1jTdKZuomOjhCcBx9nHUNn0pu6NopuFFrTh/TRZIKEj+76vLWFu9BNKk+Q==}
engines: {node: '>=4'}
- dev: false
/duplexer2@0.1.4:
resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==}
@@ -38557,7 +40340,7 @@ packages:
/eslint-import-resolver-node@0.3.7:
resolution: {integrity: sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==}
dependencies:
- debug: 3.2.7(supports-color@8.1.1)
+ debug: 3.2.7(supports-color@5.5.0)
is-core-module: 2.13.0
resolve: 1.22.2
transitivePeerDependencies:
@@ -38572,7 +40355,7 @@ packages:
webpack: '>=1.11.0'
dependencies:
array.prototype.find: 2.2.2
- debug: 3.2.7(supports-color@8.1.1)
+ debug: 3.2.7(supports-color@5.5.0)
enhanced-resolve: 0.9.1
eslint-plugin-import: 2.28.1(@typescript-eslint/parser@5.58.0)(eslint-import-resolver-webpack@0.13.7)(eslint@8.38.0)
find-root: 1.1.0
@@ -38610,7 +40393,7 @@ packages:
optional: true
dependencies:
'@typescript-eslint/parser': 5.58.0(eslint@8.38.0)(typescript@4.9.5)
- debug: 3.2.7(supports-color@8.1.1)
+ debug: 3.2.7(supports-color@5.5.0)
eslint: 8.38.0
eslint-import-resolver-node: 0.3.7
eslint-import-resolver-webpack: 0.13.7(eslint-plugin-import@2.28.1)(webpack@5.78.0)
@@ -38640,7 +40423,7 @@ packages:
optional: true
dependencies:
'@typescript-eslint/parser': 5.58.0(eslint@8.51.0)(typescript@4.9.5)
- debug: 3.2.7(supports-color@8.1.1)
+ debug: 3.2.7(supports-color@5.5.0)
eslint: 8.51.0
eslint-import-resolver-node: 0.3.7
eslint-import-resolver-webpack: 0.13.7(eslint-plugin-import@2.28.1)(webpack@5.78.0)
@@ -38675,8 +40458,8 @@ packages:
'@babel/plugin-transform-react-jsx': ^7.14.9
eslint: ^8.1.0
dependencies:
- '@babel/plugin-syntax-flow': 7.22.5(@babel/core@7.23.2)
- '@babel/plugin-transform-react-jsx': 7.22.15(@babel/core@7.23.2)
+ '@babel/plugin-syntax-flow': 7.22.5(@babel/core@7.24.4)
+ '@babel/plugin-transform-react-jsx': 7.22.15(@babel/core@7.24.4)
eslint: 8.51.0
lodash: 4.17.21
string-natural-compare: 3.0.1
@@ -38721,7 +40504,7 @@ packages:
array.prototype.findlastindex: 1.2.3
array.prototype.flat: 1.3.1
array.prototype.flatmap: 1.3.1
- debug: 3.2.7(supports-color@8.1.1)
+ debug: 3.2.7(supports-color@5.5.0)
doctrine: 2.1.0
eslint: 8.38.0
eslint-import-resolver-node: 0.3.7
@@ -38756,7 +40539,7 @@ packages:
array.prototype.findlastindex: 1.2.3
array.prototype.flat: 1.3.1
array.prototype.flatmap: 1.3.1
- debug: 3.2.7(supports-color@8.1.1)
+ debug: 3.2.7(supports-color@5.5.0)
doctrine: 2.1.0
eslint: 8.51.0
eslint-import-resolver-node: 0.3.7
@@ -38839,7 +40622,7 @@ packages:
damerau-levenshtein: 1.0.8
emoji-regex: 9.2.2
eslint: 8.51.0
- has: 1.0.3
+ has: 1.0.4
jsx-ast-utils: 3.3.3
language-tags: 1.0.5
minimatch: 3.1.2
@@ -39503,6 +41286,17 @@ packages:
jest-message-util: 29.5.0
jest-util: 29.5.0
+ /expect@29.7.0:
+ resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ '@jest/expect-utils': 29.7.0
+ jest-get-type: 29.6.3
+ jest-matcher-utils: 29.7.0
+ jest-message-util: 29.7.0
+ jest-util: 29.7.0
+ dev: true
+
/expo-server-sdk@3.7.0:
resolution: {integrity: sha512-SMZuBiIWejAdMMIOTjGQlprcwvSyLfeUQlooyGB5q6GvZ8zHjp+if8Q4k7xczUBTqIqTzs5IvTZnTiqA9Oe9WA==}
dependencies:
@@ -39793,6 +41587,17 @@ packages:
dependencies:
pend: 1.2.0
+ /fdir@5.2.0(picomatch@2.3.1):
+ resolution: {integrity: sha512-skyI2Laxtj9GYzmktPgY6DT8uswXq+VoxH26SskykvEhTSbi7tRM/787uZt/p8maxrQCJdzC90zX1btbxiJ6lw==}
+ peerDependencies:
+ picomatch: 2.x
+ peerDependenciesMeta:
+ picomatch:
+ optional: true
+ dependencies:
+ picomatch: 2.3.1
+ dev: true
+
/fecha@4.2.3:
resolution: {integrity: sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==}
@@ -40151,7 +41956,7 @@ packages:
tslib: 2.6.2
dev: false
- /follow-redirects@1.15.2(debug@4.3.4):
+ /follow-redirects@1.15.2:
resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==}
engines: {node: '>=4.0'}
peerDependencies:
@@ -40159,10 +41964,8 @@ packages:
peerDependenciesMeta:
debug:
optional: true
- dependencies:
- debug: 4.3.4(supports-color@8.1.1)
- /follow-redirects@1.15.5:
+ /follow-redirects@1.15.5(debug@4.3.4):
resolution: {integrity: sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==}
engines: {node: '>=4.0'}
peerDependencies:
@@ -40170,6 +41973,8 @@ packages:
peerDependenciesMeta:
debug:
optional: true
+ dependencies:
+ debug: 4.3.4(supports-color@8.1.1)
/for-each@0.3.3:
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
@@ -40517,6 +42322,14 @@ packages:
dev: true
optional: true
+ /fsevents@2.3.2:
+ resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
@@ -41958,7 +43771,7 @@ packages:
engines: {node: '>=8.0.0'}
dependencies:
eventemitter3: 4.0.7
- follow-redirects: 1.15.2(debug@4.3.4)
+ follow-redirects: 1.15.2
requires-port: 1.0.0
transitivePeerDependencies:
- debug
@@ -43177,6 +44990,19 @@ packages:
transitivePeerDependencies:
- supports-color
+ /istanbul-lib-instrument@6.0.2:
+ resolution: {integrity: sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==}
+ engines: {node: '>=10'}
+ dependencies:
+ '@babel/core': 7.24.4
+ '@babel/parser': 7.23.9
+ '@istanbuljs/schema': 0.1.3
+ istanbul-lib-coverage: 3.2.0
+ semver: 7.5.4
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
/istanbul-lib-processinfo@2.0.3:
resolution: {integrity: sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==}
engines: {node: '>=8'}
@@ -43292,6 +45118,15 @@ packages:
p-limit: 3.1.0
dev: true
+ /jest-changed-files@29.7.0:
+ resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ execa: 5.1.1
+ jest-util: 29.7.0
+ p-limit: 3.1.0
+ dev: true
+
/jest-circus@27.5.1:
resolution: {integrity: sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
@@ -43347,6 +45182,35 @@ packages:
- supports-color
dev: true
+ /jest-circus@29.7.0:
+ resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ '@jest/environment': 29.7.0
+ '@jest/expect': 29.7.0
+ '@jest/test-result': 29.7.0
+ '@jest/types': 29.6.3
+ '@types/node': 14.18.42
+ chalk: 4.1.2
+ co: 4.6.0
+ dedent: 1.5.1
+ is-generator-fn: 2.1.0
+ jest-each: 29.7.0
+ jest-matcher-utils: 29.7.0
+ jest-message-util: 29.7.0
+ jest-runtime: 29.7.0
+ jest-snapshot: 29.7.0
+ jest-util: 29.7.0
+ p-limit: 3.1.0
+ pretty-format: 29.7.0
+ pure-rand: 6.0.1
+ slash: 3.0.0
+ stack-utils: 2.0.6
+ transitivePeerDependencies:
+ - babel-plugin-macros
+ - supports-color
+ dev: true
+
/jest-cli@27.5.1(ts-node@10.9.1):
resolution: {integrity: sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
@@ -43433,6 +45297,34 @@ packages:
- ts-node
dev: true
+ /jest-cli@29.7.0(@types/node@14.18.42)(ts-node@10.9.1):
+ resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ hasBin: true
+ peerDependencies:
+ node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
+ peerDependenciesMeta:
+ node-notifier:
+ optional: true
+ dependencies:
+ '@jest/core': 29.7.0(ts-node@10.9.1)
+ '@jest/test-result': 29.7.0
+ '@jest/types': 29.6.3
+ chalk: 4.1.2
+ create-jest: 29.7.0(@types/node@14.18.42)(ts-node@10.9.1)
+ exit: 0.1.2
+ import-local: 3.1.0
+ jest-config: 29.7.0(@types/node@14.18.42)(ts-node@10.9.1)
+ jest-util: 29.7.0
+ jest-validate: 29.7.0
+ yargs: 17.7.2
+ transitivePeerDependencies:
+ - '@types/node'
+ - babel-plugin-macros
+ - supports-color
+ - ts-node
+ dev: true
+
/jest-config@27.5.1(ts-node@10.9.1):
resolution: {integrity: sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
@@ -43594,6 +45486,47 @@ packages:
- supports-color
dev: true
+ /jest-config@29.7.0(@types/node@14.18.42)(ts-node@10.9.1):
+ resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ peerDependencies:
+ '@types/node': '*'
+ ts-node: '>=9.0.0'
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ ts-node:
+ optional: true
+ dependencies:
+ '@babel/core': 7.23.2
+ '@jest/test-sequencer': 29.7.0
+ '@jest/types': 29.6.3
+ '@types/node': 14.18.42
+ babel-jest: 29.7.0(@babel/core@7.23.2)
+ chalk: 4.1.2
+ ci-info: 3.8.0
+ deepmerge: 4.3.1
+ glob: 7.2.3
+ graceful-fs: 4.2.11
+ jest-circus: 29.7.0
+ jest-environment-node: 29.7.0
+ jest-get-type: 29.6.3
+ jest-regex-util: 29.6.3
+ jest-resolve: 29.7.0
+ jest-runner: 29.7.0
+ jest-util: 29.7.0
+ jest-validate: 29.7.0
+ micromatch: 4.0.5
+ parse-json: 5.2.0
+ pretty-format: 29.7.0
+ slash: 3.0.0
+ strip-json-comments: 3.1.1
+ ts-node: 10.9.1(@types/node@16.11.7)(typescript@4.9.5)
+ transitivePeerDependencies:
+ - babel-plugin-macros
+ - supports-color
+ dev: true
+
/jest-diff@24.9.0:
resolution: {integrity: sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ==}
engines: {node: '>= 6'}
@@ -43623,6 +45556,16 @@ packages:
jest-get-type: 29.4.3
pretty-format: 29.7.0
+ /jest-diff@29.7.0:
+ resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ chalk: 4.1.2
+ diff-sequences: 29.6.3
+ jest-get-type: 29.6.3
+ pretty-format: 29.7.0
+ dev: true
+
/jest-docblock@27.5.1:
resolution: {integrity: sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
@@ -43637,6 +45580,13 @@ packages:
detect-newline: 3.1.0
dev: true
+ /jest-docblock@29.7.0:
+ resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ detect-newline: 3.1.0
+ dev: true
+
/jest-each@27.5.1:
resolution: {integrity: sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
@@ -43659,6 +45609,17 @@ packages:
pretty-format: 29.7.0
dev: true
+ /jest-each@29.7.0:
+ resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ '@jest/types': 29.6.3
+ chalk: 4.1.2
+ jest-get-type: 29.6.3
+ jest-util: 29.7.0
+ pretty-format: 29.7.0
+ dev: true
+
/jest-environment-jsdom@27.5.1:
resolution: {integrity: sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
@@ -43724,6 +45685,18 @@ packages:
jest-util: 29.5.0
dev: true
+ /jest-environment-node@29.7.0:
+ resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ '@jest/environment': 29.7.0
+ '@jest/fake-timers': 29.7.0
+ '@jest/types': 29.6.3
+ '@types/node': 14.18.42
+ jest-mock: 29.7.0
+ jest-util: 29.7.0
+ dev: true
+
/jest-fetch-mock@3.0.3:
resolution: {integrity: sha512-Ux1nWprtLrdrH4XwE7O7InRY6psIi3GOsqNESJgMJ+M5cv4A8Lh7SN9d2V2kKRZ8ebAfcd1LNyZguAOb6JiDqw==}
dependencies:
@@ -43747,6 +45720,11 @@ packages:
resolution: {integrity: sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ /jest-get-type@29.6.3:
+ resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dev: true
+
/jest-haste-map@27.5.1:
resolution: {integrity: sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
@@ -43785,6 +45763,25 @@ packages:
optionalDependencies:
fsevents: 2.3.3
+ /jest-haste-map@29.7.0:
+ resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ '@jest/types': 29.6.3
+ '@types/graceful-fs': 4.1.6
+ '@types/node': 14.18.42
+ anymatch: 3.1.3
+ fb-watchman: 2.0.2
+ graceful-fs: 4.2.11
+ jest-regex-util: 29.6.3
+ jest-util: 29.7.0
+ jest-worker: 29.7.0
+ micromatch: 4.0.5
+ walker: 1.0.8
+ optionalDependencies:
+ fsevents: 2.3.3
+ dev: true
+
/jest-jasmine2@27.5.1:
resolution: {integrity: sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
@@ -43826,6 +45823,14 @@ packages:
pretty-format: 29.7.0
dev: true
+ /jest-leak-detector@29.7.0:
+ resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ jest-get-type: 29.6.3
+ pretty-format: 29.7.0
+ dev: true
+
/jest-matcher-utils@24.9.0:
resolution: {integrity: sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA==}
engines: {node: '>= 6'}
@@ -43855,6 +45860,16 @@ packages:
jest-get-type: 29.4.3
pretty-format: 29.7.0
+ /jest-matcher-utils@29.7.0:
+ resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ chalk: 4.1.2
+ jest-diff: 29.7.0
+ jest-get-type: 29.6.3
+ pretty-format: 29.7.0
+ dev: true
+
/jest-message-util@27.5.1:
resolution: {integrity: sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
@@ -43899,6 +45914,21 @@ packages:
slash: 3.0.0
stack-utils: 2.0.6
+ /jest-message-util@29.7.0:
+ resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ '@babel/code-frame': 7.22.13
+ '@jest/types': 29.6.3
+ '@types/stack-utils': 2.0.1
+ chalk: 4.1.2
+ graceful-fs: 4.2.11
+ micromatch: 4.0.5
+ pretty-format: 29.7.0
+ slash: 3.0.0
+ stack-utils: 2.0.6
+ dev: true
+
/jest-mock@27.5.1:
resolution: {integrity: sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
@@ -43916,6 +45946,15 @@ packages:
jest-util: 29.5.0
dev: true
+ /jest-mock@29.7.0:
+ resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ '@jest/types': 29.6.3
+ '@types/node': 14.18.42
+ jest-util: 29.7.0
+ dev: true
+
/jest-node-exports-resolver@1.1.6:
resolution: {integrity: sha512-NU412Qcb6WSRetCyEGMCC7IWHzO12LhSKaF1s9cyfM+EOYs4YN2gcNUT8hgu22X0oPFYNwLSPevgstBgLbD9ig==}
dev: true
@@ -43944,6 +45983,18 @@ packages:
jest-resolve: 29.5.0
dev: true
+ /jest-pnp-resolver@1.2.3(jest-resolve@29.7.0):
+ resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==}
+ engines: {node: '>=6'}
+ peerDependencies:
+ jest-resolve: '*'
+ peerDependenciesMeta:
+ jest-resolve:
+ optional: true
+ dependencies:
+ jest-resolve: 29.7.0
+ dev: true
+
/jest-regex-util@27.5.1:
resolution: {integrity: sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
@@ -43958,6 +46009,11 @@ packages:
resolution: {integrity: sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ /jest-regex-util@29.6.3:
+ resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dev: true
+
/jest-resolve-dependencies@27.5.1:
resolution: {integrity: sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
@@ -43979,6 +46035,16 @@ packages:
- supports-color
dev: true
+ /jest-resolve-dependencies@29.7.0:
+ resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ jest-regex-util: 29.6.3
+ jest-snapshot: 29.7.0
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
/jest-resolve@27.5.1:
resolution: {integrity: sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
@@ -44010,6 +46076,21 @@ packages:
slash: 3.0.0
dev: true
+ /jest-resolve@29.7.0:
+ resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ chalk: 4.1.2
+ graceful-fs: 4.2.11
+ jest-haste-map: 29.7.0
+ jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0)
+ jest-util: 29.7.0
+ jest-validate: 29.7.0
+ resolve: 1.22.2
+ resolve.exports: 2.0.2
+ slash: 3.0.0
+ dev: true
+
/jest-runner@27.5.1:
resolution: {integrity: sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
@@ -44071,6 +46152,35 @@ packages:
- supports-color
dev: true
+ /jest-runner@29.7.0:
+ resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ '@jest/console': 29.7.0
+ '@jest/environment': 29.7.0
+ '@jest/test-result': 29.7.0
+ '@jest/transform': 29.7.0
+ '@jest/types': 29.6.3
+ '@types/node': 14.18.42
+ chalk: 4.1.2
+ emittery: 0.13.1
+ graceful-fs: 4.2.11
+ jest-docblock: 29.7.0
+ jest-environment-node: 29.7.0
+ jest-haste-map: 29.7.0
+ jest-leak-detector: 29.7.0
+ jest-message-util: 29.7.0
+ jest-resolve: 29.7.0
+ jest-runtime: 29.7.0
+ jest-util: 29.7.0
+ jest-watcher: 29.7.0
+ jest-worker: 29.7.0
+ p-limit: 3.1.0
+ source-map-support: 0.5.13
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
/jest-runtime@27.5.1:
resolution: {integrity: sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
@@ -44131,6 +46241,36 @@ packages:
- supports-color
dev: true
+ /jest-runtime@29.7.0:
+ resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ '@jest/environment': 29.7.0
+ '@jest/fake-timers': 29.7.0
+ '@jest/globals': 29.7.0
+ '@jest/source-map': 29.6.3
+ '@jest/test-result': 29.7.0
+ '@jest/transform': 29.7.0
+ '@jest/types': 29.6.3
+ '@types/node': 14.18.42
+ chalk: 4.1.2
+ cjs-module-lexer: 1.2.2
+ collect-v8-coverage: 1.0.1
+ glob: 7.2.3
+ graceful-fs: 4.2.11
+ jest-haste-map: 29.7.0
+ jest-message-util: 29.7.0
+ jest-mock: 29.7.0
+ jest-regex-util: 29.6.3
+ jest-resolve: 29.7.0
+ jest-snapshot: 29.7.0
+ jest-util: 29.7.0
+ slash: 3.0.0
+ strip-bom: 4.0.0
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
/jest-serializer@27.5.1:
resolution: {integrity: sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
@@ -44200,6 +46340,34 @@ packages:
- supports-color
dev: true
+ /jest-snapshot@29.7.0:
+ resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ '@babel/core': 7.23.2
+ '@babel/generator': 7.23.0
+ '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.23.2)
+ '@babel/types': 7.23.0
+ '@jest/expect-utils': 29.7.0
+ '@jest/transform': 29.7.0
+ '@jest/types': 29.6.3
+ babel-preset-current-node-syntax: 1.0.1(@babel/core@7.23.2)
+ chalk: 4.1.2
+ expect: 29.7.0
+ graceful-fs: 4.2.11
+ jest-diff: 29.7.0
+ jest-get-type: 29.6.3
+ jest-matcher-utils: 29.7.0
+ jest-message-util: 29.7.0
+ jest-util: 29.7.0
+ natural-compare: 1.4.0
+ pretty-format: 29.7.0
+ semver: 7.5.4
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
/jest-transform-stub@2.0.0:
resolution: {integrity: sha512-lspHaCRx/mBbnm3h4uMMS3R5aZzMwyNpNIJLXj4cEsV0mIUtS4IjYJLSoyjRCtnxb6RIGJ4NL2quZzfIeNhbkg==}
dev: true
@@ -44239,6 +46407,18 @@ packages:
graceful-fs: 4.2.11
picomatch: 2.3.1
+ /jest-util@29.7.0:
+ resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ '@jest/types': 29.6.3
+ '@types/node': 14.18.42
+ chalk: 4.1.2
+ ci-info: 3.8.0
+ graceful-fs: 4.2.11
+ picomatch: 2.3.1
+ dev: true
+
/jest-validate@27.5.1:
resolution: {integrity: sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
@@ -44263,6 +46443,18 @@ packages:
pretty-format: 29.7.0
dev: true
+ /jest-validate@29.7.0:
+ resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ '@jest/types': 29.6.3
+ camelcase: 6.3.0
+ chalk: 4.1.2
+ jest-get-type: 29.6.3
+ leven: 3.1.0
+ pretty-format: 29.7.0
+ dev: true
+
/jest-watch-typeahead@1.1.0(jest@27.5.1):
resolution: {integrity: sha512-Va5nLSJTN7YFtC2jd+7wsoe1pNe5K4ShLux/E5iHEwlB9AxaxmggY7to9KUqKojhaJw3aXqt5WAb4jGPOolpEw==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -44320,6 +46512,20 @@ packages:
string-length: 4.0.2
dev: true
+ /jest-watcher@29.7.0:
+ resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ '@jest/test-result': 29.7.0
+ '@jest/types': 29.6.3
+ '@types/node': 14.18.42
+ ansi-escapes: 4.3.2
+ chalk: 4.1.2
+ emittery: 0.13.1
+ jest-util: 29.7.0
+ string-length: 4.0.2
+ dev: true
+
/jest-worker@26.6.2:
resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==}
engines: {node: '>= 10.13.0'}
@@ -44355,6 +46561,16 @@ packages:
merge-stream: 2.0.0
supports-color: 8.1.1
+ /jest-worker@29.7.0:
+ resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ dependencies:
+ '@types/node': 14.18.42
+ jest-util: 29.7.0
+ merge-stream: 2.0.0
+ supports-color: 8.1.1
+ dev: true
+
/jest@27.5.1(ts-node@10.9.1):
resolution: {integrity: sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
@@ -44416,6 +46632,27 @@ packages:
- ts-node
dev: true
+ /jest@29.7.0(@types/node@14.18.42)(ts-node@10.9.1):
+ resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ hasBin: true
+ peerDependencies:
+ node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
+ peerDependenciesMeta:
+ node-notifier:
+ optional: true
+ dependencies:
+ '@jest/core': 29.7.0(ts-node@10.9.1)
+ '@jest/types': 29.6.3
+ import-local: 3.1.0
+ jest-cli: 29.7.0(@types/node@14.18.42)(ts-node@10.9.1)
+ transitivePeerDependencies:
+ - '@types/node'
+ - babel-plugin-macros
+ - supports-color
+ - ts-node
+ dev: true
+
/jira-prepare-commit-msg@1.7.2:
resolution: {integrity: sha512-vPmwqPoi5TfMF1rXh9XN6u7TiSG+FwdcbeL01nMBUbRRxTMXvIqQZoJSRoNoprgY1JUpYXplc3HGRSVsV22rLg==}
engines: {node: '>=14'}
@@ -44547,7 +46784,7 @@ packages:
hasBin: true
requiresBuild: true
dependencies:
- '@babel/parser': 7.23.0
+ '@babel/parser': 7.23.9
'@jsdoc/salty': 0.2.5
'@types/markdown-it': 12.2.3
bluebird: 3.7.2
@@ -47296,8 +49533,8 @@ packages:
yargs-unparser: 2.0.0
dev: true
- /mocha@10.3.0:
- resolution: {integrity: sha512-uF2XJs+7xSLsrmIvn37i/wnc91nw7XjOQB8ccyx5aEgdnohr7n+rEiZP23WkCYHjilR6+EboEnbq/ZQDz4LSbg==}
+ /mocha@10.4.0:
+ resolution: {integrity: sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==}
engines: {node: '>= 14.0.0'}
hasBin: true
dependencies:
@@ -47655,7 +49892,7 @@ packages:
hasBin: true
requiresBuild: true
dependencies:
- debug: 3.2.7(supports-color@8.1.1)
+ debug: 3.2.7(supports-color@5.5.0)
iconv-lite: 0.6.3
sax: 1.2.4
transitivePeerDependencies:
@@ -47994,6 +50231,7 @@ packages:
/node-gyp-build@4.6.0:
resolution: {integrity: sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==}
hasBin: true
+ requiresBuild: true
/node-gyp@9.3.1:
resolution: {integrity: sha512-4Q16ZCqq3g8awk6UplT7AuxQ35XN4R/yf/+wSAwcBUAjg7l58RTactWaP8fIDTi0FzI7YcVLujwExakZlfWkXg==}
@@ -49952,6 +52190,22 @@ packages:
find-up: 3.0.0
dev: true
+ /playwright-core@1.42.1:
+ resolution: {integrity: sha512-mxz6zclokgrke9p1vtdy/COWBH+eOZgYUVVU34C73M+4j4HLlQJHtfcqiqqxpP0o8HhMkflvfbquLX5dg6wlfA==}
+ engines: {node: '>=16'}
+ hasBin: true
+ dev: true
+
+ /playwright@1.42.1:
+ resolution: {integrity: sha512-PgwB03s2DZBcNRoW+1w9E+VkLBxweib6KTXM0M3tkiT4jVxKSi6PmVJ591J+0u10LUrgxB7dLRbiJqO5s2QPMg==}
+ engines: {node: '>=16'}
+ hasBin: true
+ dependencies:
+ playwright-core: 1.42.1
+ optionalDependencies:
+ fsevents: 2.3.2
+ dev: true
+
/please-upgrade-node@3.2.0:
resolution: {integrity: sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==}
dependencies:
@@ -50030,7 +52284,7 @@ packages:
engines: {node: '>= 0.12.0'}
dependencies:
async: 2.6.4
- debug: 3.2.7(supports-color@8.1.1)
+ debug: 3.2.7(supports-color@5.5.0)
mkdirp: 0.5.6
transitivePeerDependencies:
- supports-color
@@ -52644,6 +54898,24 @@ packages:
history: 5.3.0
react: 17.0.2
+ /react-scanner@1.1.0:
+ resolution: {integrity: sha512-27G8K1TJ4FUp9+Ix5mkwhWnFdoIwYj95Ffwom0gWh3V+7zds1SRfbbRzi89EXMtZj9IiLhgEyBOBy/k6IysGNg==}
+ engines: {node: '>=14.x'}
+ hasBin: true
+ dependencies:
+ '@typescript-eslint/typescript-estree': 5.20.0(typescript@4.6.3)
+ astray: 1.1.1
+ dlv: 1.1.3
+ dset: 3.1.2
+ fdir: 5.2.0(picomatch@2.3.1)
+ is-plain-object: 5.0.0
+ picomatch: 2.3.1
+ sade: 1.8.1
+ typescript: 4.6.3
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
/react-scripts@5.0.1(@babel/plugin-syntax-flow@7.22.5)(@babel/plugin-transform-react-jsx@7.22.15)(@swc/core@1.3.49)(esbuild@0.18.20)(eslint-import-resolver-webpack@0.13.7)(eslint@8.51.0)(react@17.0.2)(ts-node@10.9.1)(typescript@4.9.5):
resolution: {integrity: sha512-8VAmEm/ZAwQzJ+GOMLbBsTdDKOpuZh7RPs0UymvBR2vRk4iZWCskjbFnxqjrzoIvlNNRZ3QJFx6/qDSi6zSnaQ==}
engines: {node: '>=14.0.0'}
@@ -56665,7 +58937,7 @@ packages:
tslib: 1.14.1
dev: true
- /ts-jest@27.1.5(@babel/core@7.23.2)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5):
+ /ts-jest@27.1.5(@babel/core@7.24.4)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5):
resolution: {integrity: sha512-Xv6jBQPoBEvBq/5i2TeSG9tt/nqkbpcurrEG1b+2yfBrcJelOZF9Ml6dmyMh7bcW9JyFbRYpR5rxROSlBLTZHA==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
hasBin: true
@@ -56686,7 +58958,7 @@ packages:
esbuild:
optional: true
dependencies:
- '@babel/core': 7.23.2
+ '@babel/core': 7.24.4
'@types/jest': 27.5.2
bs-logger: 0.2.6
fast-json-stable-stringify: 2.1.0
@@ -56700,7 +58972,7 @@ packages:
yargs-parser: 20.2.9
dev: true
- /ts-jest@27.1.5(@babel/core@7.23.2)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5):
+ /ts-jest@27.1.5(@babel/core@7.24.4)(@types/jest@29.5.1)(jest@27.5.1)(typescript@4.9.5):
resolution: {integrity: sha512-Xv6jBQPoBEvBq/5i2TeSG9tt/nqkbpcurrEG1b+2yfBrcJelOZF9Ml6dmyMh7bcW9JyFbRYpR5rxROSlBLTZHA==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
hasBin: true
@@ -56721,7 +58993,7 @@ packages:
esbuild:
optional: true
dependencies:
- '@babel/core': 7.23.2
+ '@babel/core': 7.24.4
'@types/jest': 29.5.1
bs-logger: 0.2.6
fast-json-stable-stringify: 2.1.0
@@ -56735,7 +59007,7 @@ packages:
yargs-parser: 20.2.9
dev: true
- /ts-jest@27.1.5(@babel/core@7.23.2)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5):
+ /ts-jest@27.1.5(@babel/core@7.24.4)(@types/jest@29.5.2)(jest@27.5.1)(typescript@4.9.5):
resolution: {integrity: sha512-Xv6jBQPoBEvBq/5i2TeSG9tt/nqkbpcurrEG1b+2yfBrcJelOZF9Ml6dmyMh7bcW9JyFbRYpR5rxROSlBLTZHA==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
hasBin: true
@@ -56756,7 +59028,7 @@ packages:
esbuild:
optional: true
dependencies:
- '@babel/core': 7.23.2
+ '@babel/core': 7.24.4
'@types/jest': 29.5.2
bs-logger: 0.2.6
fast-json-stable-stringify: 2.1.0
@@ -56770,7 +59042,7 @@ packages:
yargs-parser: 20.2.9
dev: true
- /ts-jest@29.1.0(@babel/core@7.23.2)(esbuild@0.18.20)(jest@29.5.0)(typescript@4.9.5):
+ /ts-jest@29.1.0(@babel/core@7.24.4)(esbuild@0.18.20)(jest@29.5.0)(typescript@4.9.5):
resolution: {integrity: sha512-ZhNr7Z4PcYa+JjMl62ir+zPiNJfXJN6E8hSLnaUKhOgqcn8vb3e537cpkd0FuAfRK3sR1LSqM1MOhliXNgOFPA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
hasBin: true
@@ -56791,7 +59063,7 @@ packages:
esbuild:
optional: true
dependencies:
- '@babel/core': 7.23.2
+ '@babel/core': 7.24.4
bs-logger: 0.2.6
esbuild: 0.18.20
fast-json-stable-stringify: 2.1.0
@@ -56805,7 +59077,7 @@ packages:
yargs-parser: 21.1.1
dev: true
- /ts-jest@29.1.0(@babel/core@7.23.2)(jest@29.5.0)(typescript@4.9.5):
+ /ts-jest@29.1.0(@babel/core@7.24.4)(jest@29.5.0)(typescript@4.9.5):
resolution: {integrity: sha512-ZhNr7Z4PcYa+JjMl62ir+zPiNJfXJN6E8hSLnaUKhOgqcn8vb3e537cpkd0FuAfRK3sR1LSqM1MOhliXNgOFPA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
hasBin: true
@@ -56826,7 +59098,7 @@ packages:
esbuild:
optional: true
dependencies:
- '@babel/core': 7.23.2
+ '@babel/core': 7.24.4
bs-logger: 0.2.6
fast-json-stable-stringify: 2.1.0
jest: 29.5.0(@types/node@14.18.42)(ts-node@10.9.1)
@@ -56839,6 +59111,40 @@ packages:
yargs-parser: 21.1.1
dev: true
+ /ts-jest@29.1.2(@babel/core@7.24.4)(jest@29.7.0)(typescript@4.9.5):
+ resolution: {integrity: sha512-br6GJoH/WUX4pu7FbZXuWGKGNDuU7b8Uj77g/Sp7puZV6EXzuByl6JrECvm0MzVzSTkSHWTihsXt+5XYER5b+g==}
+ engines: {node: ^16.10.0 || ^18.0.0 || >=20.0.0}
+ hasBin: true
+ peerDependencies:
+ '@babel/core': '>=7.0.0-beta.0 <8'
+ '@jest/types': ^29.0.0
+ babel-jest: ^29.0.0
+ esbuild: '*'
+ jest: ^29.0.0
+ typescript: '>=4.3 <6'
+ peerDependenciesMeta:
+ '@babel/core':
+ optional: true
+ '@jest/types':
+ optional: true
+ babel-jest:
+ optional: true
+ esbuild:
+ optional: true
+ dependencies:
+ '@babel/core': 7.24.4
+ bs-logger: 0.2.6
+ fast-json-stable-stringify: 2.1.0
+ jest: 29.7.0(@types/node@14.18.42)(ts-node@10.9.1)
+ jest-util: 29.5.0
+ json5: 2.2.3
+ lodash.memoize: 4.1.2
+ make-error: 1.3.6
+ semver: 7.5.4
+ typescript: 4.9.5
+ yargs-parser: 21.1.1
+ dev: true
+
/ts-loader@9.4.2(typescript@4.9.5)(webpack@5.78.0):
resolution: {integrity: sha512-OmlC4WVmFv5I0PpaxYb+qGeGOdm5giHU7HwDDUjw59emP2UYMHy9fFSDcYgSNoH8sXcj4hGCSEhlDZ9ULeDraA==}
engines: {node: '>=12.0.0'}
@@ -56926,8 +59232,8 @@ packages:
'@tsconfig/node14': 1.0.3
'@tsconfig/node16': 1.0.3
'@types/node': 16.11.7
- acorn: 8.11.3
- acorn-walk: 8.3.2
+ acorn: 8.10.0
+ acorn-walk: 8.2.0
arg: 4.1.3
create-require: 1.1.1
diff: 4.0.2
@@ -56957,8 +59263,8 @@ packages:
'@tsconfig/node14': 1.0.3
'@tsconfig/node16': 1.0.3
'@types/node': 16.11.7
- acorn: 8.11.3
- acorn-walk: 8.3.2
+ acorn: 8.10.0
+ acorn-walk: 8.2.0
arg: 4.1.3
create-require: 1.1.1
diff: 4.0.2
@@ -56988,8 +59294,8 @@ packages:
'@tsconfig/node14': 1.0.3
'@tsconfig/node16': 1.0.3
'@types/node': 20.5.1
- acorn: 8.11.3
- acorn-walk: 8.3.2
+ acorn: 8.10.0
+ acorn-walk: 8.2.0
arg: 4.1.3
create-require: 1.1.1
diff: 4.0.2
@@ -57113,6 +59419,16 @@ packages:
/tslib@2.6.2:
resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
+ /tsutils@3.21.0(typescript@4.6.3):
+ resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
+ engines: {node: '>= 6'}
+ peerDependencies:
+ typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta'
+ dependencies:
+ tslib: 1.14.1
+ typescript: 4.6.3
+ dev: true
+
/tsutils@3.21.0(typescript@4.9.5):
resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
engines: {node: '>= 6'}
@@ -57323,6 +59639,12 @@ packages:
resolution: {integrity: sha512-GQ90TcKpIH4XxYTI2F98yEQYZgjNMOGPpOgdjIBhaLaWji5HPWlRnZ4AeA1hfBxtY7bCGDJsqDDHk/KaHOl5bA==}
dev: true
+ /typescript@4.6.3:
+ resolution: {integrity: sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==}
+ engines: {node: '>=4.2.0'}
+ hasBin: true
+ dev: true
+
/typescript@4.9.5:
resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==}
engines: {node: '>=4.2.0'}
@@ -58970,7 +61292,7 @@ packages:
optional: true
dependencies:
'@types/eslint-scope': 3.7.4
- '@types/estree': 1.0.1
+ '@types/estree': 1.0.5
'@webassemblyjs/ast': 1.11.5
'@webassemblyjs/wasm-edit': 1.11.5
'@webassemblyjs/wasm-parser': 1.11.5
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index 8118e6c86c2..ed81fa8c04c 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -11,3 +11,4 @@ packages:
# all packages in enterprise modules
- 'enterprise/packages/*'
- 'enterprise/packages/libs/*'
+ - 'enterprise/packages/web/*'
diff --git a/providers/africas-talking/package.json b/providers/africas-talking/package.json
index 35b0e05d9bc..e300e549d66 100644
--- a/providers/africas-talking/package.json
+++ b/providers/africas-talking/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/africas-talking",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "An Africa's Talking wrapper for Novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -30,7 +30,7 @@
"access": "public"
},
"dependencies": {
- "@novu/stateless": "^0.24.0",
+ "@novu/stateless": "^0.24.1",
"africastalking": "^0.6.2"
},
"devDependencies": {
diff --git a/providers/apns/package.json b/providers/apns/package.json
index f40a042636c..ae81adcf168 100644
--- a/providers/apns/package.json
+++ b/providers/apns/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/apns",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
+ "@novu/stateless": "^0.24.1",
"@parse/node-apn": "^5.2.3"
},
"devDependencies": {
diff --git a/providers/azure-sms/package.json b/providers/azure-sms/package.json
index b55e4e30229..39095c3d3ee 100644
--- a/providers/azure-sms/package.json
+++ b/providers/azure-sms/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/azure-sms",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "A azure-sms wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -30,7 +30,7 @@
},
"dependencies": {
"@azure/communication-sms": "^1.0.0",
- "@novu/stateless": "^0.24.0"
+ "@novu/stateless": "^0.24.1"
},
"devDependencies": {
"@istanbuljs/nyc-config-typescript": "~1.0.1",
diff --git a/providers/bandwidth/package.json b/providers/bandwidth/package.json
index 1298b0865c4..1cc174eb1c7 100644
--- a/providers/bandwidth/package.json
+++ b/providers/bandwidth/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/bandwidth",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "A bandwidth wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -30,7 +30,7 @@
},
"dependencies": {
"@bandwidth/messaging": "^4.1.3",
- "@novu/stateless": "^0.24.0"
+ "@novu/stateless": "^0.24.1"
},
"devDependencies": {
"@istanbuljs/nyc-config-typescript": "~1.0.1",
diff --git a/providers/braze/package.json b/providers/braze/package.json
index 33cb2d16b05..154aa48027c 100644
--- a/providers/braze/package.json
+++ b/providers/braze/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/braze",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "A braze wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -29,7 +29,7 @@
"access": "public"
},
"dependencies": {
- "@novu/stateless": "^0.24.0",
+ "@novu/stateless": "^0.24.1",
"braze-api": "^2.5.6"
},
"devDependencies": {
diff --git a/providers/brevo-sms/package.json b/providers/brevo-sms/package.json
index ac8f1983999..c8bd4cfe6f4 100644
--- a/providers/brevo-sms/package.json
+++ b/providers/brevo-sms/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/brevo-sms",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "A brevo-sms wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -29,7 +29,7 @@
"access": "public"
},
"dependencies": {
- "@novu/stateless": "^0.24.0",
+ "@novu/stateless": "^0.24.1",
"cross-fetch": "^4.0.0",
"proxy-agent": "^6.3.1"
},
diff --git a/providers/bulk-sms/package.json b/providers/bulk-sms/package.json
index 3d5fc356637..fc8eb084fa4 100644
--- a/providers/bulk-sms/package.json
+++ b/providers/bulk-sms/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/bulk-sms",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "A bulk-sms wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -29,7 +29,7 @@
"access": "public"
},
"dependencies": {
- "@novu/stateless": "^0.24.0",
+ "@novu/stateless": "^0.24.1",
"axios": "^1.6.0"
},
"devDependencies": {
diff --git a/providers/burst-sms/package.json b/providers/burst-sms/package.json
index 040e3f55eef..6e9961ca5a6 100644
--- a/providers/burst-sms/package.json
+++ b/providers/burst-sms/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/burst-sms",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
+ "@novu/stateless": "^0.24.1",
"axios": "^1.6.2",
"qs": "^6.11.0"
},
diff --git a/providers/clickatell/package.json b/providers/clickatell/package.json
index 8881aa0a46e..089a2f852be 100644
--- a/providers/clickatell/package.json
+++ b/providers/clickatell/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/clickatell",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
+ "@novu/stateless": "^0.24.1",
"axios": "^1.6.2"
},
"devDependencies": {
diff --git a/providers/clicksend/package.json b/providers/clicksend/package.json
index b9e9595fb59..f226ac8c0b4 100644
--- a/providers/clicksend/package.json
+++ b/providers/clicksend/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/clicksend",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "A clicksend wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -29,7 +29,7 @@
"access": "public"
},
"dependencies": {
- "@novu/stateless": "^0.24.0",
+ "@novu/stateless": "^0.24.1",
"axios": "^1.6.0"
},
"devDependencies": {
diff --git a/providers/discord/package.json b/providers/discord/package.json
index 06ce40c7d44..708cf1f5ece 100644
--- a/providers/discord/package.json
+++ b/providers/discord/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/discord",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
+ "@novu/stateless": "^0.24.1",
"axios": "^1.6.2"
},
"devDependencies": {
diff --git a/providers/email-webhook/package.json b/providers/email-webhook/package.json
index 2e3c22a3bce..d6ea4f4f7aa 100644
--- a/providers/email-webhook/package.json
+++ b/providers/email-webhook/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/email-webhook",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "An email channel webhook provider wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -38,7 +38,7 @@
"node": ">=10"
},
"dependencies": {
- "@novu/stateless": "^0.24.0",
+ "@novu/stateless": "^0.24.1",
"axios": "^1.6.2"
},
"devDependencies": {
diff --git a/providers/emailjs/package.json b/providers/emailjs/package.json
index 2cd95ef271a..beced3a5f00 100644
--- a/providers/emailjs/package.json
+++ b/providers/emailjs/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/emailjs",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
+ "@novu/stateless": "^0.24.1",
"emailjs": "^3.6.0"
},
"devDependencies": {
diff --git a/providers/expo/package.json b/providers/expo/package.json
index 6bec3ccb42e..6badb7d6ecf 100644
--- a/providers/expo/package.json
+++ b/providers/expo/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/expo",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
+ "@novu/stateless": "^0.24.1",
"expo-server-sdk": "^3.6.0"
},
"devDependencies": {
diff --git a/providers/fcm/package.json b/providers/fcm/package.json
index 2dca1c24a56..965488faf6d 100644
--- a/providers/fcm/package.json
+++ b/providers/fcm/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/fcm",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
+ "@novu/stateless": "^0.24.1",
"firebase-admin": "^11.10.1"
},
"devDependencies": {
diff --git a/providers/firetext/package.json b/providers/firetext/package.json
index 6769a3c36f7..78bcc0b611d 100644
--- a/providers/firetext/package.json
+++ b/providers/firetext/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/firetext",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
+ "@novu/stateless": "^0.24.1",
"node-fetch": "^3.2.10"
},
"devDependencies": {
diff --git a/providers/forty-six-elks/package.json b/providers/forty-six-elks/package.json
index 6d385317390..e86e824bc55 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.24.0",
+ "version": "0.24.1",
"description": "A 46elks wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -29,7 +29,7 @@
"access": "public"
},
"dependencies": {
- "@novu/stateless": "^0.24.0",
+ "@novu/stateless": "^0.24.1",
"axios": "^1.6.2"
},
"devDependencies": {
diff --git a/providers/generic-sms/package.json b/providers/generic-sms/package.json
index 82ab3f58830..1efe38bace5 100644
--- a/providers/generic-sms/package.json
+++ b/providers/generic-sms/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/generic-sms",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "A generic-sms wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -29,7 +29,7 @@
"access": "public"
},
"dependencies": {
- "@novu/stateless": "^0.24.0",
+ "@novu/stateless": "^0.24.1",
"axios": "^1.6.2"
},
"devDependencies": {
diff --git a/providers/getstream/package.json b/providers/getstream/package.json
index 9836c49c4ca..63cc99ab47c 100644
--- a/providers/getstream/package.json
+++ b/providers/getstream/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/getstream",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "A getstream wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -29,7 +29,7 @@
"access": "public"
},
"dependencies": {
- "@novu/stateless": "^0.24.0",
+ "@novu/stateless": "^0.24.1",
"axios": "^1.6.2"
},
"devDependencies": {
diff --git a/providers/grafana-on-call/package.json b/providers/grafana-on-call/package.json
index 4c0dcdf3fb2..d2d98da757e 100644
--- a/providers/grafana-on-call/package.json
+++ b/providers/grafana-on-call/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/grafana-on-call",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "A grafana-on-call wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -29,7 +29,7 @@
"access": "public"
},
"dependencies": {
- "@novu/stateless": "^0.24.0",
+ "@novu/stateless": "^0.24.1",
"axios": "^1.6.2",
"uuid": "^9.0.0"
},
diff --git a/providers/gupshup/package.json b/providers/gupshup/package.json
index d8ba602eb21..f30ae30d27a 100644
--- a/providers/gupshup/package.json
+++ b/providers/gupshup/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/gupshup",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.23.1",
+ "@novu/stateless": "^0.24.1",
"axios": "^1.6.7",
"node-fetch": "^3.2.10"
},
diff --git a/providers/infobip/package.json b/providers/infobip/package.json
index 06fe1b6a831..b8cd73f1784 100644
--- a/providers/infobip/package.json
+++ b/providers/infobip/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/infobip",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.3.2",
- "@novu/stateless": "^0.24.0"
+ "@novu/stateless": "^0.24.1"
},
"devDependencies": {
"@istanbuljs/nyc-config-typescript": "^1.0.1",
diff --git a/providers/isend-sms/package.json b/providers/isend-sms/package.json
index 853ddea826e..66c0d01bcee 100644
--- a/providers/isend-sms/package.json
+++ b/providers/isend-sms/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/isend-sms",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "A isend-sms wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -29,7 +29,7 @@
"access": "public"
},
"dependencies": {
- "@novu/stateless": "^0.24.0",
+ "@novu/stateless": "^0.24.1",
"axios": "^1.6.0"
},
"devDependencies": {
diff --git a/providers/kannel/package.json b/providers/kannel/package.json
index 6813616f61c..1bffe067f58 100644
--- a/providers/kannel/package.json
+++ b/providers/kannel/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/kannel",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
+ "@novu/stateless": "^0.24.1",
"axios": "^1.6.2"
},
"devDependencies": {
diff --git a/providers/mailersend/package.json b/providers/mailersend/package.json
index 941a53d9b85..825f3660153 100644
--- a/providers/mailersend/package.json
+++ b/providers/mailersend/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/mailersend",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
+ "@novu/stateless": "^0.24.1",
"mailersend": "^1.3.1"
},
"devDependencies": {
diff --git a/providers/mailgun/package.json b/providers/mailgun/package.json
index 3db7080f890..c77b139918e 100644
--- a/providers/mailgun/package.json
+++ b/providers/mailgun/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/mailgun",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
+ "@novu/stateless": "^0.24.1",
"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 c851934a804..2e3aaf9d9d5 100644
--- a/providers/mailjet/package.json
+++ b/providers/mailjet/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/mailjet",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
+ "@novu/stateless": "^0.24.1",
"node-mailjet": "^6.0.5"
},
"devDependencies": {
diff --git a/providers/mailtrap/package.json b/providers/mailtrap/package.json
index 167309cfe9d..1a1a18846dd 100644
--- a/providers/mailtrap/package.json
+++ b/providers/mailtrap/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/mailtrap",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "A mailtrap wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -29,7 +29,7 @@
"access": "public"
},
"dependencies": {
- "@novu/stateless": "^0.24.0",
+ "@novu/stateless": "^0.24.1",
"mailtrap": "^3.1.1"
},
"devDependencies": {
diff --git a/providers/mandrill/package.json b/providers/mandrill/package.json
index 2b6e4428a25..53f210275ea 100644
--- a/providers/mandrill/package.json
+++ b/providers/mandrill/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/mandrill",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.50",
- "@novu/stateless": "^0.24.0"
+ "@novu/stateless": "^0.24.1"
},
"devDependencies": {
"@istanbuljs/nyc-config-typescript": "1.0.2",
diff --git a/providers/maqsam/package.json b/providers/maqsam/package.json
index 25171149609..3a2ae95544a 100644
--- a/providers/maqsam/package.json
+++ b/providers/maqsam/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/maqsam",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "A maqsam wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -29,7 +29,7 @@
"access": "public"
},
"dependencies": {
- "@novu/stateless": "^0.24.0",
+ "@novu/stateless": "^0.24.1",
"axios": "^1.6.2",
"date-fns": "2.29.3",
"moment": "^2.29.4"
diff --git a/providers/mattermost/package.json b/providers/mattermost/package.json
index a007ead7890..280bf7342b1 100644
--- a/providers/mattermost/package.json
+++ b/providers/mattermost/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/mattermost",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "A mattermost wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -29,7 +29,7 @@
"access": "public"
},
"dependencies": {
- "@novu/stateless": "^0.24.0",
+ "@novu/stateless": "^0.24.1",
"axios": "^1.6.2"
},
"devDependencies": {
diff --git a/providers/messagebird/package.json b/providers/messagebird/package.json
index 2160998722f..95a4974c00c 100644
--- a/providers/messagebird/package.json
+++ b/providers/messagebird/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/messagebird",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "A messagebird wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -29,7 +29,7 @@
"access": "public"
},
"dependencies": {
- "@novu/stateless": "^0.24.0",
+ "@novu/stateless": "^0.24.1",
"messagebird": "^4.0.1"
},
"devDependencies": {
diff --git a/providers/ms-teams/package.json b/providers/ms-teams/package.json
index 82134b4bd80..734a1b4731a 100644
--- a/providers/ms-teams/package.json
+++ b/providers/ms-teams/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/ms-teams",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "A MS-Teams wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -32,7 +32,7 @@
"node": ">=10"
},
"dependencies": {
- "@novu/stateless": "^0.24.0",
+ "@novu/stateless": "^0.24.1",
"axios": "^1.6.2"
},
"devDependencies": {
diff --git a/providers/netcore/package.json b/providers/netcore/package.json
index 4d68a3be5d7..2c4081216f5 100644
--- a/providers/netcore/package.json
+++ b/providers/netcore/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/netcore",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
+ "@novu/stateless": "^0.24.1",
"axios": "^1.6.2"
},
"devDependencies": {
diff --git a/providers/nexmo/package.json b/providers/nexmo/package.json
index aa9b3a29f16..28c67cf8655 100644
--- a/providers/nexmo/package.json
+++ b/providers/nexmo/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/nexmo",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
+ "@novu/stateless": "^0.24.1",
"@vonage/auth": "^1.7.0",
"@vonage/server-sdk": "^3.10.0"
},
diff --git a/providers/nodemailer/package.json b/providers/nodemailer/package.json
index f433de729e7..e8bce50edeb 100644
--- a/providers/nodemailer/package.json
+++ b/providers/nodemailer/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/nodemailer",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
+ "@novu/stateless": "^0.24.1",
"nodemailer": "^6.6.5"
},
"devDependencies": {
diff --git a/providers/one-signal/package.json b/providers/one-signal/package.json
index 3601f286935..31449464e64 100644
--- a/providers/one-signal/package.json
+++ b/providers/one-signal/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/one-signal",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "A OneSignal wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -30,7 +30,7 @@
"access": "public"
},
"dependencies": {
- "@novu/stateless": "^0.24.0",
+ "@novu/stateless": "^0.24.1",
"axios": "^1.6.0"
},
"devDependencies": {
diff --git a/providers/outlook365/package.json b/providers/outlook365/package.json
index a2ddcfedaf1..2cd2517cff3 100644
--- a/providers/outlook365/package.json
+++ b/providers/outlook365/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/outlook365",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
+ "@novu/stateless": "^0.24.1",
"nodemailer": "^6.6.5"
},
"devDependencies": {
diff --git a/providers/plivo/package.json b/providers/plivo/package.json
index 837524ff6d0..e3e346b955e 100644
--- a/providers/plivo/package.json
+++ b/providers/plivo/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/plivo",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
+ "@novu/stateless": "^0.24.1",
"plivo": "^4.60.1"
},
"devDependencies": {
diff --git a/providers/plunk/package.json b/providers/plunk/package.json
index 413aa47a2ec..b19a4770192 100644
--- a/providers/plunk/package.json
+++ b/providers/plunk/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/plunk",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "A plunk wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -29,7 +29,7 @@
"access": "public"
},
"dependencies": {
- "@novu/stateless": "^0.24.0",
+ "@novu/stateless": "^0.24.1",
"@plunk/node": "2.0.0"
},
"devDependencies": {
diff --git a/providers/postmark/package.json b/providers/postmark/package.json
index b3f87c5d763..7e13168c222 100644
--- a/providers/postmark/package.json
+++ b/providers/postmark/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/postmark",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
+ "@novu/stateless": "^0.24.1",
"axios": "^1.6.2",
"postmark": "^4.0.2"
},
diff --git a/providers/push-webhook/package.json b/providers/push-webhook/package.json
index 23c206cf7ee..7e408eebf1e 100644
--- a/providers/push-webhook/package.json
+++ b/providers/push-webhook/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/push-webhook",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "A push-webhook wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -30,7 +30,7 @@
"access": "public"
},
"dependencies": {
- "@novu/stateless": "^0.24.0",
+ "@novu/stateless": "^0.24.1",
"axios": "^1.6.2"
},
"devDependencies": {
diff --git a/providers/pusher-beams/package.json b/providers/pusher-beams/package.json
index a012b38e446..6cfcd1d9cc2 100644
--- a/providers/pusher-beams/package.json
+++ b/providers/pusher-beams/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/pusher-beams",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "A pusher-beams wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -29,7 +29,7 @@
"access": "public"
},
"dependencies": {
- "@novu/stateless": "^0.24.0",
+ "@novu/stateless": "^0.24.1",
"axios": "^1.6.0"
},
"devDependencies": {
diff --git a/providers/pushpad/package.json b/providers/pushpad/package.json
index 739592e6c44..d9fb0e1163f 100644
--- a/providers/pushpad/package.json
+++ b/providers/pushpad/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/pushpad",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "A pushpad wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -32,7 +32,7 @@
"node": ">=10"
},
"dependencies": {
- "@novu/stateless": "^0.24.0",
+ "@novu/stateless": "^0.24.1",
"pushpad": "1.0.0"
},
"devDependencies": {
diff --git a/providers/resend/package.json b/providers/resend/package.json
index a98584db6f0..7488c247c0b 100644
--- a/providers/resend/package.json
+++ b/providers/resend/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/resend",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
+ "@novu/stateless": "^0.24.1",
"resend": "^2.1.0"
},
"devDependencies": {
diff --git a/providers/resend/src/lib/resend.provider.ts b/providers/resend/src/lib/resend.provider.ts
index cf8061ab72b..597fba28220 100644
--- a/providers/resend/src/lib/resend.provider.ts
+++ b/providers/resend/src/lib/resend.provider.ts
@@ -44,6 +44,10 @@ export class ResendEmailProvider implements IEmailProvider {
bcc: options.bcc,
});
+ if (response.error) {
+ throw new Error(response.error.message);
+ }
+
return {
id: response.data?.id,
date: new Date().toISOString(),
diff --git a/providers/ring-central/package.json b/providers/ring-central/package.json
index 81818e56f61..d1c1d1f2247 100644
--- a/providers/ring-central/package.json
+++ b/providers/ring-central/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/ring-central",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "A ring-central wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -29,7 +29,7 @@
"access": "public"
},
"dependencies": {
- "@novu/stateless": "^0.24.0",
+ "@novu/stateless": "^0.24.1",
"@ringcentral/sdk": "^5.0.1"
},
"devDependencies": {
diff --git a/providers/rocket-chat/package.json b/providers/rocket-chat/package.json
index a5a02e9ae52..09120302ea9 100644
--- a/providers/rocket-chat/package.json
+++ b/providers/rocket-chat/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/rocket-chat",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "A rocket-chat wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -29,7 +29,7 @@
"access": "public"
},
"dependencies": {
- "@novu/stateless": "^0.24.0",
+ "@novu/stateless": "^0.24.1",
"axios": "^1.6.2"
},
"devDependencies": {
diff --git a/providers/ryver/package.json b/providers/ryver/package.json
index c75a5fe1ff9..811e3f7c7dc 100644
--- a/providers/ryver/package.json
+++ b/providers/ryver/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/ryver",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "A ryver wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -32,7 +32,7 @@
"node": ">=10"
},
"dependencies": {
- "@novu/stateless": "^0.24.0",
+ "@novu/stateless": "^0.24.1",
"axios": "^1.6.2"
},
"devDependencies": {
diff --git a/providers/sendchamp/package.json b/providers/sendchamp/package.json
index e631725c983..9afcc397364 100644
--- a/providers/sendchamp/package.json
+++ b/providers/sendchamp/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/sendchamp",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "A sendchamp wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -29,7 +29,7 @@
"access": "public"
},
"dependencies": {
- "@novu/stateless": "^0.24.0",
+ "@novu/stateless": "^0.24.1",
"axios": "^1.6.2"
},
"devDependencies": {
diff --git a/providers/sendgrid/package.json b/providers/sendgrid/package.json
index 69c506fbb23..1a7fbf0c4aa 100644
--- a/providers/sendgrid/package.json
+++ b/providers/sendgrid/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/sendgrid",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
+ "@novu/stateless": "^0.24.1",
"@sendgrid/mail": "^8.1.0"
},
"devDependencies": {
diff --git a/providers/sendinblue/package.json b/providers/sendinblue/package.json
index ea99eb94808..dbc2b35edee 100644
--- a/providers/sendinblue/package.json
+++ b/providers/sendinblue/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/sendinblue",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "A sendinblue wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -29,7 +29,7 @@
"access": "public"
},
"dependencies": {
- "@novu/stateless": "^0.24.0",
+ "@novu/stateless": "^0.24.1",
"axios": "^1.6.2"
},
"devDependencies": {
diff --git a/providers/ses/package.json b/providers/ses/package.json
index 01e6e661f4d..3b6e1c6220b 100644
--- a/providers/ses/package.json
+++ b/providers/ses/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/ses",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
+ "@novu/stateless": "^0.24.1",
"nodemailer": "^6.6.5"
},
"devDependencies": {
diff --git a/providers/simpletexting/package.json b/providers/simpletexting/package.json
index 595ca17b46f..5ed46b58d56 100644
--- a/providers/simpletexting/package.json
+++ b/providers/simpletexting/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/simpletexting",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "A simpletexting wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -29,7 +29,7 @@
"access": "public"
},
"dependencies": {
- "@novu/stateless": "^0.24.0",
+ "@novu/stateless": "^0.24.1",
"axios": "^1.6.2"
},
"devDependencies": {
diff --git a/providers/slack/package.json b/providers/slack/package.json
index 6d82c82d8a9..9758843e149 100644
--- a/providers/slack/package.json
+++ b/providers/slack/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/slack",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
+ "@novu/stateless": "^0.24.1",
"axios": "^1.6.2"
},
"devDependencies": {
diff --git a/providers/sms-central/package.json b/providers/sms-central/package.json
index 6856e96c8dc..e672a807584 100644
--- a/providers/sms-central/package.json
+++ b/providers/sms-central/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/sms-central",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "A sms-central wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -29,7 +29,7 @@
"access": "public"
},
"dependencies": {
- "@novu/stateless": "^0.24.0",
+ "@novu/stateless": "^0.24.1",
"axios": "^1.6.2"
},
"devDependencies": {
diff --git a/providers/sms77/package.json b/providers/sms77/package.json
index 2cb6ea5009d..27a32e93b8e 100644
--- a/providers/sms77/package.json
+++ b/providers/sms77/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/sms77",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
+ "@novu/stateless": "^0.24.1",
"node-fetch": "^2.6.7",
"sms77-client": "^2.14.0"
},
diff --git a/providers/sns/package.json b/providers/sns/package.json
index 23409071195..72d06680f6c 100644
--- a/providers/sns/package.json
+++ b/providers/sns/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/sns",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0"
+ "@novu/stateless": "^0.24.1"
},
"devDependencies": {
"@istanbuljs/nyc-config-typescript": "^1.0.1",
diff --git a/providers/sparkpost/package.json b/providers/sparkpost/package.json
index cb2181f3a70..dbfb40440af 100644
--- a/providers/sparkpost/package.json
+++ b/providers/sparkpost/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/sparkpost",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
+ "@novu/stateless": "^0.24.1",
"axios": "^1.6.2"
},
"devDependencies": {
diff --git a/providers/telnyx/package.json b/providers/telnyx/package.json
index 3e307f824a8..dfc676f3771 100644
--- a/providers/telnyx/package.json
+++ b/providers/telnyx/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/telnyx",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
+ "@novu/stateless": "^0.24.1",
"telnyx": "^1.23.0"
},
"devDependencies": {
diff --git a/providers/termii/package.json b/providers/termii/package.json
index cd7bef3f559..38a375a0691 100644
--- a/providers/termii/package.json
+++ b/providers/termii/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/termii",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
+ "@novu/stateless": "^0.24.1",
"node-fetch": "^3.2.10"
},
"devDependencies": {
diff --git a/providers/twilio/package.json b/providers/twilio/package.json
index 9f2e318a390..1eae0e282d8 100644
--- a/providers/twilio/package.json
+++ b/providers/twilio/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/twilio",
- "version": "0.24.0",
+ "version": "0.24.1",
"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.24.0",
+ "@novu/stateless": "^0.24.1",
"twilio": "^4.19.3"
},
"devDependencies": {
diff --git a/providers/zulip/package.json b/providers/zulip/package.json
index c8c952a9353..d496a95c45d 100644
--- a/providers/zulip/package.json
+++ b/providers/zulip/package.json
@@ -1,6 +1,6 @@
{
"name": "@novu/zulip",
- "version": "0.24.0",
+ "version": "0.24.1",
"description": "A zulip wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
@@ -32,7 +32,7 @@
"node": ">=10"
},
"dependencies": {
- "@novu/stateless": "^0.24.0",
+ "@novu/stateless": "^0.24.1",
"axios": "^1.6.2"
},
"devDependencies": {
diff --git a/scripts/github-conventional-comments.js b/scripts/github-conventional-comments.js
new file mode 100644
index 00000000000..ce84cdc6921
--- /dev/null
+++ b/scripts/github-conventional-comments.js
@@ -0,0 +1,77 @@
+/* eslint-disable max-len */
+
+/**
+ * Novu Conventional Comments as GitHub Saved Replies
+ * Based on https://gist.github.com/ifyoumakeit/4148a8c3e61b7868935651272c03f793
+ *
+ * To install:
+ * 1. Go to https://github.com/settings/replies
+ * 2. Open Developer Tools
+ * 3. Paste and run below code in JavaScript console
+ */
+
+(async function generateReplies(document) {
+ // https://conventionalcomments.org/#labels
+ const LABEL = {
+ praise: 'praise',
+ note: 'note',
+ nitpick: 'nitpick',
+ thought: 'thought',
+ suggestion: 'suggestion',
+ question: 'question',
+ chore: 'chore',
+ issue: 'issue',
+ };
+
+ const NON_BLOCKING = [LABEL.nitpick, LABEL.thought, LABEL.note];
+
+ const COMMENT = {
+ [LABEL.praise]:
+ 'Praises highlight something positive. Try to leave at least one of these comments per review. Do not leave false praise (which can actually be damaging). Do look for something to sincerely praise.',
+ [LABEL.note]: 'Notes are always non-blocking and simply highlight something the reader should take note of.',
+ [LABEL.nitpick]: 'Nitpicks are trivial preference-based requests. These should be non-blocking by nature.',
+ [LABEL.thought]:
+ 'Thoughts represent an idea that popped up from reviewing. These comments are non-blocking by nature, but they are extremely valuable and can lead to more focused initiatives and mentoring opportunities.',
+ [LABEL.suggestion]:
+ "Suggestions propose improvements to the current subject. It's important to be explicit and clear on what is being suggested and why it is an improvement. Consider using patches and the blocking or non-blocking decorations to further communicate your intent.",
+ [LABEL.question]:
+ "Questions are appropriate if you have a potential concern but are not quite sure if it's relevant or not. Asking the author for clarification or investigation can lead to a quick resolution.",
+ [LABEL.chore]:
+ 'Chores are simple tasks that must be done before the subject can be “officially” accepted. Usually, these comments reference some common process. Try to leave a link to the process description so that the reader knows how to resolve the chore.',
+ [LABEL.issue]:
+ 'Issues highlight specific problems with the subject under review. These problems can be user-facing or behind the scenes. It is strongly recommended to pair this comment with a suggestion. If you are not sure if a problem exists or not, consider leaving a question.',
+ };
+
+ const EMOJI = {
+ [LABEL.praise]: '\u{1F44F}',
+ [LABEL.note]: '\u{1F5D2}',
+ [LABEL.nitpick]: '\u{1F913}',
+ [LABEL.thought]: '\u{1F4AD}',
+ [LABEL.suggestion]: '\u{270F}',
+ [LABEL.question]: '\u{2753}',
+ [LABEL.chore]: '\u{2611}',
+ [LABEL.issue]: '\u{26A0}',
+ };
+
+ function post(key, token) {
+ const blockingText = NON_BLOCKING.includes(key) ? ' (non-blocking)' : '';
+
+ return fetch('replies', {
+ headers: { 'content-type': 'application/x-www-form-urlencoded' },
+ method: 'POST',
+ mode: 'cors',
+ credentials: 'include',
+ body: new URLSearchParams({
+ body: `\n${EMOJI[key]} **${key}${blockingText}:** `,
+ authenticity_token: token,
+ title: `${key[0].toUpperCase()}${key.slice(1)}${blockingText}`,
+ }).toString(),
+ });
+ }
+
+ const form = document.querySelector('.new_saved_reply');
+ const token = form.querySelector('[name=authenticity_token]').value;
+ // Replies are order alphabetically, so order doesn't need to preserved.
+ await Promise.all(Object.keys(LABEL).map((key) => post(key, token)));
+ console.log('All added! Refresh the page!');
+})(window.document);