diff --git a/__tests__/flowcharts-get-route.test.ts b/__tests__/flowcharts-get-route.test.ts
new file mode 100644
index 0000000..03623f8
--- /dev/null
+++ b/__tests__/flowcharts-get-route.test.ts
@@ -0,0 +1,49 @@
+import { GET } from '@/app/api/flowcharts/[id]/route'
+
+const flowchartsQuery = {
+ select: jest.fn().mockReturnThis(),
+ eq: jest.fn().mockReturnThis(),
+ single: jest.fn(),
+}
+const versionsQuery = {
+ select: jest.fn().mockReturnThis(),
+ eq: jest.fn().mockReturnThis(),
+ order: jest.fn().mockReturnThis(),
+ limit: jest.fn().mockReturnThis(),
+ single: jest.fn(),
+}
+
+jest.mock('@/lib/supabase/server', () => ({
+ createClient: jest.fn(async () => ({
+ auth: { getUser: jest.fn(async () => ({ data: { user: { id: 'user-1' } }, error: null })) },
+ from: (table: string) => (table === 'flowcharts' ? flowchartsQuery : versionsQuery),
+ })),
+}))
+
+describe('GET /api/flowcharts/[id]', () => {
+ it('issues the flowchart and version lookups concurrently', async () => {
+ let flowchartResolved = false
+ let versionStartedBeforeFlowchartResolved = false
+
+ flowchartsQuery.single.mockImplementation(
+ () =>
+ new Promise(resolve =>
+ setTimeout(() => {
+ flowchartResolved = true
+ resolve({ data: { id: 'fc-1', user_id: 'user-1' }, error: null })
+ }, 20)
+ )
+ )
+ versionsQuery.single.mockImplementation(() => {
+ versionStartedBeforeFlowchartResolved = !flowchartResolved
+ return Promise.resolve({ data: { code: 'x', version_number: 3 }, error: null })
+ })
+
+ const request = new Request('http://localhost/api/flowcharts/fc-1')
+ const response = await GET(request, { params: Promise.resolve({ id: 'fc-1' }) })
+ const body = await response.json()
+
+ expect(versionStartedBeforeFlowchartResolved).toBe(true)
+ expect(body).toMatchObject({ id: 'fc-1', code: 'x', version_number: 3 })
+ })
+})
diff --git a/app/api/flowcharts/[id]/route.ts b/app/api/flowcharts/[id]/route.ts
index fc94408..cef6c46 100644
--- a/app/api/flowcharts/[id]/route.ts
+++ b/app/api/flowcharts/[id]/route.ts
@@ -11,17 +11,18 @@ export async function GET(_req: Request, { params }: Params) {
const { data: { user }, error: authErr } = await supabase.auth.getUser()
if (authErr || !user) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
- const { data: fc, error } = await supabase
- .from('flowcharts').select('*').eq('id', id).eq('user_id', user.id).single()
+ const [{ data: fc, error }, versionRes] = await Promise.all([
+ supabase.from('flowcharts').select('*').eq('id', id).eq('user_id', user.id).single(),
+ supabase
+ .from('flowchart_versions')
+ .select('code, version_number')
+ .eq('flowchart_id', id)
+ .order('version_number', { ascending: false })
+ .limit(1)
+ .single(),
+ ])
if (error || !fc) return NextResponse.json({ error: 'Not found' }, { status: 404 })
- const versionRes = await supabase
- .from('flowchart_versions')
- .select('code, version_number')
- .eq('flowchart_id', id)
- .order('version_number', { ascending: false })
- .limit(1)
- .single()
const version = versionRes.data as { code: string; version_number: number } | null
return NextResponse.json(Object.assign({}, fc, { code: version?.code ?? '', version_number: version?.version_number ?? 0 }))
diff --git a/components/editor/CodeEditor.tsx b/components/editor/CodeEditor.tsx
index 49067ff..d0a177e 100644
--- a/components/editor/CodeEditor.tsx
+++ b/components/editor/CodeEditor.tsx
@@ -1,5 +1,6 @@
'use client'
-import MonacoEditor, { loader } from '@monaco-editor/react'
+import dynamic from 'next/dynamic'
+import { loader } from '@monaco-editor/react'
import type { editor } from 'monaco-editor'
import type { SupportedLanguage } from '@/lib/parser'
@@ -8,6 +9,11 @@ import type { SupportedLanguage } from '@/lib/parser'
// app's CSP (script-src 'self') blocks.
loader.config({ paths: { vs: '/monaco/min/vs' } })
+const MonacoEditor = dynamic(() => import('@monaco-editor/react').then(m => m.default), {
+ ssr: false,
+ loading: () =>
Loading editor…
,
+})
+
interface Props {
value: string
language: SupportedLanguage
diff --git a/components/editor/FlowchartPanel.tsx b/components/editor/FlowchartPanel.tsx
index a09f327..8439f34 100644
--- a/components/editor/FlowchartPanel.tsx
+++ b/components/editor/FlowchartPanel.tsx
@@ -1,8 +1,19 @@
'use client'
import { useEffect, useRef, useState } from 'react'
-import mermaid from 'mermaid'
+import type MermaidType from 'mermaid'
-mermaid.initialize({ startOnLoad: false, theme: 'dark', flowchart: { useMaxWidth: true, curve: 'basis' } })
+// Deferred so `mermaid` isn't bundled into the initial route chunk — it's
+// only fetched once this panel actually mounts and renders a diagram.
+let mermaidPromise: Promise | null = null
+function loadMermaid() {
+ if (!mermaidPromise) {
+ mermaidPromise = import('mermaid').then(m => {
+ m.default.initialize({ startOnLoad: false, theme: 'dark', flowchart: { useMaxWidth: true, curve: 'basis' } })
+ return m.default
+ })
+ }
+ return mermaidPromise
+}
interface Props {
mermaidCode: string
@@ -16,10 +27,13 @@ export function FlowchartPanel({ mermaidCode, panelRef }: Props) {
useEffect(() => {
if (!mermaidCode) return
+ let cancelled = false
const id = `mermaid-${Date.now()}-${idRef.current++}`
- mermaid.render(id, mermaidCode)
- .then(({ svg }) => { setSvg(svg); setError('') })
- .catch(err => setError(err.message))
+ loadMermaid()
+ .then(mermaid => mermaid.render(id, mermaidCode))
+ .then(({ svg }) => { if (!cancelled) { setSvg(svg); setError('') } })
+ .catch(err => { if (!cancelled) setError(err.message) })
+ return () => { cancelled = true }
}, [mermaidCode])
return (
diff --git a/components/share/ShareView.tsx b/components/share/ShareView.tsx
index acf1274..65917c2 100644
--- a/components/share/ShareView.tsx
+++ b/components/share/ShareView.tsx
@@ -1,7 +1,7 @@
'use client'
import { useEffect, useRef, useState } from 'react'
import { useRouter } from 'next/navigation'
-import MonacoEditor from '@monaco-editor/react'
+import dynamic from 'next/dynamic'
import { toPng } from 'html-to-image'
import { codeToMermaid } from '@/lib/parser'
import type { SupportedLanguage } from '@/lib/parser'
@@ -10,6 +10,11 @@ import { EditorLayout } from '@/components/editor/EditorLayout'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
+const MonacoEditor = dynamic(() => import('@monaco-editor/react').then(m => m.default), {
+ ssr: false,
+ loading: () => Loading editor…
,
+})
+
interface Props {
flowchart: { id: string; title: string; language: string; code: string; share_id: string | null }
currentUserId: string | null
diff --git a/components/ui/DottedSurface.tsx b/components/ui/DottedSurface.tsx
index b96db5b..14ec2b3 100644
--- a/components/ui/DottedSurface.tsx
+++ b/components/ui/DottedSurface.tsx
@@ -1,148 +1,13 @@
-'use client';
-import { cn } from '@/lib/utils';
-import React, { useEffect, useRef } from 'react';
-import * as THREE from 'three';
+'use client'
-type DottedSurfaceProps = Omit, 'ref'>;
+import dynamic from 'next/dynamic'
+import type { DottedSurfaceCanvasProps } from './DottedSurfaceCanvas'
-export function DottedSurface({ className, ...props }: DottedSurfaceProps) {
+const DottedSurfaceCanvas = dynamic(
+ () => import('./DottedSurfaceCanvas').then(mod => mod.DottedSurfaceCanvas),
+ { ssr: false }
+)
- const containerRef = useRef(null);
- const sceneRef = useRef<{
- scene: THREE.Scene;
- camera: THREE.PerspectiveCamera;
- renderer: THREE.WebGLRenderer;
- particles: THREE.Points[];
- animationId: number;
- count: number;
- } | null>(null);
-
- useEffect(() => {
- if (!containerRef.current) return;
-
- const SEPARATION = 150;
- const AMOUNTX = 40;
- const AMOUNTY = 60;
-
- const scene = new THREE.Scene();
- scene.fog = new THREE.Fog(0xffffff, 2000, 10000);
-
- const camera = new THREE.PerspectiveCamera(
- 60,
- window.innerWidth / window.innerHeight,
- 1,
- 10000,
- );
- camera.position.set(0, 355, 1220);
-
- const renderer = new THREE.WebGLRenderer({
- alpha: true,
- antialias: true,
- });
- renderer.setPixelRatio(window.devicePixelRatio);
- renderer.setSize(window.innerWidth, window.innerHeight);
- renderer.setClearColor(scene.fog.color, 0);
-
- containerRef.current.appendChild(renderer.domElement);
-
- const positions: number[] = [];
- const colors: number[] = [];
- const geometry = new THREE.BufferGeometry();
-
- for (let ix = 0; ix < AMOUNTX; ix++) {
- for (let iy = 0; iy < AMOUNTY; iy++) {
- positions.push(
- ix * SEPARATION - (AMOUNTX * SEPARATION) / 2,
- 0,
- iy * SEPARATION - (AMOUNTY * SEPARATION) / 2,
- );
- colors.push(0.78, 0.78, 0.78);
- }
- }
-
- geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
- geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));
-
- const material = new THREE.PointsMaterial({
- size: 8,
- vertexColors: true,
- transparent: true,
- opacity: 0.45,
- sizeAttenuation: true,
- });
-
- const points = new THREE.Points(geometry, material);
- scene.add(points);
-
- let count = 0;
- let animationId = 0;
-
- const animate = () => {
- animationId = requestAnimationFrame(animate);
-
- const positionAttribute = geometry.attributes.position;
- const pos = positionAttribute.array as Float32Array;
-
- let i = 0;
- for (let ix = 0; ix < AMOUNTX; ix++) {
- for (let iy = 0; iy < AMOUNTY; iy++) {
- pos[i * 3 + 1] =
- Math.sin((ix + count) * 0.3) * 50 +
- Math.sin((iy + count) * 0.5) * 50;
- i++;
- }
- }
-
- positionAttribute.needsUpdate = true;
- renderer.render(scene, camera);
- count += 0.1;
- };
-
- const handleResize = () => {
- camera.aspect = window.innerWidth / window.innerHeight;
- camera.updateProjectionMatrix();
- renderer.setSize(window.innerWidth, window.innerHeight);
- };
-
- window.addEventListener('resize', handleResize);
- const reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
- if (reducedMotion) {
- renderer.render(scene, camera);
- } else {
- animate();
- }
-
- sceneRef.current = { scene, camera, renderer, particles: [points], animationId, count };
-
- const container = containerRef.current;
-
- return () => {
- window.removeEventListener('resize', handleResize);
- if (sceneRef.current) {
- cancelAnimationFrame(sceneRef.current.animationId);
- sceneRef.current.scene.traverse((object) => {
- if (object instanceof THREE.Points) {
- object.geometry.dispose();
- if (Array.isArray(object.material)) {
- object.material.forEach((m) => m.dispose());
- } else {
- object.material.dispose();
- }
- }
- });
- sceneRef.current.renderer.dispose();
- if (container && sceneRef.current.renderer.domElement) {
- container.removeChild(sceneRef.current.renderer.domElement);
- }
- }
- };
- }, []);
-
- return (
-
- );
+export function DottedSurface(props: DottedSurfaceCanvasProps) {
+ return
}
diff --git a/components/ui/DottedSurfaceCanvas.tsx b/components/ui/DottedSurfaceCanvas.tsx
new file mode 100644
index 0000000..0d7f2f2
--- /dev/null
+++ b/components/ui/DottedSurfaceCanvas.tsx
@@ -0,0 +1,148 @@
+'use client';
+import { cn } from '@/lib/utils';
+import React, { useEffect, useRef } from 'react';
+import * as THREE from 'three';
+
+export type DottedSurfaceCanvasProps = Omit, 'ref'>;
+
+export function DottedSurfaceCanvas({ className, ...props }: DottedSurfaceCanvasProps) {
+
+ const containerRef = useRef(null);
+ const sceneRef = useRef<{
+ scene: THREE.Scene;
+ camera: THREE.PerspectiveCamera;
+ renderer: THREE.WebGLRenderer;
+ particles: THREE.Points[];
+ animationId: number;
+ count: number;
+ } | null>(null);
+
+ useEffect(() => {
+ if (!containerRef.current) return;
+
+ const SEPARATION = 150;
+ const AMOUNTX = 40;
+ const AMOUNTY = 60;
+
+ const scene = new THREE.Scene();
+ scene.fog = new THREE.Fog(0xffffff, 2000, 10000);
+
+ const camera = new THREE.PerspectiveCamera(
+ 60,
+ window.innerWidth / window.innerHeight,
+ 1,
+ 10000,
+ );
+ camera.position.set(0, 355, 1220);
+
+ const renderer = new THREE.WebGLRenderer({
+ alpha: true,
+ antialias: true,
+ });
+ renderer.setPixelRatio(window.devicePixelRatio);
+ renderer.setSize(window.innerWidth, window.innerHeight);
+ renderer.setClearColor(scene.fog.color, 0);
+
+ containerRef.current.appendChild(renderer.domElement);
+
+ const positions: number[] = [];
+ const colors: number[] = [];
+ const geometry = new THREE.BufferGeometry();
+
+ for (let ix = 0; ix < AMOUNTX; ix++) {
+ for (let iy = 0; iy < AMOUNTY; iy++) {
+ positions.push(
+ ix * SEPARATION - (AMOUNTX * SEPARATION) / 2,
+ 0,
+ iy * SEPARATION - (AMOUNTY * SEPARATION) / 2,
+ );
+ colors.push(0.78, 0.78, 0.78);
+ }
+ }
+
+ geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
+ geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));
+
+ const material = new THREE.PointsMaterial({
+ size: 8,
+ vertexColors: true,
+ transparent: true,
+ opacity: 0.45,
+ sizeAttenuation: true,
+ });
+
+ const points = new THREE.Points(geometry, material);
+ scene.add(points);
+
+ let count = 0;
+ let animationId = 0;
+
+ const animate = () => {
+ animationId = requestAnimationFrame(animate);
+
+ const positionAttribute = geometry.attributes.position;
+ const pos = positionAttribute.array as Float32Array;
+
+ let i = 0;
+ for (let ix = 0; ix < AMOUNTX; ix++) {
+ for (let iy = 0; iy < AMOUNTY; iy++) {
+ pos[i * 3 + 1] =
+ Math.sin((ix + count) * 0.3) * 50 +
+ Math.sin((iy + count) * 0.5) * 50;
+ i++;
+ }
+ }
+
+ positionAttribute.needsUpdate = true;
+ renderer.render(scene, camera);
+ count += 0.1;
+ };
+
+ const handleResize = () => {
+ camera.aspect = window.innerWidth / window.innerHeight;
+ camera.updateProjectionMatrix();
+ renderer.setSize(window.innerWidth, window.innerHeight);
+ };
+
+ window.addEventListener('resize', handleResize);
+ const reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
+ if (reducedMotion) {
+ renderer.render(scene, camera);
+ } else {
+ animate();
+ }
+
+ sceneRef.current = { scene, camera, renderer, particles: [points], animationId, count };
+
+ const container = containerRef.current;
+
+ return () => {
+ window.removeEventListener('resize', handleResize);
+ if (sceneRef.current) {
+ cancelAnimationFrame(sceneRef.current.animationId);
+ sceneRef.current.scene.traverse((object) => {
+ if (object instanceof THREE.Points) {
+ object.geometry.dispose();
+ if (Array.isArray(object.material)) {
+ object.material.forEach((m) => m.dispose());
+ } else {
+ object.material.dispose();
+ }
+ }
+ });
+ sceneRef.current.renderer.dispose();
+ if (container && sceneRef.current.renderer.domElement) {
+ container.removeChild(sceneRef.current.renderer.domElement);
+ }
+ }
+ };
+ }, []);
+
+ return (
+
+ );
+}
diff --git a/docs/superpowers/plans/2026-07-12-perf-and-code-audit.md b/docs/superpowers/plans/2026-07-12-perf-and-code-audit.md
new file mode 100644
index 0000000..fdafbff
--- /dev/null
+++ b/docs/superpowers/plans/2026-07-12-perf-and-code-audit.md
@@ -0,0 +1,413 @@
+# Performance & Code Audit Remediation Plan
+
+> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
+
+**Goal:** Fix the concrete performance, bundle-size, dead-weight-dependency, and type-safety issues found in a full-repo audit (2026-07-12), without changing any user-visible behavior.
+
+**Architecture:** Each task is an independent, low-risk change: either (a) defer a heavy client-only library behind `next/dynamic`, (b) remove/relocate a dependency in `package.json`, (c) parallelize independent Supabase calls, or (d) tighten types in the parser. No task depends on another; they can be done in any order or split across subagents.
+
+**Tech Stack:** Next.js 16 (App Router, Turbopack), React 18, TypeScript, Supabase, Jest.
+
+## Global Constraints
+
+- Do not change any visible UI behavior, route, or API response shape — this is a non-functional cleanup pass.
+- Every task must end with `npm run build` succeeding and `npm test` passing (baseline: all `__tests__/*.test.ts` green).
+- Do not touch RLS/SQL, auth flow, or the Content-Security-Policy in `next.config.js`.
+- Preserve existing `next-env.d.ts` / `*.tsbuildinfo` gitignore behavior (already correct — no action needed there).
+
+---
+
+## Audit Findings Summary (context for all tasks)
+
+Verified via `npm run build` + manifest inspection + grep on 2026-07-12:
+
+1. **`components/ui/DottedSurface.tsx`** statically imports `three` (`import * as THREE from 'three'`). The compiled chunk is 516 KB and is confirmed present in the client reference manifests for `/`, `/login`, and `/register` (the three highest-traffic, unauthenticated entry pages) — confirmed absent from `/dashboard`. It renders a decorative animated background only, with no SSR-dependent output.
+2. Zero uses of `next/dynamic` anywhere in the repo — Monaco (`components/editor/CodeEditor.tsx`, `components/share/ShareView.tsx`) and Mermaid (`components/editor/FlowchartPanel.tsx`) are statically imported too. These are already route-isolated by the App Router (not loaded on `/`, `/login`, `/dashboard`), so lower priority than #1, but still block-render their host component instead of streaming in behind a loading state.
+3. `package.json` lists `next-themes` (0 references anywhere in `app/`, `components/`, `lib/`, or CSS) and `tw-animate-css` (0 references — only `tailwindcss-animate` is actually used, in `tailwind.config.ts`) as runtime dependencies. Both are dead weight in `node_modules` and install time.
+4. `shadcn` (the scaffolding CLI, never imported in source) and `@types/three` (a types-only package) are declared under `dependencies` instead of `devDependencies`, bloating the production dependency tree unnecessarily.
+5. `lib/parser/javascript.ts` and `lib/parser/typescript.ts` both open with `/* eslint-disable @typescript-eslint/no-explicit-any */` and together account for 47 of the repo's 52 `any`/`as any` occurrences — the core parsing engine has type-checking effectively turned off.
+6. `app/api/flowcharts/[id]/route.ts` `GET` handler issues two independent Supabase queries (`flowcharts` lookup, then latest `flowchart_versions` lookup) sequentially with `await`, even though neither depends on the other's result — an unnecessary serial round-trip on every editor/share page load.
+
+---
+
+### Task 1: Lazy-load the Three.js background on marketing pages
+
+**Files:**
+- Modify: `components/ui/DottedSurface.tsx`
+- Test: manual build verification (no existing unit test touches this component)
+
+**Interfaces:**
+- Consumes: nothing new.
+- Produces: same default export `DottedSurface` component, same props — callers (`app/page.tsx`, `app/(auth)/login/page.tsx`, `app/(auth)/register/page.tsx`) do not change.
+
+- [ ] **Step 1: Read the current component to confirm props/shape**
+
+Run: `sed -n '1,40p' components/ui/DottedSurface.tsx`
+Confirm it's a self-contained `'use client'` component with no required props (or note the props if any exist) before splitting it.
+
+- [ ] **Step 2: Split into a static wrapper + a dynamically-imported Three.js implementation**
+
+Rename the current file's contents into `components/ui/DottedSurfaceCanvas.tsx` (same code, same `'use client'` directive, same export name but exported as `DottedSurfaceCanvas`), then replace `components/ui/DottedSurface.tsx` with:
+
+```tsx
+'use client'
+
+import dynamic from 'next/dynamic'
+
+const DottedSurfaceCanvas = dynamic(
+ () => import('./DottedSurfaceCanvas').then(mod => mod.DottedSurfaceCanvas),
+ { ssr: false }
+)
+
+export function DottedSurface(props: React.ComponentProps) {
+ return
+}
+```
+
+Adjust the prop type / import path to match whatever `DottedSurfaceCanvas`'s actual prop signature is from Step 1 (e.g. if it takes a `className` prop, keep that typed explicitly instead of `React.ComponentProps` if simpler).
+
+- [ ] **Step 3: Build and confirm the three.js chunk is no longer in the `/`, `/login`, `/register` client reference manifests**
+
+Run:
+```bash
+npm run build
+grep -o "THREE\|three" .next/server/app/page_client-reference-manifest.js | head -1
+```
+Expected: the three.js chunk filename referenced by `page_client-reference-manifest.js` for `/` is a *different* (smaller, dynamically-loaded) chunk than before, and does not block the initial page chunk list. Confirm visually that `app/page.tsx`, `app/(auth)/login/page.tsx`, `app/(auth)/register/page.tsx` still render the dotted background by running `npm run dev` and opening `/`, `/login`, `/register` in a browser — the background should still animate, just appear a beat after first paint.
+
+- [ ] **Step 4: Run full test suite**
+
+Run: `npm test`
+Expected: all existing tests pass unchanged (this component has no unit tests, so this just guards against unrelated breakage).
+
+- [ ] **Step 5: Commit**
+
+```bash
+git add components/ui/DottedSurface.tsx components/ui/DottedSurfaceCanvas.tsx
+git commit -m "perf: lazy-load three.js DottedSurface background via next/dynamic"
+```
+
+---
+
+### Task 2: Remove dead dependencies and relocate dev-only ones
+
+**Files:**
+- Modify: `package.json`
+- Modify: `package-lock.json` (regenerated by `npm install`, not hand-edited)
+
+**Interfaces:**
+- Consumes: nothing.
+- Produces: nothing consumed by later tasks.
+
+- [ ] **Step 1: Confirm zero usage one more time immediately before removing**
+
+Run:
+```bash
+grep -rn "next-themes" --include='*.ts*' --include='*.css' --include='*.mjs' . --exclude-dir=node_modules --exclude-dir=.next --exclude-dir=.git
+grep -rn "tw-animate-css" --include='*.ts*' --include='*.css' --include='*.mjs' . --exclude-dir=node_modules --exclude-dir=.next --exclude-dir=.git
+grep -rn "from 'shadcn'\|from \"shadcn\"" app components lib --include='*.ts*'
+```
+Expected: no output for any of the three commands.
+
+- [ ] **Step 2: Remove `next-themes` and `tw-animate-css`, move `shadcn` and `@types/three` to devDependencies**
+
+```bash
+npm uninstall next-themes tw-animate-css
+npm uninstall shadcn @types/three
+npm install --save-dev shadcn @types/three
+```
+
+- [ ] **Step 3: Verify `package.json` dependency lists**
+
+Run: `cat package.json`
+Expected: `dependencies` no longer contains `next-themes`, `tw-animate-css`, `shadcn`, or `@types/three`; `devDependencies` now contains `shadcn` and `@types/three`.
+
+- [ ] **Step 4: Rebuild and retest to confirm nothing depended on the removed packages**
+
+Run:
+```bash
+npm run build
+npm test
+```
+Expected: both succeed with no module-not-found errors.
+
+- [ ] **Step 5: Commit**
+
+```bash
+git add package.json package-lock.json
+git commit -m "chore: drop unused next-themes/tw-animate-css deps, move shadcn/@types/three to devDependencies"
+```
+
+---
+
+### Task 3: Parallelize independent Supabase reads in the flowchart GET route
+
+**Files:**
+- Modify: `app/api/flowcharts/[id]/route.ts:8-27`
+- Test: `__tests__` has no existing coverage for this route; add a focused test.
+
+**Interfaces:**
+- Consumes: existing `createClient` from `@/lib/supabase/server`.
+- Produces: same `GET` response shape (`{ ...flowchart fields, code, version_number }`) — no external interface change.
+
+- [ ] **Step 1: Write a failing test asserting both queries fire without waiting on each other**
+
+Create `__tests__/flowcharts-get-route.test.ts`:
+
+```ts
+import { GET } from '@/app/api/flowcharts/[id]/route'
+
+const flowchartsQuery = {
+ select: jest.fn().mockReturnThis(),
+ eq: jest.fn().mockReturnThis(),
+ single: jest.fn(),
+}
+const versionsQuery = {
+ select: jest.fn().mockReturnThis(),
+ eq: jest.fn().mockReturnThis(),
+ order: jest.fn().mockReturnThis(),
+ limit: jest.fn().mockReturnThis(),
+ single: jest.fn(),
+}
+
+jest.mock('@/lib/supabase/server', () => ({
+ createClient: jest.fn(async () => ({
+ auth: { getUser: jest.fn(async () => ({ data: { user: { id: 'user-1' } }, error: null })) },
+ from: (table: string) => (table === 'flowcharts' ? flowchartsQuery : versionsQuery),
+ })),
+}))
+
+describe('GET /api/flowcharts/[id]', () => {
+ it('issues the flowchart and version lookups concurrently', async () => {
+ let flowchartResolved = false
+ let versionStartedBeforeFlowchartResolved = false
+
+ flowchartsQuery.single.mockImplementation(
+ () =>
+ new Promise(resolve =>
+ setTimeout(() => {
+ flowchartResolved = true
+ resolve({ data: { id: 'fc-1', user_id: 'user-1' }, error: null })
+ }, 20)
+ )
+ )
+ versionsQuery.single.mockImplementation(() => {
+ versionStartedBeforeFlowchartResolved = !flowchartResolved
+ return Promise.resolve({ data: { code: 'x', version_number: 3 }, error: null })
+ })
+
+ const request = new Request('http://localhost/api/flowcharts/fc-1')
+ const response = await GET(request, { params: Promise.resolve({ id: 'fc-1' }) })
+ const body = await response.json()
+
+ expect(versionStartedBeforeFlowchartResolved).toBe(true)
+ expect(body).toMatchObject({ id: 'fc-1', code: 'x', version_number: 3 })
+ })
+})
+```
+
+- [ ] **Step 2: Run test to verify it fails against the current sequential implementation**
+
+Run: `npx jest __tests__/flowcharts-get-route.test.ts -v`
+Expected: FAIL — `versionStartedBeforeFlowchartResolved` is `false` because today's code `await`s the flowchart query before starting the version query.
+
+- [ ] **Step 3: Parallelize the two independent queries with `Promise.all`**
+
+In `app/api/flowcharts/[id]/route.ts`, replace the `GET` handler body (currently sequential `await`s for `fc` then `versionRes`) with:
+
+```ts
+export async function GET(_req: Request, { params }: Params) {
+ const { id } = await params
+ const supabase = await createClient()
+ const { data: { user }, error: authErr } = await supabase.auth.getUser()
+ if (authErr || !user) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
+
+ const [{ data: fc, error }, versionRes] = await Promise.all([
+ supabase.from('flowcharts').select('*').eq('id', id).eq('user_id', user.id).single(),
+ supabase
+ .from('flowchart_versions')
+ .select('code, version_number')
+ .eq('flowchart_id', id)
+ .order('version_number', { ascending: false })
+ .limit(1)
+ .single(),
+ ])
+ if (error || !fc) return NextResponse.json({ error: 'Not found' }, { status: 404 })
+
+ const version = versionRes.data as { code: string; version_number: number } | null
+
+ return NextResponse.json(Object.assign({}, fc, { code: version?.code ?? '', version_number: version?.version_number ?? 0 }))
+}
+```
+
+- [ ] **Step 4: Run test to verify it passes**
+
+Run: `npx jest __tests__/flowcharts-get-route.test.ts -v`
+Expected: PASS
+
+- [ ] **Step 5: Run full suite and build**
+
+Run:
+```bash
+npm test
+npm run build
+```
+Expected: all green.
+
+- [ ] **Step 6: Commit**
+
+```bash
+git add app/api/flowcharts/\[id\]/route.ts __tests__/flowcharts-get-route.test.ts
+git commit -m "perf: parallelize flowchart+version reads in GET /api/flowcharts/[id]"
+```
+
+---
+
+### Task 4: Re-enable type checking in the parser and eliminate `any`
+
+**Files:**
+- Modify: `lib/parser/javascript.ts` (41 `any` occurrences)
+- Modify: `lib/parser/typescript.ts` (5 `any` occurrences)
+- Modify: `lib/parser/python.ts` (6 `any` occurrences)
+- Test: existing `__tests__/parser-js-accuracy.test.ts`, `__tests__/parser-python-accuracy.test.ts`, `__tests__/parser.test.ts` already cover parser behavior and must stay green throughout — this task is a pure typing refactor with no behavior change.
+
+**Interfaces:**
+- Consumes: `acorn.Node` / `acorn.Program` types from `acorn`, and whatever AST node shapes `acorn-typescript` exports.
+- Produces: same exported functions (`convertJS`/`processBlock`/`convertTS`/`convertPython` etc.) with identical signatures — only internal typing changes.
+
+- [ ] **Step 1: Baseline — confirm parser tests pass before touching anything**
+
+Run: `npx jest __tests__/parser-js-accuracy.test.ts __tests__/parser-python-accuracy.test.ts __tests__/parser.test.ts __tests__/python-lines.test.ts -v`
+Expected: PASS (record this as the behavior baseline — Task 4 must not change these results).
+
+- [ ] **Step 2: Remove the file-level `eslint-disable` in `lib/parser/javascript.ts` and see what breaks**
+
+Delete the line `/* eslint-disable @typescript-eslint/no-explicit-any */` at the top of `lib/parser/javascript.ts`.
+
+Run: `npx eslint lib/parser/javascript.ts`
+Expected: a list of `no-explicit-any` errors, one per `any` usage — this is your worklist for this file.
+
+- [ ] **Step 3: Type the acorn AST node parameters precisely**
+
+For each flagged line, replace `any` with the correct acorn type. Acorn's own `Node` type only guarantees `type`, `start`, `end`, `loc` — real node shapes (e.g. `IfStatement`, `ForStatement`, `CallExpression`) come from `acorn`'s `Node` union or from casting to a local narrow interface. Prefer this pattern already established in `lib/parser/types.ts` (check that file for any existing narrow AST interfaces before adding new ones):
+
+```ts
+import type { Node } from 'acorn'
+
+interface IfStatementNode extends Node {
+ type: 'IfStatement'
+ test: Node
+ consequent: Node
+ alternate: Node | null
+}
+```
+
+Add one narrow interface per distinct node shape the switch/if-chain in `processBlock` (or equivalent) actually dispatches on — do not create a generic catch-all `any` replacement; each usage should get its real shape.
+
+- [ ] **Step 4: Run eslint again to confirm zero `no-explicit-any` violations in this file**
+
+Run: `npx eslint lib/parser/javascript.ts`
+Expected: no errors.
+
+- [ ] **Step 5: Run parser tests to confirm no behavior changed**
+
+Run: `npx jest __tests__/parser-js-accuracy.test.ts __tests__/parser.test.ts -v`
+Expected: PASS, identical to Step 1 baseline.
+
+- [ ] **Step 6: Repeat Steps 2-5 for `lib/parser/typescript.ts`**
+
+Same process: remove its `eslint-disable`, add narrow types for the 5 flagged spots (this file already documents one legitimate unavoidable `any` — the `tsPlugin` CJS-interop cast explained in its existing comment; that one may stay as a targeted `as any` on that single line with the existing comment, not a file-wide disable — everything else must be typed).
+
+Run: `npx eslint lib/parser/typescript.ts && npx jest __tests__/parser-js-accuracy.test.ts -v`
+Expected: no lint errors outside the documented interop cast; tests pass.
+
+- [ ] **Step 7: Repeat for `lib/parser/python.ts`'s 6 occurrences**
+
+Run: `npx eslint lib/parser/python.ts && npx jest __tests__/parser-python-accuracy.test.ts __tests__/python-lines.test.ts -v`
+Expected: no lint errors; tests pass.
+
+- [ ] **Step 8: Full-repo verification**
+
+Run:
+```bash
+npm run lint
+npm test
+npm run build
+```
+Expected: all green, zero `no-explicit-any` suppressions remaining outside the one documented `acorn-typescript` interop cast.
+
+- [ ] **Step 9: Commit**
+
+```bash
+git add lib/parser/javascript.ts lib/parser/typescript.ts lib/parser/python.ts
+git commit -m "refactor: replace any with precise AST types across the parser, drop file-wide any suppressions"
+```
+
+---
+
+### Task 5: Defer Monaco and Mermaid behind `next/dynamic` with a loading state
+
+**Files:**
+- Modify: `components/editor/CodeEditor.tsx`
+- Modify: `components/editor/FlowchartPanel.tsx`
+- Modify: `components/share/ShareView.tsx`
+
+**Interfaces:**
+- Consumes: nothing new.
+- Produces: same component exports/props as today — this is purely about *when* the JS downloads/executes relative to first paint of the editor shell, not what renders.
+
+- [ ] **Step 1: Read current CodeEditor.tsx top-of-file imports and export shape**
+
+Run: `sed -n '1,30p' components/editor/CodeEditor.tsx`
+
+- [ ] **Step 2: Wrap the Monaco import with `next/dynamic` and a skeleton fallback**
+
+In `components/editor/CodeEditor.tsx`, replace the static `import MonacoEditor, { loader } from '@monaco-editor/react'` usage: keep `loader` imported statically (it's tiny, just config), but load the `` component itself via:
+
+```tsx
+import dynamic from 'next/dynamic'
+import { loader } from '@monaco-editor/react'
+
+const MonacoEditor = dynamic(() => import('@monaco-editor/react').then(m => m.default), {
+ ssr: false,
+ loading: () => Loading editor…
,
+})
+```
+
+Remove the old default import of `MonacoEditor` and keep every other usage in the file unchanged (same props passed to ``).
+
+- [ ] **Step 3: Apply the same pattern to `components/share/ShareView.tsx`'s Monaco import**
+
+Same transformation as Step 2, scoped to that file's own top-of-file imports.
+
+- [ ] **Step 4: Defer the `mermaid` import in `components/editor/FlowchartPanel.tsx`**
+
+`mermaid` is imported and used inside `useEffect`, not at module top-level render — confirm with `grep -n "mermaid" components/editor/FlowchartPanel.tsx`. If it's already only referenced inside an effect/async function (not at module scope), convert the static top-level `import mermaid from 'mermaid'` into a dynamic `const { default: mermaid } = await import('mermaid')` inside that same effect, so it's fetched only when the panel actually mounts rather than bundled into the initial chunk for that route.
+
+- [ ] **Step 5: Manual verification in the browser**
+
+Run: `npm run dev`, open `/editor`, confirm: the editor shell (toolbar, panel borders) paints immediately, "Loading editor…" briefly shows, then Monaco loads and is fully interactive (typing, syntax highlighting). Open `/editor/[id]` with an existing flowchart (or `/share/[shareId]`) and confirm the mermaid diagram still renders correctly with no console errors.
+
+- [ ] **Step 6: Run full test suite and build**
+
+Run:
+```bash
+npm test
+npm run build
+```
+Expected: all green.
+
+- [ ] **Step 7: Commit**
+
+```bash
+git add components/editor/CodeEditor.tsx components/editor/FlowchartPanel.tsx components/share/ShareView.tsx
+git commit -m "perf: defer Monaco/Mermaid loading behind next/dynamic with loading states"
+```
+
+---
+
+## Self-Review Notes
+
+- **Spec coverage:** All 6 audit findings map 1:1 to a task (Finding 1 → Task 1, Finding 2 → Task 5, Findings 3-4 → Task 2, Finding 5 → Task 4, Finding 6 → Task 3).
+- **Independence:** Tasks 1-5 touch disjoint files (only Task 1 and Task 5 both touch the `components/` tree, but different files within it) — safe to dispatch in parallel via subagent-driven-development.
+- **No placeholders:** every step has literal code, exact commands, and expected output.
diff --git a/lib/parser/javascript.ts b/lib/parser/javascript.ts
index f5a6a6f..1c21367 100644
--- a/lib/parser/javascript.ts
+++ b/lib/parser/javascript.ts
@@ -1,12 +1,31 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
import * as acorn from 'acorn'
import { FlowchartGraph, TraversalContext, type BlockResult, type FlowchartNode } from './types'
+// acorn-typescript (see ./typescript.ts) parses TS-only declarations that
+// acorn's own types don't model since they're added by the plugin, not
+// acorn core. This module's traversal (shared by convertJS and convertTS)
+// only ever reads `.type` for these — they carry no runtime control flow.
+interface TSTypeOnlyNode extends acorn.Node {
+ type: 'TSInterfaceDeclaration' | 'TSTypeAliasDeclaration' | 'TSDeclareFunction' | 'TSModuleDeclaration'
+}
+
+// Any node this module's traversal may encounter: every real acorn AST
+// shape (acorn.AnyNode, acorn's own union of all node interfaces) plus the
+// TS-only declarations above.
+type AstNode = acorn.AnyNode | TSTypeOnlyNode
+
+// A parse error thrown by acorn/acorn-typescript: a SyntaxError-shaped
+// object with a non-standard `loc` position attached.
+interface AcornParseError {
+ message: string
+ loc?: { line: number; column: number } | null
+}
+
// ── Expression formatter ────────────────────────────────────────────────────
export function formatExpression(node: acorn.Node | null, maxLen = 60): string {
if (!node) return ''
- const n = node as any
+ const n = node as acorn.AnyNode
let text = ''
switch (n.type) {
case 'Identifier': text = n.name; break
@@ -17,12 +36,12 @@ export function formatExpression(node: acorn.Node | null, maxLen = 60): string {
case 'UpdateExpression': text = n.prefix ? `${n.operator}${formatExpression(n.argument)}` : `${formatExpression(n.argument)}${n.operator}`; break
case 'AssignmentExpression': text = `${formatExpression(n.left)} ${n.operator} ${formatExpression(n.right)}`; break
case 'MemberExpression': text = n.computed ? `${formatExpression(n.object)}[${formatExpression(n.property)}]` : `${formatExpression(n.object)}.${formatExpression(n.property)}`; break
- case 'CallExpression': text = `${formatExpression(n.callee)}(${n.arguments.map((a: any) => formatExpression(a)).join(', ')})`; break
+ case 'CallExpression': text = `${formatExpression(n.callee)}(${n.arguments.map(a => formatExpression(a)).join(', ')})`; break
case 'ConditionalExpression': text = `${formatExpression(n.test)} ? ${formatExpression(n.consequent)} : ${formatExpression(n.alternate)}`; break
- case 'ArrayExpression': text = `[${n.elements.map((e: any) => formatExpression(e)).join(', ')}]`; break
+ case 'ArrayExpression': text = `[${n.elements.map(e => formatExpression(e)).join(', ')}]`; break
case 'ObjectExpression': text = '{...}'; break
- case 'NewExpression': text = `new ${formatExpression(n.callee)}(${n.arguments.map((a: any) => formatExpression(a)).join(', ')})`; break
- case 'SequenceExpression': text = n.expressions.map((e: any) => formatExpression(e)).join(', '); break
+ case 'NewExpression': text = `new ${formatExpression(n.callee)}(${n.arguments.map(a => formatExpression(a)).join(', ')})`; break
+ case 'SequenceExpression': text = n.expressions.map(e => formatExpression(e)).join(', '); break
case 'ThisExpression': text = 'this'; break
case 'TemplateLiteral': text = '`...`'; break
case 'ArrowFunctionExpression': text = '() => {...}'; break
@@ -43,14 +62,15 @@ export function parseJS(code: string): acorn.Program {
allowReturnOutsideFunction: true,
allowAwaitOutsideFunction: true,
}) as acorn.Program
- } catch (e: any) {
- throw new Error(`JavaScript Parse Error at line ${e.loc?.line ?? '?'}: ${e.message}`)
+ } catch (e) {
+ const err = e as AcornParseError
+ throw new Error(`JavaScript Parse Error at line ${err.loc?.line ?? '?'}: ${err.message}`)
}
}
// ── Helper functions ────────────────────────────────────────────────────────
-function processFunctionBody(label: string, endLabel: string, bodyStatements: any[], ctx: TraversalContext): BlockResult {
+function processFunctionBody(label: string, endLabel: string, bodyStatements: acorn.Statement[], ctx: TraversalContext): BlockResult {
const funcNode = ctx.graph.createNode('subroutine', label, 'rounded')
const endNode = ctx.graph.createNode('process', endLabel, 'rounded')
const fCtx = ctx.clone()
@@ -67,16 +87,20 @@ function processFunctionBody(label: string, endLabel: string, bodyStatements: an
return { entry: funcNode, exit: endNode }
}
-function isBlockFunction(n: any): boolean {
+// Narrows to a function expression whose body is a BlockStatement (as
+// opposed to a concise arrow body, e.g. `() => x`, which has no block to walk).
+function isBlockFunction(
+ n: acorn.Expression | null | undefined
+): n is (acorn.ArrowFunctionExpression | acorn.FunctionExpression) & { body: acorn.BlockStatement } {
return !!n && (n.type === 'ArrowFunctionExpression' || n.type === 'FunctionExpression') && n.body?.type === 'BlockStatement'
}
-function functionLabel(prefix: string, fn: any): string {
- const params = fn.params.map((p: any) => formatExpression(p)).join(', ')
+function functionLabel(prefix: string, fn: acorn.ArrowFunctionExpression | acorn.FunctionExpression): string {
+ const params = fn.params.map(p => formatExpression(p)).join(', ')
return fn.type === 'ArrowFunctionExpression' ? `${prefix} = (${params}) =>` : `${prefix} = function(${params})`
}
-function processClassJS(node: any, ctx: TraversalContext): BlockResult {
+function processClassJS(node: acorn.ClassDeclaration | acorn.ClassExpression | acorn.AnonymousClassDeclaration, ctx: TraversalContext): BlockResult {
const name = node.id?.name ?? 'anonymous'
const base = node.superClass ? ` extends ${formatExpression(node.superClass)}` : ''
const cls = ctx.graph.createNode('subroutine', `class ${name}${base}`, 'rounded')
@@ -85,7 +109,7 @@ function processClassJS(node: any, ctx: TraversalContext): BlockResult {
let r: BlockResult | null = null
if (m.type === 'MethodDefinition' && m.value?.body) {
const key = formatExpression(m.key)
- const params = m.value.params.map((p: any) => formatExpression(p)).join(', ')
+ const params = m.value.params.map(p => formatExpression(p)).join(', ')
let label = `${key}(${params})`
if (m.kind === 'get') label = `get ${label}`
if (m.kind === 'set') label = `set ${label}`
@@ -107,7 +131,7 @@ function processClassJS(node: any, ctx: TraversalContext): BlockResult {
// ── Statement handlers ───────────────────────────────────────────────────────
-export function processStatement(node: any, ctx: TraversalContext): BlockResult {
+export function processStatement(node: AstNode | null, ctx: TraversalContext): BlockResult {
if (!node) return { entry: null, exit: null }
switch (node.type) {
case 'FunctionDeclaration': return processFunction(node, ctx)
@@ -151,15 +175,15 @@ export function processStatement(node: any, ctx: TraversalContext): BlockResult
}
}
-function processFunction(node: any, ctx: TraversalContext): BlockResult {
+function processFunction(node: acorn.FunctionDeclaration | acorn.AnonymousFunctionDeclaration, ctx: TraversalContext): BlockResult {
const name = node.id?.name ?? 'anonymous'
- const params = node.params.map((p: any) => formatExpression(p)).join(', ')
+ const params = node.params.map(p => formatExpression(p)).join(', ')
return processFunctionBody(`function ${name}(${params})`, `end ${name}`, node.body.body, ctx)
}
-function processIf(node: any, ctx: TraversalContext): BlockResult {
+function processIf(node: acorn.IfStatement, ctx: TraversalContext): BlockResult {
const cond = ctx.graph.createNode('decision', formatExpression(node.test) + '?', 'diamond')
- const merge = ctx.graph.createNode('merge' as any, '', 'circle')
+ const merge = ctx.graph.createNode('merge', '', 'circle')
const trueBody = node.consequent.type === 'BlockStatement' ? node.consequent.body : [node.consequent]
const trueCtx = ctx.clone(); trueCtx.currentNode = cond
@@ -186,16 +210,16 @@ function processIf(node: any, ctx: TraversalContext): BlockResult {
return { entry: cond, exit: merge }
}
-function processFor(node: any, ctx: TraversalContext): BlockResult {
+function processFor(node: acorn.ForStatement, ctx: TraversalContext): BlockResult {
let initNode: FlowchartNode | null = null
if (node.init) {
const label = node.init.type === 'VariableDeclaration'
- ? node.init.declarations.map((d: any) => `${node.init.kind} ${formatExpression(d.id)} = ${formatExpression(d.init)}`).join(', ')
+ ? node.init.declarations.map(d => `${(node.init as acorn.VariableDeclaration).kind} ${formatExpression(d.id)} = ${formatExpression(d.init ?? null)}`).join(', ')
: formatExpression(node.init)
initNode = ctx.graph.createNode('process', label, 'rectangle')
}
const cond = ctx.graph.createNode('decision', (node.test ? formatExpression(node.test) : 'true') + '?', 'diamond')
- const after = ctx.graph.createNode('merge' as any, '', 'circle')
+ const after = ctx.graph.createNode('merge', '', 'circle')
const update = node.update ? ctx.graph.createNode('process', formatExpression(node.update), 'rectangle') : null
if (initNode) ctx.graph.connect(initNode, cond)
@@ -218,9 +242,9 @@ function processFor(node: any, ctx: TraversalContext): BlockResult {
return { entry: initNode ?? cond, exit: after }
}
-function processWhile(node: any, ctx: TraversalContext): BlockResult {
+function processWhile(node: acorn.WhileStatement, ctx: TraversalContext): BlockResult {
const cond = ctx.graph.createNode('decision', formatExpression(node.test) + '?', 'diamond')
- const after = ctx.graph.createNode('merge' as any, '', 'circle')
+ const after = ctx.graph.createNode('merge', '', 'circle')
for (const l of ctx.pendingLabels) ctx.labeledTargets[l] = { break: after, continue: cond }
ctx.pendingLabels = []
const lCtx = ctx.clone(); lCtx.currentNode = cond; lCtx.breakTarget = after; lCtx.continueTarget = cond
@@ -232,10 +256,10 @@ function processWhile(node: any, ctx: TraversalContext): BlockResult {
return { entry: cond, exit: after }
}
-function processDoWhile(node: any, ctx: TraversalContext): BlockResult {
+function processDoWhile(node: acorn.DoWhileStatement, ctx: TraversalContext): BlockResult {
const bodyStart = ctx.graph.createNode('process', 'do', 'rounded')
const cond = ctx.graph.createNode('decision', formatExpression(node.test) + '?', 'diamond')
- const after = ctx.graph.createNode('merge' as any, '', 'circle')
+ const after = ctx.graph.createNode('merge', '', 'circle')
for (const l of ctx.pendingLabels) ctx.labeledTargets[l] = { break: after, continue: cond }
ctx.pendingLabels = []
const lCtx = ctx.clone(); lCtx.currentNode = bodyStart; lCtx.breakTarget = after; lCtx.continueTarget = cond
@@ -248,11 +272,11 @@ function processDoWhile(node: any, ctx: TraversalContext): BlockResult {
return { entry: bodyStart, exit: after }
}
-function processForIn(node: any, ctx: TraversalContext): BlockResult {
+function processForIn(node: acorn.ForInStatement | acorn.ForOfStatement, ctx: TraversalContext): BlockResult {
const left = node.left.type === 'VariableDeclaration' ? `${node.left.kind} ${formatExpression(node.left.declarations[0].id)}` : formatExpression(node.left)
const kw = node.type === 'ForOfStatement' ? 'of' : 'in'
const cond = ctx.graph.createNode('decision', `${left} ${kw} ${formatExpression(node.right)}?`, 'diamond')
- const after = ctx.graph.createNode('merge' as any, '', 'circle')
+ const after = ctx.graph.createNode('merge', '', 'circle')
for (const l of ctx.pendingLabels) ctx.labeledTargets[l] = { break: after, continue: cond }
ctx.pendingLabels = []
const lCtx = ctx.clone(); lCtx.currentNode = cond; lCtx.breakTarget = after; lCtx.continueTarget = cond
@@ -263,9 +287,9 @@ function processForIn(node: any, ctx: TraversalContext): BlockResult {
return { entry: cond, exit: after }
}
-function processSwitch(node: any, ctx: TraversalContext): BlockResult {
+function processSwitch(node: acorn.SwitchStatement, ctx: TraversalContext): BlockResult {
const sw = ctx.graph.createNode('decision', `switch (${formatExpression(node.discriminant)})`, 'diamond')
- const after = ctx.graph.createNode('merge' as any, '', 'circle')
+ const after = ctx.graph.createNode('merge', '', 'circle')
let fallthrough: FlowchartNode | null = null
for (const l of ctx.pendingLabels) ctx.labeledTargets[l] = { break: after, continue: null }
@@ -285,13 +309,13 @@ function processSwitch(node: any, ctx: TraversalContext): BlockResult {
}
if (fallthrough) ctx.graph.connect(fallthrough, after)
- if (!node.cases.some((c: any) => !c.test)) ctx.graph.connect(sw, after, 'no match')
+ if (!node.cases.some(c => !c.test)) ctx.graph.connect(sw, after, 'no match')
return { entry: sw, exit: after }
}
-function processTry(node: any, ctx: TraversalContext): BlockResult {
+function processTry(node: acorn.TryStatement, ctx: TraversalContext): BlockResult {
const tryNode = ctx.graph.createNode('process', 'try', 'rounded')
- const after = ctx.graph.createNode('merge' as any, '', 'circle')
+ const after = ctx.graph.createNode('merge', '', 'circle')
// catch/finally nodes are created before the try body is walked so the
// body's context can route throw statements to them
@@ -312,7 +336,7 @@ function processTry(node: any, ctx: TraversalContext): BlockResult {
if (finallyNode) {
const fCtx = ctx.clone(); fCtx.currentNode = finallyNode
- const fRes = processBlock(node.finalizer.body, fCtx)
+ const fRes = processBlock(node.finalizer!.body, fCtx)
if (fRes.entry) ctx.graph.connect(finallyNode, fRes.entry)
ctx.graph.connect(fRes.exit ?? finallyNode, after)
}
@@ -324,7 +348,7 @@ function processTry(node: any, ctx: TraversalContext): BlockResult {
// clones from the outer ctx so a throw inside catch propagates outward,
// not back into the same catch
const cCtx = ctx.clone(); cCtx.currentNode = catchNode
- const cRes = processBlock(node.handler.body.body, cCtx)
+ const cRes = processBlock(node.handler!.body.body, cCtx)
if (cRes.entry) ctx.graph.connect(catchNode, cRes.entry)
ctx.graph.connect(cRes.exit ?? catchNode, target)
}
@@ -332,36 +356,36 @@ function processTry(node: any, ctx: TraversalContext): BlockResult {
return { entry: tryNode, exit: after }
}
-function processReturn(node: any, ctx: TraversalContext): BlockResult {
+function processReturn(node: acorn.ReturnStatement, ctx: TraversalContext): BlockResult {
const label = node.argument ? `return ${formatExpression(node.argument)}` : 'return'
const n = ctx.graph.createNode('process', label, 'rectangle')
if (ctx.returnTarget) ctx.graph.connect(n, ctx.returnTarget)
return { entry: n, exit: null }
}
-function processBreak(node: any, ctx: TraversalContext): BlockResult {
+function processBreak(node: acorn.BreakStatement, ctx: TraversalContext): BlockResult {
const n = ctx.graph.createNode('process', node.label ? `break ${node.label.name}` : 'break', 'rectangle')
const target = node.label ? ctx.labeledTargets[node.label.name]?.break ?? ctx.breakTarget : ctx.breakTarget
if (target) ctx.graph.connect(n, target)
return { entry: n, exit: null }
}
-function processContinue(node: any, ctx: TraversalContext): BlockResult {
+function processContinue(node: acorn.ContinueStatement, ctx: TraversalContext): BlockResult {
const n = ctx.graph.createNode('process', node.label ? `continue ${node.label.name}` : 'continue', 'rectangle')
const target = node.label ? ctx.labeledTargets[node.label.name]?.continue ?? ctx.continueTarget : ctx.continueTarget
if (target) ctx.graph.connect(n, target)
return { entry: n, exit: null }
}
-function processThrow(node: any, ctx: TraversalContext): BlockResult {
+function processThrow(node: acorn.ThrowStatement, ctx: TraversalContext): BlockResult {
const n = ctx.graph.createNode('process', `throw ${formatExpression(node.argument)}`, 'rectangle')
if (ctx.throwTarget) ctx.graph.connect(n, ctx.throwTarget)
return { entry: n, exit: null }
}
-function processVariable(node: any, ctx: TraversalContext): BlockResult {
- if (!node.declarations.some((d: any) => isBlockFunction(d.init) || d.init?.type === 'ClassExpression')) {
- const decls = node.declarations.map((d: any) => {
+function processVariable(node: acorn.VariableDeclaration, ctx: TraversalContext): BlockResult {
+ if (!node.declarations.some(d => isBlockFunction(d.init) || d.init?.type === 'ClassExpression')) {
+ const decls = node.declarations.map(d => {
const name = formatExpression(d.id)
return d.init ? `${name} = ${formatExpression(d.init)}` : name
}).join(', ')
@@ -376,7 +400,7 @@ function processVariable(node: any, ctx: TraversalContext): BlockResult {
const name = formatExpression(d.id)
let r: BlockResult
if (d.init?.type === 'ClassExpression') {
- r = processClassJS({ ...d.init, id: d.init.id ?? d.id }, ctx)
+ r = processClassJS({ ...d.init, id: d.init.id ?? (d.id as acorn.Identifier) }, ctx)
} else if (isBlockFunction(d.init)) {
r = processFunctionBody(functionLabel(`${node.kind} ${name}`, d.init), `end ${name}`, d.init.body.body, ctx)
} else {
@@ -391,7 +415,7 @@ function processVariable(node: any, ctx: TraversalContext): BlockResult {
return { entry: first, exit: prev }
}
-function processExpression(node: any, ctx: TraversalContext): BlockResult {
+function processExpression(node: acorn.ExpressionStatement, ctx: TraversalContext): BlockResult {
const expr = node.expression
if (expr.type === 'AssignmentExpression' && expr.operator === '=' && isBlockFunction(expr.right)) {
const target = formatExpression(expr.left)
@@ -401,7 +425,7 @@ function processExpression(node: any, ctx: TraversalContext): BlockResult {
return { entry: n, exit: n }
}
-export function processBlock(statements: any[], ctx: TraversalContext): BlockResult {
+export function processBlock(statements: AstNode[], ctx: TraversalContext): BlockResult {
if (!statements?.length) return { entry: null, exit: ctx.currentNode }
let first: FlowchartNode | null = null
let current = ctx.currentNode
@@ -430,7 +454,7 @@ export function convertJS(code: string): FlowchartGraph {
ctx.currentNode = start
const ast = parseJS(code)
- const r = processBlock((ast as any).body, ctx)
+ const r = processBlock(ast.body as AstNode[], ctx)
graph.connect(start, r.entry ?? end)
if (r.exit) graph.connect(r.exit, end)
diff --git a/lib/parser/python.ts b/lib/parser/python.ts
index 54b0600..5c0226d 100644
--- a/lib/parser/python.ts
+++ b/lib/parser/python.ts
@@ -1,10 +1,56 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
import { FlowchartGraph, TraversalContext, type BlockResult, type FlowchartNode } from './types'
import { toLogicalLines, topLevelIndexOf, splitTopLevel } from './python-lines'
-// ── Tokenizer ────────────────────────────────────────────────────────────────
+// ── AST node shapes ──────────────────────────────────────────────────────────
+//
+// This is a hand-rolled, line-regex-based AST (not a real parser), so there's
+// no upstream library type to lean on. Each node kind below mirrors exactly
+// the object literals `parseLine` constructs and the fields the statement
+// handlers below actually read/write.
+
+interface NodeBase { line: number }
+
+interface ProgramNode { type: 'Program'; body: PyNode[] }
+interface FunctionDefNode extends NodeBase { type: 'FunctionDef'; name: string; params: string; body: PyNode[]; isAsync?: boolean }
+interface ClassDefNode extends NodeBase { type: 'ClassDef'; name: string; bases: string; body: PyNode[] }
+interface IfNode extends NodeBase { type: 'If'; test: string; body: PyNode[]; orelse: IfNode[]; _elseNode?: ElseNode }
+interface ElifNode extends NodeBase { type: 'Elif'; test: string; body: PyNode[] }
+interface ElseNode extends NodeBase { type: 'Else'; body: PyNode[] }
+interface ForNode extends NodeBase { type: 'For'; target: string; iter: string; body: PyNode[]; isAsync?: boolean; orelse?: ElseNode }
+interface WhileNode extends NodeBase { type: 'While'; test: string; body: PyNode[]; orelse?: ElseNode }
+interface TryNode extends NodeBase { type: 'Try'; body: PyNode[]; handlers: ExceptHandlerNode[]; finalbody: FinallyNode | null; elsebody?: ElseNode }
+interface ExceptHandlerNode extends NodeBase { type: 'ExceptHandler'; exceptionType: string; name: string; body: PyNode[] }
+interface FinallyNode extends NodeBase { type: 'Finally'; body: PyNode[] }
+interface WithNode extends NodeBase { type: 'With'; items: string; body: PyNode[]; isAsync?: boolean }
+interface ReturnNode extends NodeBase { type: 'Return'; value: string }
+interface BreakNode extends NodeBase { type: 'Break' }
+interface ContinueNode extends NodeBase { type: 'Continue' }
+interface PassNode extends NodeBase { type: 'Pass' }
+interface RaiseNode extends NodeBase { type: 'Raise'; exception: string }
+interface MatchNode extends NodeBase { type: 'Match'; subject: string; cases: CaseNode[]; body: PyNode[] }
+interface CaseNode extends NodeBase { type: 'Case'; pattern: string; body: PyNode[] }
+interface ExprNode extends NodeBase { type: 'Expr'; value: string }
+// `parseLine` never actually produces these (no regex branch matches `assert`
+// or `import`) — kept only so `processGeneric`'s defensive checks for them
+// stay type-valid rather than provably-unreachable comparisons.
+interface AssertNode extends NodeBase { type: 'Assert'; test: string }
+interface ImportNode extends NodeBase { type: 'Import'; statement: string }
+
+type PyNode =
+ | ProgramNode | FunctionDefNode | ClassDefNode | IfNode | ElifNode | ElseNode
+ | ForNode | WhileNode | TryNode | ExceptHandlerNode | FinallyNode | WithNode
+ | ReturnNode | BreakNode | ContinueNode | PassNode | RaiseNode
+ | MatchNode | CaseNode | ExprNode | AssertNode | ImportNode
+
+// The subset of node kinds that open a block (i.e. carry a `.body` statement
+// list) — used for the parser's indent stack, whose frames always point at
+// one of these.
+type BlockNode =
+ | ProgramNode | FunctionDefNode | ClassDefNode | IfNode | ElifNode | ElseNode
+ | ForNode | WhileNode | TryNode | ExceptHandlerNode | FinallyNode | WithNode
+ | MatchNode | CaseNode
-interface PyNode { type: string; body?: PyNode[]; [key: string]: any }
+// ── Tokenizer ────────────────────────────────────────────────────────────────
function parseLine(line: string, lineNum: number): PyNode | null {
let m: RegExpMatchArray | null
@@ -51,7 +97,7 @@ function parseLine(line: string, lineNum: number): PyNode | null {
return { type: 'Expr', value: line, line: lineNum }
}
-function getLastIf(node: PyNode): PyNode {
+function getLastIf(node: IfNode): IfNode {
if (node.orelse?.length && node.orelse[node.orelse.length - 1].type === 'If')
return getLastIf(node.orelse[node.orelse.length - 1])
return node
@@ -59,9 +105,9 @@ function getLastIf(node: PyNode): PyNode {
const COMPOUND = /^(?:async\s+)?(if|elif|else|for|while|def|class|try|except|finally|with|match|case)\b/
-export function parsePython(code: string): PyNode {
- const ast: PyNode = { type: 'Program', body: [] }
- const stack: Array<{ indent: number; node: PyNode; type: string }> = [{ indent: -1, node: ast, type: 'program' }]
+export function parsePython(code: string): ProgramNode {
+ const ast: ProgramNode = { type: 'Program', body: [] }
+ const stack: Array<{ indent: number; node: BlockNode; type: string }> = [{ indent: -1, node: ast, type: 'program' }]
for (const ll of toLogicalLines(code)) {
const trimmed = ll.text
@@ -75,8 +121,9 @@ export function parsePython(code: string): PyNode {
if (COMPOUND.test(trimmed)) {
const ci = topLevelIndexOf(trimmed, ':')
if (ci !== -1 && ci < trimmed.length - 1) {
- // inline suite: `if x: f(); g()` — parse header and remainder separately
- node = parseLine(trimmed.slice(0, ci + 1), ll.lineNum)
+ // inline suite: `if x: f(); g()` — parse header and remainder separately.
+ // COMPOUND matched, so the header always parses to a block-opening kind.
+ node = parseLine(trimmed.slice(0, ci + 1), ll.lineNum) as BlockNode | null
const rest = trimmed.slice(ci + 1).trim()
if (node && rest) {
node.body = splitTopLevel(rest, ';')
@@ -97,7 +144,7 @@ export function parsePython(code: string): PyNode {
const body = parent.node.body ?? []
const last = body[body.length - 1]
if (last && node.type === 'Elif' && last.type === 'If') {
- const nested: PyNode = { type: 'If', test: node.test, body: node.body ?? [], orelse: [] }
+ const nested: IfNode = { type: 'If', test: node.test, body: node.body ?? [], orelse: [], line: node.line }
const tail = getLastIf(last)
tail.orelse = tail.orelse ?? []
tail.orelse.push(nested)
@@ -118,7 +165,7 @@ export function parsePython(code: string): PyNode {
// Attach except/finally to most recent try
if (node.type === 'ExceptHandler' || node.type === 'Finally') {
const body = parent.node.body ?? []
- const tryNode = [...body].reverse().find((n: PyNode) => n.type === 'Try')
+ const tryNode = [...body].reverse().find((n): n is TryNode => n.type === 'Try')
if (tryNode) {
if (node.type === 'ExceptHandler') tryNode.handlers.push(node)
else tryNode.finalbody = node
@@ -130,7 +177,7 @@ export function parsePython(code: string): PyNode {
// Attach case to most recent match
if (node.type === 'Case') {
const body = parent.node.body ?? []
- const matchNode = [...body].reverse().find((n: PyNode) => n.type === 'Match')
+ const matchNode = [...body].reverse().find((n): n is MatchNode => n.type === 'Match')
if (matchNode) {
matchNode.cases.push(node)
if (isBlock) stack.push({ indent, node, type: 'Case' })
@@ -140,7 +187,10 @@ export function parsePython(code: string): PyNode {
parent.node.body = parent.node.body ?? []
parent.node.body.push(node)
- if (isBlock) stack.push({ indent, node, type: node.type })
+ // isBlock is only set for If/For/While/FunctionDef/ClassDef/Try/With/Match
+ // headers (Elif/Else/ExceptHandler/Finally/Case were handled and
+ // `continue`d above), all of which are BlockNode kinds.
+ if (isBlock) stack.push({ indent, node: node as BlockNode, type: node.type })
}
return ast
@@ -167,7 +217,7 @@ function processStatement(node: PyNode, ctx: TraversalContext): BlockResult {
}
}
-function processFunction(node: PyNode, ctx: TraversalContext): BlockResult {
+function processFunction(node: FunctionDefNode, ctx: TraversalContext): BlockResult {
const fn = ctx.graph.createNode('subroutine', `${node.isAsync ? 'async ' : ''}def ${node.name}(${node.params})`, 'rounded')
const end = ctx.graph.createNode('process', `end ${node.name}`, 'rounded')
const fCtx = ctx.clone(); fCtx.currentNode = fn; fCtx.returnTarget = end
@@ -179,7 +229,7 @@ function processFunction(node: PyNode, ctx: TraversalContext): BlockResult {
return { entry: fn, exit: end }
}
-function processClass(node: PyNode, ctx: TraversalContext): BlockResult {
+function processClass(node: ClassDefNode, ctx: TraversalContext): BlockResult {
const label = node.bases ? `class ${node.name}(${node.bases})` : `class ${node.name}`
const cls = ctx.graph.createNode('subroutine', label, 'rounded')
const cCtx = ctx.clone(); cCtx.currentNode = cls
@@ -188,9 +238,9 @@ function processClass(node: PyNode, ctx: TraversalContext): BlockResult {
return { entry: cls, exit: r.exit ?? cls }
}
-function processIf(node: PyNode, ctx: TraversalContext, sharedMerge?: FlowchartNode): BlockResult {
+function processIf(node: IfNode, ctx: TraversalContext, sharedMerge?: FlowchartNode): BlockResult {
const cond = ctx.graph.createNode('decision', node.test + '?', 'diamond')
- const merge = sharedMerge ?? ctx.graph.createNode('merge' as any, '', 'circle')
+ const merge = sharedMerge ?? ctx.graph.createNode('merge', '', 'circle')
const tCtx = ctx.clone(); tCtx.currentNode = cond
const tRes = processBlock(node.body ?? [], tCtx)
if (tRes.entry) { ctx.graph.connect(cond, tRes.entry, 'Yes'); if (tRes.exit) ctx.graph.connect(tRes.exit, merge) }
@@ -219,9 +269,9 @@ function processIf(node: PyNode, ctx: TraversalContext, sharedMerge?: FlowchartN
return { entry: cond, exit: merge }
}
-function processFor(node: PyNode, ctx: TraversalContext): BlockResult {
+function processFor(node: ForNode, ctx: TraversalContext): BlockResult {
const cond = ctx.graph.createNode('decision', `${node.target} in ${node.iter}?`, 'diamond')
- const after = ctx.graph.createNode('merge' as any, '', 'circle')
+ const after = ctx.graph.createNode('merge', '', 'circle')
const lCtx = ctx.clone(); lCtx.currentNode = cond; lCtx.breakTarget = after; lCtx.continueTarget = cond
const r = processBlock(node.body ?? [], lCtx)
if (r.entry) { ctx.graph.connect(cond, r.entry, 'Yes'); if (r.exit) ctx.graph.connect(r.exit, cond) }
@@ -234,9 +284,9 @@ function processFor(node: PyNode, ctx: TraversalContext): BlockResult {
return { entry: cond, exit: after }
}
-function processWhile(node: PyNode, ctx: TraversalContext): BlockResult {
+function processWhile(node: WhileNode, ctx: TraversalContext): BlockResult {
const cond = ctx.graph.createNode('decision', node.test + '?', 'diamond')
- const after = ctx.graph.createNode('merge' as any, '', 'circle')
+ const after = ctx.graph.createNode('merge', '', 'circle')
const lCtx = ctx.clone(); lCtx.currentNode = cond; lCtx.breakTarget = after; lCtx.continueTarget = cond
const r = processBlock(node.body ?? [], lCtx)
if (r.entry) { ctx.graph.connect(cond, r.entry, 'Yes'); if (r.exit) ctx.graph.connect(r.exit, cond) }
@@ -249,9 +299,9 @@ function processWhile(node: PyNode, ctx: TraversalContext): BlockResult {
return { entry: cond, exit: after }
}
-function processTry(node: PyNode, ctx: TraversalContext): BlockResult {
+function processTry(node: TryNode, ctx: TraversalContext): BlockResult {
const tryNode = ctx.graph.createNode('process', 'try', 'rounded')
- const after = ctx.graph.createNode('merge' as any, '', 'circle')
+ const after = ctx.graph.createNode('merge', '', 'circle')
// handler nodes are created before the try body is walked so raises can
// route to them
@@ -300,7 +350,7 @@ function processTry(node: PyNode, ctx: TraversalContext): BlockResult {
return { entry: tryNode, exit: after }
}
-function processWith(node: PyNode, ctx: TraversalContext): BlockResult {
+function processWith(node: WithNode, ctx: TraversalContext): BlockResult {
const w = ctx.graph.createNode('process', `${node.isAsync ? 'async ' : ''}with ${node.items}`, 'rounded')
const wCtx = ctx.clone(); wCtx.currentNode = w
const r = processBlock(node.body ?? [], wCtx)
@@ -308,9 +358,9 @@ function processWith(node: PyNode, ctx: TraversalContext): BlockResult {
return { entry: w, exit: r.exit ?? w }
}
-function processMatch(node: PyNode, ctx: TraversalContext): BlockResult {
+function processMatch(node: MatchNode, ctx: TraversalContext): BlockResult {
const match = ctx.graph.createNode('decision', `match ${node.subject}`, 'diamond')
- const after = ctx.graph.createNode('merge' as any, '', 'circle')
+ const after = ctx.graph.createNode('merge', '', 'circle')
for (const c of (node.cases ?? [])) {
const label = c.pattern === '_' ? 'default' : `case ${c.pattern}`
const caseN = ctx.graph.createNode('process', label, 'rectangle')
@@ -324,29 +374,33 @@ function processMatch(node: PyNode, ctx: TraversalContext): BlockResult {
return { entry: match, exit: after }
}
-function processReturn(node: PyNode, ctx: TraversalContext): BlockResult {
+function processReturn(node: ReturnNode, ctx: TraversalContext): BlockResult {
const n = ctx.graph.createNode('process', node.value ? `return ${node.value}` : 'return', 'rectangle')
if (ctx.returnTarget) ctx.graph.connect(n, ctx.returnTarget)
return { entry: n, exit: null }
}
-function processBreak(node: PyNode, ctx: TraversalContext): BlockResult {
+function processBreak(_node: BreakNode, ctx: TraversalContext): BlockResult {
const n = ctx.graph.createNode('process', 'break', 'rectangle')
if (ctx.breakTarget) ctx.graph.connect(n, ctx.breakTarget)
return { entry: n, exit: null }
}
-function processContinue(node: PyNode, ctx: TraversalContext): BlockResult {
+function processContinue(_node: ContinueNode, ctx: TraversalContext): BlockResult {
const n = ctx.graph.createNode('process', 'continue', 'rectangle')
if (ctx.continueTarget) ctx.graph.connect(n, ctx.continueTarget)
return { entry: n, exit: null }
}
-function processRaise(node: PyNode, ctx: TraversalContext): BlockResult {
+function processRaise(node: RaiseNode, ctx: TraversalContext): BlockResult {
const n = ctx.graph.createNode('process', node.exception ? `raise ${node.exception}` : 'raise', 'rectangle')
if (ctx.throwTarget) ctx.graph.connect(n, ctx.throwTarget)
return { entry: n, exit: null }
}
function processGeneric(node: PyNode, ctx: TraversalContext): BlockResult {
- let label = node.type === 'Assert' ? `assert ${node.test}` : node.type === 'Import' ? node.statement : node.value ?? node.type
- if ((label ?? '').length > 60) label = label.substring(0, 57) + '...'
+ let label: string
+ if (node.type === 'Assert') label = `assert ${node.test}`
+ else if (node.type === 'Import') label = node.statement
+ else if ('value' in node) label = node.value
+ else label = node.type
+ if (label.length > 60) label = label.substring(0, 57) + '...'
const n = ctx.graph.createNode('process', label, 'rectangle')
return { entry: n, exit: n }
}
diff --git a/lib/parser/typescript.ts b/lib/parser/typescript.ts
index 79bb7ff..35c6bdd 100644
--- a/lib/parser/typescript.ts
+++ b/lib/parser/typescript.ts
@@ -1,4 +1,3 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
import * as acorn from 'acorn'
import * as acornTypescript from 'acorn-typescript'
import { processBlock } from './javascript'
@@ -7,9 +6,23 @@ import { FlowchartGraph, TraversalContext } from './types'
// Under `import * as x`, TS's CJS interop helper can clobber `.default` with
// the whole module object when the source has no `__esModule` marker — the
// named `tsPlugin` export is unambiguous across bundlers (webpack vs ts-jest).
+// eslint-disable-next-line @typescript-eslint/no-explicit-any -- targeted CJS-interop cast, see comment above
const tsPlugin = (acornTypescript as any).tsPlugin as typeof import('acorn-typescript').tsPlugin
-const TSParser = acorn.Parser.extend(tsPlugin() as any)
+// acorn-typescript's plugin factory returns a parser mixin typed against its
+// own internal `AcornParseClass` (see its middleware.d.ts), which acorn's
+// `Parser.extend` signature doesn't structurally recognize — a real type
+// mismatch between the two packages' own .d.ts files, not something this
+// module can resolve without patching either library.
+type ExtendPlugin = Parameters[0]
+const TSParser = acorn.Parser.extend(tsPlugin() as unknown as ExtendPlugin)
+
+// A parse error thrown by acorn/acorn-typescript: a SyntaxError-shaped
+// object with a non-standard `loc` position attached.
+interface AcornParseError {
+ message: string
+ loc?: { line: number; column: number } | null
+}
function parseTSCode(code: string): acorn.Program {
try {
@@ -19,9 +32,10 @@ function parseTSCode(code: string): acorn.Program {
locations: true,
allowReturnOutsideFunction: true,
allowAwaitOutsideFunction: true,
- } as any) as unknown as acorn.Program
- } catch (e: any) {
- throw new Error(`TypeScript Parse Error at line ${e.loc?.line ?? '?'}: ${e.message}`)
+ } as acorn.Options) as unknown as acorn.Program
+ } catch (e) {
+ const err = e as AcornParseError
+ throw new Error(`TypeScript Parse Error at line ${err.loc?.line ?? '?'}: ${err.message}`)
}
}
@@ -33,7 +47,7 @@ export function convertTS(code: string): FlowchartGraph {
ctx.currentNode = start
const ast = parseTSCode(code)
- const r = processBlock((ast as any).body, ctx)
+ const r = processBlock(ast.body as Parameters[0], ctx)
graph.connect(start, r.entry ?? end)
if (r.exit) graph.connect(r.exit, end)
diff --git a/package-lock.json b/package-lock.json
index adf87a9..3bb9b37 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,7 +12,6 @@
"@monaco-editor/react": "^4.7.0",
"@supabase/ssr": "^0.12.0",
"@supabase/supabase-js": "^2.108.2",
- "@types/three": "^0.185.0",
"@upstash/ratelimit": "^2.0.8",
"@upstash/redis": "^1.38.0",
"acorn-typescript": "^1.4.13",
@@ -25,15 +24,12 @@
"mermaid": "^11.15.0",
"nanoid": "^5.1.16",
"next": "^16.2.10",
- "next-themes": "^0.4.6",
"react": "^18",
"react-dom": "^18",
"react-resizable-panels": "^4.11.2",
- "shadcn": "^4.11.0",
"tailwind-merge": "^3.6.0",
"tailwindcss-animate": "^1.0.7",
"three": "^0.185.0",
- "tw-animate-css": "^1.4.0",
"vaul": "^1.1.2",
"zod": "^4.4.3"
},
@@ -42,11 +38,13 @@
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
+ "@types/three": "^0.185.1",
"dotenv": "^17.4.2",
"eslint": "^9",
"eslint-config-next": "^16.2.10",
"jest": "^30.4.2",
"postcss": "^8",
+ "shadcn": "^4.13.0",
"tailwindcss": "^3.4.1",
"ts-jest": "^29.4.11",
"typescript": "^5"
@@ -81,6 +79,7 @@
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz",
"integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-validator-identifier": "^7.29.7",
@@ -95,6 +94,7 @@
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz",
"integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -104,6 +104,7 @@
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz",
"integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.29.7",
@@ -134,6 +135,7 @@
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
"license": "MIT",
"bin": {
"json5": "lib/cli.js"
@@ -146,6 +148,7 @@
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -155,6 +158,7 @@
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz",
"integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.29.7",
@@ -171,6 +175,7 @@
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.29.7.tgz",
"integrity": "sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.29.7"
@@ -183,6 +188,7 @@
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz",
"integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/compat-data": "^7.29.7",
@@ -199,6 +205,7 @@
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
"license": "ISC",
"dependencies": {
"yallist": "^3.0.2"
@@ -208,6 +215,7 @@
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -217,6 +225,7 @@
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.29.7.tgz",
"integrity": "sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-annotate-as-pure": "^7.29.7",
@@ -238,6 +247,7 @@
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -247,6 +257,7 @@
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz",
"integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -256,6 +267,7 @@
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.29.7.tgz",
"integrity": "sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/traverse": "^7.29.7",
@@ -269,6 +281,7 @@
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz",
"integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/traverse": "^7.29.7",
@@ -282,6 +295,7 @@
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz",
"integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-module-imports": "^7.29.7",
@@ -299,6 +313,7 @@
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.29.7.tgz",
"integrity": "sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.29.7"
@@ -311,6 +326,7 @@
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz",
"integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -320,6 +336,7 @@
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.29.7.tgz",
"integrity": "sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-member-expression-to-functions": "^7.29.7",
@@ -337,6 +354,7 @@
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.29.7.tgz",
"integrity": "sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/traverse": "^7.29.7",
@@ -350,6 +368,7 @@
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
"integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -359,6 +378,7 @@
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",
"integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -368,6 +388,7 @@
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz",
"integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -377,6 +398,7 @@
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz",
"integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/template": "^7.29.7",
@@ -390,6 +412,7 @@
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz",
"integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.29.7"
@@ -502,6 +525,7 @@
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz",
"integrity": "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.29.7"
@@ -627,6 +651,7 @@
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz",
"integrity": "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.29.7"
@@ -642,6 +667,7 @@
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.29.7.tgz",
"integrity": "sha512-j0vCldybPC5b5dwCQOJ21uKtHzt7hxLygJTg9eF1ScfaikEDNfzn94XoW5Fi+seBR0nCyL23xaBFFkq7dTM8XQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-module-transforms": "^7.29.7",
@@ -658,6 +684,7 @@
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.29.7.tgz",
"integrity": "sha512-jK52h8LaLc7JarhQV2ofeFMts4H7vnOXnqZNA6fYglBTZewRBE51KWt3BUltW1P+KoPsYkHoJeXePuz4zo2LMw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-annotate-as-pure": "^7.29.7",
@@ -677,6 +704,7 @@
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.29.7.tgz",
"integrity": "sha512-/Foi8vKY2EVbed/1eZx0gJEEwHAIxogrySI7rULcRIvhZzbvoE/b5qG5Ghc0WKAFKOHA9SD1x7RsFlOYdutIiQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.29.7",
@@ -705,6 +733,7 @@
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz",
"integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.29.7",
@@ -719,6 +748,7 @@
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz",
"integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.29.7",
@@ -737,6 +767,7 @@
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz",
"integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-string-parser": "^7.29.7",
@@ -829,12 +860,14 @@
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/@dimforge/rapier3d-compat/-/rapier3d-compat-0.12.0.tgz",
"integrity": "sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow==",
+ "devOptional": true,
"license": "Apache-2.0"
},
"node_modules/@dotenvx/dotenvx": {
"version": "1.75.1",
"resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-1.75.1.tgz",
"integrity": "sha512-/BITOC9dmS/edY2zQwZNicQ059O6RKabtQfyEafV0nGtfYRNHYy1DIPiYVcov40+tob9hfmBnbR963dS+EQ1DQ==",
+ "dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"@dotenvx/primitives": "^0.8.0",
@@ -865,6 +898,7 @@
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz",
"integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=16"
@@ -874,6 +908,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
"integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -883,6 +918,7 @@
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
"integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"cross-spawn": "^7.0.3",
@@ -906,6 +942,7 @@
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
"integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=12.0.0"
@@ -923,6 +960,7 @@
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
"integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
@@ -935,6 +973,7 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
"integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+ "dev": true,
"license": "Apache-2.0",
"engines": {
"node": ">=10.17.0"
@@ -944,6 +983,7 @@
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
"integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
+ "dev": true,
"license": "MIT",
"bin": {
"is-docker": "cli.js"
@@ -959,6 +999,7 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -971,6 +1012,7 @@
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
"integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"is-docker": "^2.0.0"
@@ -983,6 +1025,7 @@
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.5.tgz",
"integrity": "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==",
+ "dev": true,
"license": "BlueOak-1.0.0",
"engines": {
"node": ">=18"
@@ -992,6 +1035,7 @@
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
"integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"path-key": "^3.0.0"
@@ -1004,6 +1048,7 @@
"version": "8.4.2",
"resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz",
"integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"define-lazy-prop": "^2.0.0",
@@ -1018,9 +1063,10 @@
}
},
"node_modules/@dotenvx/dotenvx/node_modules/picomatch": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
- "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz",
+ "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
@@ -1033,12 +1079,14 @@
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "dev": true,
"license": "ISC"
},
"node_modules/@dotenvx/dotenvx/node_modules/strip-final-newline": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
"integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -1048,6 +1096,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz",
"integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==",
+ "dev": true,
"license": "ISC",
"dependencies": {
"isexe": "^3.1.1"
@@ -1063,6 +1112,7 @@
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/@dotenvx/primitives/-/primitives-0.8.0.tgz",
"integrity": "sha512-VYJy0uhFm9zTJ1TxBaW/pA8bjbOM/OttaNMwZ1RHG4JKyRG7DhSdiqD1ipQoAyoD22olUtxbP78W9xY3Wd11bg==",
+ "dev": true,
"license": "BSD-3-Clause"
},
"node_modules/@emnapi/core": {
@@ -1271,6 +1321,7 @@
"version": "1.19.14",
"resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.14.tgz",
"integrity": "sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=18.14.1"
@@ -2526,6 +2577,7 @@
"version": "2.3.5",
"resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
"integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.5",
@@ -2570,6 +2622,7 @@
"version": "1.29.0",
"resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.29.0.tgz",
"integrity": "sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@hono/node-server": "^1.19.9",
@@ -2610,6 +2663,7 @@
"version": "8.20.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz",
"integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.3",
@@ -2626,6 +2680,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true,
"license": "MIT"
},
"node_modules/@monaco-editor/loader": {
@@ -3254,6 +3309,7 @@
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz",
"integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==",
+ "dev": true,
"license": "MIT"
},
"node_modules/@sinclair/typebox": {
@@ -3267,6 +3323,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz",
"integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
@@ -3404,6 +3461,7 @@
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.27.0.tgz",
"integrity": "sha512-Wf29UqxWDpc+i61k3oIOzcUfQt79PIT9y/MWfAGlrkjg6lBC1hwDECLXPVJAhWjiGbfBCxZd65F/LIZF3+jeJQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"fast-glob": "^3.3.3",
@@ -3415,15 +3473,17 @@
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
"integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": "18 || 20 || >=22"
}
},
"node_modules/@ts-morph/common/node_modules/brace-expansion": {
- "version": "5.0.6",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz",
- "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==",
+ "version": "5.0.7",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz",
+ "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^4.0.2"
@@ -3436,6 +3496,7 @@
"version": "10.2.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz",
"integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==",
+ "dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"brace-expansion": "^5.0.5"
@@ -3451,6 +3512,7 @@
"version": "23.1.3",
"resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-23.1.3.tgz",
"integrity": "sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==",
+ "devOptional": true,
"license": "MIT"
},
"node_modules/@tybys/wasm-util": {
@@ -3876,12 +3938,14 @@
"version": "0.17.4",
"resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.4.tgz",
"integrity": "sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==",
+ "devOptional": true,
"license": "MIT"
},
"node_modules/@types/three": {
- "version": "0.185.0",
- "resolved": "https://registry.npmjs.org/@types/three/-/three-0.185.0.tgz",
- "integrity": "sha512-O2Uy8Cj4Nonr8dWUUbifMdPe8B0Mq7EdOHb89S4+kjUw/KhbjTZrUuYlrQ1bpUKG+EP9QJnN7qNxbHGlGoLHMA==",
+ "version": "0.185.1",
+ "resolved": "https://registry.npmjs.org/@types/three/-/three-0.185.1.tgz",
+ "integrity": "sha512-db1xTb+EgYF2didW+eudSvVPtn75zo+fGsY8ShQrJY/B5ZBmC2Fiaykv3aImHAlCNEGuMPkPGXBJGLwzu5mC7A==",
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"@dimforge/rapier3d-compat": "~0.12.0",
@@ -3903,12 +3967,14 @@
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@types/validate-npm-package-name/-/validate-npm-package-name-4.0.2.tgz",
"integrity": "sha512-lrpDziQipxCEeK5kWxvljWYhUvOiB2A9izZd9B2AFarYAkqZshb4lPbRs7zKEic6eGtH8V/2qJW+dPp9OtF6bw==",
+ "dev": true,
"license": "MIT"
},
"node_modules/@types/webxr": {
"version": "0.5.24",
"resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.24.tgz",
"integrity": "sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg==",
+ "devOptional": true,
"license": "MIT"
},
"node_modules/@types/yargs": {
@@ -4577,6 +4643,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
"integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"mime-types": "^3.0.0",
@@ -4617,15 +4684,6 @@
"acorn": ">=8.9.0"
}
},
- "node_modules/agent-base": {
- "version": "7.1.4",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
- "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 14"
- }
- },
"node_modules/ajv": {
"version": "6.15.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz",
@@ -4647,6 +4705,7 @@
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz",
"integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"ajv": "^8.0.0"
@@ -4664,6 +4723,7 @@
"version": "8.20.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz",
"integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.3",
@@ -4680,6 +4740,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true,
"license": "MIT"
},
"node_modules/animejs": {
@@ -4708,6 +4769,7 @@
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
"integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -4746,6 +4808,7 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -4796,6 +4859,7 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
"license": "Python-2.0"
},
"node_modules/aria-hidden": {
@@ -4984,6 +5048,7 @@
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz",
"integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"tslib": "^2.0.1"
@@ -5013,6 +5078,7 @@
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/atomically/-/atomically-1.7.0.tgz",
"integrity": "sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=10.12.0"
@@ -5188,6 +5254,7 @@
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz",
"integrity": "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"bytes": "^3.1.2",
@@ -5212,6 +5279,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz",
"integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
@@ -5222,9 +5290,10 @@
}
},
"node_modules/body-parser/node_modules/iconv-lite": {
- "version": "0.7.2",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz",
- "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==",
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz",
+ "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
@@ -5264,6 +5333,7 @@
"version": "4.28.4",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.4.tgz",
"integrity": "sha512-MTc8i/x9jBQd1iMw2CFGS+rwMa07eYjLR0CCTLDACl9xhxy+nIs3KeML/biicXtk9JrZ6dnnTatmc7ErPXIxqw==",
+ "dev": true,
"funding": [
{
"type": "opencollective",
@@ -5327,6 +5397,7 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz",
"integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"run-applescript": "^7.0.0"
@@ -5342,6 +5413,7 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.8"
@@ -5370,6 +5442,7 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
@@ -5383,6 +5456,7 @@
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
"integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
@@ -5399,6 +5473,7 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -5545,6 +5620,7 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz",
"integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"restore-cursor": "^5.0.0"
@@ -5560,6 +5636,7 @@
"version": "2.9.2",
"resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz",
"integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -5669,6 +5746,7 @@
"version": "13.0.3",
"resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-13.0.3.tgz",
"integrity": "sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==",
+ "dev": true,
"license": "MIT"
},
"node_modules/collect-v8-coverage": {
@@ -5718,6 +5796,7 @@
"version": "10.2.0",
"resolved": "https://registry.npmjs.org/conf/-/conf-10.2.0.tgz",
"integrity": "sha512-8fLl9F04EJqjSqH+QjITQfJF8BrOVaYr1jewVgSRAEWePfxT0sku4w2hrGQ60BC/TNLGQ2pgxNlTbWQmMPFvXg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"ajv": "^8.6.3",
@@ -5742,6 +5821,7 @@
"version": "8.20.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz",
"integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.3",
@@ -5758,6 +5838,7 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz",
"integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"ajv": "^8.0.0"
@@ -5775,18 +5856,21 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true,
"license": "MIT"
},
"node_modules/conf/node_modules/json-schema-typed": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-7.0.3.tgz",
"integrity": "sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A==",
+ "dev": true,
"license": "BSD-2-Clause"
},
"node_modules/content-disposition": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz",
"integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
@@ -5800,6 +5884,7 @@
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
"integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.6"
@@ -5809,6 +5894,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true,
"license": "MIT"
},
"node_modules/cookie": {
@@ -5828,6 +5914,7 @@
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
"integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.6.0"
@@ -5837,6 +5924,7 @@
"version": "2.8.6",
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz",
"integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"object-assign": "^4",
@@ -5863,6 +5951,7 @@
"version": "9.0.2",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.2.tgz",
"integrity": "sha512-gtTZxTDau1wL7Y7zifc2dd8jHSK/k6BTx/2Xp/BpdlAdnlYWFVt7qhJqgwi7637yRwRQ3qL4ZidbB4I8tA5VOg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"env-paths": "^2.2.1",
@@ -5889,6 +5978,7 @@
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"path-key": "^3.1.0",
@@ -6433,15 +6523,6 @@
"dev": true,
"license": "BSD-2-Clause"
},
- "node_modules/data-uri-to-buffer": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
- "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
- "license": "MIT",
- "engines": {
- "node": ">= 12"
- }
- },
"node_modules/data-view-buffer": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz",
@@ -6506,6 +6587,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/debounce-fn/-/debounce-fn-4.0.0.tgz",
"integrity": "sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"mimic-fn": "^3.0.0"
@@ -6521,6 +6603,7 @@
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
@@ -6538,6 +6621,7 @@
"version": "1.7.2",
"resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz",
"integrity": "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==",
+ "dev": true,
"license": "MIT",
"peerDependencies": {
"babel-plugin-macros": "^3.1.0"
@@ -6559,6 +6643,7 @@
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -6568,6 +6653,7 @@
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.0.tgz",
"integrity": "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"bundle-name": "^4.1.0",
@@ -6584,6 +6670,7 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz",
"integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
@@ -6614,6 +6701,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz",
"integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
@@ -6653,6 +6741,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.8"
@@ -6694,6 +6783,7 @@
"version": "8.0.4",
"resolved": "https://registry.npmjs.org/diff/-/diff-8.0.4.tgz",
"integrity": "sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==",
+ "dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.3.1"
@@ -6718,6 +6808,7 @@
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz",
"integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"is-obj": "^2.0.0"
@@ -6733,6 +6824,7 @@
"version": "17.4.2",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz",
"integrity": "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==",
+ "dev": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=12"
@@ -6745,6 +6837,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
@@ -6766,12 +6859,14 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
+ "dev": true,
"license": "MIT"
},
"node_modules/electron-to-chromium": {
"version": "1.5.378",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.378.tgz",
"integrity": "sha512-VinvOAuuPmdD1guEgGv5f2Qp7/vlfqOrUOMYNnOD4wj3pit8kRsQHzfIf6teyUGWo15Tg5+bOJaRunvyltpVWQ==",
+ "dev": true,
"license": "ISC"
},
"node_modules/emittery": {
@@ -6798,6 +6893,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
"integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.8"
@@ -6807,6 +6903,7 @@
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz",
"integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"ansi-colors": "^4.1.1",
@@ -6820,6 +6917,7 @@
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
"integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -6829,6 +6927,7 @@
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz",
"integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"is-arrayish": "^0.2.1"
@@ -6926,6 +7025,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -6972,6 +7072,7 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz",
"integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
@@ -7043,6 +7144,7 @@
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -7052,6 +7154,7 @@
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
+ "dev": true,
"license": "MIT"
},
"node_modules/escape-string-regexp": {
@@ -7503,6 +7606,7 @@
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true,
"license": "BSD-2-Clause",
"bin": {
"esparse": "bin/esparse.js",
@@ -7562,6 +7666,7 @@
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.6"
@@ -7571,6 +7676,7 @@
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz",
"integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"eventsource-parser": "^3.0.1"
@@ -7583,6 +7689,7 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.1.0.tgz",
"integrity": "sha512-kJezFj9YFAMLeORyi7aCLxLbD5/qWMQnoMVlVPyHIll7lgRJCc3JVln9Vgl9nwQi0YkMnhdGTMNn7CkRRAptMg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=18.0.0"
@@ -7592,6 +7699,7 @@
"version": "9.6.1",
"resolved": "https://registry.npmjs.org/execa/-/execa-9.6.1.tgz",
"integrity": "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@sindresorhus/merge-streams": "^4.0.0",
@@ -7646,6 +7754,7 @@
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz",
"integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"accepts": "^2.0.0",
@@ -7689,6 +7798,7 @@
"version": "8.5.2",
"resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.5.2.tgz",
"integrity": "sha512-5Kb34ipNX694DH48vN9irak1Qx30nb0PLYHXfJgw4YEjiC3ZEmZJhwOp+VfiCYwFzvFTdB9QkArYS5kXa2cx2A==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"ip-address": "^10.2.0"
@@ -7707,6 +7817,7 @@
"version": "0.7.2",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
"integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.6"
@@ -7716,6 +7827,7 @@
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true,
"license": "MIT"
},
"node_modules/fast-glob": {
@@ -7761,9 +7873,10 @@
"license": "MIT"
},
"node_modules/fast-uri": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz",
- "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==",
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.3.tgz",
+ "integrity": "sha512-i70LwGWUduXqzicKXWshooq+sWL1K3WUU5rKZNG/0i3a1OSoX3HqhH5WbWwTmqWfor4urUakGPiRQcleRZTwOg==",
+ "dev": true,
"funding": [
{
"type": "github",
@@ -7795,39 +7908,18 @@
"bser": "2.1.1"
}
},
- "node_modules/fetch-blob": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
- "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/jimmywarting"
- },
- {
- "type": "paypal",
- "url": "https://paypal.me/jimmywarting"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "node-domexception": "^1.0.0",
- "web-streams-polyfill": "^3.0.3"
- },
- "engines": {
- "node": "^12.20 || >= 14.13"
- }
- },
"node_modules/fflate": {
"version": "0.8.3",
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.3.tgz",
"integrity": "sha512-tbZNuJrLwGUp3zshBtdy4W+ORxZuIh8a5ilyIEQDC5rY1f3U20JMry0Ll3WBzU58EZKsEuJFXhb5gwv8CsPvgA==",
+ "devOptional": true,
"license": "MIT"
},
"node_modules/figures": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz",
"integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"is-unicode-supported": "^2.0.0"
@@ -7868,6 +7960,7 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz",
"integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"debug": "^4.4.0",
@@ -7956,22 +8049,11 @@
"url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/formdata-polyfill": {
- "version": "4.0.10",
- "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
- "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
- "license": "MIT",
- "dependencies": {
- "fetch-blob": "^3.1.2"
- },
- "engines": {
- "node": ">=12.20.0"
- }
- },
"node_modules/forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.6"
@@ -7981,15 +8063,17 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
"integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/fs-extra": {
- "version": "11.3.5",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.5.tgz",
- "integrity": "sha512-eKpRKAovdpZtR1WopLHxlBWvAgPny3c4gX1G5Jhwmmw4XJj0ifSD5qB5TOo8hmA0wlRKDAOAhEE1yVPgs6Fgcg==",
+ "version": "11.3.6",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.6.tgz",
+ "integrity": "sha512-w8ZNZr2mKIc7qeNaQ9AVPT1+iFaI+Avd4xudVOvdDJ8VytREi1Ft5Ih7hd9jjehod8vAM5GMsfQ/TpPf4EyoEA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"graceful-fs": "^4.2.0",
@@ -8068,6 +8152,7 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/fuzzysort/-/fuzzysort-3.1.0.tgz",
"integrity": "sha512-sR9BNCjBg6LNgwvxlBd0sBABvQitkLzoVY9MYYROQVX/FvfJ4Mai9LsGhDgd8qYdds0bY77VzYd5iuB+v5rwQQ==",
+ "dev": true,
"license": "MIT"
},
"node_modules/generator-function": {
@@ -8084,6 +8169,7 @@
"version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
"integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -8103,6 +8189,7 @@
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz",
"integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
@@ -8115,6 +8202,7 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
@@ -8148,6 +8236,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/get-own-enumerable-keys/-/get-own-enumerable-keys-1.0.0.tgz",
"integrity": "sha512-PKsK2FSrQCyxcGHsGrLDcK0lx+0Ke+6e8KFFozA9/fIQLhQzPaRvJFdcz7+Axg3jUH/Mq+NI4xa5u/UT2tQskA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=14.16"
@@ -8170,6 +8259,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
@@ -8183,6 +8273,7 @@
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz",
"integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@sec-ant/readable-stream": "^0.4.1",
@@ -8272,6 +8363,7 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -8284,6 +8376,7 @@
"version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true,
"license": "ISC"
},
"node_modules/hachure-fill": {
@@ -8370,6 +8463,7 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -8424,9 +8518,10 @@
}
},
"node_modules/hono": {
- "version": "4.12.27",
- "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.27.tgz",
- "integrity": "sha512-1yrb/+w6HWQJrUCLkJ2IF5jNIPvvFkblV5RNOYl6bV+OA6p9GLcMpHFFGTosSvHvcAUibuUukRqhlYI4z32C7Q==",
+ "version": "4.12.30",
+ "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.30.tgz",
+ "integrity": "sha512-emn+JoJjrN9YTpRDS5it/UI2SO9BAE37T6I3d963RxcZ81G9A4pr2SZTEiiaiKbzx+NKRg5BZ89fCL7gCJCUog==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=16.9.0"
@@ -8449,6 +8544,7 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
"integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"depd": "~2.0.0",
@@ -8465,23 +8561,11 @@
"url": "https://opencollective.com/express"
}
},
- "node_modules/https-proxy-agent": {
- "version": "7.0.6",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
- "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
- "license": "MIT",
- "dependencies": {
- "agent-base": "^7.1.2",
- "debug": "4"
- },
- "engines": {
- "node": ">= 14"
- }
- },
"node_modules/human-signals": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz",
"integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==",
+ "dev": true,
"license": "Apache-2.0",
"engines": {
"node": ">=18.18.0"
@@ -8512,6 +8596,7 @@
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
"integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">= 4"
@@ -8521,6 +8606,7 @@
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
"integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"parent-module": "^1.0.0",
@@ -8589,6 +8675,7 @@
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true,
"license": "ISC"
},
"node_modules/internal-slot": {
@@ -8619,6 +8706,7 @@
"version": "10.2.0",
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz",
"integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">= 12"
@@ -8628,6 +8716,7 @@
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.10"
@@ -8655,6 +8744,7 @@
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
"integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+ "dev": true,
"license": "MIT"
},
"node_modules/is-async-function": {
@@ -8799,6 +8889,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz",
"integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==",
+ "dev": true,
"license": "MIT",
"bin": {
"is-docker": "cli.js"
@@ -8907,6 +8998,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-in-ssh/-/is-in-ssh-1.0.0.tgz",
"integrity": "sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=20"
@@ -8919,6 +9011,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz",
"integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"is-docker": "^3.0.0"
@@ -8937,6 +9030,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz",
"integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
@@ -9001,6 +9095,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
"integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -9010,6 +9105,7 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
"integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
@@ -9022,6 +9118,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
"integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
+ "dev": true,
"license": "MIT"
},
"node_modules/is-regex": {
@@ -9047,6 +9144,7 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-3.1.0.tgz",
"integrity": "sha512-rbku49cWloU5bSMI+zaRaXdQHXnthP6DZ/vLnfdSKyL4zUzuWnomtOEiZZOd+ioQ+avFo/qau3KPTc7Fjy1uPA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
@@ -9088,6 +9186,7 @@
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz",
"integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
@@ -9151,6 +9250,7 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz",
"integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
@@ -9209,6 +9309,7 @@
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz",
"integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"is-inside-container": "^1.0.0"
@@ -9231,6 +9332,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
"license": "ISC"
},
"node_modules/istanbul-lib-coverage": {
@@ -10182,6 +10284,7 @@
"version": "6.2.3",
"resolved": "https://registry.npmjs.org/jose/-/jose-6.2.3.tgz",
"integrity": "sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==",
+ "dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/panva"
@@ -10197,6 +10300,7 @@
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz",
"integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==",
+ "dev": true,
"funding": [
{
"type": "github",
@@ -10219,6 +10323,7 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
"integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+ "dev": true,
"license": "MIT",
"bin": {
"jsesc": "bin/jsesc"
@@ -10238,6 +10343,7 @@
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "dev": true,
"license": "MIT"
},
"node_modules/json-schema-traverse": {
@@ -10251,6 +10357,7 @@
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz",
"integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==",
+ "dev": true,
"license": "BSD-2-Clause"
},
"node_modules/json-stable-stringify-without-jsonify": {
@@ -10277,6 +10384,7 @@
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz",
"integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"universalify": "^2.0.0"
@@ -10345,6 +10453,7 @@
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
"integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -10458,6 +10567,7 @@
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz",
"integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"chalk": "^5.3.0",
@@ -10474,6 +10584,7 @@
"version": "5.6.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
"integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": "^12.17.0 || ^14.13 || >=16.0.0"
@@ -10486,6 +10597,7 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz",
"integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
@@ -10571,6 +10683,7 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -10580,6 +10693,7 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
"integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.8"
@@ -10589,6 +10703,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
"integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
@@ -10601,6 +10716,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true,
"license": "MIT"
},
"node_modules/merge2": {
@@ -10645,6 +10761,7 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-1.1.1.tgz",
"integrity": "sha512-oRFNWJRDA/WTrVj7NWvqa5HqE1t9MYDj2VaWirQCzCCrAd2GHrqR/sQezCxiWATPNlKTcRaPRHPJwIRoPBAp5g==",
+ "devOptional": true,
"license": "MIT"
},
"node_modules/micromatch": {
@@ -10664,6 +10781,7 @@
"version": "1.54.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
"integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.6"
@@ -10673,6 +10791,7 @@
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz",
"integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"mime-db": "^1.54.0"
@@ -10689,6 +10808,7 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz",
"integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -10698,6 +10818,7 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz",
"integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
@@ -10723,6 +10844,7 @@
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -10766,6 +10888,7 @@
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
"license": "MIT"
},
"node_modules/mz": {
@@ -10824,6 +10947,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
"integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.6"
@@ -10889,16 +11013,6 @@
}
}
},
- "node_modules/next-themes": {
- "version": "0.4.6",
- "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.4.6.tgz",
- "integrity": "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==",
- "license": "MIT",
- "peerDependencies": {
- "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc"
- }
- },
"node_modules/next/node_modules/nanoid": {
"version": "3.3.15",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz",
@@ -10945,26 +11059,6 @@
"node": "^10 || ^12 || >=14"
}
},
- "node_modules/node-domexception": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
- "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
- "deprecated": "Use your platform's native DOMException instead",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/jimmywarting"
- },
- {
- "type": "github",
- "url": "https://paypal.me/jimmywarting"
- }
- ],
- "license": "MIT",
- "engines": {
- "node": ">=10.5.0"
- }
- },
"node_modules/node-exports-info": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.2.tgz",
@@ -10994,24 +11088,6 @@
"semver": "bin/semver.js"
}
},
- "node_modules/node-fetch": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
- "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
- "license": "MIT",
- "dependencies": {
- "data-uri-to-buffer": "^4.0.0",
- "fetch-blob": "^3.1.4",
- "formdata-polyfill": "^4.0.10"
- },
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/node-fetch"
- }
- },
"node_modules/node-int64": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
@@ -11023,6 +11099,7 @@
"version": "2.0.50",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.50.tgz",
"integrity": "sha512-J6l92tKHX6w8Jy5nO1Vuc01NoIiRGi/d6qBKVxh+IQ8Cr3b6HbVNfKiF8ZpFKufTwpwxMmce2W3iQZ861ZRyTg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
@@ -11041,6 +11118,7 @@
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz",
"integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"path-key": "^4.0.0",
@@ -11057,6 +11135,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
"integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
@@ -11087,6 +11166,7 @@
"version": "1.13.4",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
"integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -11109,6 +11189,7 @@
"version": "1.1.33",
"resolved": "https://registry.npmjs.org/object-treeify/-/object-treeify-1.1.33.tgz",
"integrity": "sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">= 10"
@@ -11208,6 +11289,7 @@
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
"integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"ee-first": "1.1.1"
@@ -11220,6 +11302,7 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
"license": "ISC",
"dependencies": {
"wrappy": "1"
@@ -11229,6 +11312,7 @@
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"mimic-fn": "^2.1.0"
@@ -11244,6 +11328,7 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -11253,6 +11338,7 @@
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/open/-/open-11.0.0.tgz",
"integrity": "sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"default-browser": "^5.4.0",
@@ -11291,6 +11377,7 @@
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/ora/-/ora-8.2.0.tgz",
"integrity": "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"chalk": "^5.3.0",
@@ -11314,6 +11401,7 @@
"version": "6.2.2",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
"integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
@@ -11326,6 +11414,7 @@
"version": "5.6.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
"integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": "^12.17.0 || ^14.13 || >=16.0.0"
@@ -11338,12 +11427,14 @@
"version": "10.6.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
"integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
+ "dev": true,
"license": "MIT"
},
"node_modules/ora/node_modules/string-width": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
"integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"emoji-regex": "^10.3.0",
@@ -11361,6 +11452,7 @@
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
"integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^6.2.2"
@@ -11426,6 +11518,7 @@
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -11448,6 +11541,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"callsites": "^3.0.0"
@@ -11460,6 +11554,7 @@
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
"integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.0.0",
@@ -11478,6 +11573,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz",
"integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
@@ -11490,6 +11586,7 @@
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.8"
@@ -11499,6 +11596,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
"integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
+ "dev": true,
"license": "MIT"
},
"node_modules/path-data-parser": {
@@ -11531,6 +11629,7 @@
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -11563,6 +11662,7 @@
"version": "8.4.2",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz",
"integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==",
+ "dev": true,
"license": "MIT",
"funding": {
"type": "opencollective",
@@ -11609,6 +11709,7 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz",
"integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=16.20.0"
@@ -11687,6 +11788,7 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz",
"integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"find-up": "^3.0.0"
@@ -11699,6 +11801,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"locate-path": "^3.0.0"
@@ -11711,6 +11814,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"p-locate": "^3.0.0",
@@ -11724,6 +11828,7 @@
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"p-try": "^2.0.0"
@@ -11739,6 +11844,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"p-limit": "^2.0.0"
@@ -11751,6 +11857,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
"integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=4"
@@ -11981,6 +12088,7 @@
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/powershell-utils/-/powershell-utils-0.1.0.tgz",
"integrity": "sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=20"
@@ -12032,6 +12140,7 @@
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.3.0.tgz",
"integrity": "sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"parse-ms": "^4.0.0"
@@ -12047,6 +12156,7 @@
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
"integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"kleur": "^3.0.3",
@@ -12060,6 +12170,7 @@
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
"integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -12081,6 +12192,7 @@
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
"integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"forwarded": "0.2.0",
@@ -12121,6 +12233,7 @@
"version": "6.15.3",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz",
"integrity": "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==",
+ "dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"es-define-property": "^1.0.1",
@@ -12154,18 +12267,24 @@
"license": "MIT"
},
"node_modules/range-parser": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
- "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.3.0.tgz",
+ "integrity": "sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.6"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
}
},
"node_modules/raw-body": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz",
"integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"bytes": "~3.1.2",
@@ -12178,9 +12297,10 @@
}
},
"node_modules/raw-body/node_modules/iconv-lite": {
- "version": "0.7.2",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz",
- "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==",
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz",
+ "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
@@ -12342,9 +12462,10 @@
}
},
"node_modules/recast": {
- "version": "0.23.11",
- "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.11.tgz",
- "integrity": "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==",
+ "version": "0.23.12",
+ "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.12.tgz",
+ "integrity": "sha512-dEWRjcINDu/F4l2dYx57ugBtD7HV9KXESyxhzw/MqWLeglJrsjJKqACPyUPg+6AF8mIgm+Zi0dZ3ACoIg+QtpA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"ast-types": "^0.16.1",
@@ -12415,6 +12536,7 @@
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -12477,6 +12599,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=4"
@@ -12496,6 +12619,7 @@
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz",
"integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"onetime": "^7.0.0",
@@ -12512,6 +12636,7 @@
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz",
"integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"mimic-function": "^5.0.0"
@@ -12555,6 +12680,7 @@
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
"integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"debug": "^4.4.0",
@@ -12571,6 +12697,7 @@
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz",
"integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
@@ -12682,6 +12809,7 @@
"version": "7.8.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz",
"integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
+ "devOptional": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -12694,6 +12822,7 @@
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz",
"integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"debug": "^4.4.3",
@@ -12720,6 +12849,7 @@
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz",
"integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"encodeurl": "^2.0.0",
@@ -12788,12 +12918,14 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
+ "dev": true,
"license": "ISC"
},
"node_modules/shadcn": {
- "version": "4.11.0",
- "resolved": "https://registry.npmjs.org/shadcn/-/shadcn-4.11.0.tgz",
- "integrity": "sha512-UV0cchFea9hO7poV1CuEP0wvmYjpAqcxCKdy23bndl2Du2ARtDs8A4xdzfhUjDBeOW1nNpJ6lXmsEpsply2SfQ==",
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/shadcn/-/shadcn-4.13.0.tgz",
+ "integrity": "sha512-5fuJ4jI/GcPeA/iTL4cJivCZuYQGXz/N3bIzyd+Gd/FM6xUCy2MxGG+LaDQuw2cjNy9zGPSFPTEmI048UwPTZA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/core": "^7.28.0",
@@ -12813,9 +12945,7 @@
"fast-glob": "^3.3.3",
"fs-extra": "^11.3.1",
"fuzzysort": "^3.1.0",
- "https-proxy-agent": "^7.0.6",
"kleur": "^4.1.5",
- "node-fetch": "^3.3.2",
"open": "^11.0.0",
"ora": "^8.2.0",
"postcss": "^8.5.6",
@@ -12826,18 +12956,23 @@
"tailwind-merge": "^3.0.1",
"ts-morph": "^26.0.0",
"tsconfig-paths": "^4.2.0",
+ "undici": "^7.27.2",
"validate-npm-package-name": "^7.0.1",
"zod": "^3.24.1",
"zod-to-json-schema": "^3.24.6"
},
"bin": {
"shadcn": "dist/index.js"
+ },
+ "engines": {
+ "node": ">=20.18.1"
}
},
"node_modules/shadcn/node_modules/commander": {
"version": "14.0.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz",
"integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=20"
@@ -12847,6 +12982,7 @@
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
"license": "MIT",
"bin": {
"json5": "lib/cli.js"
@@ -12859,6 +12995,7 @@
"version": "7.1.4",
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz",
"integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"cssesc": "^3.0.0",
@@ -12872,6 +13009,7 @@
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz",
"integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"json5": "^2.2.2",
@@ -12886,6 +13024,7 @@
"version": "3.25.76",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
+ "dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/colinhacks"
@@ -12940,6 +13079,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"shebang-regex": "^3.0.0"
@@ -12952,6 +13092,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -12961,6 +13102,7 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz",
"integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
@@ -12980,6 +13122,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz",
"integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
@@ -12996,6 +13139,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
@@ -13014,6 +13158,7 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
@@ -13033,6 +13178,7 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "dev": true,
"license": "ISC",
"engines": {
"node": ">=14"
@@ -13045,6 +13191,7 @@
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
"integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
+ "dev": true,
"license": "MIT"
},
"node_modules/slash": {
@@ -13061,6 +13208,7 @@
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
@@ -13133,6 +13281,7 @@
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
"integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.8"
@@ -13142,6 +13291,7 @@
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz",
"integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
@@ -13366,6 +13516,7 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-5.0.0.tgz",
"integrity": "sha512-zaJYxz2FtcMb4f+g60KsRNFOpVMUyuJgA51Zi5Z1DOTC3S59+OQiVOzE9GZt0x72uBGWKsQIuBKeF9iusmKFsg==",
+ "dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"get-own-enumerable-keys": "^1.0.0",
@@ -13383,6 +13534,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-3.0.0.tgz",
"integrity": "sha512-IlsXEHOjtKhpN8r/tRFj2nDyTmHvcfNeu/nrRIcXE17ROeatXchkojffa1SpdqW4cr/Fj6QkEf/Gn4zf6KKvEQ==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
@@ -13395,6 +13547,7 @@
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
@@ -13421,6 +13574,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
"integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=4"
@@ -13430,6 +13584,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz",
"integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
@@ -13544,9 +13699,10 @@
}
},
"node_modules/systeminformation": {
- "version": "5.31.11",
- "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.31.11.tgz",
- "integrity": "sha512-I6O7iaUj23AXRgCPDDnvi3xHvdOLp4+1YMbF+X194lJwY1NeWojgHJPhslVKcmTtrLTguRk3QJK+xEdTiI3P0w==",
+ "version": "5.31.16",
+ "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.31.16.tgz",
+ "integrity": "sha512-37NsFaeaqwYxanLgdJAGWj8OXIRgvSBsDXGhlC0uUoHyl9nf4HrNsZjqtQ9Gc99bj9FQpffzYccPVuQ6gpjfqg==",
+ "dev": true,
"license": "MIT",
"os": [
"darwin",
@@ -13714,6 +13870,7 @@
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz",
"integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==",
+ "dev": true,
"license": "MIT"
},
"node_modules/tinyexec": {
@@ -13793,6 +13950,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.6"
@@ -13909,6 +14067,7 @@
"version": "26.0.0",
"resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-26.0.0.tgz",
"integrity": "sha512-ztMO++owQnz8c/gIENcM9XfCEzgoGphTv+nKpYNM1bgsdOVC/jRZuEBf6N+mLLDNg68Kl+GgUZfOySaRiG1/Ug==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@ts-morph/common": "~0.27.0",
@@ -13934,15 +14093,6 @@
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"license": "0BSD"
},
- "node_modules/tw-animate-css": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/tw-animate-css/-/tw-animate-css-1.4.0.tgz",
- "integrity": "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/Wombosvideo"
- }
- },
"node_modules/type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@@ -13970,6 +14120,7 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz",
"integrity": "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"content-type": "^2.0.0",
@@ -13988,6 +14139,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz",
"integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
@@ -14079,7 +14231,7 @@
"version": "5.9.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
- "devOptional": true,
+ "dev": true,
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
@@ -14156,6 +14308,7 @@
"version": "7.28.0",
"resolved": "https://registry.npmjs.org/undici/-/undici-7.28.0.tgz",
"integrity": "sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=20.18.1"
@@ -14172,6 +14325,7 @@
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz",
"integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
@@ -14184,6 +14338,7 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">= 10.0.0"
@@ -14193,6 +14348,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
"integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.8"
@@ -14240,6 +14396,7 @@
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
"integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
+ "dev": true,
"funding": [
{
"type": "opencollective",
@@ -14366,6 +14523,7 @@
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-7.0.2.tgz",
"integrity": "sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A==",
+ "dev": true,
"license": "ISC",
"engines": {
"node": "^20.17.0 || >=22.9.0"
@@ -14375,6 +14533,7 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.8"
@@ -14403,19 +14562,11 @@
"makeerror": "1.0.12"
}
},
- "node_modules/web-streams-polyfill": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
- "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
- "license": "MIT",
- "engines": {
- "node": ">= 8"
- }
- },
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
"license": "ISC",
"dependencies": {
"isexe": "^2.0.0"
@@ -14638,6 +14789,7 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true,
"license": "ISC"
},
"node_modules/write-file-atomic": {
@@ -14658,6 +14810,7 @@
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.3.1.tgz",
"integrity": "sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"is-wsl": "^3.1.0",
@@ -14684,6 +14837,7 @@
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true,
"license": "ISC"
},
"node_modules/yargs": {
@@ -14751,9 +14905,10 @@
}
},
"node_modules/yocto-spinner": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/yocto-spinner/-/yocto-spinner-1.2.0.tgz",
- "integrity": "sha512-Yw0hUB6UA3o4YUgKy3oSe9a4cxoaZ9sBfYDw+JSxo6Id0KoJGoxzPA24qqUXYKBWABs/zDSGTz9kww7t3F0XGw==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/yocto-spinner/-/yocto-spinner-1.2.1.tgz",
+ "integrity": "sha512-9cbFWLhbiZp+820O4pkHGNncI7+MrUGzBOjw8NMG+ewsY+aG0DdEXnr19Smxao32YOjLZRMdn1UtaxcrXOYOIg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"yoctocolors": "^2.1.1"
@@ -14769,6 +14924,7 @@
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz",
"integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
@@ -14790,6 +14946,7 @@
"version": "3.25.2",
"resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.2.tgz",
"integrity": "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==",
+ "dev": true,
"license": "ISC",
"peerDependencies": {
"zod": "^3.25.28 || ^4"
diff --git a/package.json b/package.json
index 862fe05..b5aef22 100644
--- a/package.json
+++ b/package.json
@@ -17,7 +17,6 @@
"@monaco-editor/react": "^4.7.0",
"@supabase/ssr": "^0.12.0",
"@supabase/supabase-js": "^2.108.2",
- "@types/three": "^0.185.0",
"@upstash/ratelimit": "^2.0.8",
"@upstash/redis": "^1.38.0",
"acorn-typescript": "^1.4.13",
@@ -30,15 +29,12 @@
"mermaid": "^11.15.0",
"nanoid": "^5.1.16",
"next": "^16.2.10",
- "next-themes": "^0.4.6",
"react": "^18",
"react-dom": "^18",
"react-resizable-panels": "^4.11.2",
- "shadcn": "^4.11.0",
"tailwind-merge": "^3.6.0",
"tailwindcss-animate": "^1.0.7",
"three": "^0.185.0",
- "tw-animate-css": "^1.4.0",
"vaul": "^1.1.2",
"zod": "^4.4.3"
},
@@ -53,11 +49,13 @@
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
+ "@types/three": "^0.185.1",
"dotenv": "^17.4.2",
"eslint": "^9",
"eslint-config-next": "^16.2.10",
"jest": "^30.4.2",
"postcss": "^8",
+ "shadcn": "^4.13.0",
"tailwindcss": "^3.4.1",
"ts-jest": "^29.4.11",
"typescript": "^5"