diff --git a/apps/api/package.json b/apps/api/package.json index c5a33095967..cfa05e3dc7b 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -78,7 +78,7 @@ "ajv-formats": "^2.1.1", "axios": "^1.9.0", "bcrypt": "^5.0.0", - "body-parser": "^2.2.0", + "body-parser": "^2.2.1", "bull": "^4.2.1", "class-transformer": "0.5.1", "class-validator": "0.14.1", diff --git a/apps/api/src/app/events/e2e/bridge-trigger.e2e.ts b/apps/api/src/app/events/e2e/bridge-trigger.e2e.ts index 5381ce57288..eeedf0ecfaf 100644 --- a/apps/api/src/app/events/e2e/bridge-trigger.e2e.ts +++ b/apps/api/src/app/events/e2e/bridge-trigger.e2e.ts @@ -31,11 +31,7 @@ type Context = { name: string; isStateful: boolean }; const contexts: Context[] = [{ name: 'stateful', isStateful: true }]; contexts.forEach((context: Context) => { - /** - * For some reason, the bridge trigger is very flaky in setting up the test server, - * It's not clear why, but it's causing the tests to fail. - */ - describe.skip('Self-Hosted Bridge Trigger #novu-v2', async () => { + describe('Self-Hosted Bridge Trigger #novu-v2', async () => { let session: UserSession; let bridgeServer: TestBridgeServer; const messageRepository = new MessageRepository(); @@ -1678,7 +1674,7 @@ contexts.forEach((context: Context) => { transactionId: transactionIdNoSkip, type: StepTypeEnum.DELAY, }); - expect(delayJobNoSkip?.status).to.equal(JobStatusEnum.COMPLETED, 'Scenario 1: Delay job should be COMPLETED'); + expect(delayJobNoSkip?.status).to.equal(JobStatusEnum.SKIPPED, 'Scenario 1: Delay job should be SKIPPED'); const failedExecDetailsNoSkip = await executionDetailsRepository.find({ _environmentId: session.environment._id, diff --git a/apps/api/src/app/workflows-v2/dtos/get-list-query-params.ts b/apps/api/src/app/workflows-v2/dtos/get-list-query-params.ts index 112f7350b4d..36a03850a9a 100644 --- a/apps/api/src/app/workflows-v2/dtos/get-list-query-params.ts +++ b/apps/api/src/app/workflows-v2/dtos/get-list-query-params.ts @@ -1,6 +1,7 @@ import { ApiPropertyOptional } from '@nestjs/swagger'; import { WorkflowResponseDto } from '@novu/application-generic'; import { WorkflowStatusEnum } from '@novu/shared'; +import { Transform } from 'class-transformer'; import { IsArray, IsEnum, IsOptional, IsString } from 'class-validator'; import { LimitOffsetPaginationQueryDto } from '../../shared/dtos/limit-offset-pagination.dto'; @@ -25,6 +26,7 @@ export class GetListQueryParamsDto extends LimitOffsetPaginationQueryDto(Workflo required: false, }) @IsOptional() + @Transform(({ value }) => (value === undefined ? undefined : Array.isArray(value) ? value : [value])) @IsArray() @IsString({ each: true }) tags?: string[]; @@ -37,6 +39,7 @@ export class GetListQueryParamsDto extends LimitOffsetPaginationQueryDto(Workflo required: false, }) @IsOptional() + @Transform(({ value }) => (value === undefined ? undefined : Array.isArray(value) ? value : [value])) @IsArray() @IsEnum(WorkflowStatusEnum, { each: true }) status?: WorkflowStatusEnum[]; diff --git a/apps/api/src/app/workflows-v2/workflow.controller.e2e.ts b/apps/api/src/app/workflows-v2/workflow.controller.e2e.ts index 1e49044d4ab..12a4cb22d68 100644 --- a/apps/api/src/app/workflows-v2/workflow.controller.e2e.ts +++ b/apps/api/src/app/workflows-v2/workflow.controller.e2e.ts @@ -561,6 +561,42 @@ describe('Workflow Controller E2E API Testing #novu-v2', () => { return { workflowV2Id, workflowId, name: listWorkflowResponse.workflows[0].name }; } + it('should filter workflows by a single tag', async () => { + await createWorkflow(apiClient, buildWorkflow({ name: 'Tagged Workflow 1', tags: ['ai'] })); + await createWorkflow(apiClient, buildWorkflow({ name: 'Tagged Workflow 2', tags: ['ai', 'ml'] })); + await createWorkflow(apiClient, buildWorkflow({ name: 'Untagged Workflow', tags: ['other'] })); + + const res = await apiClient.workflows.list({ tags: ['ai'] }); + expect(res.result.totalCount).to.equal(2); + expect(res.result.workflows).to.have.lengthOf(2); + const names = res.result.workflows.map((w) => w.name); + expect(names).to.include('Tagged Workflow 1'); + expect(names).to.include('Tagged Workflow 2'); + }); + + it('should filter workflows by multiple tags', async () => { + await createWorkflow(apiClient, buildWorkflow({ name: 'AI Workflow', tags: ['ai'] })); + await createWorkflow(apiClient, buildWorkflow({ name: 'ML Workflow', tags: ['ml'] })); + await createWorkflow(apiClient, buildWorkflow({ name: 'Both Tags Workflow', tags: ['ai', 'ml'] })); + await createWorkflow(apiClient, buildWorkflow({ name: 'No Match Workflow', tags: ['other'] })); + + const res = await apiClient.workflows.list({ tags: ['ai', 'ml'] }); + expect(res.result.totalCount).to.equal(3); + expect(res.result.workflows).to.have.lengthOf(3); + const names = res.result.workflows.map((w) => w.name); + expect(names).to.include('AI Workflow'); + expect(names).to.include('ML Workflow'); + expect(names).to.include('Both Tags Workflow'); + }); + + it('should return empty results when filtering by non-existent tag', async () => { + await createWorkflow(apiClient, buildWorkflow({ name: 'Some Workflow', tags: ['existing'] })); + + const res = await apiClient.workflows.list({ tags: ['non-existent'] }); + expect(res.result.totalCount).to.equal(0); + expect(res.result.workflows).to.have.lengthOf(0); + }); + it('old list endpoint should not retrieve the new workflow', async () => { const { workflowV2Id, name } = await getV2WorkflowIdAndExternalId('Test Workflow'); const [, , workflowV0Created] = await Promise.all([ diff --git a/apps/dashboard/package.json b/apps/dashboard/package.json index 37c7451c4d8..7036f58ffea 100644 --- a/apps/dashboard/package.json +++ b/apps/dashboard/package.json @@ -160,7 +160,7 @@ "@novu/dal": "workspace:*", "@novu/ee-auth": "workspace:*", "@novu/testing": "workspace:*", - "@playwright/test": "^1.46.1", + "@playwright/test": "^1.55.1", "@sentry/vite-plugin": "^2.22.6", "@tiptap/core": "^2.11.5", "@types/json-schema": "^7.0.15", diff --git a/apps/dashboard/src/components/workflow-editor/base-node.tsx b/apps/dashboard/src/components/workflow-editor/base-node.tsx index a6c761e3308..cfc1ab98773 100644 --- a/apps/dashboard/src/components/workflow-editor/base-node.tsx +++ b/apps/dashboard/src/components/workflow-editor/base-node.tsx @@ -38,8 +38,8 @@ const nodeBadgeVariants = cva( export interface NodeIconProps extends React.HTMLAttributes, VariantProps {} -export const NodeIcon = ({ children, variant }: NodeIconProps) => { - return {children}; +export const NodeIcon = ({ children, variant, className }: NodeIconProps) => { + return {children}; }; export const NodeName = ({ children }: { children: ReactNode }) => { diff --git a/apps/dashboard/src/components/workflow-editor/editor-breadcrumbs.tsx b/apps/dashboard/src/components/workflow-editor/editor-breadcrumbs.tsx index 94b8b4c32fa..17baff84028 100644 --- a/apps/dashboard/src/components/workflow-editor/editor-breadcrumbs.tsx +++ b/apps/dashboard/src/components/workflow-editor/editor-breadcrumbs.tsx @@ -1,10 +1,11 @@ import { ResourceOriginEnum, StepResponseDto, WorkflowResponseDto } from '@novu/shared'; import React from 'react'; import { FaCode } from 'react-icons/fa6'; -import { RiArrowLeftSLine } from 'react-icons/ri'; +import { RiArrowLeftSLine, RiExpandUpDownLine } from 'react-icons/ri'; import { useLocation, useNavigate, useParams } from 'react-router-dom'; import { RouteFill } from '@/components/icons'; +import { STEP_TYPE_TO_ICON } from '@/components/icons/utils'; import { Badge } from '@/components/primitives/badge'; import { Breadcrumb, @@ -15,15 +16,35 @@ import { BreadcrumbSeparator, } from '@/components/primitives/breadcrumb'; import { CompactButton } from '@/components/primitives/button-compact'; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from '@/components/primitives/dropdown-menu'; import TruncatedText from '@/components/truncated-text'; import { useEnvironment } from '@/context/environment/hooks'; import { useFetchWorkflow } from '@/hooks/use-fetch-workflow'; -import { STEP_TYPE_LABELS } from '@/utils/constants'; +import type { ProviderColorToken } from '@/utils/color'; +import { STEP_TYPE_TO_COLOR } from '@/utils/color'; +import { STEP_TYPE_LABELS, TEMPLATE_CONFIGURABLE_STEP_TYPES } from '@/utils/constants'; import { buildRoute, ROUTES } from '@/utils/routes'; +import { cn } from '@/utils/ui'; import { SavingStatusIndicator } from './saving-status-indicator'; -import { getStepTypeIcon } from './steps/utils/preview-context.utils'; import { useWorkflow } from './workflow-provider'; +const COLOR_TOKEN_TO_TEXT: Record = { + neutral: 'text-neutral-400', + stable: 'text-stable/30', + information: 'text-information/30', + feature: 'text-feature/30', + destructive: 'text-destructive/30', + verified: 'text-verified/30', + alert: 'text-alert/30', + highlighted: 'text-highlighted/30', + warning: 'text-warning/30', +}; + type BreadcrumbData = { label: string; href: string; @@ -144,16 +165,71 @@ function WorkflowBreadcrumbContent({ } function StepBreadcrumb({ step }: { step: StepResponseDto }) { - const Icon = getStepTypeIcon(step.type); - const { isUpdatePatchPending, lastSaveError } = useWorkflow(); + const Icon = STEP_TYPE_TO_ICON[step.type]; + const { isUpdatePatchPending, lastSaveError, workflow } = useWorkflow(); + const navigate = useNavigate(); + const { currentEnvironment } = useEnvironment(); + const { workflowSlug = '' } = useParams<{ workflowSlug: string }>(); + const steps = workflow?.steps ?? []; + const hasMultipleSteps = steps.length > 1; + + function handleStepSwitch(targetStep: StepResponseDto) { + if (!workflow || !currentEnvironment?.slug) return; + if (targetStep.slug === step.slug) return; + + const basePath = + buildRoute(ROUTES.EDIT_WORKFLOW, { + environmentSlug: currentEnvironment.slug, + workflowSlug, + }) + `/steps/${targetStep.slug}`; + + const isTemplateConfigurable = TEMPLATE_CONFIGURABLE_STEP_TYPES.includes(targetStep.type); + const finalPath = isTemplateConfigurable ? `${basePath}/editor` : basePath; + + navigate(finalPath); + } return ( - -
- {step.name || STEP_TYPE_LABELS[step.type]} -
+ {hasMultipleSteps ? ( + + + + + {step.name || STEP_TYPE_LABELS[step.type]} + + + + + {steps.map((s) => { + const StepIcon = STEP_TYPE_TO_ICON[s.type]; + const isCurrentStep = s.slug === step.slug; + + return ( + handleStepSwitch(s)} + className={cn( + 'flex cursor-pointer items-center gap-1 px-1 py-1 text-xs', + isCurrentStep && 'bg-neutral-alpha-50' + )} + > + + {s.name || STEP_TYPE_LABELS[s.type]} + + ); + })} + + + ) : ( + <> + +
+ {step.name || STEP_TYPE_LABELS[step.type]} +
+ + )}
diff --git a/apps/dashboard/src/components/workflow-editor/node-utils.ts b/apps/dashboard/src/components/workflow-editor/node-utils.ts index 0e43e653237..a4633ba667a 100644 --- a/apps/dashboard/src/components/workflow-editor/node-utils.ts +++ b/apps/dashboard/src/components/workflow-editor/node-utils.ts @@ -139,6 +139,7 @@ export const createNode = ({ controlValues, isPending, type, + stepResolverHash, }: { x: number; y: number; @@ -150,6 +151,7 @@ export const createNode = ({ controlValues: Record; isPending?: boolean; type: StepTypeEnum; + stepResolverHash?: string; }): Node => { return { // the random id is used to identify the node and to be able to re-render the nodes and edges @@ -163,6 +165,7 @@ export const createNode = ({ error, controlValues, isPending, + stepResolverHash, }, type, }; @@ -195,6 +198,7 @@ export const mapStepToNode = ({ error: error?.message ?? '', controlValues: step.controls.values, type: step.type, + stepResolverHash: step.stepResolverHash, }); }; diff --git a/apps/dashboard/src/components/workflow-editor/nodes.tsx b/apps/dashboard/src/components/workflow-editor/nodes.tsx index 335a36947d8..8e2be0c335f 100644 --- a/apps/dashboard/src/components/workflow-editor/nodes.tsx +++ b/apps/dashboard/src/components/workflow-editor/nodes.tsx @@ -1,7 +1,8 @@ import { Slug } from '@novu/shared'; import { Node as FlowNode, Handle, NodeProps, Position } from '@xyflow/react'; +import { FileCode2 } from 'lucide-react'; import { AnimatePresence, motion } from 'motion/react'; -import { ComponentProps, KeyboardEventHandler, useCallback, useState } from 'react'; +import { ComponentProps, ComponentType, KeyboardEventHandler, useCallback, useState } from 'react'; import { RiInsertRowTop, RiPlayCircleLine } from 'react-icons/ri'; import { RQBJsonLogic } from 'react-querybuilder'; import { Link } from 'react-router-dom'; @@ -26,6 +27,7 @@ export type NodeData = { controlValues?: Record; isPending?: boolean; triggerLink?: string; + stepResolverHash?: string; }; export type NodeType = FlowNode; @@ -34,6 +36,44 @@ const topHandleClasses = `data-[handlepos=top]:w-2! data-[handlepos=top]:h-2! da const bottomHandleClasses = `data-[handlepos=bottom]:w-2! data-[handlepos=bottom]:h-2! data-[handlepos=bottom]:bg-transparent! data-[handlepos=bottom]:rounded-none! data-[handlepos=bottom]:before:absolute! data-[handlepos=bottom]:before:bottom-0! data-[handlepos=bottom]:before:left-0! data-[handlepos=bottom]:before:w-full! data-[handlepos=bottom]:before:h-full! data-[handlepos=bottom]:before:bg-neutral-alpha-200! data-[handlepos=bottom]:before:rotate-45!`; const handleClassName = `${topHandleClasses} ${bottomHandleClasses}`; +const VARIANT_TO_TEXT_CLASS: Record = { + neutral: 'text-neutral-500', + feature: 'text-feature', + information: 'text-information', + highlighted: 'text-highlighted', + stable: 'text-stable', + verified: 'text-verified', + destructive: 'text-destructive', + success: 'text-success', + warning: 'text-warning', + alert: 'text-alert', +}; + +const StepNodeIcon = ({ + stepResolverHash, + color, + Icon, +}: { + stepResolverHash?: string; + color: string; + Icon: ComponentType; +}) => { + if (stepResolverHash) { + return ( + + ); + } + + return ( + + + + ); +}; + export const TriggerNode = ({ data }: NodeProps>) => { const { isReadOnly, showStepPreview } = useCanvasContext(); const content = ( @@ -246,9 +286,11 @@ export const EmailNode = ({ id, data }: NodeProps) => { - - - + {data.name || 'Email Step'} @@ -275,9 +317,11 @@ export const SmsNode = (props: NodeProps) => { - - - + {data.name || 'SMS Step'} @@ -302,9 +346,11 @@ export const InAppNode = (props: NodeProps) => { - - - + {data.name || 'In-App Step'} @@ -329,9 +375,11 @@ export const PushNode = (props: NodeProps) => { - - - + {data.name || 'Push Step'} @@ -356,9 +404,11 @@ export const ChatNode = (props: NodeProps) => { - - - + {data.name || 'Chat Step'} @@ -382,9 +432,11 @@ export const DelayNode = (props: NodeProps) => { - - - + {data.name || 'Delay Step'} @@ -408,9 +460,11 @@ export const DigestNode = (props: NodeProps) => { - - - + {data.name || 'Digest Step'} @@ -434,9 +488,11 @@ export const ThrottleNode = (props: NodeProps) => { - - - + {data.name || 'Throttle Step'} @@ -461,9 +517,7 @@ export const HttpRequestNode = (props: NodeProps) => { - - - + {data.name || 'HTTP Request Step'} @@ -488,9 +542,7 @@ export const CustomNode = (props: NodeProps) => { - - - + {data.name || 'Custom Step'} diff --git a/apps/dashboard/src/components/workflow-editor/steps/shared/step-editor-mode-toggle.tsx b/apps/dashboard/src/components/workflow-editor/steps/shared/step-editor-mode-toggle.tsx index b27b5d039bf..823b8913d0f 100644 --- a/apps/dashboard/src/components/workflow-editor/steps/shared/step-editor-mode-toggle.tsx +++ b/apps/dashboard/src/components/workflow-editor/steps/shared/step-editor-mode-toggle.tsx @@ -1,12 +1,15 @@ import { EnvironmentTypeEnum, FeatureFlagsKeysEnum } from '@novu/shared'; +import { ArrowRight, Check, DraftingCompass, FileCode2 } from 'lucide-react'; import { useState } from 'react'; import { ConfirmationModal } from '@/components/confirmation-modal'; -import { Tabs, TabsList, TabsTrigger } from '@/components/primitives/tabs'; +import { Switch } from '@/components/primitives/switch'; +import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/primitives/tooltip'; import { useStepEditor } from '@/components/workflow-editor/steps/context/step-editor-context'; import { useEnvironment } from '@/context/environment/hooks'; import { useDisconnectStepResolver } from '@/hooks/use-disconnect-step-resolver'; import { useFeatureFlag } from '@/hooks/use-feature-flag'; import { TEMPLATE_CONFIGURABLE_STEP_TYPES } from '@/utils/constants'; +import { cn } from '@/utils/ui'; export function StepEditorModeToggle() { const { step, isPendingResolverActivation, setIsPendingResolverActivation } = useStepEditor(); @@ -25,12 +28,10 @@ export function StepEditorModeToggle() { } const isActive = Boolean(step.stepResolverHash); - const mode = isActive || isPendingResolverActivation ? 'code' : 'novu'; + const isCodeMode = isActive || isPendingResolverActivation; - const handleValueChange = (value: string) => { - if (value === mode) return; - - if (value === 'code') { + const handleToggle = (checked: boolean) => { + if (checked) { setIsPendingResolverActivation(true); } else if (isActive) { setIsDisconnectModalOpen(true); @@ -60,16 +61,87 @@ export function StepEditorModeToggle() { isLoading={isDisconnecting} /> - - - - Novu - - - Code - - - +
+ + + + + + + + + +
+ + Manage this step in your code +
+
+

+ Write and deploy this step as a serverless function from your repository. +

+
    + {[ + { label: 'Use any template engine', detail: 'React Email, MJML...' }, + { label: 'Code-first', detail: 'define content and logic in TypeScript' }, + { label: 'Version controlled', detail: 'your handler lives in your repo' }, + ].map(({ label, detail }) => ( +
  • + + + {label}: + {detail} + +
  • + ))} +
+
+
+
+ + You can switch back anytime +
+ + Learn more + + +
+
+
+
); } diff --git a/apps/dashboard/src/components/workflow-editor/steps/shared/step-resolver-not-published.tsx b/apps/dashboard/src/components/workflow-editor/steps/shared/step-resolver-not-published.tsx index 7d796e8254a..63f5e9b249e 100644 --- a/apps/dashboard/src/components/workflow-editor/steps/shared/step-resolver-not-published.tsx +++ b/apps/dashboard/src/components/workflow-editor/steps/shared/step-resolver-not-published.tsx @@ -1,6 +1,9 @@ -import { useEffect, useRef, useState } from 'react'; -import { RiCheckLine, RiCodeSSlashLine, RiFileCopyLine, RiLoaderLine } from 'react-icons/ri'; +import { FileCode2 } from 'lucide-react'; +import { AnimatePresence, motion } from 'motion/react'; +import { useEffect, useId, useRef, useState } from 'react'; +import { RiCheckLine, RiCloseLine, RiFileCopyLine, RiLoaderLine } from 'react-icons/ri'; import { Skeleton } from '@/components/primitives/skeleton'; +import { ExternalLink } from '@/components/shared/external-link'; import { useFetchApiKeys } from '@/hooks/use-fetch-api-keys'; import { apiHostnameManager } from '@/utils/api-hostname-manager'; @@ -69,8 +72,8 @@ function CodeBlock({ displayCommand, copyCommand }: { displayCommand: string; co }; return ( -
-
+
+
Terminal
-
+
{displayCommand}
@@ -94,12 +97,198 @@ function CodeBlock({ displayCommand, copyCommand }: { displayCommand: string; co ); } +function StepResolverIllustration() { + const gid = useId(); + + return ( + + ); +} + +const FEATURE_BULLETS = [ + 'The CLI auto-scaffolds a handler file in your project — no manual setup needed.', + 'Write your step output in TypeScript using any library or template engine.', + 'Subscriber data, trigger payload, and dashboard controls are all available at runtime.', + 'Commit the file to your repo and re-publish to deploy updates at any time.', +]; + type StepResolverNotPublishedProps = { workflowId: string; stepId: string; }; +const INFO_CARD_DISMISSED_KEY = 'novu:step-resolver-info-card-dismissed'; + +const BLOCK_TRANSITION = { duration: 0.22, ease: [0.25, 0.1, 0.25, 1] }; + +function blockAnimation(delay: number) { + return { + initial: { opacity: 0, y: 8 }, + animate: { opacity: 1, y: 0 }, + transition: { ...BLOCK_TRANSITION, delay }, + }; +} + export const StepResolverNotPublished = ({ workflowId, stepId }: StepResolverNotPublishedProps) => { + const [infoCardDismissed, setInfoCardDismissed] = useState( + () => localStorage.getItem(INFO_CARD_DISMISSED_KEY) === 'true' + ); + + const handleDismissInfoCard = () => { + localStorage.setItem(INFO_CARD_DISMISSED_KEY, 'true'); + setInfoCardDismissed(true); + }; const apiKeysQuery = useFetchApiKeys(); const secretKey = apiKeysQuery.data?.data?.[0]?.key; @@ -117,35 +306,101 @@ export const StepResolverNotPublished = ({ workflowId, stepId }: StepResolverNot const fallbackCopy = `npx novu step publish --workflow=${workflowId} --step=${stepId} --secret-key=${apiUrl ? ` --api-url=${apiUrl}` : ''}`; return ( -
-
-
-
-
-
- +
+
+ + {!infoCardDismissed && ( + + {/* Novu logomark watermark — partially clipped at bottom-right */} + + +
+
+
+ + Resolve this step from your code +
+

+ Instead of defining content in the editor, your application generates the output for this step. +

+
+
    + {FEATURE_BULLETS.map((bullet) => ( +
  • + + {bullet} +
  • + ))} +
+
+ + Read the docs + +
-
+ + )} + + + + + + + +
+
+
+ 1
-
+
-

Deploy your step resolver

-

- Run this from your project root. A step file will be scaffolded at{' '} - - novu/{workflowId}/{stepId}.step.ts +

Publish your step handler

+

+ Run this from your project root. The CLI scaffolds{' '} + + novu/{workflowId}/{stepId}.step.tsx {' '} - — customize the resolver logic there anytime and re-run to redeploy. + if it doesn't exist yet — edit it with your logic and re-run to redeploy anytime.
-
💡 This bundles your handler, links it to this step, and deploys it to our{' '} - - managed infrastructure - - . +
💡 Your handler is bundled and deployed to Novu's serverless infrastructure on every publish.

{apiKeysQuery.isLoading ? ( - + ) : (
-
-
-
- -
-
- - Waiting for step resolver... - -

- Once your step resolver is deployed, you'll be able to preview it here and trigger your first - notification. -

+
+ +
+ + Waiting for first deployment… + +

+ Run the command above from your project to publish this step. +
+ Once deployed, you'll be able to preview and trigger notifications here. +

+
-
+
); diff --git a/apps/dashboard/src/utils/types.ts b/apps/dashboard/src/utils/types.ts index d3653b2b2c4..b90f5449fca 100644 --- a/apps/dashboard/src/utils/types.ts +++ b/apps/dashboard/src/utils/types.ts @@ -20,7 +20,10 @@ export type RuntimeIssue = { message: string; }; -export type Step = Pick; +export type Step = Pick< + StepResponseDto, + 'name' | 'type' | '_id' | 'stepId' | 'issues' | 'slug' | 'controls' | 'stepResolverHash' +>; /** * Omit the `environment` field from the parameters of a function. diff --git a/apps/worker/package.json b/apps/worker/package.json index 41cee97585f..b12c4fa15f6 100644 --- a/apps/worker/package.json +++ b/apps/worker/package.json @@ -48,7 +48,7 @@ "svix": "^1.64.1", "lru-cache": "^11.2.4", "axios": "^1.9.0", - "body-parser": "^2.2.0", + "body-parser": "^2.2.1", "class-transformer": "0.5.1", "class-validator": "0.14.1", "cron-parser": "^4.9.0", 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 38eefa4b52e..a563021cfc3 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 @@ -98,7 +98,7 @@ export class SendMessage { const stepType = command.step?.template?.type; let bridgeResponse: ExecuteOutput | null = null; - if (isChannelStep(stepType)) { + if (requiresBridgeExecution(stepType)) { bridgeResponse = await this.executeBridgeJob.execute({ ...command, variables, @@ -565,22 +565,8 @@ export class SendMessage { } } -const CHANNEL_STEP_MAP: Record = { - [StepTypeEnum.IN_APP]: true, - [StepTypeEnum.EMAIL]: true, - [StepTypeEnum.SMS]: true, - [StepTypeEnum.CHAT]: true, - [StepTypeEnum.PUSH]: true, - [StepTypeEnum.CUSTOM]: false, - [StepTypeEnum.HTTP_REQUEST]: false, - [StepTypeEnum.DIGEST]: false, - [StepTypeEnum.DELAY]: false, - [StepTypeEnum.TRIGGER]: false, - [StepTypeEnum.THROTTLE]: false, -}; - -function isChannelStep(stepType: StepTypeEnum | undefined): boolean { +function requiresBridgeExecution(stepType: StepTypeEnum | undefined): boolean { if (!stepType) return false; - return CHANNEL_STEP_MAP[stepType]; + return ![StepTypeEnum.TRIGGER, StepTypeEnum.DIGEST, StepTypeEnum.DELAY, StepTypeEnum.HTTP_REQUEST].includes(stepType); } diff --git a/libs/dal/src/repositories/message/message.repository.ts b/libs/dal/src/repositories/message/message.repository.ts index 465e6dd855e..6762a7d07c7 100644 --- a/libs/dal/src/repositories/message/message.repository.ts +++ b/libs/dal/src/repositories/message/message.repository.ts @@ -1083,7 +1083,26 @@ export class MessageRepository extends BaseRepository typeof token === 'string' + ); + } + } + + return messages; } async deleteMessagesByIds({ diff --git a/libs/dal/src/repositories/message/message.schema.ts b/libs/dal/src/repositories/message/message.schema.ts index 4b1bd83ebb0..341cdfb1e5a 100644 --- a/libs/dal/src/repositories/message/message.schema.ts +++ b/libs/dal/src/repositories/message/message.schema.ts @@ -72,7 +72,7 @@ const messageSchema = new Schema( phone: Schema.Types.String, directWebhookUrl: Schema.Types.String, providerId: Schema.Types.String, - deviceTokens: [Schema.Types.Array], + deviceTokens: [Schema.Types.String], title: Schema.Types.String, seen: { type: Schema.Types.Boolean, diff --git a/package.json b/package.json index 00532f48d4c..11ac41f6dc1 100644 --- a/package.json +++ b/package.json @@ -165,7 +165,11 @@ "file-type@>=13.0.0 <16.5.4": "^16.5.4", "get-func-name@<2.0.1": "^2.0.1", "glob-parent@<5.1.2": "^5.1.2", - "minimatch@>=3.0.0 <3.0.5": "^3.0.5", + "minimatch@>=3.0.0 <3.1.4": "^3.1.4", + "minimatch@>=5.0.0 <5.1.8": "^5.1.8", + "minimatch@>=7.0.0 <7.4.8": "^7.4.8", + "minimatch@>=8.0.0 <8.0.6": "^8.0.6", + "minimatch@>=9.0.0 <9.0.7": "^9.0.7", "nanoid@>=3.0.0 <3.1.31": "^3.1.31", "nth-check": "^2.1.1", "postcss@<8.4.31": "^8.4.31", diff --git a/packages/agent-toolkit/package.json b/packages/agent-toolkit/package.json index 69a121550e2..a1de0af1ef7 100644 --- a/packages/agent-toolkit/package.json +++ b/packages/agent-toolkit/package.json @@ -1,6 +1,6 @@ { "name": "@novu/agent-toolkit", - "version": "0.1.0", + "version": "0.1.1", "description": "Novu Agent Toolkit - expose Novu notification workflows as LLM agent tools.", "main": "./dist/cjs/index.cjs", "types": "./dist/cjs/index.d.cts", @@ -122,10 +122,9 @@ } }, "dependencies": { - "@novu/api": "workspace:*", + "@novu/api": "^3.14.1", "json-schema-to-zod": "^2.7.0", - "zod": "^4.0.0", - "zod-to-json-schema": "^3.25.1" + "zod": "^4.0.0" }, "devDependencies": { "@langchain/core": "^0.3.0", diff --git a/packages/agent-toolkit/src/core/novu-toolkit.ts b/packages/agent-toolkit/src/core/novu-toolkit.ts index 95f8e2c9c59..97f99c48c52 100644 --- a/packages/agent-toolkit/src/core/novu-toolkit.ts +++ b/packages/agent-toolkit/src/core/novu-toolkit.ts @@ -1,6 +1,6 @@ import { Novu } from '@novu/api'; -import type { NovuToolkitConfig, NovuToolDefinition } from './types.js'; import { builtInTools, createWorkflowTools } from '../tools/index.js'; +import type { NovuToolDefinition, NovuToolkitConfig } from './types.js'; export class NovuToolkit { private readonly client: Novu; @@ -11,7 +11,7 @@ export class NovuToolkit { constructor(config: NovuToolkitConfig) { this.config = config; this.client = new Novu({ - security: { secretKey: config.secretKey }, + secretKey: config.secretKey, serverURL: config.backendUrl, }); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c8f64f5b49b..b548e137ded 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,7 +11,11 @@ overrides: file-type@>=13.0.0 <16.5.4: ^16.5.4 get-func-name@<2.0.1: ^2.0.1 glob-parent@<5.1.2: ^5.1.2 - minimatch@>=3.0.0 <3.0.5: ^3.0.5 + minimatch@>=3.0.0 <3.1.4: ^3.1.4 + minimatch@>=5.0.0 <5.1.8: ^5.1.8 + minimatch@>=7.0.0 <7.4.8: ^7.4.8 + minimatch@>=8.0.0 <8.0.6: ^8.0.6 + minimatch@>=9.0.0 <9.0.7: ^9.0.7 nanoid@>=3.0.0 <3.1.31: ^3.1.31 nth-check: ^2.1.1 postcss@<8.4.31: ^8.4.31 @@ -354,8 +358,8 @@ importers: specifier: ^5.0.0 version: 5.0.1(encoding@0.1.13) body-parser: - specifier: ^2.2.0 - version: 2.2.0 + specifier: ^2.2.1 + version: 2.2.2 bull: specifier: ^4.2.1 version: 4.10.4 @@ -609,7 +613,7 @@ importers: version: 3.0.51(react@19.2.3)(zod@4.3.5) '@better-auth/sso': specifier: ^1.3.0 - version: 1.4.7(better-auth@1.4.7(mongodb@6.21.0(@aws-sdk/credential-providers@3.637.0(@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0)))(gcp-metadata@5.3.0(encoding@0.1.13))(socks@2.7.1))(next@14.2.35(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.46.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.77.8))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.6)(svelte@4.2.19)) + version: 1.4.7(better-auth@1.4.7(mongodb@6.21.0(@aws-sdk/credential-providers@3.637.0(@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0)))(gcp-metadata@5.3.0(encoding@0.1.13))(socks@2.7.1))(next@14.2.35(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-macros@3.1.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.77.8))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.6)(svelte@4.2.19)) '@calcom/embed-react': specifier: 1.5.2 version: 1.5.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) @@ -816,7 +820,7 @@ importers: version: 6.2.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3) better-auth: specifier: ^1.3.0 - version: 1.4.7(mongodb@6.21.0(@aws-sdk/credential-providers@3.637.0(@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0)))(gcp-metadata@5.3.0(encoding@0.1.13))(socks@2.7.1))(next@14.2.35(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.46.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.77.8))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.6)(svelte@4.2.19) + version: 1.4.7(mongodb@6.21.0(@aws-sdk/credential-providers@3.637.0(@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0)))(gcp-metadata@5.3.0(encoding@0.1.13))(socks@2.7.1))(next@14.2.35(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-macros@3.1.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.77.8))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.6)(svelte@4.2.19) class-variance-authority: specifier: ^0.7.0 version: 0.7.1 @@ -982,7 +986,7 @@ importers: version: 1.25.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@clerk/testing': specifier: ^1.3.27 - version: 1.4.22(@playwright/test@1.46.1)(cypress@13.10.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 1.4.22(@playwright/test@1.58.2)(cypress@13.10.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@clerk/types': specifier: ^4.48.0 version: 4.48.0 @@ -1002,8 +1006,8 @@ importers: specifier: workspace:* version: link:../../libs/testing '@playwright/test': - specifier: ^1.46.1 - version: 1.46.1 + specifier: ^1.55.1 + version: 1.58.2 '@sentry/vite-plugin': specifier: ^2.22.6 version: 2.22.6(encoding@0.1.13) @@ -1439,8 +1443,8 @@ importers: specifier: ^1.13.5 version: 1.13.6 body-parser: - specifier: ^2.2.0 - version: 2.2.0 + specifier: ^2.2.1 + version: 2.2.2 class-transformer: specifier: 0.5.1 version: 0.5.1 @@ -1949,7 +1953,7 @@ importers: dependencies: '@better-auth/sso': specifier: ^1.3.0 - version: 1.4.7(better-auth@1.4.7(mongodb@6.21.0(@aws-sdk/credential-providers@3.637.0(@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0)))(gcp-metadata@5.3.0(encoding@0.1.13))(socks@2.7.1))(next@14.2.35(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.46.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.77.8))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.6)(svelte@4.2.19)) + version: 1.4.7(better-auth@1.4.7(mongodb@6.21.0(@aws-sdk/credential-providers@3.637.0(@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0)))(gcp-metadata@5.3.0(encoding@0.1.13))(socks@2.7.1))(next@14.2.35(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-macros@3.1.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.77.8))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.6)(svelte@4.2.19)) '@clerk/backend': specifier: ^1.25.2 version: 1.25.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) @@ -1988,7 +1992,7 @@ importers: version: link:../../../packages/stateless better-auth: specifier: ^1.3.0 - version: 1.4.7(mongodb@6.21.0(@aws-sdk/credential-providers@3.637.0(@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0)))(gcp-metadata@5.3.0(encoding@0.1.13))(socks@2.7.1))(next@14.2.35(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.46.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.77.8))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.6)(svelte@4.2.19) + version: 1.4.7(mongodb@6.21.0(@aws-sdk/credential-providers@3.637.0(@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0)))(gcp-metadata@5.3.0(encoding@0.1.13))(socks@2.7.1))(next@14.2.35(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-macros@3.1.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.77.8))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.6)(svelte@4.2.19) class-transformer: specifier: 0.5.1 version: 0.5.1 @@ -3176,17 +3180,14 @@ importers: packages/agent-toolkit: dependencies: '@novu/api': - specifier: workspace:* - version: link:../../libs/internal-sdk + specifier: ^3.14.1 + version: 3.14.1 json-schema-to-zod: specifier: ^2.7.0 version: 2.7.0 zod: specifier: ^4.0.0 version: 4.3.5 - zod-to-json-schema: - specifier: ^3.25.1 - version: 3.25.1(zod@4.3.5) devDependencies: '@langchain/core': specifier: ^0.3.0 @@ -3284,7 +3285,7 @@ importers: version: 8.0.0(typescript@5.6.2) next: specifier: ^14.2.35 - version: 14.2.35(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.46.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.77.8) + version: 14.2.35(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-macros@3.1.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.77.8) ts-node: specifier: ^10.9.2 version: 10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.15))(@types/node@22.15.13)(typescript@5.6.2) @@ -3450,7 +3451,7 @@ importers: version: link:../react next: specifier: ^14.2.35 - version: 14.2.35(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.46.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8) + version: 14.2.35(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8) react: specifier: ^18.0.0 || ^19.0.0 || ^19.0.0-0 version: 18.3.1 @@ -4111,7 +4112,7 @@ importers: version: 5.1.6 next: specifier: 15.4.10 - version: 15.4.10(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8) + version: 15.4.10(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8) react: specifier: ^18.3.1 version: 18.3.1 @@ -8798,6 +8799,9 @@ packages: '@nothing-but/utils@0.12.1': resolution: {integrity: sha512-1qZU1Q5El0IjE7JT/ucvJNzdr2hL3W8Rm27xNf1p6gb3Nw8pGnZmxp6/GEW9h+I1k1cICxXNq25hBwknTQ7yhg==} + '@novu/api@3.14.1': + resolution: {integrity: sha512-TqCIlayGdFELzZRgAzsqA2HjfX5k5Sd3LcWgNtIWVHtl0wXtmUAXq5FsXKl1HAZe3uWkN+jisWrINW1vJ5KdPQ==} + '@novu/ntfr-client@0.0.4': resolution: {integrity: sha512-/9q+qGFHHFwMsuqoLwTADMjSx2JPagpJpm7jOZRzQZgSEDg9kwNAhADneRzVYhMyjdEXIQyjTmX/oP8ABAavFw==} engines: {node: '>=18.0.0'} @@ -10137,8 +10141,8 @@ packages: resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - '@playwright/test@1.46.1': - resolution: {integrity: sha512-Fq6SwLujA/DOIvNC2EL/SojJnkKf/rAwJ//APpJJHRyMi1PdKrY3Az+4XNQ51N4RTbItbIByQ0jgd1tayq1aeA==} + '@playwright/test@1.58.2': + resolution: {integrity: sha512-akea+6bHYBBfA9uQqSYmlJXn61cTa+jbO87xVLCWbTqbWadRVmhxlXATaOjOgcBaWU4ePo0wB41KMFv3o35IXA==} engines: {node: '>=18'} hasBin: true @@ -16010,8 +16014,8 @@ packages: resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - body-parser@2.2.0: - resolution: {integrity: sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==} + body-parser@2.2.2: + resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==} engines: {node: '>=18'} bole@5.0.3: @@ -16036,6 +16040,9 @@ packages: brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + brace-expansion@5.0.4: resolution: {integrity: sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==} engines: {node: 18 || 20 || >=22} @@ -19499,6 +19506,10 @@ packages: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + http-parser-js@0.5.8: resolution: {integrity: sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==} @@ -19609,6 +19620,10 @@ packages: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} + iconv-lite@0.7.2: + resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} + engines: {node: '>=0.10.0'} + identity-function@1.0.0: resolution: {integrity: sha512-kNrgUK0qI+9qLTBidsH85HjDLpZfrrS0ElquKKe/fJFdB3D7VeKdXXEvOPDUHSHOzdZKCAAaQIWWyp0l2yq6pw==} @@ -22087,34 +22102,23 @@ packages: resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==} engines: {node: 18 || 20 || >=22} - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - minimatch@3.1.5: resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} - minimatch@5.0.1: - resolution: {integrity: sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==} - engines: {node: '>=10'} - - minimatch@5.1.6: - resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + minimatch@5.1.9: + resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==} engines: {node: '>=10'} - minimatch@7.4.6: - resolution: {integrity: sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==} + minimatch@7.4.9: + resolution: {integrity: sha512-Brg/fp/iAVDOQoHxkuN5bEYhyQlZhxddI78yWsCbeEwTHXQjlNLtiJDUsp1GIptVqMI7/gkJMz4vVAc01mpoBw==} engines: {node: '>=10'} - minimatch@8.0.4: - resolution: {integrity: sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==} - engines: {node: '>=16 || 14 >=14.17'} - - minimatch@9.0.3: - resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} + minimatch@8.0.7: + resolution: {integrity: sha512-V+1uQNdzybxa14e/p00HZnQNNcTjnRJjDxg2V8wtkjFctq4M7hXFws4oekyTP0Jebeq7QYtpFyOeBAjc88zvYg==} engines: {node: '>=16 || 14 >=14.17'} - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + minimatch@9.0.9: + resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} engines: {node: '>=16 || 14 >=14.17'} minimist-options@3.0.2: @@ -23564,13 +23568,13 @@ packages: resolution: {integrity: sha512-8xCNE/aT/EXKenuMDZ+xTVwkT8gsoHN2z/Q29l80u0ppGEXVvsKRzNMbtKhg8LS8k1tJLAHHylf6p4VFmP6XUQ==} engines: {node: '>= 0.4.0'} - playwright-core@1.46.1: - resolution: {integrity: sha512-h9LqIQaAv+CYvWzsZ+h3RsrqCStkBHlgo6/TJlFst3cOTlLghBQlJwPOZKQJTKNaD3QIB7aAVQ+gfWbN3NXB7A==} + playwright-core@1.58.2: + resolution: {integrity: sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==} engines: {node: '>=18'} hasBin: true - playwright@1.46.1: - resolution: {integrity: sha512-oPcr1yqoXLCkgKtD5eNUPLiN40rYEM39odNpIb6VE6S7/15gJmA1NzVv6zJYusV0e7tzvkU/utBFNa/Kpxmwng==} + playwright@1.58.2: + resolution: {integrity: sha512-vA30H8Nvkq/cPBnNw4Q8TWz1EJyqgpuinBcHET0YVJVFldr8JDNiU9LaWAE1KqSkRYazuaBhTpB5ZzShOezQ6A==} engines: {node: '>=18'} hasBin: true @@ -24338,6 +24342,10 @@ packages: resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} engines: {node: '>=0.6'} + qs@6.15.0: + resolution: {integrity: sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==} + engines: {node: '>=0.6'} + query-registry@3.0.1: resolution: {integrity: sha512-M9RxRITi2mHMVPU5zysNjctUT8bAPx6ltEXo/ir9+qmiM47Y7f0Ir3+OxUO5OjYAWdicBQRew7RtHtqUXydqlg==} engines: {node: '>=20'} @@ -24398,9 +24406,9 @@ packages: resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} engines: {node: '>= 0.8'} - raw-body@3.0.0: - resolution: {integrity: sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==} - engines: {node: '>= 0.8'} + raw-body@3.0.2: + resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} + engines: {node: '>= 0.10'} rc@1.2.8: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} @@ -25791,6 +25799,10 @@ packages: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + std-env@3.9.0: resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} @@ -26851,6 +26863,10 @@ packages: resolution: {integrity: sha512-gd0sGezQYCbWSbkZr75mln4YBidWUN60+devscpLF5mtRDUpiaTvKpBNrdaCvel1NdR2k6vclXybU5fBd2i+nw==} engines: {node: '>= 0.6'} + type-is@2.0.1: + resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} + engines: {node: '>= 0.6'} + typed-array-buffer@1.0.2: resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} engines: {node: '>= 0.4'} @@ -31940,10 +31956,10 @@ snapshots: nanostores: 1.1.0 zod: 4.3.5 - '@better-auth/sso@1.4.7(better-auth@1.4.7(mongodb@6.21.0(@aws-sdk/credential-providers@3.637.0(@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0)))(gcp-metadata@5.3.0(encoding@0.1.13))(socks@2.7.1))(next@14.2.35(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.46.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.77.8))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.6)(svelte@4.2.19))': + '@better-auth/sso@1.4.7(better-auth@1.4.7(mongodb@6.21.0(@aws-sdk/credential-providers@3.637.0(@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0)))(gcp-metadata@5.3.0(encoding@0.1.13))(socks@2.7.1))(next@14.2.35(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-macros@3.1.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.77.8))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.6)(svelte@4.2.19))': dependencies: '@better-fetch/fetch': 1.1.21 - better-auth: 1.4.7(mongodb@6.21.0(@aws-sdk/credential-providers@3.637.0(@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0)))(gcp-metadata@5.3.0(encoding@0.1.13))(socks@2.7.1))(next@14.2.35(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.46.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.77.8))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.6)(svelte@4.2.19) + better-auth: 1.4.7(mongodb@6.21.0(@aws-sdk/credential-providers@3.637.0(@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0)))(gcp-metadata@5.3.0(encoding@0.1.13))(socks@2.7.1))(next@14.2.35(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-macros@3.1.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.77.8))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.6)(svelte@4.2.19) fast-xml-parser: 5.3.8 jose: 6.1.3 samlify: 2.10.2 @@ -32095,14 +32111,14 @@ snapshots: react: 19.2.3 react-dom: 19.2.3(react@19.2.3) - '@clerk/testing@1.4.22(@playwright/test@1.46.1)(cypress@13.10.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@clerk/testing@1.4.22(@playwright/test@1.58.2)(cypress@13.10.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': dependencies: '@clerk/backend': 1.25.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@clerk/shared': 2.21.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@clerk/types': 4.48.0 dotenv: 16.4.7 optionalDependencies: - '@playwright/test': 1.46.1 + '@playwright/test': 1.58.2 cypress: 13.10.0 transitivePeerDependencies: - react @@ -35289,6 +35305,10 @@ snapshots: '@nothing-but/utils@0.12.1': {} + '@novu/api@3.14.1': + dependencies: + zod: 3.25.76 + '@novu/ntfr-client@0.0.4': dependencies: https: 1.0.0 @@ -35328,7 +35348,7 @@ snapshots: ejs: 3.1.10 enquirer: 2.3.6 ignore: 5.3.2 - minimatch: 9.0.3 + minimatch: 9.0.9 nx: 20.1.2(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.15))(@swc/types@0.1.12)(typescript@5.6.2))(@swc/core@1.7.26(@swc/helpers@0.5.15)) semver: 7.6.3 tmp: 0.2.1 @@ -35340,7 +35360,7 @@ snapshots: ejs: 3.1.10 enquirer: 2.3.6 ignore: 5.3.2 - minimatch: 9.0.3 + minimatch: 9.0.9 nx: 21.3.11(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.15))(@swc/types@0.1.12)(typescript@5.6.2))(@swc/core@1.7.26(@swc/helpers@0.5.15)) semver: 7.7.3 tmp: 0.2.1 @@ -35377,7 +35397,7 @@ snapshots: jest-config: 30.0.5(@types/node@22.15.13)(babel-plugin-macros@3.1.0)(esbuild-register@3.5.0(esbuild@0.27.3))(ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.15))(@types/node@22.15.13)(typescript@5.6.2)) jest-resolve: 30.0.5 jest-util: 30.0.5 - minimatch: 9.0.3 + minimatch: 9.0.9 picocolors: 1.1.1 resolve.exports: 2.0.3 semver: 7.6.3 @@ -35421,7 +35441,7 @@ snapshots: ignore: 5.3.2 js-tokens: 4.0.0 jsonc-parser: 3.2.0 - minimatch: 9.0.3 + minimatch: 9.0.9 npm-package-arg: 11.0.1 npm-run-path: 4.0.1 ora: 5.3.0 @@ -37165,9 +37185,9 @@ snapshots: '@pkgr/core@0.2.9': {} - '@playwright/test@1.46.1': + '@playwright/test@1.58.2': dependencies: - playwright: 1.46.1 + playwright: 1.58.2 '@plunk/node@2.0.0': dependencies: @@ -42156,7 +42176,7 @@ snapshots: jsonpath-plus: 10.3.0 lodash: 4.17.21 lodash.topath: 4.5.2 - minimatch: 3.1.2 + minimatch: 3.1.5 nimma: 0.2.3 pony-cause: 1.1.1 simple-eval: 1.0.1 @@ -42495,7 +42515,7 @@ snapshots: '@swc/counter': 0.1.3 commander: 8.3.0 fast-glob: 3.3.1 - minimatch: 9.0.5 + minimatch: 9.0.9 piscina: 4.6.1 semver: 7.7.2 slash: 3.0.0 @@ -43873,7 +43893,7 @@ snapshots: debug: 4.4.3(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 - minimatch: 9.0.5 + minimatch: 9.0.9 semver: 7.7.3 ts-api-utils: 1.3.0(typescript@5.8.3) optionalDependencies: @@ -43890,7 +43910,7 @@ snapshots: debug: 4.4.3(supports-color@8.1.1) fast-glob: 3.3.2 is-glob: 4.0.3 - minimatch: 9.0.5 + minimatch: 9.0.9 semver: 7.7.3 ts-api-utils: 2.1.0(typescript@5.8.3) typescript: 5.8.3 @@ -44146,7 +44166,7 @@ snapshots: debug: 4.3.4(supports-color@8.1.1) js-yaml: 4.1.0 lodash: 4.17.21 - minimatch: 7.4.6 + minimatch: 7.4.9 yup: 0.32.11 transitivePeerDependencies: - supports-color @@ -44271,7 +44291,7 @@ snapshots: dependencies: '@verdaccio/core': 7.0.0-next-7.15 lodash: 4.17.21 - minimatch: 7.4.6 + minimatch: 7.4.9 semver: 7.6.0 '@vitejs/plugin-react@4.3.1(vite@5.4.21(@types/node@22.15.13)(less@4.2.0)(lightningcss@1.30.2)(sass@1.77.8)(sugarss@4.0.1(postcss@8.4.47))(terser@5.31.6))': @@ -45700,7 +45720,7 @@ snapshots: jsonpointer: 5.0.1 leven: 3.1.0 - better-auth@1.4.7(mongodb@6.21.0(@aws-sdk/credential-providers@3.637.0(@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0)))(gcp-metadata@5.3.0(encoding@0.1.13))(socks@2.7.1))(next@14.2.35(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.46.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.77.8))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.6)(svelte@4.2.19): + better-auth@1.4.7(mongodb@6.21.0(@aws-sdk/credential-providers@3.637.0(@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0)))(gcp-metadata@5.3.0(encoding@0.1.13))(socks@2.7.1))(next@14.2.35(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-macros@3.1.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.77.8))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.6)(svelte@4.2.19): dependencies: '@better-auth/core': 1.4.7(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.5(zod@4.3.5))(jose@6.1.3)(kysely@0.28.9)(nanostores@1.1.0) '@better-auth/telemetry': 1.4.7(@better-auth/core@1.4.7(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.5(zod@4.3.5))(jose@6.1.3)(kysely@0.28.9)(nanostores@1.1.0)) @@ -45716,7 +45736,7 @@ snapshots: zod: 4.3.5 optionalDependencies: mongodb: 6.21.0(@aws-sdk/credential-providers@3.637.0(@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0)))(gcp-metadata@5.3.0(encoding@0.1.13))(socks@2.7.1) - next: 14.2.35(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.46.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.77.8) + next: 14.2.35(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-macros@3.1.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.77.8) react: 19.2.3 react-dom: 19.2.3(react@19.2.3) solid-js: 1.9.6 @@ -45801,17 +45821,17 @@ snapshots: transitivePeerDependencies: - supports-color - body-parser@2.2.0: + body-parser@2.2.2: dependencies: bytes: 3.1.2 content-type: 1.0.5 - debug: 4.4.0 - http-errors: 2.0.0 - iconv-lite: 0.6.3 + debug: 4.4.3(supports-color@8.1.1) + http-errors: 2.0.1 + iconv-lite: 0.7.2 on-finished: 2.4.1 - qs: 6.14.0 - raw-body: 3.0.0 - type-is: 2.0.0 + qs: 6.15.0 + raw-body: 3.0.2 + type-is: 2.0.1 transitivePeerDependencies: - supports-color @@ -45846,6 +45866,10 @@ snapshots: dependencies: balanced-match: 1.0.2 + brace-expansion@2.0.2: + dependencies: + balanced-match: 1.0.2 + brace-expansion@5.0.4: dependencies: balanced-match: 4.0.4 @@ -46856,7 +46880,7 @@ snapshots: duplexer: 0.1.2 glob: 7.2.3 glob2base: 0.0.12 - minimatch: 3.1.2 + minimatch: 3.1.5 mkdirp: 0.5.6 resolve: 1.22.8 safe-buffer: 5.2.1 @@ -47407,7 +47431,6 @@ snapshots: ms: 2.1.3 optionalDependencies: supports-color: 8.1.1 - optional: true debug@4.3.1(supports-color@8.1.1): dependencies: @@ -48738,7 +48761,7 @@ snapshots: express@5.0.1: dependencies: accepts: 2.0.0 - body-parser: 2.2.0 + body-parser: 2.2.2 content-disposition: 1.0.0 content-type: 1.0.5 cookie: 0.7.1 @@ -49007,7 +49030,7 @@ snapshots: filelist@1.0.4: dependencies: - minimatch: 5.1.6 + minimatch: 5.1.9 filename-regex@2.0.1: {} @@ -49204,7 +49227,7 @@ snapshots: deepmerge: 4.3.1 fs-extra: 10.1.0 memfs: 3.5.0 - minimatch: 3.1.2 + minimatch: 3.1.5 node-abort-controller: 3.1.1 schema-utils: 3.3.0 semver: 7.6.3 @@ -49255,7 +49278,7 @@ snapshots: dezalgo: 1.0.4 hexoid: 1.0.0 once: 1.4.0 - qs: 6.14.0 + qs: 6.15.0 formidable@3.5.1: dependencies: @@ -49605,7 +49628,7 @@ snapshots: dependencies: foreground-child: 3.3.1 jackspeak: 3.4.3 - minimatch: 9.0.5 + minimatch: 9.0.9 minipass: 7.1.2 package-json-from-dist: 1.0.0 path-scurry: 1.11.1 @@ -49641,7 +49664,7 @@ snapshots: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 3.1.2 + minimatch: 3.1.5 once: 1.4.0 path-is-absolute: 1.0.1 @@ -49659,7 +49682,7 @@ snapshots: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 5.1.6 + minimatch: 5.1.9 once: 1.4.0 glob@8.1.0: @@ -49667,13 +49690,13 @@ snapshots: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 5.1.6 + minimatch: 5.1.9 once: 1.4.0 glob@9.3.5: dependencies: fs.realpath: 1.0.0 - minimatch: 8.0.4 + minimatch: 8.0.7 minipass: 4.2.8 path-scurry: 1.11.1 @@ -49804,7 +49827,7 @@ snapshots: extend: 3.0.2 gaxios: 4.3.3(encoding@0.1.13) google-auth-library: 6.1.6(encoding@0.1.13) - qs: 6.14.0 + qs: 6.15.0 url-template: 2.0.8 uuid: 8.3.2 transitivePeerDependencies: @@ -50231,6 +50254,14 @@ snapshots: statuses: 2.0.1 toidentifier: 1.0.1 + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + http-parser-js@0.5.8: {} http-proxy-agent@4.0.1: @@ -50405,6 +50436,10 @@ snapshots: dependencies: safer-buffer: 2.1.2 + iconv-lite@0.7.2: + dependencies: + safer-buffer: 2.1.2 + identity-function@1.0.0: {} identity-obj-proxy@3.0.0: @@ -53170,7 +53205,7 @@ snapshots: js-yaml: 4.1.0 jsonc-parser: 3.2.0 markdownlint: 0.27.0 - minimatch: 5.1.6 + minimatch: 5.1.9 run-con: 1.2.11 markdownlint@0.27.0: @@ -53854,37 +53889,25 @@ snapshots: dependencies: brace-expansion: 5.0.4 - minimatch@3.1.2: - dependencies: - brace-expansion: 1.1.11 - minimatch@3.1.5: dependencies: brace-expansion: 1.1.11 - minimatch@5.0.1: + minimatch@5.1.9: dependencies: brace-expansion: 2.0.1 - minimatch@5.1.6: + minimatch@7.4.9: dependencies: - brace-expansion: 2.0.1 - - minimatch@7.4.6: - dependencies: - brace-expansion: 2.0.1 - - minimatch@8.0.4: - dependencies: - brace-expansion: 2.0.1 + brace-expansion: 2.0.2 - minimatch@9.0.3: + minimatch@8.0.7: dependencies: brace-expansion: 2.0.1 - minimatch@9.0.5: + minimatch@9.0.9: dependencies: - brace-expansion: 2.0.1 + brace-expansion: 2.0.2 minimist-options@3.0.2: dependencies: @@ -53980,7 +54003,7 @@ snapshots: he: 1.2.0 js-yaml: 4.1.0 log-symbols: 4.1.0 - minimatch: 5.0.1 + minimatch: 5.1.9 ms: 2.1.3 nanoid: 3.3.3 serialize-javascript: 6.0.0 @@ -54006,7 +54029,7 @@ snapshots: he: 1.2.0 js-yaml: 4.0.0 log-symbols: 4.0.0 - minimatch: 3.1.2 + minimatch: 3.1.5 ms: 2.1.3 nanoid: 3.3.8 serialize-javascript: 5.0.1 @@ -54271,7 +54294,7 @@ snapshots: needle@2.4.0: dependencies: - debug: 3.2.7(supports-color@5.5.0) + debug: 3.2.7(supports-color@8.1.1) iconv-lite: 0.4.24 sax: 1.4.1 transitivePeerDependencies: @@ -54279,7 +54302,7 @@ snapshots: needle@3.2.0: dependencies: - debug: 3.2.7(supports-color@5.5.0) + debug: 3.2.7(supports-color@8.1.1) iconv-lite: 0.6.3 sax: 1.5.0 transitivePeerDependencies: @@ -54371,7 +54394,7 @@ snapshots: react: 19.2.3 react-dom: 19.2.3(react@19.2.3) - next@14.2.35(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.46.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8): + next@14.2.35(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8): dependencies: '@next/env': 14.2.35 '@swc/helpers': 0.5.5 @@ -54393,13 +54416,13 @@ snapshots: '@next/swc-win32-ia32-msvc': 14.2.33 '@next/swc-win32-x64-msvc': 14.2.33 '@opentelemetry/api': 1.9.0 - '@playwright/test': 1.46.1 + '@playwright/test': 1.58.2 sass: 1.77.8 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros - next@14.2.35(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.46.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.77.8): + next@14.2.35(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-macros@3.1.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.77.8): dependencies: '@next/env': 14.2.35 '@swc/helpers': 0.5.5 @@ -54421,13 +54444,13 @@ snapshots: '@next/swc-win32-ia32-msvc': 14.2.33 '@next/swc-win32-x64-msvc': 14.2.33 '@opentelemetry/api': 1.9.0 - '@playwright/test': 1.46.1 + '@playwright/test': 1.58.2 sass: 1.77.8 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros - next@15.4.10(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8): + next@15.4.10(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8): dependencies: '@next/env': 15.4.10 '@swc/helpers': 0.5.15 @@ -54446,6 +54469,7 @@ snapshots: '@next/swc-win32-arm64-msvc': 15.4.8 '@next/swc-win32-x64-msvc': 15.4.8 '@opentelemetry/api': 1.9.0 + '@playwright/test': 1.58.2 sass: 1.77.8 sharp: 0.34.5 transitivePeerDependencies: @@ -54604,7 +54628,7 @@ snapshots: chokidar: 3.5.3 debug: 3.2.7(supports-color@5.5.0) ignore-by-default: 1.0.1 - minimatch: 3.1.2 + minimatch: 3.1.5 pstree.remy: 1.1.8 semver: 7.5.4 simple-update-notifier: 2.0.0 @@ -54661,7 +54685,7 @@ snapshots: chalk: 2.4.2 cross-spawn: 6.0.5 memorystream: 0.3.1 - minimatch: 3.1.2 + minimatch: 3.1.5 pidtree: 0.3.1 read-pkg: 3.0.0 shell-quote: 1.8.1 @@ -54747,7 +54771,7 @@ snapshots: jest-diff: 29.7.0 jsonc-parser: 3.2.0 lines-and-columns: 2.0.3 - minimatch: 9.0.3 + minimatch: 9.0.9 node-machine-id: 1.1.12 npm-run-path: 4.0.1 open: 8.4.2 @@ -54797,7 +54821,7 @@ snapshots: jest-diff: 30.0.5 jsonc-parser: 3.2.0 lines-and-columns: 2.0.3 - minimatch: 9.0.3 + minimatch: 9.0.9 node-machine-id: 1.1.12 npm-run-path: 4.0.1 open: 8.4.2 @@ -55595,11 +55619,11 @@ snapshots: pkginfo@0.4.1: {} - playwright-core@1.46.1: {} + playwright-core@1.58.2: {} - playwright@1.46.1: + playwright@1.58.2: dependencies: - playwright-core: 1.46.1 + playwright-core: 1.58.2 optionalDependencies: fsevents: 2.3.2 @@ -55716,7 +55740,7 @@ snapshots: portfinder@1.0.32: dependencies: async: 2.6.4 - debug: 3.2.7(supports-color@5.5.0) + debug: 3.2.7(supports-color@8.1.1) mkdirp: 0.5.6 transitivePeerDependencies: - supports-color @@ -56551,6 +56575,10 @@ snapshots: dependencies: side-channel: 1.1.0 + qs@6.15.0: + dependencies: + side-channel: 1.1.0 + query-registry@3.0.1: dependencies: query-string: 9.1.0 @@ -56601,11 +56629,11 @@ snapshots: iconv-lite: 0.4.24 unpipe: 1.0.0 - raw-body@3.0.0: + raw-body@3.0.2: dependencies: bytes: 3.1.2 - http-errors: 2.0.0 - iconv-lite: 0.6.3 + http-errors: 2.0.1 + iconv-lite: 0.7.2 unpipe: 1.0.0 rc@1.2.8: @@ -57751,7 +57779,7 @@ snapshots: escape-html: 1.0.3 etag: 1.8.1 fresh: 0.5.2 - http-errors: 2.0.0 + http-errors: 2.0.1 mime-types: 2.1.35 ms: 2.1.3 on-finished: 2.4.1 @@ -58359,6 +58387,8 @@ snapshots: statuses@2.0.1: {} + statuses@2.0.2: {} + std-env@3.9.0: {} steno@0.4.4: @@ -58739,7 +58769,7 @@ snapshots: formidable: 3.5.1 methods: 1.1.2 mime: 2.6.0 - qs: 6.14.0 + qs: 6.15.0 transitivePeerDependencies: - supports-color @@ -58753,7 +58783,7 @@ snapshots: formidable: 2.1.2 methods: 1.1.2 mime: 2.6.0 - qs: 6.14.0 + qs: 6.15.0 semver: 7.7.3 transitivePeerDependencies: - supports-color @@ -58768,7 +58798,7 @@ snapshots: formidable: 3.5.1 methods: 1.1.2 mime: 2.6.0 - qs: 6.14.0 + qs: 6.15.0 transitivePeerDependencies: - supports-color @@ -59805,6 +59835,12 @@ snapshots: media-typer: 1.1.0 mime-types: 3.0.0 + type-is@2.0.1: + dependencies: + content-type: 1.0.5 + media-typer: 1.1.0 + mime-types: 3.0.0 + typed-array-buffer@1.0.2: dependencies: call-bind: 1.0.7 @@ -59847,7 +59883,7 @@ snapshots: dependencies: lunr: 2.3.9 marked: 4.3.0 - minimatch: 9.0.3 + minimatch: 9.0.9 shiki: 0.14.1 typescript: 5.6.2 @@ -59977,7 +60013,7 @@ snapshots: union@0.5.0: dependencies: - qs: 6.14.0 + qs: 6.15.0 unique-string@2.0.0: dependencies: @@ -61255,10 +61291,6 @@ snapshots: dependencies: zod: 3.25.76 - zod-to-json-schema@3.25.1(zod@4.3.5): - dependencies: - zod: 4.3.5 - zod-validation-error@3.3.0(zod@3.25.20): dependencies: zod: 3.25.20