From 3a97205931496b316875aeb6bee9c8e334cb8dbf Mon Sep 17 00:00:00 2001 From: Manik Date: Tue, 24 Mar 2026 22:05:00 +0530 Subject: [PATCH 1/3] feat(slack): convert markdown lists to bullets and bold key elements in Slack output Co-Authored-By: Claude Sonnet 4.6 --- .../app/services/channels/slack/outbound.ts | 127 +------- .../channels/slack/slack-format.test.ts | 272 +++++++++++++++++ .../services/channels/slack/slack-format.ts | 258 ++++++++++++++++ apps/webapp/package.json | 6 +- apps/webapp/vitest.config.ts | 8 + pnpm-lock.yaml | 280 +++++++++++++++++- 6 files changed, 818 insertions(+), 133 deletions(-) create mode 100644 apps/webapp/app/services/channels/slack/slack-format.test.ts create mode 100644 apps/webapp/app/services/channels/slack/slack-format.ts create mode 100644 apps/webapp/vitest.config.ts diff --git a/apps/webapp/app/services/channels/slack/outbound.ts b/apps/webapp/app/services/channels/slack/outbound.ts index 2c20dc42d..7a0e0772d 100644 --- a/apps/webapp/app/services/channels/slack/outbound.ts +++ b/apps/webapp/app/services/channels/slack/outbound.ts @@ -2,129 +2,10 @@ import { prisma } from "~/db.server"; import { sendSlackDM, sendSlackMessage } from "./client"; import { logger } from "~/services/logger.service"; import type { ReplyMetadata } from "../types"; - -// --------------------------------------------------------------------------- -// Markdown → Slack Block Kit conversion -// --------------------------------------------------------------------------- - -function convertInlineMd(text: string): string { - return text - .replace(/\*\*(.+?)\*\*/g, "*$1*") // **bold** → *bold* - .replace(/(?"); // [text](url) → -} - -function stripInlineMd(text: string): string { - return text - .replace(/\*\*(.+?)\*\*/g, "$1") - .replace(/\*(.+?)\*/g, "$1") - .replace(/_(.+?)_/g, "$1") - .replace(/~~(.+?)~~/g, "$1") - .replace(/\[(.+?)\]\(.+?\)/g, "$1") - .replace(/`(.+?)`/g, "$1"); -} - -function chunkText(text: string, max: number): string[] { - if (text.length <= max) return [text]; - const chunks: string[] = []; - let remaining = text; - while (remaining.length > max) { - const idx = remaining.lastIndexOf("\n\n", max); - const at = idx > 0 ? idx : max; - chunks.push(remaining.slice(0, at).trim()); - remaining = remaining.slice(at).trim(); - } - if (remaining) chunks.push(remaining); - return chunks; -} - -function markdownToSlackBlocks(markdown: string): unknown[] { - const blocks: unknown[] = []; - const lines = markdown.split("\n"); - let sectionLines: string[] = []; - - function flushSection() { - if (sectionLines.length === 0) return; - const text = convertInlineMd(sectionLines.join("\n").trimEnd()); - sectionLines = []; - if (!text.trim()) return; - for (const chunk of chunkText(text, 3000)) { - blocks.push({ type: "section", text: { type: "mrkdwn", text: chunk } }); - } - } - - for (const line of lines) { - // H1/H2 → header block - const h2 = line.match(/^#{1,2}\s+(.+)/); - if (h2) { - flushSection(); - blocks.push({ - type: "header", - text: { - type: "plain_text", - text: stripInlineMd(h2[1]).slice(0, 150), - emoji: true, - }, - }); - continue; - } - - // H3–H6 → bold section - const h3 = line.match(/^#{3,6}\s+(.+)/); - if (h3) { - flushSection(); - blocks.push({ - type: "section", - text: { type: "mrkdwn", text: `*${convertInlineMd(h3[1])}*` }, - }); - continue; - } - - // Horizontal rule → divider - if (line.match(/^[-*_]{3,}\s*$/)) { - flushSection(); - blocks.push({ type: "divider" }); - continue; - } - - // Table separator row — skip - if (line.match(/^\|[\s:|-]+\|/)) { - continue; - } - - // Table data row — flatten to text - if (line.startsWith("|")) { - const cells = line - .split("|") - .filter((c) => c.trim()) - .map((c) => convertInlineMd(c.trim())); - sectionLines.push(cells.join(" | ")); - continue; - } - - sectionLines.push(line); - } - - flushSection(); - - // Slack enforces max 50 blocks - return blocks.slice(0, 50); -} - -function markdownToPlainText(markdown: string): string { - return markdown - .replace(/^#{1,6}\s+/gm, "") - .replace(/\*\*(.+?)\*\*/g, "$1") - .replace(/\*(.+?)\*/g, "$1") - .replace(/_(.+?)_/g, "$1") - .replace(/~~(.+?)~~/g, "$1") - .replace(/\[(.+?)\]\(.+?\)/g, "$1") - .replace(/`(.+?)`/g, "$1") - .replace(/^\|[\s:|-]+\|.*$/gm, "") - .replace(/^[-*_]{3,}\s*$/gm, "") - .trim(); -} +import { + markdownToSlackBlocks, + markdownToPlainText, +} from "./slack-format"; /** * Look up the Slack bot token for a given Slack user ID. diff --git a/apps/webapp/app/services/channels/slack/slack-format.test.ts b/apps/webapp/app/services/channels/slack/slack-format.test.ts new file mode 100644 index 000000000..6ba34dad1 --- /dev/null +++ b/apps/webapp/app/services/channels/slack/slack-format.test.ts @@ -0,0 +1,272 @@ +import { describe, it, expect } from "vitest"; +import { + convertInlineMd, + convertMarkdownListsToSlackBullets, + boldKeyElements, + markdownToSlackBlocks, + markdownToPlainText, + chunkText, +} from "./slack-format"; + +// --------------------------------------------------------------------------- +// convertMarkdownListsToSlackBullets +// --------------------------------------------------------------------------- +describe("convertMarkdownListsToSlackBullets", () => { + it("converts hyphen list items to Slack bullets", () => { + const result = convertMarkdownListsToSlackBullets("- Item one\n- Item two"); + expect(result).toBe("• Item one\n• Item two"); + }); + + it("converts asterisk list items to Slack bullets", () => { + const result = convertMarkdownListsToSlackBullets("* Item one\n* Item two"); + expect(result).toBe("• Item one\n• Item two"); + }); + + it("preserves fenced code block contents unchanged", () => { + const input = "```\n- not a bullet\n* also not\n```"; + expect(convertMarkdownListsToSlackBullets(input)).toBe(input); + }); + + it("does not convert horizontal rules (--- / ***)", () => { + expect(convertMarkdownListsToSlackBullets("---")).toBe("---"); + expect(convertMarkdownListsToSlackBullets("***")).toBe("***"); + expect(convertMarkdownListsToSlackBullets("___")).toBe("___"); + }); + + it("preserves non-list lines unchanged", () => { + expect(convertMarkdownListsToSlackBullets("Hello world")).toBe("Hello world"); + }); + + it("handles indented list items", () => { + expect(convertMarkdownListsToSlackBullets(" - Indented item")).toBe( + " • Indented item" + ); + }); + + it("converts only list lines, leaving surrounding text intact", () => { + const input = "Intro text\n- Item\nTrailing text"; + const result = convertMarkdownListsToSlackBullets(input); + expect(result).toBe("Intro text\n• Item\nTrailing text"); + }); + + it("mixed list items in same block", () => { + const result = convertMarkdownListsToSlackBullets("- First\n* Second\n- Third"); + expect(result).toBe("• First\n• Second\n• Third"); + }); +}); + +// --------------------------------------------------------------------------- +// boldKeyElements +// --------------------------------------------------------------------------- +describe("boldKeyElements", () => { + it('bolds "Action Required"', () => { + expect(boldKeyElements("Action Required: please fix")).toContain( + "*Action Required*" + ); + }); + + it('bolds "action required" (case-insensitive)', () => { + expect(boldKeyElements("action required to proceed")).toContain( + "*action required*" + ); + }); + + it("bolds P1 as a standalone word", () => { + expect(boldKeyElements("This is P1 priority")).toBe("This is *P1* priority"); + }); + + it("bolds P2 as a standalone word", () => { + expect(boldKeyElements("P2 issue found")).toBe("*P2* issue found"); + }); + + it("bolds P3 as a standalone word", () => { + expect(boldKeyElements("Severity: P3")).toContain("*P3*"); + }); + + it("does not bold P1 inside inline code spans", () => { + expect(boldKeyElements("`P1 value`")).toBe("`P1 value`"); + }); + + it("does not bold Action Required inside Slack URL tokens", () => { + const url = ""; + expect(boldKeyElements(url)).toBe(url); + }); + + it("does not modify arbitrary Slack tokens", () => { + const token = ""; + expect(boldKeyElements(token)).toBe(token); + }); + + it("bolds a Key: Value pattern at the start of a line", () => { + const result = boldKeyElements("Status: active"); + expect(result).toContain("*Status*:"); + }); + + it("bolds a Key: Value pattern after a Slack bullet", () => { + const result = boldKeyElements("• Priority: high"); + expect(result).toContain("*Priority*:"); + }); + + it("does not double-bold already-bolded text", () => { + const input = "*Status*: active"; + expect(boldKeyElements(input)).toBe("*Status*: active"); + }); + + it("preserves text with no special elements unchanged", () => { + expect(boldKeyElements("just some regular text")).toBe( + "just some regular text" + ); + }); +}); + +// --------------------------------------------------------------------------- +// markdownToSlackBlocks — list conversion +// --------------------------------------------------------------------------- +describe("markdownToSlackBlocks — list conversion", () => { + it("converts markdown list items to Slack bullets in section blocks", () => { + const blocks = markdownToSlackBlocks("- Item one\n- Item two") as any[]; + expect(blocks).toHaveLength(1); + expect(blocks[0].text.text).toContain("• Item one"); + expect(blocks[0].text.text).toContain("• Item two"); + }); + + it("does not convert list syntax inside fenced code blocks", () => { + const input = "```\n- not a bullet\n```"; + const blocks = markdownToSlackBlocks(input) as any[]; + const text = blocks[0].text.text; + expect(text).toContain("- not a bullet"); + expect(text).not.toContain("• not a bullet"); + }); + + it("handles mixed content: text, list, then text", () => { + const input = "Intro\n- Item\nOutro"; + const blocks = markdownToSlackBlocks(input) as any[]; + const text = blocks[0].text.text; + expect(text).toContain("• Item"); + expect(text).toContain("Intro"); + expect(text).toContain("Outro"); + }); +}); + +// --------------------------------------------------------------------------- +// markdownToSlackBlocks — bolding +// --------------------------------------------------------------------------- +describe("markdownToSlackBlocks — bolding", () => { + it("bolds Action Required in section content", () => { + const blocks = markdownToSlackBlocks("Action Required: fix this") as any[]; + expect(blocks[0].text.text).toContain("*Action Required*"); + }); + + it("does not bold Action Required inside fenced code blocks", () => { + const blocks = markdownToSlackBlocks( + "```\nAction Required: fix\n```" + ) as any[]; + const text = blocks[0].text.text; + expect(text).not.toMatch(/\*Action Required\*/); + }); + + it("bolds P1/P2/P3 in section content", () => { + const blocks = markdownToSlackBlocks("Ticket is P2 priority") as any[]; + expect(blocks[0].text.text).toContain("*P2*"); + }); + + it("does not bold P1 inside a code block", () => { + const blocks = markdownToSlackBlocks("```\nP1 config\n```") as any[]; + expect(blocks[0].text.text).not.toContain("*P1*"); + }); +}); + +// --------------------------------------------------------------------------- +// markdownToSlackBlocks — existing behaviour preserved +// --------------------------------------------------------------------------- +describe("markdownToSlackBlocks — existing formatting preserved", () => { + it("creates a header block for H1", () => { + const blocks = markdownToSlackBlocks("# My Title") as any[]; + expect(blocks[0]).toMatchObject({ type: "header" }); + expect(blocks[0].text.text).toBe("My Title"); + }); + + it("creates a header block for H2", () => { + const blocks = markdownToSlackBlocks("## Sub Title") as any[]; + expect(blocks[0]).toMatchObject({ type: "header" }); + }); + + it("creates a bold section for H3", () => { + const blocks = markdownToSlackBlocks("### Section") as any[]; + expect(blocks[0].text.text).toBe("*Section*"); + }); + + it("creates a divider for horizontal rule", () => { + const blocks = markdownToSlackBlocks("---") as any[]; + expect(blocks[0]).toMatchObject({ type: "divider" }); + }); + + it("converts **bold** to Slack *bold*", () => { + const blocks = markdownToSlackBlocks("**important** word") as any[]; + expect(blocks[0].text.text).toContain("*important*"); + }); + + it("converts [text](url) to Slack ", () => { + const blocks = markdownToSlackBlocks( + "[click here](https://example.com)" + ) as any[]; + expect(blocks[0].text.text).toContain(""); + }); + + it("caps output at 50 blocks", () => { + const md = Array.from({ length: 60 }, (_, i) => `# Heading ${i}`).join("\n"); + const blocks = markdownToSlackBlocks(md); + expect(blocks.length).toBeLessThanOrEqual(50); + }); +}); + +// --------------------------------------------------------------------------- +// convertInlineMd +// --------------------------------------------------------------------------- +describe("convertInlineMd", () => { + it("converts **bold** to *bold*", () => { + expect(convertInlineMd("**hello**")).toBe("*hello*"); + }); + + it("converts [text](url) to ", () => { + expect(convertInlineMd("[click](https://x.com)")).toBe( + "" + ); + }); + + it("converts ~~strike~~ to ~strike~", () => { + expect(convertInlineMd("~~del~~")).toBe("~del~"); + }); +}); + +// --------------------------------------------------------------------------- +// markdownToPlainText +// --------------------------------------------------------------------------- +describe("markdownToPlainText", () => { + it("strips heading markers", () => { + expect(markdownToPlainText("# Title")).toBe("Title"); + }); + + it("strips bold markers", () => { + expect(markdownToPlainText("**bold**")).toBe("bold"); + }); + + it("strips link syntax, keeping text", () => { + expect(markdownToPlainText("[click](https://x.com)")).toBe("click"); + }); +}); + +// --------------------------------------------------------------------------- +// chunkText +// --------------------------------------------------------------------------- +describe("chunkText", () => { + it("returns single element for short text", () => { + expect(chunkText("hello", 100)).toEqual(["hello"]); + }); + + it("splits text longer than max", () => { + const long = "a".repeat(3001); + const chunks = chunkText(long, 3000); + expect(chunks.length).toBeGreaterThan(1); + }); +}); diff --git a/apps/webapp/app/services/channels/slack/slack-format.ts b/apps/webapp/app/services/channels/slack/slack-format.ts new file mode 100644 index 000000000..ef8f300cf --- /dev/null +++ b/apps/webapp/app/services/channels/slack/slack-format.ts @@ -0,0 +1,258 @@ +// --------------------------------------------------------------------------- +// Slack mrkdwn formatting utilities +// --------------------------------------------------------------------------- + +/** + * Convert common markdown inline syntax to Slack mrkdwn equivalents. + */ +export function convertInlineMd(text: string): string { + // Use a placeholder to protect bold markers from being re-processed as italic. + const BOLD_PLACEHOLDER = "\x00BOLD\x00"; + return text + .replace(/\*\*(.+?)\*\*/g, `${BOLD_PLACEHOLDER}$1${BOLD_PLACEHOLDER}`) // **bold** → placeholder + .replace(/(?") // [text](url) → + .replace(new RegExp(BOLD_PLACEHOLDER, "g"), "*"); // restore bold markers +} + +/** + * Strip all markdown inline syntax from text, leaving plain content. + */ +export function stripInlineMd(text: string): string { + return text + .replace(/\*\*(.+?)\*\*/g, "$1") + .replace(/\*(.+?)\*/g, "$1") + .replace(/_(.+?)_/g, "$1") + .replace(/~~(.+?)~~/g, "$1") + .replace(/\[(.+?)\]\(.+?\)/g, "$1") + .replace(/`(.+?)`/g, "$1"); +} + +/** + * Split text into chunks no larger than `max` characters, preferring paragraph breaks. + */ +export function chunkText(text: string, max: number): string[] { + if (text.length <= max) return [text]; + const chunks: string[] = []; + let remaining = text; + while (remaining.length > max) { + const idx = remaining.lastIndexOf("\n\n", max); + const at = idx > 0 ? idx : max; + chunks.push(remaining.slice(0, at).trim()); + remaining = remaining.slice(at).trim(); + } + if (remaining) chunks.push(remaining); + return chunks; +} + +/** + * Convert markdown list items (`- item` or `* item`) to Slack bullet points (`• item`). + * Skips content inside fenced code blocks. + */ +export function convertMarkdownListsToSlackBullets(text: string): string { + const lines = text.split("\n"); + const result: string[] = []; + let inCodeFence = false; + + for (const line of lines) { + if (line.match(/^```/)) { + inCodeFence = !inCodeFence; + result.push(line); + continue; + } + if (inCodeFence) { + result.push(line); + continue; + } + // Match list items: optional leading whitespace, then `- ` or `* ` with content. + // The {3,} horizontal rule check happens upstream; here we rely on requiring a space + // after the marker so `---` and `***` are not affected. + const listMatch = line.match(/^(\s*)[-*] (.+)/); + if (listMatch) { + result.push(`${listMatch[1]}• ${listMatch[2]}`); + } else { + result.push(line); + } + } + return result.join("\n"); +} + +/** + * Apply Slack-specific bolding to key elements in a text segment. + * Skips content inside inline code spans and Slack URL tokens to avoid corruption. + * + * Bolded patterns: + * - "Action Required" (case-insensitive) + * - Standalone priority markers: P1, P2, P3 + * - Key: Value patterns at the start of a line or after a bullet point (• ) + */ +export function boldKeyElements(text: string): string { + // Split by inline code spans (`...`) and Slack URL tokens (<...>), transform only plain segments. + const parts: string[] = []; + const safePattern = /(`[^`\n]+`|<[^>]+>)/g; + let lastIndex = 0; + let match: RegExpExecArray | null; + + while ((match = safePattern.exec(text)) !== null) { + if (match.index > lastIndex) { + parts.push(applyBoldingToSegment(text.slice(lastIndex, match.index))); + } + parts.push(match[0]); // preserve code span / URL token as-is + lastIndex = match.index + match[0].length; + } + if (lastIndex < text.length) { + parts.push(applyBoldingToSegment(text.slice(lastIndex))); + } + return parts.join(""); +} + +function applyBoldingToSegment(text: string): string { + return ( + text + // "Action Required" — whole phrase, case-insensitive + .replace(/\b(Action\s+Required)\b/gi, "*$1*") + // Priority markers P1 / P2 / P3 as standalone words + .replace(/\b(P[123])\b/g, "*$1*") + // Key: Value — capital-led word(s) at start of line followed by a colon + .replace(/^([A-Z][A-Za-z][A-Za-z\s]{0,20}):/gm, "*$1*:") + // Key: Value — capital-led word(s) right after a Slack bullet (• ) + .replace(/(• )([A-Z][A-Za-z][A-Za-z\s]{0,20}):/g, "$1*$2*:") + ); +} + +/** + * Convert a markdown string into Slack Block Kit blocks. + * + * Enhancements over raw markdown pass-through: + * - Markdown list items (`-` / `*`) become Slack bullet points (•) + * - Key phrases (Action Required, P1/P2/P3, Key: Value) are bolded + * - Code blocks are passed through without any transformation + */ +export function markdownToSlackBlocks(markdown: string): unknown[] { + const blocks: unknown[] = []; + const lines = markdown.split("\n"); + let sectionLines: string[] = []; + let codeBlockLines: string[] = []; + let inCodeFence = false; + + function flushSection() { + if (sectionLines.length === 0) return; + const raw = sectionLines.join("\n").trimEnd(); + sectionLines = []; + if (!raw.trim()) return; + // Pipeline: convert lists → inline markdown → bold key elements + const withBullets = convertMarkdownListsToSlackBullets(raw); + const withMd = convertInlineMd(withBullets); + const text = boldKeyElements(withMd); + for (const chunk of chunkText(text, 3000)) { + blocks.push({ type: "section", text: { type: "mrkdwn", text: chunk } }); + } + } + + function flushCodeBlock() { + if (codeBlockLines.length === 0) return; + const text = codeBlockLines.join("\n"); + codeBlockLines = []; + if (!text.trim()) return; + // Code blocks are passed through as-is (no list/bold transformation) + for (const chunk of chunkText(text, 3000)) { + blocks.push({ type: "section", text: { type: "mrkdwn", text: chunk } }); + } + } + + for (const line of lines) { + // Fenced code block boundary + if (line.match(/^```/)) { + if (!inCodeFence) { + flushSection(); + codeBlockLines.push(line); + inCodeFence = true; + } else { + codeBlockLines.push(line); + inCodeFence = false; + flushCodeBlock(); + } + continue; + } + + if (inCodeFence) { + codeBlockLines.push(line); + continue; + } + + // H1/H2 → header block + const h2 = line.match(/^#{1,2}\s+(.+)/); + if (h2) { + flushSection(); + blocks.push({ + type: "header", + text: { + type: "plain_text", + text: stripInlineMd(h2[1]).slice(0, 150), + emoji: true, + }, + }); + continue; + } + + // H3–H6 → bold section + const h3 = line.match(/^#{3,6}\s+(.+)/); + if (h3) { + flushSection(); + blocks.push({ + type: "section", + text: { type: "mrkdwn", text: `*${convertInlineMd(h3[1])}*` }, + }); + continue; + } + + // Horizontal rule → divider (checked before list detection) + if (line.match(/^[-*_]{3,}\s*$/)) { + flushSection(); + blocks.push({ type: "divider" }); + continue; + } + + // Table separator row — skip + if (line.match(/^\|[\s:|-]+\|/)) { + continue; + } + + // Table data row — flatten to text + if (line.startsWith("|")) { + const cells = line + .split("|") + .filter((c) => c.trim()) + .map((c) => convertInlineMd(c.trim())); + sectionLines.push(cells.join(" | ")); + continue; + } + + sectionLines.push(line); + } + + flushSection(); + // Handle unclosed code fence gracefully + if (codeBlockLines.length > 0) flushCodeBlock(); + + // Slack enforces max 50 blocks + return blocks.slice(0, 50); +} + +/** + * Convert markdown to plain text by stripping all markup. + */ +export function markdownToPlainText(markdown: string): string { + return markdown + .replace(/^#{1,6}\s+/gm, "") + .replace(/\*\*(.+?)\*\*/g, "$1") + .replace(/\*(.+?)\*/g, "$1") + .replace(/_(.+?)_/g, "$1") + .replace(/~~(.+?)~~/g, "$1") + .replace(/\[(.+?)\]\(.+?\)/g, "$1") + .replace(/`(.+?)`/g, "$1") + .replace(/^\|[\s:|-]+\|.*$/gm, "") + .replace(/^[-*_]{3,}\s*$/gm, "") + .trim(); +} diff --git a/apps/webapp/package.json b/apps/webapp/package.json index ac0626768..32c94b3f8 100644 --- a/apps/webapp/package.json +++ b/apps/webapp/package.json @@ -11,7 +11,8 @@ "start": "node server.js", "typecheck": "tsc", "trigger:dev": "pnpm dlx trigger.dev@4.3.0 dev", - "trigger:deploy": "pnpm dlx trigger.dev@4.3.0 deploy" + "trigger:deploy": "pnpm dlx trigger.dev@4.3.0 deploy", + "test": "vitest run" }, "dependencies": { "@ai-sdk/amazon-bedrock": "3.0.47", @@ -211,7 +212,8 @@ "tsx": "4.20.6", "typescript": "5.8.3", "vite": "^6.0.0", - "vite-tsconfig-paths": "^4.2.1" + "vite-tsconfig-paths": "^4.2.1", + "vitest": "^1.6.1" }, "engines": { "node": ">=20.0.0" diff --git a/apps/webapp/vitest.config.ts b/apps/webapp/vitest.config.ts new file mode 100644 index 000000000..4215f3b73 --- /dev/null +++ b/apps/webapp/vitest.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + environment: "node", + include: ["app/**/*.test.ts"], + }, +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 96d49c0a7..8bb4eec53 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -622,6 +622,9 @@ importers: vite-tsconfig-paths: specifier: ^4.2.1 version: 4.3.2(typescript@5.8.3)(vite@6.3.5(@types/node@20.19.7)(jiti@2.4.2)(less@4.4.0)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.42.0)(tsx@4.20.6)(yaml@2.8.0)) + vitest: + specifier: ^1.6.1 + version: 1.6.1(@types/node@20.19.7)(less@4.4.0)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.42.0) packages/cli: dependencies: @@ -2896,6 +2899,10 @@ packages: resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} engines: {node: '>=18.0.0'} + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -2917,9 +2924,6 @@ packages: '@jridgewell/source-map@0.3.6': resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} - '@jridgewell/sourcemap-codec@1.5.0': - resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} - '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} @@ -5159,6 +5163,9 @@ packages: '@sideway/pinpoint@2.0.0': resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} + '@sinclair/typebox@0.27.10': + resolution: {integrity: sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==} + '@sindresorhus/merge-streams@2.3.0': resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} engines: {node: '>=18'} @@ -6889,6 +6896,21 @@ packages: resolution: {integrity: sha512-Fw28YZpRnA3cAHHDlkt7xQHiJ0fcL+NRcIqsocZQUSmbzeIKRpwttJjik5ZGanXP+vlA4SbTg+AbA3bP363l+w==} engines: {node: '>= 20'} + '@vitest/expect@1.6.1': + resolution: {integrity: sha512-jXL+9+ZNIJKruofqXuuTClf44eSpcHlgj3CiuNihUF3Ioujtmc0zIa3UJOW5RjDK1YLBJZnWBlPuqhYycLioog==} + + '@vitest/runner@1.6.1': + resolution: {integrity: sha512-3nSnYXkVkf3mXFfE7vVyPmi3Sazhb/2cfZGGs0JRzFsPFvAMBEcrweV1V1GsrstdXeKCTXlJbvnQwGWgEIHmOA==} + + '@vitest/snapshot@1.6.1': + resolution: {integrity: sha512-WvidQuWAzU2p95u8GAKlRMqMyN1yOJkGHnx3M1PL9Raf7AQ1kwLKg04ADlCa3+OXUZE7BceOhVZiuWAbzCKcUQ==} + + '@vitest/spy@1.6.1': + resolution: {integrity: sha512-MGcMmpGkZebsMZhbQKkAf9CX5zGvjkBTqf8Zx3ApYWXr3wG+QvEu2eXWfnIIWYSJExIp4V9FCKDEeygzkYrXMw==} + + '@vitest/utils@1.6.1': + resolution: {integrity: sha512-jOrrUvXM4Av9ZWiG1EajNto0u96kWAhJ1LmPmJhXXQx/32MecEKd10pOLYgS2BQx1TgkGhloPU1ArDW2vvaY6g==} + '@vue/compiler-core@3.5.26': resolution: {integrity: sha512-vXyI5GMfuoBCnv5ucIT7jhHKl55Y477yxP6fc4eUswjP8FG3FFVFd41eNDArR+Uk3QKn2Z85NavjaxLxOC19/w==} @@ -7183,6 +7205,9 @@ packages: resolution: {integrity: sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==} engines: {node: '>=12'} + assertion-error@1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + ast-types-flow@0.0.8: resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} @@ -7440,6 +7465,10 @@ packages: ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + chai@4.5.0: + resolution: {integrity: sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==} + engines: {node: '>=4'} + chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -7471,6 +7500,9 @@ packages: chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + check-error@1.0.3: + resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + cheerio-select@2.1.0: resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} @@ -8115,6 +8147,10 @@ packages: babel-plugin-macros: optional: true + deep-eql@4.1.4: + resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==} + engines: {node: '>=6'} + deep-equal@2.2.3: resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==} engines: {node: '>= 0.4'} @@ -8219,6 +8255,10 @@ packages: diff-match-patch@1.0.5: resolution: {integrity: sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==} + diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + diff@4.0.4: resolution: {integrity: sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==} engines: {node: '>=0.3.1'} @@ -9243,6 +9283,9 @@ packages: resolution: {integrity: sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==} engines: {node: '>=18'} + get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + get-intrinsic@1.3.0: resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} @@ -10031,6 +10074,9 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + js-tokens@9.0.1: + resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + js-types@4.0.0: resolution: {integrity: sha512-/c+n06zvqFQGxdz1BbElF7S3nEghjNchLN1TjQnk2j10HYDaUc57rcvl6BbnziTx8NQmrg0JOs/iwRpvcYaxjQ==} engines: {node: '>=18.20'} @@ -10273,6 +10319,10 @@ packages: resolution: {integrity: sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==} engines: {node: '>= 12.13.0'} + local-pkg@0.5.1: + resolution: {integrity: sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==} + engines: {node: '>=14'} + local-pkg@1.1.1: resolution: {integrity: sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==} engines: {node: '>=14'} @@ -10358,6 +10408,9 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true + loupe@2.3.7: + resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + lowercase-keys@3.0.0: resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -11249,6 +11302,10 @@ packages: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} + p-limit@5.0.0: + resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} + engines: {node: '>=18'} + p-locate@4.1.0: resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} engines: {node: '>=8'} @@ -11414,6 +11471,9 @@ packages: pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + pathval@1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + peberminta@0.9.0: resolution: {integrity: sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ==} @@ -11810,6 +11870,10 @@ packages: resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + pretty-hrtime@1.0.3: resolution: {integrity: sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==} engines: {node: '>= 0.8'} @@ -12086,6 +12150,9 @@ packages: react-is@17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + react-lifecycles-compat@3.0.4: resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==} @@ -12660,6 +12727,9 @@ packages: resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} engines: {node: '>= 0.4'} + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + sigma@3.0.2: resolution: {integrity: sha512-/BUbeOwPGruiBOm0YQQ6ZMcLIZ6tf/W+Jcm7dxZyAX0tK3WP9/sq7/NAWBxPIxVahdGjCJoGwej0Gdrv0DxlQQ==} @@ -12782,6 +12852,9 @@ packages: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + standard-as-callback@2.1.0: resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} @@ -12911,6 +12984,9 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + strip-literal@2.1.1: + resolution: {integrity: sha512-631UJ6O00eNGfMiWG78ck80dfBab8X6IVFB51jZK5Icd7XAs60Z5y7QdSd/wGIklnWvRbUNloVzhOKKmutxQ6Q==} + stripe@20.3.0: resolution: {integrity: sha512-DYzcmV1MfYhycr1GwjCjeQVYk9Gu8dpxyTlu7qeDCsuguug7oUTxPsUQuZeSf/OPzK7pofqobvOKVqAwlpgf/Q==} engines: {node: '>=16'} @@ -13116,6 +13192,9 @@ packages: tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} @@ -13134,6 +13213,14 @@ packages: tinykeys@3.0.0: resolution: {integrity: sha512-nazawuGv5zx6MuDfDY0rmfXjuOGhD5XU2z0GLURQ1nzl0RUe9OuCJq+0u8xxJZINHe+mr7nw8PWYYZ9WhMFujw==} + tinypool@0.8.4: + resolution: {integrity: sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==} + engines: {node: '>=14.0.0'} + + tinyspy@2.2.1: + resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==} + engines: {node: '>=14.0.0'} + tippy.js@6.3.7: resolution: {integrity: sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==} @@ -13345,6 +13432,10 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} + type-detect@4.1.0: + resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} + engines: {node: '>=4'} + type-fest@0.13.1: resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} engines: {node: '>=10'} @@ -13730,6 +13821,31 @@ packages: yaml: optional: true + vitest@1.6.1: + resolution: {integrity: sha512-Ljb1cnSJSivGN0LqXd/zmDbWEM0RNNg2t1QW/XUhYl/qPqyu7CsqeWtqQXHVaJsecLPuDoak2oJcZN2QoRIOag==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 1.6.1 + '@vitest/ui': 1.6.1 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + w3c-keyname@2.2.8: resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} @@ -13828,6 +13944,11 @@ packages: engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} hasBin: true + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + widest-line@5.0.0: resolution: {integrity: sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==} engines: {node: '>=18'} @@ -13989,6 +14110,10 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + yocto-queue@1.2.2: + resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} + engines: {node: '>=12.20'} + yoctocolors@2.1.1: resolution: {integrity: sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==} engines: {node: '>=18'} @@ -16757,6 +16882,10 @@ snapshots: dependencies: minipass: 7.1.2 + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.10 + '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -16765,7 +16894,7 @@ snapshots: '@jridgewell/gen-mapping@0.3.8': dependencies: '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/sourcemap-codec': 1.5.5 '@jridgewell/trace-mapping': 0.3.25 '@jridgewell/remapping@2.3.5': @@ -16783,14 +16912,12 @@ snapshots: '@jridgewell/trace-mapping': 0.3.31 optional: true - '@jridgewell/sourcemap-codec@1.5.0': {} - '@jridgewell/sourcemap-codec@1.5.5': {} '@jridgewell/trace-mapping@0.3.25': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/sourcemap-codec': 1.5.5 '@jridgewell/trace-mapping@0.3.31': dependencies: @@ -19409,6 +19536,8 @@ snapshots: '@sideway/pinpoint@2.0.0': {} + '@sinclair/typebox@0.27.10': {} + '@sindresorhus/merge-streams@2.3.0': {} '@sindresorhus/merge-streams@4.0.0': {} @@ -21701,6 +21830,35 @@ snapshots: '@vercel/oidc@3.1.0': {} + '@vitest/expect@1.6.1': + dependencies: + '@vitest/spy': 1.6.1 + '@vitest/utils': 1.6.1 + chai: 4.5.0 + + '@vitest/runner@1.6.1': + dependencies: + '@vitest/utils': 1.6.1 + p-limit: 5.0.0 + pathe: 1.1.2 + + '@vitest/snapshot@1.6.1': + dependencies: + magic-string: 0.30.21 + pathe: 1.1.2 + pretty-format: 29.7.0 + + '@vitest/spy@1.6.1': + dependencies: + tinyspy: 2.2.1 + + '@vitest/utils@1.6.1': + dependencies: + diff-sequences: 29.6.3 + estree-walker: 3.0.3 + loupe: 2.3.7 + pretty-format: 29.7.0 + '@vue/compiler-core@3.5.26': dependencies: '@babel/parser': 7.28.5 @@ -22074,6 +22232,8 @@ snapshots: arrify@3.0.0: {} + assertion-error@1.1.0: {} + ast-types-flow@0.0.8: {} astring@1.9.0: {} @@ -22413,6 +22573,16 @@ snapshots: ccount@2.0.1: {} + chai@4.5.0: + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.3 + deep-eql: 4.1.4 + get-func-name: 2.0.2 + loupe: 2.3.7 + pathval: 1.1.1 + type-detect: 4.1.0 + chalk@2.4.2: dependencies: ansi-styles: 3.2.1 @@ -22438,6 +22608,10 @@ snapshots: chardet@0.7.0: {} + check-error@1.0.3: + dependencies: + get-func-name: 2.0.2 + cheerio-select@2.1.0: dependencies: boolbase: 1.0.0 @@ -23107,6 +23281,10 @@ snapshots: dedent@1.6.0: {} + deep-eql@4.1.4: + dependencies: + type-detect: 4.1.0 + deep-equal@2.2.3: dependencies: array-buffer-byte-length: 1.0.2 @@ -23205,6 +23383,8 @@ snapshots: diff-match-patch@1.0.5: {} + diff-sequences@29.6.3: {} + diff@4.0.4: {} diff@5.2.0: {} @@ -24756,6 +24936,8 @@ snapshots: get-east-asian-width@1.4.0: {} + get-func-name@2.0.2: {} + get-intrinsic@1.3.0: dependencies: call-bind-apply-helpers: 1.0.2 @@ -25570,6 +25752,8 @@ snapshots: js-tokens@4.0.0: {} + js-tokens@9.0.1: {} + js-types@4.0.0: {} js-yaml@3.14.1: @@ -25797,6 +25981,11 @@ snapshots: loader-utils@3.3.1: {} + local-pkg@0.5.1: + dependencies: + mlly: 1.7.4 + pkg-types: 1.3.1 + local-pkg@1.1.1: dependencies: mlly: 1.7.4 @@ -25868,6 +26057,10 @@ snapshots: dependencies: js-tokens: 4.0.0 + loupe@2.3.7: + dependencies: + get-func-name: 2.0.2 + lowercase-keys@3.0.0: {} lowlight@3.3.0: @@ -25901,7 +26094,7 @@ snapshots: magic-string@0.30.17: dependencies: - '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/sourcemap-codec': 1.5.5 magic-string@0.30.21: dependencies: @@ -27109,6 +27302,10 @@ snapshots: dependencies: yocto-queue: 0.1.0 + p-limit@5.0.0: + dependencies: + yocto-queue: 1.2.2 + p-locate@4.1.0: dependencies: p-limit: 2.3.0 @@ -27261,6 +27458,8 @@ snapshots: pathe@2.0.3: {} + pathval@1.1.1: {} + peberminta@0.9.0: {} peek-stream@1.1.3: @@ -27600,6 +27799,12 @@ snapshots: ansi-styles: 5.2.0 react-is: 17.0.2 + pretty-format@29.7.0: + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.3.1 + pretty-hrtime@1.0.3: {} pretty-ms@7.0.1: @@ -28001,6 +28206,8 @@ snapshots: react-is@17.0.2: {} + react-is@18.3.1: {} + react-lifecycles-compat@3.0.4: {} react-markdown@10.1.0(@types/react@19.2.13)(react@19.2.4): @@ -28748,6 +28955,8 @@ snapshots: side-channel-map: 1.0.1 side-channel-weakmap: 1.0.2 + siginfo@2.0.0: {} + sigma@3.0.2(graphology-types@0.24.8): dependencies: events: 3.3.0 @@ -28906,6 +29115,8 @@ snapshots: dependencies: escape-string-regexp: 2.0.0 + stackback@0.0.2: {} + standard-as-callback@2.1.0: {} standardwebhooks@1.0.0: @@ -29055,6 +29266,10 @@ snapshots: strip-json-comments@3.1.1: {} + strip-literal@2.1.1: + dependencies: + js-tokens: 9.0.1 + stripe@20.3.0(@types/node@20.19.7): optionalDependencies: '@types/node': 20.19.7 @@ -29295,6 +29510,8 @@ snapshots: tiny-invariant@1.3.3: {} + tinybench@2.9.0: {} + tinyexec@0.3.2: {} tinyexec@1.0.2: {} @@ -29311,6 +29528,10 @@ snapshots: tinykeys@3.0.0: {} + tinypool@0.8.4: {} + + tinyspy@2.2.1: {} + tippy.js@6.3.7: dependencies: '@popperjs/core': 2.11.8 @@ -29553,6 +29774,8 @@ snapshots: dependencies: prelude-ls: 1.2.1 + type-detect@4.1.0: {} + type-fest@0.13.1: {} type-fest@0.20.2: {} @@ -29982,6 +30205,40 @@ snapshots: tsx: 4.20.6 yaml: 2.8.0 + vitest@1.6.1(@types/node@20.19.7)(less@4.4.0)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.42.0): + dependencies: + '@vitest/expect': 1.6.1 + '@vitest/runner': 1.6.1 + '@vitest/snapshot': 1.6.1 + '@vitest/spy': 1.6.1 + '@vitest/utils': 1.6.1 + acorn-walk: 8.3.4 + chai: 4.5.0 + debug: 4.4.3 + execa: 8.0.1 + local-pkg: 0.5.1 + magic-string: 0.30.21 + pathe: 1.1.2 + picocolors: 1.1.1 + std-env: 3.9.0 + strip-literal: 2.1.1 + tinybench: 2.9.0 + tinypool: 0.8.4 + vite: 5.4.19(@types/node@20.19.7)(less@4.4.0)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.42.0) + vite-node: 1.6.1(@types/node@20.19.7)(less@4.4.0)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.42.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 20.19.7 + transitivePeerDependencies: + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + w3c-keyname@2.2.8: {} watchpack@2.4.4: @@ -30156,6 +30413,11 @@ snapshots: dependencies: isexe: 2.0.0 + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + widest-line@5.0.0: dependencies: string-width: 7.2.0 @@ -30307,6 +30569,8 @@ snapshots: yocto-queue@0.1.0: {} + yocto-queue@1.2.2: {} + yoctocolors@2.1.1: {} yoga-layout@3.2.1: {} From 45e2bfdca2784437446e4ba5f145a83ee2285683 Mon Sep 17 00:00:00 2001 From: Manik Date: Wed, 25 Mar 2026 10:11:43 +0530 Subject: [PATCH 2/3] chore(slack): remove vitest test files and dependency Test framework not yet established in this project; keeping changes focused to formatting logic only. --- .../channels/slack/slack-format.test.ts | 272 ------------------ apps/webapp/package.json | 6 +- apps/webapp/vitest.config.ts | 8 - 3 files changed, 2 insertions(+), 284 deletions(-) delete mode 100644 apps/webapp/app/services/channels/slack/slack-format.test.ts delete mode 100644 apps/webapp/vitest.config.ts diff --git a/apps/webapp/app/services/channels/slack/slack-format.test.ts b/apps/webapp/app/services/channels/slack/slack-format.test.ts deleted file mode 100644 index 6ba34dad1..000000000 --- a/apps/webapp/app/services/channels/slack/slack-format.test.ts +++ /dev/null @@ -1,272 +0,0 @@ -import { describe, it, expect } from "vitest"; -import { - convertInlineMd, - convertMarkdownListsToSlackBullets, - boldKeyElements, - markdownToSlackBlocks, - markdownToPlainText, - chunkText, -} from "./slack-format"; - -// --------------------------------------------------------------------------- -// convertMarkdownListsToSlackBullets -// --------------------------------------------------------------------------- -describe("convertMarkdownListsToSlackBullets", () => { - it("converts hyphen list items to Slack bullets", () => { - const result = convertMarkdownListsToSlackBullets("- Item one\n- Item two"); - expect(result).toBe("• Item one\n• Item two"); - }); - - it("converts asterisk list items to Slack bullets", () => { - const result = convertMarkdownListsToSlackBullets("* Item one\n* Item two"); - expect(result).toBe("• Item one\n• Item two"); - }); - - it("preserves fenced code block contents unchanged", () => { - const input = "```\n- not a bullet\n* also not\n```"; - expect(convertMarkdownListsToSlackBullets(input)).toBe(input); - }); - - it("does not convert horizontal rules (--- / ***)", () => { - expect(convertMarkdownListsToSlackBullets("---")).toBe("---"); - expect(convertMarkdownListsToSlackBullets("***")).toBe("***"); - expect(convertMarkdownListsToSlackBullets("___")).toBe("___"); - }); - - it("preserves non-list lines unchanged", () => { - expect(convertMarkdownListsToSlackBullets("Hello world")).toBe("Hello world"); - }); - - it("handles indented list items", () => { - expect(convertMarkdownListsToSlackBullets(" - Indented item")).toBe( - " • Indented item" - ); - }); - - it("converts only list lines, leaving surrounding text intact", () => { - const input = "Intro text\n- Item\nTrailing text"; - const result = convertMarkdownListsToSlackBullets(input); - expect(result).toBe("Intro text\n• Item\nTrailing text"); - }); - - it("mixed list items in same block", () => { - const result = convertMarkdownListsToSlackBullets("- First\n* Second\n- Third"); - expect(result).toBe("• First\n• Second\n• Third"); - }); -}); - -// --------------------------------------------------------------------------- -// boldKeyElements -// --------------------------------------------------------------------------- -describe("boldKeyElements", () => { - it('bolds "Action Required"', () => { - expect(boldKeyElements("Action Required: please fix")).toContain( - "*Action Required*" - ); - }); - - it('bolds "action required" (case-insensitive)', () => { - expect(boldKeyElements("action required to proceed")).toContain( - "*action required*" - ); - }); - - it("bolds P1 as a standalone word", () => { - expect(boldKeyElements("This is P1 priority")).toBe("This is *P1* priority"); - }); - - it("bolds P2 as a standalone word", () => { - expect(boldKeyElements("P2 issue found")).toBe("*P2* issue found"); - }); - - it("bolds P3 as a standalone word", () => { - expect(boldKeyElements("Severity: P3")).toContain("*P3*"); - }); - - it("does not bold P1 inside inline code spans", () => { - expect(boldKeyElements("`P1 value`")).toBe("`P1 value`"); - }); - - it("does not bold Action Required inside Slack URL tokens", () => { - const url = ""; - expect(boldKeyElements(url)).toBe(url); - }); - - it("does not modify arbitrary Slack tokens", () => { - const token = ""; - expect(boldKeyElements(token)).toBe(token); - }); - - it("bolds a Key: Value pattern at the start of a line", () => { - const result = boldKeyElements("Status: active"); - expect(result).toContain("*Status*:"); - }); - - it("bolds a Key: Value pattern after a Slack bullet", () => { - const result = boldKeyElements("• Priority: high"); - expect(result).toContain("*Priority*:"); - }); - - it("does not double-bold already-bolded text", () => { - const input = "*Status*: active"; - expect(boldKeyElements(input)).toBe("*Status*: active"); - }); - - it("preserves text with no special elements unchanged", () => { - expect(boldKeyElements("just some regular text")).toBe( - "just some regular text" - ); - }); -}); - -// --------------------------------------------------------------------------- -// markdownToSlackBlocks — list conversion -// --------------------------------------------------------------------------- -describe("markdownToSlackBlocks — list conversion", () => { - it("converts markdown list items to Slack bullets in section blocks", () => { - const blocks = markdownToSlackBlocks("- Item one\n- Item two") as any[]; - expect(blocks).toHaveLength(1); - expect(blocks[0].text.text).toContain("• Item one"); - expect(blocks[0].text.text).toContain("• Item two"); - }); - - it("does not convert list syntax inside fenced code blocks", () => { - const input = "```\n- not a bullet\n```"; - const blocks = markdownToSlackBlocks(input) as any[]; - const text = blocks[0].text.text; - expect(text).toContain("- not a bullet"); - expect(text).not.toContain("• not a bullet"); - }); - - it("handles mixed content: text, list, then text", () => { - const input = "Intro\n- Item\nOutro"; - const blocks = markdownToSlackBlocks(input) as any[]; - const text = blocks[0].text.text; - expect(text).toContain("• Item"); - expect(text).toContain("Intro"); - expect(text).toContain("Outro"); - }); -}); - -// --------------------------------------------------------------------------- -// markdownToSlackBlocks — bolding -// --------------------------------------------------------------------------- -describe("markdownToSlackBlocks — bolding", () => { - it("bolds Action Required in section content", () => { - const blocks = markdownToSlackBlocks("Action Required: fix this") as any[]; - expect(blocks[0].text.text).toContain("*Action Required*"); - }); - - it("does not bold Action Required inside fenced code blocks", () => { - const blocks = markdownToSlackBlocks( - "```\nAction Required: fix\n```" - ) as any[]; - const text = blocks[0].text.text; - expect(text).not.toMatch(/\*Action Required\*/); - }); - - it("bolds P1/P2/P3 in section content", () => { - const blocks = markdownToSlackBlocks("Ticket is P2 priority") as any[]; - expect(blocks[0].text.text).toContain("*P2*"); - }); - - it("does not bold P1 inside a code block", () => { - const blocks = markdownToSlackBlocks("```\nP1 config\n```") as any[]; - expect(blocks[0].text.text).not.toContain("*P1*"); - }); -}); - -// --------------------------------------------------------------------------- -// markdownToSlackBlocks — existing behaviour preserved -// --------------------------------------------------------------------------- -describe("markdownToSlackBlocks — existing formatting preserved", () => { - it("creates a header block for H1", () => { - const blocks = markdownToSlackBlocks("# My Title") as any[]; - expect(blocks[0]).toMatchObject({ type: "header" }); - expect(blocks[0].text.text).toBe("My Title"); - }); - - it("creates a header block for H2", () => { - const blocks = markdownToSlackBlocks("## Sub Title") as any[]; - expect(blocks[0]).toMatchObject({ type: "header" }); - }); - - it("creates a bold section for H3", () => { - const blocks = markdownToSlackBlocks("### Section") as any[]; - expect(blocks[0].text.text).toBe("*Section*"); - }); - - it("creates a divider for horizontal rule", () => { - const blocks = markdownToSlackBlocks("---") as any[]; - expect(blocks[0]).toMatchObject({ type: "divider" }); - }); - - it("converts **bold** to Slack *bold*", () => { - const blocks = markdownToSlackBlocks("**important** word") as any[]; - expect(blocks[0].text.text).toContain("*important*"); - }); - - it("converts [text](url) to Slack ", () => { - const blocks = markdownToSlackBlocks( - "[click here](https://example.com)" - ) as any[]; - expect(blocks[0].text.text).toContain(""); - }); - - it("caps output at 50 blocks", () => { - const md = Array.from({ length: 60 }, (_, i) => `# Heading ${i}`).join("\n"); - const blocks = markdownToSlackBlocks(md); - expect(blocks.length).toBeLessThanOrEqual(50); - }); -}); - -// --------------------------------------------------------------------------- -// convertInlineMd -// --------------------------------------------------------------------------- -describe("convertInlineMd", () => { - it("converts **bold** to *bold*", () => { - expect(convertInlineMd("**hello**")).toBe("*hello*"); - }); - - it("converts [text](url) to ", () => { - expect(convertInlineMd("[click](https://x.com)")).toBe( - "" - ); - }); - - it("converts ~~strike~~ to ~strike~", () => { - expect(convertInlineMd("~~del~~")).toBe("~del~"); - }); -}); - -// --------------------------------------------------------------------------- -// markdownToPlainText -// --------------------------------------------------------------------------- -describe("markdownToPlainText", () => { - it("strips heading markers", () => { - expect(markdownToPlainText("# Title")).toBe("Title"); - }); - - it("strips bold markers", () => { - expect(markdownToPlainText("**bold**")).toBe("bold"); - }); - - it("strips link syntax, keeping text", () => { - expect(markdownToPlainText("[click](https://x.com)")).toBe("click"); - }); -}); - -// --------------------------------------------------------------------------- -// chunkText -// --------------------------------------------------------------------------- -describe("chunkText", () => { - it("returns single element for short text", () => { - expect(chunkText("hello", 100)).toEqual(["hello"]); - }); - - it("splits text longer than max", () => { - const long = "a".repeat(3001); - const chunks = chunkText(long, 3000); - expect(chunks.length).toBeGreaterThan(1); - }); -}); diff --git a/apps/webapp/package.json b/apps/webapp/package.json index 32c94b3f8..ac0626768 100644 --- a/apps/webapp/package.json +++ b/apps/webapp/package.json @@ -11,8 +11,7 @@ "start": "node server.js", "typecheck": "tsc", "trigger:dev": "pnpm dlx trigger.dev@4.3.0 dev", - "trigger:deploy": "pnpm dlx trigger.dev@4.3.0 deploy", - "test": "vitest run" + "trigger:deploy": "pnpm dlx trigger.dev@4.3.0 deploy" }, "dependencies": { "@ai-sdk/amazon-bedrock": "3.0.47", @@ -212,8 +211,7 @@ "tsx": "4.20.6", "typescript": "5.8.3", "vite": "^6.0.0", - "vite-tsconfig-paths": "^4.2.1", - "vitest": "^1.6.1" + "vite-tsconfig-paths": "^4.2.1" }, "engines": { "node": ">=20.0.0" diff --git a/apps/webapp/vitest.config.ts b/apps/webapp/vitest.config.ts deleted file mode 100644 index 4215f3b73..000000000 --- a/apps/webapp/vitest.config.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { defineConfig } from "vitest/config"; - -export default defineConfig({ - test: { - environment: "node", - include: ["app/**/*.test.ts"], - }, -}); From e031e2f447956afd7c557f53c406e22ecf1dc287 Mon Sep 17 00:00:00 2001 From: Manik Date: Wed, 25 Mar 2026 10:14:20 +0530 Subject: [PATCH 3/3] chore: remove vitest entries from pnpm-lock.yaml --- pnpm-lock.yaml | 269 ------------------------------------------------- 1 file changed, 269 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8bb4eec53..d55aa6f59 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -622,9 +622,6 @@ importers: vite-tsconfig-paths: specifier: ^4.2.1 version: 4.3.2(typescript@5.8.3)(vite@6.3.5(@types/node@20.19.7)(jiti@2.4.2)(less@4.4.0)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.42.0)(tsx@4.20.6)(yaml@2.8.0)) - vitest: - specifier: ^1.6.1 - version: 1.6.1(@types/node@20.19.7)(less@4.4.0)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.42.0) packages/cli: dependencies: @@ -2899,10 +2896,6 @@ packages: resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} engines: {node: '>=18.0.0'} - '@jest/schemas@29.6.3': - resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -5163,9 +5156,6 @@ packages: '@sideway/pinpoint@2.0.0': resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} - '@sinclair/typebox@0.27.10': - resolution: {integrity: sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==} - '@sindresorhus/merge-streams@2.3.0': resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} engines: {node: '>=18'} @@ -6896,21 +6886,6 @@ packages: resolution: {integrity: sha512-Fw28YZpRnA3cAHHDlkt7xQHiJ0fcL+NRcIqsocZQUSmbzeIKRpwttJjik5ZGanXP+vlA4SbTg+AbA3bP363l+w==} engines: {node: '>= 20'} - '@vitest/expect@1.6.1': - resolution: {integrity: sha512-jXL+9+ZNIJKruofqXuuTClf44eSpcHlgj3CiuNihUF3Ioujtmc0zIa3UJOW5RjDK1YLBJZnWBlPuqhYycLioog==} - - '@vitest/runner@1.6.1': - resolution: {integrity: sha512-3nSnYXkVkf3mXFfE7vVyPmi3Sazhb/2cfZGGs0JRzFsPFvAMBEcrweV1V1GsrstdXeKCTXlJbvnQwGWgEIHmOA==} - - '@vitest/snapshot@1.6.1': - resolution: {integrity: sha512-WvidQuWAzU2p95u8GAKlRMqMyN1yOJkGHnx3M1PL9Raf7AQ1kwLKg04ADlCa3+OXUZE7BceOhVZiuWAbzCKcUQ==} - - '@vitest/spy@1.6.1': - resolution: {integrity: sha512-MGcMmpGkZebsMZhbQKkAf9CX5zGvjkBTqf8Zx3ApYWXr3wG+QvEu2eXWfnIIWYSJExIp4V9FCKDEeygzkYrXMw==} - - '@vitest/utils@1.6.1': - resolution: {integrity: sha512-jOrrUvXM4Av9ZWiG1EajNto0u96kWAhJ1LmPmJhXXQx/32MecEKd10pOLYgS2BQx1TgkGhloPU1ArDW2vvaY6g==} - '@vue/compiler-core@3.5.26': resolution: {integrity: sha512-vXyI5GMfuoBCnv5ucIT7jhHKl55Y477yxP6fc4eUswjP8FG3FFVFd41eNDArR+Uk3QKn2Z85NavjaxLxOC19/w==} @@ -7205,9 +7180,6 @@ packages: resolution: {integrity: sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==} engines: {node: '>=12'} - assertion-error@1.1.0: - resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} - ast-types-flow@0.0.8: resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} @@ -7465,10 +7437,6 @@ packages: ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} - chai@4.5.0: - resolution: {integrity: sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==} - engines: {node: '>=4'} - chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -7500,9 +7468,6 @@ packages: chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} - check-error@1.0.3: - resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} - cheerio-select@2.1.0: resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} @@ -8147,10 +8112,6 @@ packages: babel-plugin-macros: optional: true - deep-eql@4.1.4: - resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==} - engines: {node: '>=6'} - deep-equal@2.2.3: resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==} engines: {node: '>= 0.4'} @@ -8255,10 +8216,6 @@ packages: diff-match-patch@1.0.5: resolution: {integrity: sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==} - diff-sequences@29.6.3: - resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - diff@4.0.4: resolution: {integrity: sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==} engines: {node: '>=0.3.1'} @@ -9283,9 +9240,6 @@ packages: resolution: {integrity: sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==} engines: {node: '>=18'} - get-func-name@2.0.2: - resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} - get-intrinsic@1.3.0: resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} @@ -10074,9 +10028,6 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - js-tokens@9.0.1: - resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} - js-types@4.0.0: resolution: {integrity: sha512-/c+n06zvqFQGxdz1BbElF7S3nEghjNchLN1TjQnk2j10HYDaUc57rcvl6BbnziTx8NQmrg0JOs/iwRpvcYaxjQ==} engines: {node: '>=18.20'} @@ -10319,10 +10270,6 @@ packages: resolution: {integrity: sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==} engines: {node: '>= 12.13.0'} - local-pkg@0.5.1: - resolution: {integrity: sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==} - engines: {node: '>=14'} - local-pkg@1.1.1: resolution: {integrity: sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==} engines: {node: '>=14'} @@ -10408,9 +10355,6 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true - loupe@2.3.7: - resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} - lowercase-keys@3.0.0: resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -11302,10 +11246,6 @@ packages: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} - p-limit@5.0.0: - resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} - engines: {node: '>=18'} - p-locate@4.1.0: resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} engines: {node: '>=8'} @@ -11471,9 +11411,6 @@ packages: pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - pathval@1.1.1: - resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} - peberminta@0.9.0: resolution: {integrity: sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ==} @@ -11870,10 +11807,6 @@ packages: resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} - pretty-format@29.7.0: - resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - pretty-hrtime@1.0.3: resolution: {integrity: sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==} engines: {node: '>= 0.8'} @@ -12150,9 +12083,6 @@ packages: react-is@17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} - react-is@18.3.1: - resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} - react-lifecycles-compat@3.0.4: resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==} @@ -12727,9 +12657,6 @@ packages: resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} engines: {node: '>= 0.4'} - siginfo@2.0.0: - resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} - sigma@3.0.2: resolution: {integrity: sha512-/BUbeOwPGruiBOm0YQQ6ZMcLIZ6tf/W+Jcm7dxZyAX0tK3WP9/sq7/NAWBxPIxVahdGjCJoGwej0Gdrv0DxlQQ==} @@ -12852,9 +12779,6 @@ packages: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} - stackback@0.0.2: - resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - standard-as-callback@2.1.0: resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} @@ -12984,9 +12908,6 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - strip-literal@2.1.1: - resolution: {integrity: sha512-631UJ6O00eNGfMiWG78ck80dfBab8X6IVFB51jZK5Icd7XAs60Z5y7QdSd/wGIklnWvRbUNloVzhOKKmutxQ6Q==} - stripe@20.3.0: resolution: {integrity: sha512-DYzcmV1MfYhycr1GwjCjeQVYk9Gu8dpxyTlu7qeDCsuguug7oUTxPsUQuZeSf/OPzK7pofqobvOKVqAwlpgf/Q==} engines: {node: '>=16'} @@ -13192,9 +13113,6 @@ packages: tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} - tinybench@2.9.0: - resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} @@ -13213,14 +13131,6 @@ packages: tinykeys@3.0.0: resolution: {integrity: sha512-nazawuGv5zx6MuDfDY0rmfXjuOGhD5XU2z0GLURQ1nzl0RUe9OuCJq+0u8xxJZINHe+mr7nw8PWYYZ9WhMFujw==} - tinypool@0.8.4: - resolution: {integrity: sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==} - engines: {node: '>=14.0.0'} - - tinyspy@2.2.1: - resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==} - engines: {node: '>=14.0.0'} - tippy.js@6.3.7: resolution: {integrity: sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==} @@ -13432,10 +13342,6 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} - type-detect@4.1.0: - resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} - engines: {node: '>=4'} - type-fest@0.13.1: resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} engines: {node: '>=10'} @@ -13821,31 +13727,6 @@ packages: yaml: optional: true - vitest@1.6.1: - resolution: {integrity: sha512-Ljb1cnSJSivGN0LqXd/zmDbWEM0RNNg2t1QW/XUhYl/qPqyu7CsqeWtqQXHVaJsecLPuDoak2oJcZN2QoRIOag==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@edge-runtime/vm': '*' - '@types/node': ^18.0.0 || >=20.0.0 - '@vitest/browser': 1.6.1 - '@vitest/ui': 1.6.1 - happy-dom: '*' - jsdom: '*' - peerDependenciesMeta: - '@edge-runtime/vm': - optional: true - '@types/node': - optional: true - '@vitest/browser': - optional: true - '@vitest/ui': - optional: true - happy-dom: - optional: true - jsdom: - optional: true - w3c-keyname@2.2.8: resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} @@ -13944,11 +13825,6 @@ packages: engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} hasBin: true - why-is-node-running@2.3.0: - resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} - engines: {node: '>=8'} - hasBin: true - widest-line@5.0.0: resolution: {integrity: sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==} engines: {node: '>=18'} @@ -14110,10 +13986,6 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} - yocto-queue@1.2.2: - resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} - engines: {node: '>=12.20'} - yoctocolors@2.1.1: resolution: {integrity: sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==} engines: {node: '>=18'} @@ -16882,10 +16754,6 @@ snapshots: dependencies: minipass: 7.1.2 - '@jest/schemas@29.6.3': - dependencies: - '@sinclair/typebox': 0.27.10 - '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -19536,8 +19404,6 @@ snapshots: '@sideway/pinpoint@2.0.0': {} - '@sinclair/typebox@0.27.10': {} - '@sindresorhus/merge-streams@2.3.0': {} '@sindresorhus/merge-streams@4.0.0': {} @@ -21830,35 +21696,6 @@ snapshots: '@vercel/oidc@3.1.0': {} - '@vitest/expect@1.6.1': - dependencies: - '@vitest/spy': 1.6.1 - '@vitest/utils': 1.6.1 - chai: 4.5.0 - - '@vitest/runner@1.6.1': - dependencies: - '@vitest/utils': 1.6.1 - p-limit: 5.0.0 - pathe: 1.1.2 - - '@vitest/snapshot@1.6.1': - dependencies: - magic-string: 0.30.21 - pathe: 1.1.2 - pretty-format: 29.7.0 - - '@vitest/spy@1.6.1': - dependencies: - tinyspy: 2.2.1 - - '@vitest/utils@1.6.1': - dependencies: - diff-sequences: 29.6.3 - estree-walker: 3.0.3 - loupe: 2.3.7 - pretty-format: 29.7.0 - '@vue/compiler-core@3.5.26': dependencies: '@babel/parser': 7.28.5 @@ -22232,8 +22069,6 @@ snapshots: arrify@3.0.0: {} - assertion-error@1.1.0: {} - ast-types-flow@0.0.8: {} astring@1.9.0: {} @@ -22573,16 +22408,6 @@ snapshots: ccount@2.0.1: {} - chai@4.5.0: - dependencies: - assertion-error: 1.1.0 - check-error: 1.0.3 - deep-eql: 4.1.4 - get-func-name: 2.0.2 - loupe: 2.3.7 - pathval: 1.1.1 - type-detect: 4.1.0 - chalk@2.4.2: dependencies: ansi-styles: 3.2.1 @@ -22608,10 +22433,6 @@ snapshots: chardet@0.7.0: {} - check-error@1.0.3: - dependencies: - get-func-name: 2.0.2 - cheerio-select@2.1.0: dependencies: boolbase: 1.0.0 @@ -23281,10 +23102,6 @@ snapshots: dedent@1.6.0: {} - deep-eql@4.1.4: - dependencies: - type-detect: 4.1.0 - deep-equal@2.2.3: dependencies: array-buffer-byte-length: 1.0.2 @@ -23383,8 +23200,6 @@ snapshots: diff-match-patch@1.0.5: {} - diff-sequences@29.6.3: {} - diff@4.0.4: {} diff@5.2.0: {} @@ -24936,8 +24751,6 @@ snapshots: get-east-asian-width@1.4.0: {} - get-func-name@2.0.2: {} - get-intrinsic@1.3.0: dependencies: call-bind-apply-helpers: 1.0.2 @@ -25752,8 +25565,6 @@ snapshots: js-tokens@4.0.0: {} - js-tokens@9.0.1: {} - js-types@4.0.0: {} js-yaml@3.14.1: @@ -25981,11 +25792,6 @@ snapshots: loader-utils@3.3.1: {} - local-pkg@0.5.1: - dependencies: - mlly: 1.7.4 - pkg-types: 1.3.1 - local-pkg@1.1.1: dependencies: mlly: 1.7.4 @@ -26057,10 +25863,6 @@ snapshots: dependencies: js-tokens: 4.0.0 - loupe@2.3.7: - dependencies: - get-func-name: 2.0.2 - lowercase-keys@3.0.0: {} lowlight@3.3.0: @@ -27302,10 +27104,6 @@ snapshots: dependencies: yocto-queue: 0.1.0 - p-limit@5.0.0: - dependencies: - yocto-queue: 1.2.2 - p-locate@4.1.0: dependencies: p-limit: 2.3.0 @@ -27458,8 +27256,6 @@ snapshots: pathe@2.0.3: {} - pathval@1.1.1: {} - peberminta@0.9.0: {} peek-stream@1.1.3: @@ -27799,12 +27595,6 @@ snapshots: ansi-styles: 5.2.0 react-is: 17.0.2 - pretty-format@29.7.0: - dependencies: - '@jest/schemas': 29.6.3 - ansi-styles: 5.2.0 - react-is: 18.3.1 - pretty-hrtime@1.0.3: {} pretty-ms@7.0.1: @@ -28206,8 +27996,6 @@ snapshots: react-is@17.0.2: {} - react-is@18.3.1: {} - react-lifecycles-compat@3.0.4: {} react-markdown@10.1.0(@types/react@19.2.13)(react@19.2.4): @@ -28955,8 +28743,6 @@ snapshots: side-channel-map: 1.0.1 side-channel-weakmap: 1.0.2 - siginfo@2.0.0: {} - sigma@3.0.2(graphology-types@0.24.8): dependencies: events: 3.3.0 @@ -29115,8 +28901,6 @@ snapshots: dependencies: escape-string-regexp: 2.0.0 - stackback@0.0.2: {} - standard-as-callback@2.1.0: {} standardwebhooks@1.0.0: @@ -29266,10 +29050,6 @@ snapshots: strip-json-comments@3.1.1: {} - strip-literal@2.1.1: - dependencies: - js-tokens: 9.0.1 - stripe@20.3.0(@types/node@20.19.7): optionalDependencies: '@types/node': 20.19.7 @@ -29510,8 +29290,6 @@ snapshots: tiny-invariant@1.3.3: {} - tinybench@2.9.0: {} - tinyexec@0.3.2: {} tinyexec@1.0.2: {} @@ -29528,10 +29306,6 @@ snapshots: tinykeys@3.0.0: {} - tinypool@0.8.4: {} - - tinyspy@2.2.1: {} - tippy.js@6.3.7: dependencies: '@popperjs/core': 2.11.8 @@ -29774,8 +29548,6 @@ snapshots: dependencies: prelude-ls: 1.2.1 - type-detect@4.1.0: {} - type-fest@0.13.1: {} type-fest@0.20.2: {} @@ -30205,40 +29977,6 @@ snapshots: tsx: 4.20.6 yaml: 2.8.0 - vitest@1.6.1(@types/node@20.19.7)(less@4.4.0)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.42.0): - dependencies: - '@vitest/expect': 1.6.1 - '@vitest/runner': 1.6.1 - '@vitest/snapshot': 1.6.1 - '@vitest/spy': 1.6.1 - '@vitest/utils': 1.6.1 - acorn-walk: 8.3.4 - chai: 4.5.0 - debug: 4.4.3 - execa: 8.0.1 - local-pkg: 0.5.1 - magic-string: 0.30.21 - pathe: 1.1.2 - picocolors: 1.1.1 - std-env: 3.9.0 - strip-literal: 2.1.1 - tinybench: 2.9.0 - tinypool: 0.8.4 - vite: 5.4.19(@types/node@20.19.7)(less@4.4.0)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.42.0) - vite-node: 1.6.1(@types/node@20.19.7)(less@4.4.0)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.42.0) - why-is-node-running: 2.3.0 - optionalDependencies: - '@types/node': 20.19.7 - transitivePeerDependencies: - - less - - lightningcss - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - w3c-keyname@2.2.8: {} watchpack@2.4.4: @@ -30413,11 +30151,6 @@ snapshots: dependencies: isexe: 2.0.0 - why-is-node-running@2.3.0: - dependencies: - siginfo: 2.0.0 - stackback: 0.0.2 - widest-line@5.0.0: dependencies: string-width: 7.2.0 @@ -30569,8 +30302,6 @@ snapshots: yocto-queue@0.1.0: {} - yocto-queue@1.2.2: {} - yoctocolors@2.1.1: {} yoga-layout@3.2.1: {}